diff --git a/include/curves/bezier_curve.h b/include/curves/bezier_curve.h
index 36eb7e1a63f54a35576b1e6795b13b24c41ac0ff..ee15b7df95578a3f63efefa9e9ddad0f120f2862 100644
--- a/include/curves/bezier_curve.h
+++ b/include/curves/bezier_curve.h
@@ -39,8 +39,10 @@ struct bezier_curve : public curve_abc<Time, Numeric, Safe, Point> {
   typedef std::vector<point_t, Eigen::aligned_allocator<point_t> > t_point_t;
   typedef typename t_point_t::const_iterator cit_point_t;
   typedef bezier_curve<Time, Numeric, Safe, Point> bezier_curve_t;
-  typedef piecewise_curve<Time, Numeric, Safe, point_t, t_point_t, bezier_curve_t> piecewise_bezier_curve_t;
+  typedef boost::shared_ptr<bezier_curve_t> bezier_curve_ptr_t;
+  typedef piecewise_curve<Time, Numeric, Safe, point_t> piecewise_curve_t;
   typedef curve_abc<Time, Numeric, Safe, point_t> curve_abc_t;  // parent class
+  typedef typename curve_abc_t::curve_ptr_t curve_ptr_t;
 
   /* Constructors - destructors */
  public:
@@ -158,6 +160,13 @@ struct bezier_curve : public curve_abc<Time, Numeric, Safe, Point> {
     return deriv.compute_derivate(order - 1);
   }
 
+  ///  \brief Compute the derived curve at order N.
+  ///  \param order : order of derivative.
+  ///  \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve.
+  bezier_curve_t* compute_derivate_ptr(const std::size_t order) const {
+    return new bezier_curve_t(compute_derivate(order));
+  }
+
   ///  \brief Compute the primitive of the curve at order N.
   ///  Computes the primitive at order N of bezier curve of parametric equation \f$x(t)\f$. <br>
   ///  At order \f$N=1\f$, the primitve \f$X(t)\f$ of \f$x(t)\f$ is such as \f$\frac{dX(t)}{dt} = x(t)\f$.
@@ -190,8 +199,7 @@ struct bezier_curve : public curve_abc<Time, Numeric, Safe, Point> {
   ///  \return \f$\frac{d^Nx(t)}{dt^N}\f$ point corresponding on derived curve of order N at time t.
   ///
   virtual point_t derivate(const time_t t, const std::size_t order) const {
-    bezier_curve_t deriv = compute_derivate(order);
-    return deriv(t);
+    return compute_derivate(order)(t);
   }
 
   /// \brief Evaluate all Bernstein polynomes for a certain degree.
@@ -325,12 +333,12 @@ struct bezier_curve : public curve_abc<Time, Numeric, Safe, Point> {
   }
 
   /// \brief Split the bezier curve in several curves, all accessible
-  /// within a piecewise_bezier_curve_t.
+  /// within a piecewise_curve_t.
   /// \param times : list of times of size n.
-  /// \return a piecewise_bezier_curve_t comprising n+1 curves
+  /// \return a piecewise_curve_t comprising n+1 curves
   ///
-  piecewise_bezier_curve_t split(const vector_x_t& times) const {
-    typename piecewise_bezier_curve_t::t_curve_t curves;
+  piecewise_curve_t split(const vector_x_t& times) const {
+    std::vector<bezier_curve_t> curves;
     bezier_curve_t current = *this;
     for (int i = 0; i < times.rows(); ++i) {
       std::pair<bezier_curve_t, bezier_curve_t> pairsplit = current.split(times[i]);
@@ -338,7 +346,12 @@ struct bezier_curve : public curve_abc<Time, Numeric, Safe, Point> {
       current = pairsplit.second;
     }
     curves.push_back(current);
-    return piecewise_bezier_curve_t(curves);
+    piecewise_curve_t res;
+    for(typename std::vector<bezier_curve_t>::const_iterator cit = curves.begin(); cit != curves.end() ; ++cit){
+      typename piecewise_curve_t::curve_ptr_t ptr(new bezier_curve_t(*cit));
+      res.add_curve_ptr(ptr);
+    }
+    return res;
   }
 
   /// \brief Extract a bezier curve defined between \f$[t_1,t_2]\f$ from the actual bezier curve
@@ -414,6 +427,9 @@ struct bezier_curve : public curve_abc<Time, Numeric, Safe, Point> {
   /// \brief Get the maximum time for which the curve is defined.
   /// \return \f$t_{max}\f$, upper bound of time range.
   virtual time_t max() const { return T_max_; }
+  /// \brief Get the degree of the curve.
+  /// \return \f$degree\f$, the degree of the curve.
+  virtual std::size_t  degree() const {return degree_;}
   /*Helpers*/
 
   /* Attributes */
diff --git a/include/curves/cubic_hermite_spline.h b/include/curves/cubic_hermite_spline.h
index 79a7a9b76643d931bec3e141832d47b53a58efcf..e7c7efe0d668dbccb6d7f450936bcb38db3f7eb3 100644
--- a/include/curves/cubic_hermite_spline.h
+++ b/include/curves/cubic_hermite_spline.h
@@ -39,6 +39,7 @@ struct cubic_hermite_spline : public curve_abc<Time, Numeric, Safe, Point> {
   typedef std::vector<Time> vector_time_t;
   typedef Numeric num_t;
   typedef curve_abc<Time, Numeric, Safe, point_t> curve_abc_t;  // parent class
+  typedef cubic_hermite_spline<Time, Numeric, Safe, point_t> cubic_hermite_spline_t;
 
 
  public:
@@ -112,6 +113,19 @@ struct cubic_hermite_spline : public curve_abc<Time, Numeric, Safe, Point> {
     return evalCubicHermiteSpline(t, order);
   }
 
+  cubic_hermite_spline_t compute_derivate(const std::size_t /*order*/) const {
+    throw std::logic_error("Compute derivate for cubic hermite spline is not implemented yet.");
+  }
+
+  ///  \brief Compute the derived curve at order N.
+  ///  \param order : order of derivative.
+  ///  \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve.
+  cubic_hermite_spline_t* compute_derivate_ptr(const std::size_t order) const {
+    return new cubic_hermite_spline_t(compute_derivate(order));
+  }
+
+
+
   /// \brief Set time of each control point of cubic hermite spline.
   /// Set duration of each spline, Exemple : \f$( 0., 0.5, 0.9, ..., 4.5 )\f$ with
   /// values corresponding to times for \f$P_0, P_1, P_2, ..., P_N\f$ respectively.<br>
@@ -325,6 +339,9 @@ struct cubic_hermite_spline : public curve_abc<Time, Numeric, Safe, Point> {
   /// \brief Get the maximum time for which the curve is defined.
   /// \return \f$t_{max}\f$, upper bound of time range.
   Time virtual max() const { return time_control_points_.back(); }
+  /// \brief Get the degree of the curve.
+  /// \return \f$degree\f$, the degree of the curve.
+  virtual std::size_t  degree() const {return degree_;}
   /*Helpers*/
 
   /*Attributes*/
diff --git a/include/curves/curve_abc.h b/include/curves/curve_abc.h
index acfa3c78dbe59c79098af133a1a366fa7a608cb2..72a2e31a8061439ba75db285532c3e8dcb6454cd 100644
--- a/include/curves/curve_abc.h
+++ b/include/curves/curve_abc.h
@@ -15,6 +15,7 @@
 #include "serialization/archive.hpp"
 #include "serialization/eigen-matrix.hpp"
 #include <boost/serialization/shared_ptr.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
 
 #include <functional>
 
@@ -28,6 +29,8 @@ struct curve_abc : std::unary_function<Time, Point>, public serialization::Seria
   typedef Point point_t;
   typedef Point_derivate point_derivate_t;
   typedef Time time_t;
+  typedef curve_abc<Time, Numeric, Safe, point_t,point_derivate_t> curve_t; // parent class
+  typedef boost::shared_ptr<curve_t> curve_ptr_t;
 
   /* Constructors - destructors */
  public:
@@ -44,12 +47,19 @@ struct curve_abc : std::unary_function<Time, Point>, public serialization::Seria
   ///  \return \f$x(t)\f$, point corresponding on curve at time t.
   virtual point_t operator()(const time_t t) const = 0;
 
+
+  ///  \brief Compute the derived curve at order N.
+  ///  \param order : order of derivative.
+  ///  \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve.
+  virtual curve_t* compute_derivate_ptr(const std::size_t order) const = 0;
+
   /// \brief Evaluate the derivative of order N of curve at time t.
   /// \param t : time when to evaluate the spline.
   /// \param order : order of derivative.
   /// \return \f$\frac{d^Nx(t)}{dt^N}\f$, point corresponding on derivative curve of order N at time t.
   virtual point_derivate_t derivate(const time_t t, const std::size_t order) const = 0;
 
+
   /*Operations*/
 
   /*Helpers*/
@@ -62,6 +72,10 @@ struct curve_abc : std::unary_function<Time, Point>, public serialization::Seria
   /// \brief Get the maximum time for which the curve is defined.
   /// \return \f$t_{max}\f$, upper bound of time range.
   virtual time_t max() const = 0;
+  /// \brief Get the degree of the curve.
+  /// \return \f$degree\f$, the degree of the curve.
+  virtual std::size_t  degree() const =0;
+
   std::pair<time_t, time_t> timeRange() { return std::make_pair(min(), max()); }
   /*Helpers*/
 
diff --git a/include/curves/curve_conversion.h b/include/curves/curve_conversion.h
index 3bb3a434bb313053bf8399dad4fb10455f8e14f7..194eac1a156a2ee2ad23ffa2c16b431c4ba49914 100644
--- a/include/curves/curve_conversion.h
+++ b/include/curves/curve_conversion.h
@@ -16,38 +16,38 @@ namespace curves {
 /// \brief Converts a cubic hermite spline or a bezier curve to a polynomial.
 /// \param curve   : the bezier curve/cubic hermite spline defined between [Tmin,Tmax] to convert.
 /// \return the equivalent polynomial.
-template <typename Polynomial, typename curveTypeToConvert>
-Polynomial polynomial_from_curve(const curveTypeToConvert& curve) {
+template <typename Polynomial>
+Polynomial polynomial_from_curve(const typename Polynomial::curve_abc_t& curve) {
   typedef typename Polynomial::t_point_t t_point_t;
   typedef typename Polynomial::num_t num_t;
   t_point_t coefficients;
-  curveTypeToConvert current(curve);
   coefficients.push_back(curve(curve.min()));
   num_t fact = 1;
-  for (std::size_t i = 1; i <= curve.degree_; ++i) {
+  for (std::size_t i = 1; i <= curve.degree(); ++i) {
     fact *= (num_t)i;
-    coefficients.push_back(current.derivate(current.min(), i) / fact);
+    coefficients.push_back(curve.derivate(curve.min(), i) / fact);
   }
+
+
   return Polynomial(coefficients, curve.min(), curve.max());
 }
 
 /// \brief Converts a cubic hermite spline or polynomial of order 3 or less to a cubic bezier curve.
 /// \param curve   : the polynomial of order 3 or less/cubic hermite spline defined between [Tmin,Tmax] to convert.
 /// \return the equivalent cubic bezier curve.
-template <typename Bezier, typename curveTypeToConvert>
-Bezier bezier_from_curve(const curveTypeToConvert& curve) {
+template <typename Bezier>
+Bezier bezier_from_curve(const typename Bezier::curve_abc_t& curve) {
   typedef typename Bezier::point_t point_t;
   typedef typename Bezier::t_point_t t_point_t;
   typedef typename Bezier::num_t num_t;
-  curveTypeToConvert current(curve);
-  num_t T_min = current.min();
-  num_t T_max = current.max();
+  num_t T_min = curve.min();
+  num_t T_max = curve.max();
   num_t T = T_max - T_min;
   // Positions and derivatives
-  point_t p0 = current(T_min);
-  point_t p1 = current(T_max);
-  point_t m0 = current.derivate(T_min, 1);
-  point_t m1 = current.derivate(T_max, 1);
+  point_t p0 = curve(T_min);
+  point_t p1 = curve(T_max);
+  point_t m0 = curve.derivate(T_min, 1);
+  point_t m1 = curve.derivate(T_max, 1);
   // Convert to bezier control points
   // for t in [Tmin,Tmax] and T=Tmax-Tmin : x'(0)=3(b_p1-b_p0)/T and x'(1)=3(b_p3-b_p2)/T
   // so : m0=3(b_p1-b_p0)/T and m1=3(b_p3-b_p2)/T
@@ -61,26 +61,25 @@ Bezier bezier_from_curve(const curveTypeToConvert& curve) {
   control_points.push_back(b_p1);
   control_points.push_back(b_p2);
   control_points.push_back(b_p3);
-  return Bezier(control_points.begin(), control_points.end(), current.min(), current.max());
+  return Bezier(control_points.begin(), control_points.end(), curve.min(), curve.max());
 }
 
 /// \brief Converts a polynomial of order 3 or less/cubic bezier curve to a cubic hermite spline.
 /// \param curve   : the polynomial of order 3 or less/cubic bezier curve defined between [Tmin,Tmax] to convert.
 /// \return the equivalent cubic hermite spline.
-template <typename Hermite, typename curveTypeToConvert>
-Hermite hermite_from_curve(const curveTypeToConvert& curve) {
+template <typename Hermite>
+Hermite hermite_from_curve(const typename Hermite::curve_abc_t& curve) {
   typedef typename Hermite::pair_point_tangent_t pair_point_tangent_t;
   typedef typename Hermite::t_pair_point_tangent_t t_pair_point_tangent_t;
   typedef typename Hermite::point_t point_t;
   typedef typename Hermite::num_t num_t;
-  curveTypeToConvert current(curve);
-  num_t T_min = current.min();
-  num_t T_max = current.max();
+  num_t T_min = curve.min();
+  num_t T_max = curve.max();
   // Positions and derivatives
-  point_t p0 = current(T_min);
-  point_t p1 = current(T_max);
-  point_t m0 = current.derivate(T_min, 1);
-  point_t m1 = current.derivate(T_max, 1);
+  point_t p0 = curve(T_min);
+  point_t p1 = curve(T_max);
+  point_t m0 = curve.derivate(T_min, 1);
+  point_t m1 = curve.derivate(T_max, 1);
   // Create pairs pos/vel
   pair_point_tangent_t pair0(p0, m0);
   pair_point_tangent_t pair1(p1, m1);
diff --git a/include/curves/exact_cubic.h b/include/curves/exact_cubic.h
index 4991067286d775d4fbd7bf10389b125fb48b7096..994c9604625a580c6b04394315a0bf0e3d4975bf 100644
--- a/include/curves/exact_cubic.h
+++ b/include/curves/exact_cubic.h
@@ -39,7 +39,7 @@ template <typename Time = double, typename Numeric = Time, bool Safe = false,
           typename Point = Eigen::Matrix<Numeric, Eigen::Dynamic, 1>,
           typename T_Point = std::vector<Point, Eigen::aligned_allocator<Point> >,
           typename SplineBase = polynomial<Time, Numeric, Safe, Point, T_Point> >
-struct exact_cubic : public piecewise_curve<Time, Numeric, Safe, Point, T_Point, SplineBase> {
+struct exact_cubic : public piecewise_curve<Time, Numeric, Safe, Point> {
   typedef Point point_t;
   typedef T_Point t_point_t;
   typedef Eigen::Matrix<Numeric, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
@@ -53,8 +53,9 @@ struct exact_cubic : public piecewise_curve<Time, Numeric, Safe, Point, T_Point,
   typedef curve_constraints<Point> spline_constraints;
 
   typedef exact_cubic<Time, Numeric, Safe, Point, T_Point, SplineBase> exact_cubic_t;
-  typedef piecewise_curve<Time, Numeric, Safe, Point, T_Point, SplineBase> piecewise_curve_t;
   typedef curve_abc<Time, Numeric, Safe, point_t> curve_abc_t;  // parent class
+  typedef piecewise_curve<Time, Numeric, Safe, Point> piecewise_curve_t;
+  typedef typename piecewise_curve_t::t_curve_ptr_t t_curve_ptr_t;
 
   /* Constructors - destructors */
  public:
@@ -68,7 +69,13 @@ struct exact_cubic : public piecewise_curve<Time, Numeric, Safe, Point, T_Point,
   ///
   template <typename In>
   exact_cubic(In wayPointsBegin, In wayPointsEnd)
-      : piecewise_curve_t(computeWayPoints<In>(wayPointsBegin, wayPointsEnd)) {}
+      : piecewise_curve_t()
+  {
+    t_spline_t subSplines = computeWayPoints<In>(wayPointsBegin, wayPointsEnd);
+    for (cit_spline_t it = subSplines.begin() ; it != subSplines.end() ; ++it){
+      this->add_curve(*it);
+    }
+  }
 
   /// \brief Constructor.
   /// \param wayPointsBegin : an iterator pointing to the first element of a waypoint container.
@@ -77,11 +84,24 @@ struct exact_cubic : public piecewise_curve<Time, Numeric, Safe, Point, T_Point,
   ///
   template <typename In>
   exact_cubic(In wayPointsBegin, In wayPointsEnd, const spline_constraints& constraints)
-      : piecewise_curve_t(computeWayPoints<In>(wayPointsBegin, wayPointsEnd, constraints)) {}
+      : piecewise_curve_t()
+  {
+    t_spline_t subSplines = computeWayPoints<In>(wayPointsBegin, wayPointsEnd,constraints);
+    for (cit_spline_t it = subSplines.begin() ; it != subSplines.end() ; ++it){
+      this->add_curve(*it);
+    }
+  }
 
   /// \brief Constructor.
   /// \param subSplines: vector of subSplines.
-  exact_cubic(const t_spline_t& subSplines) : piecewise_curve_t(subSplines) {}
+  exact_cubic(const t_spline_t& subSplines) : piecewise_curve_t()
+  {
+    for (cit_spline_t it = subSplines.begin() ; it != subSplines.end() ; ++it){
+      this->add_curve(*it);
+    }
+  }
+
+  exact_cubic(const t_curve_ptr_t& subSplines) : piecewise_curve_t(subSplines)  { }
 
   /// \brief Copy Constructor.
   exact_cubic(const exact_cubic& other) : piecewise_curve_t(other) {}
@@ -91,7 +111,13 @@ struct exact_cubic : public piecewise_curve<Time, Numeric, Safe, Point, T_Point,
 
   std::size_t getNumberSplines() { return this->getNumberCurves(); }
 
-  spline_t getSplineAt(std::size_t index) { return this->curves_.at(index); }
+  spline_t getSplineAt(std::size_t index) {
+    boost::shared_ptr<spline_t> s_ptr = boost::dynamic_pointer_cast<spline_t>(this->curves_.at(index));
+    if(s_ptr)
+      return *s_ptr;
+    else
+      throw std::runtime_error("Parent piecewise curve do not contain only curves created from exact_cubic class methods");
+  }
 
  private:
   /// \brief Compute polynom of exact cubic spline from waypoints.
diff --git a/include/curves/fwd.h b/include/curves/fwd.h
index 78098e0882f7d165b90c32cd1dd0fdf810a78041..da951b88b335843b00a1e537a59f7008faeef3d9 100644
--- a/include/curves/fwd.h
+++ b/include/curves/fwd.h
@@ -9,6 +9,9 @@
 
 #ifndef CURVES_FWD_H
 #define CURVES_FWD_H
+#include <Eigen/Dense>
+#include <vector>
+#include <boost/smart_ptr/shared_ptr.hpp>
 
 namespace curves {
 
@@ -21,12 +24,12 @@ template <typename Time, typename Numeric, bool Safe,typename Point >
 template <typename Time, typename Numeric, bool Safe,typename Point >
   struct cubic_hermite_spline;
 
-template <typename Time, typename Numeric, bool Safe, typename Point ,
-            typename T_Point , typename SplineBase >
+template <typename Time, typename Numeric, bool Safe, typename Point,
+          typename T_Point,typename SplineBase >
   struct exact_cubic;
 
 template <typename Time, typename Numeric, bool Safe, typename Point,
-            typename T_Point, typename Curve, typename Point_derivate>
+            typename Point_derivate>
   struct piecewise_curve;
 
 template <typename Time, typename Numeric, bool Safe,typename Point, typename T_Point>
@@ -49,6 +52,50 @@ template <typename Numeric, bool Safe>
 
 template <typename Numeric>
   struct quadratic_variable;
+
+// typedef of the commonly used templates arguments :
+// eigen types :
+typedef Eigen::Vector3d point3_t;
+typedef Eigen::Matrix<double, 6, 1> point6_t;
+typedef Eigen::VectorXd pointX_t;
+typedef Eigen::Matrix<double, 3, 3> matrix3_t;
+typedef Eigen::Matrix<double, 4, 4> matrix4_t;
+typedef Eigen::Quaternion<double> quaternion_t;
+typedef Eigen::Transform<double, 3, Eigen::Affine> transform_t;
+typedef std::vector<pointX_t, Eigen::aligned_allocator<point3_t> > t_point3_t;
+typedef std::vector<pointX_t, Eigen::aligned_allocator<pointX_t> > t_pointX_t;
+
+// abstract curves types:
+typedef curve_abc<double, double, true, pointX_t,pointX_t> curve_abc_t; // base abstract class
+typedef curve_abc<double, double, true, point3_t,point3_t> curve_3_t;    // generic class of curve of size 3
+typedef curve_abc<double, double, true, matrix3_t, point3_t> curve_rotation_t;  // templated class used for the rotation (return dimension are fixed)
+typedef curve_abc<double, double, true, transform_t, point6_t> curve_SE3_t;  // templated abstract class used for all the se3 curves (return dimension are fixed)
+
+// shared pointer to abstract types:
+typedef boost::shared_ptr<curve_abc_t> curve_ptr_t;
+typedef boost::shared_ptr<curve_3_t> curve3_ptr_t;
+typedef boost::shared_ptr<curve_rotation_t> curve_rotation_ptr_t;
+typedef boost::shared_ptr<curve_SE3_t> curve_SE3_ptr_t;
+
+// definition of all curves class with pointX as return type:
+typedef polynomial<double, double, true, pointX_t, t_pointX_t> polynomial_t;
+typedef exact_cubic<double, double, true, pointX_t,t_pointX_t, polynomial_t> exact_cubic_t;
+typedef bezier_curve<double, double, true, pointX_t> bezier_t;
+typedef cubic_hermite_spline<double, double, true, pointX_t> cubic_hermite_spline_t;
+typedef piecewise_curve <double, double, true, pointX_t,pointX_t> piecewise_t;
+
+// definition of all curves class with point3 as return type:
+typedef polynomial<double, double, true, point3_t, t_point3_t> polynomial3_t;
+typedef exact_cubic<double, double, true, point3_t,t_point3_t, polynomial_t> exact_cubic3_t;
+typedef bezier_curve<double, double, true, point3_t> bezier3_t;
+typedef cubic_hermite_spline<double, double, true, point3_t> cubic_hermite_spline3_t;
+typedef piecewise_curve <double, double, true, point3_t,point3_t> piecewise3_t;
+
+// special curves with return type fixed:
+typedef SO3Linear<double, double, true> SO3Linear_t;
+typedef SE3Curve<double, double, true> SE3Curve_t;
+typedef piecewise_curve <double, double, true,  transform_t, point6_t> piecewise_SE3_t;
+
 }
 
 #endif // CURVES_FWD_H
diff --git a/include/curves/helpers/effector_spline.h b/include/curves/helpers/effector_spline.h
index 383398d8e7e949911285c6b01076a61356d7f465..764d99f1150bb5139be6be48727a3baed781823e 100644
--- a/include/curves/helpers/effector_spline.h
+++ b/include/curves/helpers/effector_spline.h
@@ -102,9 +102,8 @@ exact_cubic_t* effector_spline(In wayPointsBegin, In wayPointsEnd, const Point&
   spline_t end_spline =
       make_end_spline(land_normal, landWaypoint.second, land_offset, landWaypoint.first, land_offset_duration);
   spline_constraints_t constraints = compute_required_offset_velocity_acceleration(end_spline, land_offset_duration);
-  exact_cubic_t all_but_end(waypoints.begin(), waypoints.end(), constraints);
-  t_spline_t splines = all_but_end.curves_;
-  splines.push_back(end_spline);
+  exact_cubic_t splines(waypoints.begin(), waypoints.end(), constraints);
+  splines.add_curve(end_spline);
   return new exact_cubic_t(splines);
 }
 }  // namespace helpers
diff --git a/include/curves/helpers/effector_spline_rotation.h b/include/curves/helpers/effector_spline_rotation.h
index aaf06d6649f0a4b88aa7d8f152e1506aae56c191..fed827998439c6e93ff9bcbd4ee02ce826168773 100644
--- a/include/curves/helpers/effector_spline_rotation.h
+++ b/include/curves/helpers/effector_spline_rotation.h
@@ -76,6 +76,14 @@ class rotation_spline : public curve_abc_quat_t {
     throw std::runtime_error("TODO quaternion spline does not implement derivate");
   }
 
+  ///  \brief Compute the derived curve at order N.
+  ///  \param order : order of derivative.
+  ///  \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve.
+  curve_abc_quat_t* compute_derivate_ptr(const std::size_t /*order*/) const {
+    throw std::logic_error("Compute derivate for quaternion spline is not implemented yet.");
+  }
+
+
   /// \brief Initialize time reparametrization for spline.
   exact_cubic_constraint_one_dim computeWayPoints() const {
     t_waypoint_one_dim_t waypoints;
@@ -87,6 +95,9 @@ class rotation_spline : public curve_abc_quat_t {
   virtual std::size_t dim() const { return dim_; }
   virtual time_t min() const { return min_; }
   virtual time_t max() const { return max_; }
+  /// \brief Get the degree of the curve.
+  /// \return \f$degree\f$, the degree of the curve.
+  virtual std::size_t  degree() const {return 1;}
 
   /*Attributes*/
   Eigen::Quaterniond quat_from_;                 // const
diff --git a/include/curves/optimization/integral_cost.h b/include/curves/optimization/integral_cost.h
index 28f92079046e74a977d0e0d534754d826e084004..dc5c5ce4cf9cea3357398c95c48bc0fb1c5dc6a8 100644
--- a/include/curves/optimization/integral_cost.h
+++ b/include/curves/optimization/integral_cost.h
@@ -34,7 +34,8 @@ quadratic_variable<Numeric> compute_integral_cost_internal(const problem_data<Po
   typedef typename t_point_t::const_iterator cit_point_t;
   bezier_t acc = pData.bezier->compute_derivate(num_derivate);
   const t_point_t& wps = acc.waypoints();
-  return bezier_product<Point, Numeric, cit_point_t>(wps.begin(), wps.end(), wps.begin(), wps.end(), pData.dim_);
+  quadratic_variable<Numeric> res(bezier_product<Point, Numeric, cit_point_t>(wps.begin(), wps.end(), wps.begin(), wps.end(), pData.dim_));
+  return res;
 }
 
 template <typename Point, typename Numeric>
diff --git a/include/curves/piecewise_curve.h b/include/curves/piecewise_curve.h
index c6b75d969c3123aaca8ac86943448ee2727a4bf3..359d21819fe5f97ade311dd4ecaf49ceeebbbb0c 100644
--- a/include/curves/piecewise_curve.h
+++ b/include/curves/piecewise_curve.h
@@ -10,6 +10,8 @@
 
 #include "curve_abc.h"
 #include "curve_conversion.h"
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/serialization/vector.hpp>
 
 namespace curves {
 /// \class PiecewiseCurve.
@@ -23,21 +25,19 @@ namespace curves {
 ///
 template <typename Time = double, typename Numeric = Time, bool Safe = false,
           typename Point = Eigen::Matrix<Numeric, Eigen::Dynamic, 1>,
-          typename T_Point = std::vector<Point, Eigen::aligned_allocator<Point> >,
-          typename Curve = curve_abc<Time, Numeric, Safe, Point>,
           typename Point_derivate = Point >
 struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_derivate> {
   typedef Point point_t;
-  typedef T_Point t_point_t;
-  typedef Point_derivate point_derivate_t;
+  typedef Point_derivate   point_derivate_t;
+  typedef std::vector<point_t, Eigen::aligned_allocator<point_t> > t_point_t;
+  typedef std::vector<point_derivate_t, Eigen::aligned_allocator<point_derivate_t> > t_point_derivate_t;
   typedef Time time_t;
   typedef Numeric num_t;
-  typedef Curve curve_t;
-  typedef typename std::vector<curve_t> t_curve_t;
+  typedef curve_abc<Time, Numeric, Safe, point_t,point_derivate_t> curve_t; // parent class
+  typedef boost::shared_ptr<curve_t> curve_ptr_t;
+  typedef typename std::vector<curve_ptr_t> t_curve_ptr_t;
   typedef typename std::vector<Time> t_time_t;
-  typedef curve_abc<Time, Numeric, Safe, point_t,point_derivate_t> curve_abc_t;  // parent class
-
-
+  typedef piecewise_curve<Time, Numeric, Safe, Point,Point_derivate> piecewise_curve_t;
  public:
   /// \brief Empty constructor. Add at least one curve to call other class functions.
   ///
@@ -47,19 +47,17 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
   /// Initialize a piecewise curve by giving the first curve.
   /// \param cf   : a curve.
   ///
-  piecewise_curve(const curve_t& cf) {
-    dim_ = cf.dim();
-    size_ = 0;
-    add_curve(cf);
+  piecewise_curve(const curve_ptr_t& cf):
+    dim_(0), size_(0), T_min_(0), T_max_(0)
+  {
+    add_curve_ptr(cf);
   }
 
-  piecewise_curve(const t_curve_t list_curves) {
-    if (list_curves.size() != 0) {
-      dim_ = list_curves[0].dim();
-    }
-    size_ = 0;
-    for (std::size_t i = 0; i < list_curves.size(); i++) {
-      add_curve(list_curves[i]);
+  piecewise_curve(const t_curve_ptr_t& curves_list):
+    dim_(0), size_(0), T_min_(0), T_max_(0)
+  {
+    for(typename t_curve_ptr_t::const_iterator it = curves_list.begin() ; it != curves_list.end() ; ++it){
+      add_curve_ptr(*it);
     }
   }
 
@@ -73,13 +71,13 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
 
   virtual ~piecewise_curve() {}
 
-  virtual Point operator()(const Time t) const {
+  virtual point_t operator()(const Time t) const {
     check_if_not_empty();
     if (Safe & !(T_min_ <= t && t <= T_max_)) {
       // std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<" t="<<t<<std::endl;
       throw std::out_of_range("can't evaluate piecewise curve, out of range");
     }
-    return curves_.at(find_interval(t))(t);
+    return (*curves_.at(find_interval(t)))(t);
   }
 
   ///  \brief Evaluate the derivative of order N of curve at time t.
@@ -92,7 +90,7 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
     if (Safe & !(T_min_ <= t && t <= T_max_)) {
       throw std::invalid_argument("can't evaluate piecewise curve, out of range");
     }
-    return (curves_.at(find_interval(t))).derivate(t, order);
+    return (*curves_.at(find_interval(t))).derivate(t, order);
   }
 
   /**
@@ -100,44 +98,54 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
    * @param order order of derivative
    * @return
    */
-  piecewise_curve<Time, Numeric, Safe, point_derivate_t, std::vector<point_derivate_t, Eigen::aligned_allocator<Point> >, Curve> compute_derivate(const std::size_t order) const {
-    piecewise_curve<Time, Numeric, Safe, point_derivate_t,  std::vector<point_derivate_t, Eigen::aligned_allocator<Point> >, Curve> res;
-    for (typename t_curve_t::const_iterator itc = curves_.begin(); itc < curves_.end(); ++itc) {
-      res.add_curve(itc->compute_derivate(order));
+  piecewise_curve_t* compute_derivate_ptr(const std::size_t order) const {
+    piecewise_curve_t* res(new piecewise_curve_t());
+    for (typename t_curve_ptr_t::const_iterator itc = curves_.begin(); itc < curves_.end(); ++itc) {
+      curve_ptr_t ptr((*itc)->compute_derivate_ptr(order));
+      res->add_curve_ptr(ptr);
     }
     return res;
   }
 
+
+  template <typename Curve>
+  void add_curve(const Curve& curve) {
+    curve_ptr_t curve_ptr = boost::make_shared<Curve>(curve);
+    add_curve_ptr(curve_ptr);
+  }
+
   ///  \brief Add a new curve to piecewise curve, which should be defined in \f$[T_{min},T_{max}]\f$ where
   ///  \f$T_{min}\f$
   ///         is equal to \f$T_{max}\f$ of the actual piecewise curve. The curve added should be of type Curve as
   ///         defined in the template.
   ///  \param cf : curve to add.
   ///
-  void add_curve(const curve_t& cf) {
-    if (size_ == 0 && dim_ == 0) { // first curve added
-      dim_ = cf.dim();
+  void add_curve_ptr(const curve_ptr_t& cf) {
+    if (size_ == 0) { // first curve added
+      dim_ = cf->dim();
     }
     // Check time continuity : Beginning time of cf must be equal to T_max_ of actual piecewise curve.
-    if (size_ != 0 && !(fabs(cf.min() - T_max_) < MARGIN)) {
-      throw std::invalid_argument(
-          "Can not add new Polynom to PiecewiseCurve : time discontinuity between T_max_ and pol.min()");
+    if (size_ != 0 && !(fabs(cf->min() - T_max_) < MARGIN)) {
+      std::stringstream ss; ss <<  "Can not add new Polynom to PiecewiseCurve : time discontinuity between T_max_ and pol.min(). Current T_max is "<<T_max_<<" new curve min is "<<cf->min();
+      throw std::invalid_argument(ss.str().c_str());
     }
-    if(cf.dim() != dim_){
-      throw std::invalid_argument(
-          "All the curves in a piecewiseCurve should have the same dimension");
+    if(cf->dim() != dim_){
+      std::stringstream ss; ss << "All the curves in a piecewiseCurve should have the same dimension. Current dim is "<<dim_<<" dim of the new curve is "<<cf->dim();
+      throw std::invalid_argument(ss.str().c_str());
     }
     curves_.push_back(cf);
     size_ = curves_.size();
-    T_max_ = cf.max();
+    T_max_ = cf->max();
     if (size_ == 1) {
       // First curve added
-      time_curves_.push_back(cf.min());
-      T_min_ = cf.min();
+      time_curves_.push_back(cf->min());
+      T_min_ = cf->min();
     }
     time_curves_.push_back(T_max_);
   }
 
+
+
   ///  \brief Check if the curve is continuous of order given.
   ///  \param order : order of continuity we want to check.
   ///  \return True if the curve is continuous of order given.
@@ -149,10 +157,10 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
     if(order ==0){
       point_t value_end, value_start;
       while (isContinuous && i < (size_ - 1)) {
-        curve_t current = curves_.at(i);
-        curve_t next = curves_.at(i + 1);
-        value_end = current(current.max());
-        value_start = next(next.min());
+        curve_ptr_t current = curves_.at(i);
+        curve_ptr_t next = curves_.at(i + 1);
+        value_end = (*current)(current->max());
+        value_start = (*next)(next->min());
         if (!value_end.isApprox(value_start,MARGIN)) {
           isContinuous = false;
         }
@@ -161,10 +169,10 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
     }else{
       point_derivate_t value_end, value_start;
       while (isContinuous && i < (size_ - 1)) {
-        curve_t current = curves_.at(i);
-        curve_t next = curves_.at(i + 1);
-        value_end = current.derivate(current.max(), order);
-        value_start = next.derivate(next.min(), order);
+        curve_ptr_t current = curves_.at(i);
+        curve_ptr_t next = curves_.at(i + 1);
+        value_end = current->derivate(current->max(), order);
+        value_start = next->derivate(next->min(), order);
         if (!value_end.isApprox(value_start,MARGIN)) {
           isContinuous = false;
         }
@@ -176,9 +184,9 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
 
   std::size_t num_curves() const { return curves_.size(); }
 
-  const curve_t& curve_at_time(const time_t t) const { return curves_[find_interval(t)]; }
+  const curve_ptr_t& curve_at_time(const time_t t) const { return curves_[find_interval(t)]; }
 
-  const curve_t& curve_at_index(const std::size_t idx) const {
+  const curve_ptr_t& curve_at_index(const std::size_t idx) const {
     if (Safe && idx >= num_curves()) {
       throw std::length_error(
           "curve_at_index: requested index greater than number of curves in piecewise_curve instance");
@@ -187,56 +195,54 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
   }
 
   template <typename Bezier>
-  piecewise_curve<Time, Numeric, Safe, Point, T_Point, Bezier> convert_piecewise_curve_to_bezier() {
+  piecewise_curve_t convert_piecewise_curve_to_bezier() {
     check_if_not_empty();
-    typedef piecewise_curve<Time, Numeric, Safe, Point, T_Point, Bezier> piecewise_curve_out_t;
-    // Get first curve (segment)
-    curve_t first_curve = curves_.at(0);
-    Bezier first_curve_output = bezier_from_curve<Bezier, curve_t>(first_curve);
+    // check if given Bezier curve have the correct dimension :
+    BOOST_STATIC_ASSERT(boost::is_same<typename Bezier::point_t, point_t>::value);
+    BOOST_STATIC_ASSERT(boost::is_same<typename Bezier::point_derivate_t, point_derivate_t>::value);
     // Create piecewise curve
-    piecewise_curve_out_t pc_res(first_curve_output);
+    piecewise_curve_t pc_res;
     // Convert and add all other curves (segments)
-    for (std::size_t i = 1; i < size_; i++) {
-      pc_res.add_curve(bezier_from_curve<Bezier, curve_t>(curves_.at(i)));
+    for (std::size_t i = 0; i < size_; i++) {
+      pc_res.add_curve(bezier_from_curve<Bezier>(*curves_.at(i)));
     }
     return pc_res;
   }
 
-  template <typename Hermite>
-  piecewise_curve<Time, Numeric, Safe, Point, T_Point, Hermite> convert_piecewise_curve_to_cubic_hermite() {
+ template <typename Hermite>
+ piecewise_curve_t convert_piecewise_curve_to_cubic_hermite() {
     check_if_not_empty();
-    typedef piecewise_curve<Time, Numeric, Safe, Point, T_Point, Hermite> piecewise_curve_out_t;
-    // Get first curve (segment)
-    curve_t first_curve = curves_.at(0);
-    Hermite first_curve_output = hermite_from_curve<Hermite, curve_t>(first_curve);
+    // check if given Hermite curve have the correct dimension :
+    BOOST_STATIC_ASSERT(boost::is_same<typename Hermite::point_t, point_t>::value);
+    BOOST_STATIC_ASSERT(boost::is_same<typename Hermite::point_derivate_t, point_derivate_t>::value);
     // Create piecewise curve
-    piecewise_curve_out_t pc_res(first_curve_output);
+    piecewise_curve_t pc_res;
     // Convert and add all other curves (segments)
-    for (std::size_t i = 1; i < size_; i++) {
-      pc_res.add_curve(hermite_from_curve<Hermite, curve_t>(curves_.at(i)));
+    for (std::size_t i = 0; i < size_; i++) {
+      pc_res.add_curve(hermite_from_curve<Hermite>(*curves_.at(i)));
     }
     return pc_res;
   }
 
   template <typename Polynomial>
-  piecewise_curve<Time, Numeric, Safe, Point, T_Point, Polynomial> convert_piecewise_curve_to_polynomial() {
+  piecewise_curve_t convert_piecewise_curve_to_polynomial() {
     check_if_not_empty();
-    typedef piecewise_curve<Time, Numeric, Safe, Point, T_Point, Polynomial> piecewise_curve_out_t;
-    // Get first curve (segment)
-    curve_t first_curve = curves_.at(0);
-    Polynomial first_curve_output = polynomial_from_curve<Polynomial, curve_t>(first_curve);
+    // check if given Polynomial curve have the correct dimension :
+    BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_t, point_t>::value);
+    BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_derivate_t, point_derivate_t>::value);
     // Create piecewise curve
-    piecewise_curve_out_t pc_res(first_curve_output);
+    piecewise_curve_t pc_res;
     // Convert and add all other curves (segments)
-    for (std::size_t i = 1; i < size_; i++) {
-      pc_res.add_curve(polynomial_from_curve<Polynomial, curve_t>(curves_.at(i)));
+    for (std::size_t i = 0; i < size_; i++) {
+      pc_res.add_curve(polynomial_from_curve<Polynomial>(*curves_.at(i)));
     }
     return pc_res;
   }
 
+
   template <typename Polynomial>
-  static piecewise_curve<Time, Numeric, Safe, Point, T_Point, Polynomial> convert_discrete_points_to_polynomial(
-      T_Point points, t_time_t time_points) {
+  static piecewise_curve_t convert_discrete_points_to_polynomial(
+      t_point_t points, t_time_t time_points) {
     if (Safe & !(points.size() > 1)) {
       // std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<" t="<<t<<std::endl;
       throw std::invalid_argument(
@@ -247,7 +253,10 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
           "piecewise_curve::convert_discrete_points_to_polynomial: Error, points and time_points must have the same "
           "size.");
     }
-    piecewise_curve<Time, Numeric, Safe, Point, T_Point, Polynomial> piecewise_res;
+    // check if given Polynomial curve have the correct dimension :
+    BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_t, point_t>::value);
+    BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_derivate_t, point_derivate_t>::value);
+    piecewise_curve_t piecewise_res;
 
     for (size_t i = 1; i < points.size(); ++i) {
       piecewise_res.add_curve(Polynomial(points[i - 1], points[i], time_points[i - 1], time_points[i]));
@@ -256,8 +265,8 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
   }
 
   template <typename Polynomial>
-  static piecewise_curve<Time, Numeric, Safe, Point, T_Point, Polynomial> convert_discrete_points_to_polynomial(
-      T_Point points, T_Point points_derivative, t_time_t time_points) {
+  static piecewise_curve_t convert_discrete_points_to_polynomial(
+      t_point_t points, t_point_derivate_t points_derivative, t_time_t time_points) {
     if (Safe & !(points.size() > 1)) {
       // std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<" t="<<t<<std::endl;
       throw std::invalid_argument(
@@ -273,7 +282,10 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
           "piecewise_curve::convert_discrete_points_to_polynomial: Error, points and points_derivative must have the "
           "same size.");
     }
-    piecewise_curve<Time, Numeric, Safe, Point, T_Point, Polynomial> piecewise_res;
+    // check if given Polynomial curve have the correct dimension :
+    BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_t, point_t>::value);
+    BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_derivate_t, point_derivate_t>::value);
+    piecewise_curve_t piecewise_res;
 
     for (size_t i = 1; i < points.size(); ++i) {
       piecewise_res.add_curve(Polynomial(points[i - 1], points_derivative[i - 1], points[i], points_derivative[i],
@@ -283,8 +295,8 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
   }
 
   template <typename Polynomial>
-  static piecewise_curve<Time, Numeric, Safe, Point, T_Point, Polynomial> convert_discrete_points_to_polynomial(
-      T_Point points, T_Point points_derivative, T_Point points_second_derivative, t_time_t time_points) {
+  static piecewise_curve_t convert_discrete_points_to_polynomial(
+      t_point_t points, t_point_derivate_t points_derivative, t_point_derivate_t points_second_derivative, t_time_t time_points) {
     if (Safe & !(points.size() > 1)) {
       // std::cout<<"[Min,Max]=["<<T_min_<<","<<T_max_<<"]"<<" t="<<t<<std::endl;
       throw std::invalid_argument(
@@ -305,7 +317,10 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
           "piecewise_curve::convert_discrete_points_to_polynomial: Error, points and points_second_derivative must "
           "have the same size.");
     }
-    piecewise_curve<Time, Numeric, Safe, Point, T_Point, Polynomial> piecewise_res;
+    // check if given Polynomial curve have the correct dimension :
+    BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_t, point_t>::value);
+    BOOST_STATIC_ASSERT(boost::is_same<typename Polynomial::point_derivate_t, point_derivate_t>::value);
+    piecewise_curve_t piecewise_res;
 
     for (size_t i = 1; i < points.size(); ++i) {
       piecewise_res.add_curve(Polynomial(points[i - 1], points_derivative[i - 1], points_second_derivative[i - 1],
@@ -362,12 +377,17 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
   /// \brief Get the maximum time for which the curve is defined.
   /// \return \f$t_{max}\f$, upper bound of time range.
   Time virtual max() const { return T_max_; }
+  /// \brief Get the degree of the curve.
+  /// \return \f$degree\f$, the degree of the curve.
+  virtual std::size_t  degree() const {
+    throw std::runtime_error("degree() method is not implemented for this type of curve.");
+  }
   std::size_t getNumberCurves() { return curves_.size(); }
   /*Helpers*/
 
   /* Attributes */
   std::size_t dim_;       // Dim of curve
-  t_curve_t curves_;      // for curves 0/1/2 : [ curve0, curve1, curve2 ]
+  t_curve_ptr_t curves_;  // for curves 0/1/2 : [ curve0, curve1, curve2 ]
   t_time_t time_curves_;  // for curves 0/1/2 : [ Tmin0, Tmax0,Tmax1,Tmax2 ]
   std::size_t size_;      // Number of segments in piecewise curve = size of curves_
   Time T_min_, T_max_;
@@ -382,7 +402,7 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
     if (version) {
       // Do something depending on version ?
     }
-    ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(curve_abc_t);
+    ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(curve_t);
     ar& boost::serialization::make_nvp("dim", dim_);
     ar& boost::serialization::make_nvp("curves", curves_);
     ar& boost::serialization::make_nvp("time_curves", time_curves_);
@@ -392,8 +412,9 @@ struct piecewise_curve : public curve_abc<Time, Numeric, Safe, Point,Point_deriv
   }
 };  // End struct piecewise curve
 
-template <typename Time, typename Numeric, bool Safe, typename Point, typename T_Point,typename Curve,typename Point_derivate>
-const double piecewise_curve<Time, Numeric, Safe, Point, T_Point, Curve,Point_derivate>::MARGIN(0.001);
+
+template <typename Time, typename Numeric, bool Safe, typename Point, typename Point_derivate>
+const double piecewise_curve<Time, Numeric, Safe, Point,Point_derivate >::MARGIN(0.001);
 
 }  // namespace curves
 
diff --git a/include/curves/polynomial.h b/include/curves/polynomial.h
index 757c13c00a3b042ce245756f750f7c0684aa7c49..2e75d6b6e75a7a45853c8c8e40b40a35be3efabc 100644
--- a/include/curves/polynomial.h
+++ b/include/curves/polynomial.h
@@ -41,6 +41,7 @@ struct polynomial : public curve_abc<Time, Numeric, Safe, Point> {
   typedef Eigen::MatrixXd coeff_t;
   typedef Eigen::Ref<coeff_t> coeff_t_ref;
   typedef polynomial<Time, Numeric, Safe, Point, T_Point> polynomial_t;
+  typedef typename curve_abc_t::curve_ptr_t curve_ptr_t;
 
   /* Constructors - destructors */
  public:
@@ -282,6 +283,13 @@ struct polynomial : public curve_abc<Time, Numeric, Safe, Point> {
     return deriv.compute_derivate(order - 1);
   }
 
+  ///  \brief Compute the derived curve at order N.
+  ///  \param order : order of derivative.
+  ///  \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve.
+  polynomial_t* compute_derivate_ptr(const std::size_t order) const {
+    return new polynomial_t(compute_derivate(order));
+  }
+
   Eigen::MatrixXd coeff() const { return coefficients_; }
 
   point_t coeffAtDegree(const std::size_t degree) const {
@@ -329,6 +337,9 @@ struct polynomial : public curve_abc<Time, Numeric, Safe, Point> {
   /// \brief Get the maximum time for which the curve is defined.
   /// \return \f$t_{max}\f$ upper bound of time range.
   num_t virtual max() const { return T_max_; }
+  /// \brief Get the degree of the curve.
+  /// \return \f$degree\f$, the degree of the curve.
+  virtual std::size_t  degree() const {return degree_;}
   /*Helpers*/
 
   /*Attributes*/
diff --git a/include/curves/se3_curve.h b/include/curves/se3_curve.h
index 2a4678650841cc18305187741fd022541b1db15f..c929771f290a0bf7af68b89c541d9395a27f6d21 100644
--- a/include/curves/se3_curve.h
+++ b/include/curves/se3_curve.h
@@ -164,6 +164,17 @@ struct SE3Curve : public curve_abc<Time, Numeric, Safe, Eigen::Transform<Numeric
     return res;
   }
 
+  SE3Curve_t compute_derivate(const std::size_t /*order*/) const {
+    throw std::logic_error("Compute derivate for SE3 is not implemented yet.");
+  }
+
+  ///  \brief Compute the derived curve at order N.
+  ///  \param order : order of derivative.
+  ///  \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve.
+  SE3Curve_t* compute_derivate_ptr(const std::size_t order) const {
+    return new SE3Curve_t(compute_derivate(order));
+  }
+
   /*Helpers*/
   /// \brief Get dimension of curve.
   /// \return dimension of curve.
@@ -174,6 +185,9 @@ struct SE3Curve : public curve_abc<Time, Numeric, Safe, Eigen::Transform<Numeric
   /// \brief Get the maximum time for which the curve is defined.
   /// \return \f$t_{max}\f$ upper bound of time range.
   time_t max() const { return T_max_; }
+  /// \brief Get the degree of the curve.
+  /// \return \f$degree\f$, the degree of the curve.
+  virtual std::size_t  degree() const {return translation_curve_->degree();}
   /*Helpers*/
 
   /*Attributes*/
diff --git a/include/curves/serialization/registeration.hpp b/include/curves/serialization/registeration.hpp
index 3a4a5e64b3f20c1d304c6430cb8733695577a12f..ec4f7a0f2b7f83e51431eb76e1a3a37008e8d0e4 100644
--- a/include/curves/serialization/registeration.hpp
+++ b/include/curves/serialization/registeration.hpp
@@ -26,23 +26,22 @@ namespace serialization {
 
   template <class Archive>
   void register_types(Archive& ar){
-    typedef double Scalar;
-    typedef Eigen::Matrix<Scalar, -1, 1> pointX_t;
-    typedef std::vector<pointX_t, Eigen::aligned_allocator<pointX_t> > t_point_t;
 
     //register derived class
-    ar.template register_type<bezier_curve<Scalar, Scalar, true, pointX_t> >();
-    ar.template register_type<cubic_hermite_spline<Scalar, Scalar, true, pointX_t> >();
-    ar.template register_type<exact_cubic<Scalar, Scalar, true, pointX_t,
-        t_point_t, polynomial<Scalar, Scalar, true, pointX_t,t_point_t> > >();
-    ar.template register_type<piecewise_curve<Scalar, Scalar, true, pointX_t,
-        t_point_t, polynomial<Scalar, Scalar, true, pointX_t, t_point_t> ,pointX_t> >();
-    ar.template register_type<piecewise_curve<Scalar, Scalar, true, pointX_t,
-        t_point_t, bezier_curve<Scalar, Scalar, true, pointX_t> ,pointX_t> >();
-    ar.template register_type<piecewise_curve<Scalar, Scalar, true, pointX_t,
-        t_point_t, cubic_hermite_spline<Scalar, Scalar, true, pointX_t> ,pointX_t> >();
-    ar.template register_type<polynomial<Scalar, Scalar, true, pointX_t, t_point_t> >();
-    ar.template register_type<SO3Linear<Scalar, Scalar, true> >();
+    ar.template register_type<polynomial_t >();
+    ar.template register_type<exact_cubic_t >();
+    ar.template register_type<bezier_t >();
+    ar.template register_type<cubic_hermite_spline_t >();
+    ar.template register_type<piecewise_t >();
+    ar.template register_type<polynomial3_t >();
+    ar.template register_type<exact_cubic3_t >();
+    ar.template register_type<bezier3_t >();
+    ar.template register_type<cubic_hermite_spline3_t >();
+    ar.template register_type<piecewise3_t >();
+    ar.template register_type<SO3Linear_t >();
+    ar.template register_type<SE3Curve_t >();
+    ar.template register_type<piecewise_SE3_t >();
+
   }
 
 }
diff --git a/include/curves/so3_linear.h b/include/curves/so3_linear.h
index bd8ecee748c29035386293d161837e269e46e379..61e076e531ba8f547638ba992926c3715bddaeec 100644
--- a/include/curves/so3_linear.h
+++ b/include/curves/so3_linear.h
@@ -125,6 +125,18 @@ struct SO3Linear : public curve_abc<Time, Numeric, Safe, Eigen::Matrix<Numeric,
     }
   }
 
+  SO3Linear_t compute_derivate(const std::size_t /*order*/) const {
+    throw std::logic_error("Compute derivate for SO3Linear is not implemented yet.");
+  }
+
+  ///  \brief Compute the derived curve at order N.
+  ///  \param order : order of derivative.
+  ///  \return A pointer to \f$\frac{d^Nx(t)}{dt^N}\f$ derivative order N of the curve.
+  SO3Linear_t* compute_derivate_ptr(const std::size_t order) const {
+    return new SO3Linear_t(compute_derivate(order));
+  }
+
+
   /*Helpers*/
   /// \brief Get dimension of curve.
   /// \return dimension of curve.
@@ -135,6 +147,9 @@ struct SO3Linear : public curve_abc<Time, Numeric, Safe, Eigen::Matrix<Numeric,
   /// \brief Get the maximum time for which the curve is defined.
   /// \return \f$t_{max}\f$ upper bound of time range.
   time_t max() const { return T_max_; }
+  /// \brief Get the degree of the curve.
+  /// \return \f$degree\f$, the degree of the curve.
+  virtual std::size_t  degree() const {return 1;}
   matrix3_t getInitRotation()const {return init_rot_.toRotationMatrix();}
   matrix3_t getEndRotation()const {return end_rot_.toRotationMatrix();}
   matrix3_t getInitRotation() {return init_rot_.toRotationMatrix();}
diff --git a/python/curves_python.cpp b/python/curves_python.cpp
index 1b6556e4ec50101918b556fde9554c1777988996..d8eebec8e0fcaf9f514a861efdf4065eb1ce77d2 100644
--- a/python/curves_python.cpp
+++ b/python/curves_python.cpp
@@ -17,6 +17,7 @@ using namespace boost::python;
 struct CurveWrapper : curve_abc_t, wrapper<curve_abc_t> {
   point_t operator()(const real) { return this->get_override("operator()")(); }
   point_t derivate(const real, const std::size_t) { return this->get_override("derivate")(); }
+  curve_t* compute_derivate_ptr(const real) { return this->get_override("compute_derivate")(); }
   std::size_t dim() { return this->get_override("dim")(); }
   real min() { return this->get_override("min")(); }
   real max() { return this->get_override("max")(); }
@@ -24,6 +25,7 @@ struct CurveWrapper : curve_abc_t, wrapper<curve_abc_t> {
 struct Curve3Wrapper : curve_3_t, wrapper<curve_3_t> {
   point_t operator()(const real) { return this->get_override("operator()")(); }
   point_t derivate(const real, const std::size_t) { return this->get_override("derivate")(); }
+  curve_t* compute_derivate_ptr(const real) { return this->get_override("compute_derivate")(); }
   std::size_t dim() { return this->get_override("dim")(); }
   real min() { return this->get_override("min")(); }
   real max() { return this->get_override("max")(); }
@@ -31,6 +33,15 @@ struct Curve3Wrapper : curve_3_t, wrapper<curve_3_t> {
 struct CurveRotationWrapper : curve_rotation_t, wrapper<curve_rotation_t> {
   point_t operator()(const real) { return this->get_override("operator()")(); }
   point_t derivate(const real, const std::size_t) { return this->get_override("derivate")(); }
+  curve_t* compute_derivate_ptr(const real) { return this->get_override("compute_derivate")(); }
+  std::size_t dim() { return this->get_override("dim")(); }
+  real min() { return this->get_override("min")(); }
+  real max() { return this->get_override("max")(); }
+};
+struct CurveSE3Wrapper : curve_SE3_t, wrapper<curve_SE3_t> {
+  point_t operator()(const real) { return this->get_override("operator()")(); }
+  point_t derivate(const real, const std::size_t) { return this->get_override("derivate")(); }
+  curve_t* compute_derivate_ptr(const real) { return this->get_override("compute_derivate")(); }
   std::size_t dim() { return this->get_override("dim")(); }
   real min() { return this->get_override("min")(); }
   real max() { return this->get_override("max")(); }
@@ -137,53 +148,42 @@ polynomial_t* wrapPolynomialConstructorFromBoundaryConditionsDegree3(const point
 }
 polynomial_t* wrapPolynomialConstructorFromBoundaryConditionsDegree5(const pointX_t& init, const pointX_t& d_init,
                                                                      const pointX_t& dd_init, const pointX_t& end,
-                                                                     const point_t& d_end, const point_t& dd_end,
+                                                                     const pointX_t& d_end, const pointX_t& dd_end,
                                                                      const real min, const real max) {
   return new polynomial_t(init, d_init, dd_init, end, d_end, dd_end, min, max);
 }
 /* End wrap polynomial */
 
 /* Wrap piecewise curve */
-piecewise_polynomial_curve_t* wrapPiecewisePolynomialCurveConstructor(const polynomial_t& pol) {
-  return new piecewise_polynomial_curve_t(pol);
+piecewise_t* wrapPiecewiseCurveConstructor(const curve_ptr_t& curve) {
+  return new piecewise_t(curve);
 }
-piecewise_polynomial_curve_t* wrapPiecewisePolynomialCurveEmptyConstructor() {
-  return new piecewise_polynomial_curve_t();
+piecewise_t* wrapPiecewisePolynomialCurveEmptyConstructor() {
+  return new piecewise_t();
 }
-piecewise_bezier_curve_t* wrapPiecewiseBezierCurveConstructor(const bezier_t& bc) {
-  return new piecewise_bezier_curve_t(bc);
+piecewise_SE3_t* wrapPiecewiseSE3Constructor(const curve_SE3_ptr_t& curve) {
+  return new piecewise_SE3_t(curve);
 }
-piecewise_bezier_linear_curve_t* wrapPiecewiseLinearBezierCurveConstructor(const bezier_linear_variable_t& bc) {
-  return new piecewise_bezier_linear_curve_t(bc);
-}
-piecewise_cubic_hermite_curve_t* wrapPiecewiseCubicHermiteCurveConstructor(const cubic_hermite_spline_t& ch) {
-  return new piecewise_cubic_hermite_curve_t(ch);
-}
-
-piecewise_SE3_curve_t* wrapPiecewiseSE3Constructor(const SE3Curve_t& curve) {
-  return new piecewise_SE3_curve_t(curve);
+piecewise_SE3_t* wrapPiecewiseSE3EmptyConstructor() {
+  return new piecewise_SE3_t();
 }
 
-piecewise_SE3_curve_t* wrapPiecewiseSE3EmptyConstructor() {
-  return new piecewise_SE3_curve_t();
-}
-static piecewise_polynomial_curve_t discretPointToPolynomialC0(const pointX_list_t& points,
+static piecewise_t discretPointToPolynomialC0(const pointX_list_t& points,
                                                                const time_waypoints_t& time_points) {
   t_pointX_t points_list = vectorFromEigenArray<pointX_list_t, t_pointX_t>(points);
   t_time_t time_points_list = vectorFromEigenVector<time_waypoints_t, t_time_t>(time_points);
-  return piecewise_polynomial_curve_t::convert_discrete_points_to_polynomial<polynomial_t>(points_list,
-                                                                                           time_points_list);
+  return piecewise_t::convert_discrete_points_to_polynomial<polynomial_t>(points_list,time_points_list);
 }
-static piecewise_polynomial_curve_t discretPointToPolynomialC1(const pointX_list_t& points,
+static piecewise_t discretPointToPolynomialC1(const pointX_list_t& points,
                                                                const pointX_list_t& points_derivative,
                                                                const time_waypoints_t& time_points) {
   t_pointX_t points_list = vectorFromEigenArray<pointX_list_t, t_pointX_t>(points);
   t_pointX_t points_derivative_list = vectorFromEigenArray<pointX_list_t, t_pointX_t>(points_derivative);
   t_time_t time_points_list = vectorFromEigenVector<time_waypoints_t, t_time_t>(time_points);
-  return piecewise_polynomial_curve_t::convert_discrete_points_to_polynomial<polynomial_t>(
+  return piecewise_t::convert_discrete_points_to_polynomial<polynomial_t>(
       points_list, points_derivative_list, time_points_list);
 }
-static piecewise_polynomial_curve_t discretPointToPolynomialC2(const pointX_list_t& points,
+static piecewise_t discretPointToPolynomialC2(const pointX_list_t& points,
                                                                const pointX_list_t& points_derivative,
                                                                const pointX_list_t& points_second_derivative,
                                                                const time_waypoints_t& time_points) {
@@ -192,20 +192,21 @@ static piecewise_polynomial_curve_t discretPointToPolynomialC2(const pointX_list
   t_pointX_t points_second_derivative_list = vectorFromEigenArray<pointX_list_t, t_pointX_t>(points_second_derivative);
 
   t_time_t time_points_list = vectorFromEigenVector<time_waypoints_t, t_time_t>(time_points);
-  return piecewise_polynomial_curve_t::convert_discrete_points_to_polynomial<polynomial_t>(
+  return piecewise_t::convert_discrete_points_to_polynomial<polynomial_t>(
       points_list, points_derivative_list, points_second_derivative_list, time_points_list);
 }
-void addFinalPointC0(piecewise_polynomial_curve_t& self, const pointX_t& end, const real time) {
+
+void addFinalPointC0(piecewise_t& self, const pointX_t& end, const real time) {
   if(self.num_curves() == 0)
     throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
   if (self.is_continuous(1) && self.num_curves()>1 )
     std::cout << "Warning: by adding this final point to the piecewise curve, you loose C1 continuity and only "
                  "guarantee C0 continuity."
               << std::endl;
-  polynomial_t pol(self(self.max()), end, self.max(), time);
-  self.add_curve(pol);
+  curve_ptr_t pol(new polynomial_t(self(self.max()), end, self.max(), time));
+  self.add_curve_ptr(pol);
 }
-void addFinalPointC1(piecewise_polynomial_curve_t& self, const pointX_t& end, const pointX_t& d_end, const real time) {
+void addFinalPointC1(piecewise_t& self, const pointX_t& end, const pointX_t& d_end, const real time) {
   if(self.num_curves() == 0)
     throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
   if (self.is_continuous(2) && self.num_curves()>1 )
@@ -213,10 +214,10 @@ void addFinalPointC1(piecewise_polynomial_curve_t& self, const pointX_t& end, co
                  "guarantee C1 continuity."
               << std::endl;
   if (!self.is_continuous(1)) std::cout << "Warning: the current piecewise curve is not C1 continuous." << std::endl;
-  polynomial_t pol(self(self.max()), self.derivate(self.max(), 1), end, d_end, self.max(), time);
-  self.add_curve(pol);
+  curve_ptr_t pol(new polynomial_t(self(self.max()), self.derivate(self.max(), 1), end, d_end, self.max(), time));
+  self.add_curve_ptr(pol);
 }
-void addFinalPointC2(piecewise_polynomial_curve_t& self, const pointX_t& end, const pointX_t& d_end,
+void addFinalPointC2(piecewise_t& self, const pointX_t& end, const pointX_t& d_end,
                      const pointX_t& dd_end, const real time) {
   if(self.num_curves() == 0)
     throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
@@ -225,9 +226,9 @@ void addFinalPointC2(piecewise_polynomial_curve_t& self, const pointX_t& end, co
                  "guarantee C2 continuity."
               << std::endl;
   if (!self.is_continuous(2)) std::cout << "Warning: the current piecewise curve is not C2 continuous." << std::endl;
-  polynomial_t pol(self(self.max()), self.derivate(self.max(), 1), self.derivate(self.max(), 2), end, d_end, dd_end,
-                   self.max(), time);
-  self.add_curve(pol);
+  curve_ptr_t pol(new polynomial_t(self(self.max()), self.derivate(self.max(), 1), self.derivate(self.max(), 2), end, d_end, dd_end,
+                   self.max(), time));
+  self.add_curve_ptr(pol);
 }
 
 /* end wrap piecewise polynomial curve */
@@ -281,8 +282,8 @@ bezier_t* bezier_linear_variable_t_evaluate(const bezier_linear_variable_t* b, c
   return new bezier_t(evaluateLinear<bezier_t, bezier_linear_variable_t>(*b, x));
 }
 
-bezier_t::piecewise_bezier_curve_t (bezier_t::*splitspe)(const bezier_t::vector_x_t&) const = &bezier_t::split;
-bezier_linear_variable_t::piecewise_bezier_curve_t (bezier_linear_variable_t::*split_py)(
+bezier_t::piecewise_curve_t (bezier_t::*splitspe)(const bezier_t::vector_x_t&) const = &bezier_t::split;
+bezier_linear_variable_t::piecewise_curve_t (bezier_linear_variable_t::*split_py)(
     const bezier_linear_variable_t::vector_x_t&) const = &bezier_linear_variable_t::split;
 
 /* End wrap exact cubic spline */
@@ -301,6 +302,13 @@ SO3Linear_t* wrapSO3LinearConstructorFromMatrix(const matrix3_t& init_rot, const
 /* End wrap SO3Linear */
 
 /* Wrap SE3Curves */
+
+matrix4_t se3Return(const curve_SE3_t& curve, const real t) { return curve(t).matrix(); }
+
+matrix3_t se3returnRotation(const curve_SE3_t& curve, const real t) { return curve(t).rotation(); }
+
+pointX_t se3returnTranslation(const curve_SE3_t& curve, const real t) { return pointX_t(curve(t).translation()); }
+
 SE3Curve_t* wrapSE3CurveFromTransform(const matrix4_t& init_pose, const matrix4_t& end_pose, const real min,
                                       const real max) {
   return new SE3Curve_t(transform_t(init_pose), transform_t(end_pose), min, max);
@@ -336,23 +344,12 @@ SE3Curve_t* wrapSE3CurveFromSE3Pinocchio(const SE3_t& init_pose, const SE3_t& en
                         max);
 }
 
-SE3_t se3ReturnPinocchio(const SE3Curve_t& curve, const real t) { return SE3_t(curve(t).matrix()); }
+SE3_t se3ReturnPinocchio(const curve_SE3_t& curve, const real t) { return SE3_t(curve(t).matrix()); }
 
-Motion_t se3ReturnDerivatePinocchio(const SE3Curve_t& curve, const real t, const std::size_t order) {
+Motion_t se3ReturnDerivatePinocchio(const curve_SE3_t& curve, const real t, const std::size_t order) {
   return Motion_t(curve.derivate(t, order));
 }
 #endif  // CURVES_WITH_PINOCCHIO_SUPPORT
-
-matrix4_t se3Return(const SE3Curve_t& curve, const real t) { return curve(t).matrix(); }
-
-pointX_t se3ReturnDerivate(const SE3Curve_t& curve, const real t, const std::size_t order) {
-  return curve.derivate(t, order);
-}
-
-matrix3_t se3returnRotation(const SE3Curve_t& curve, const real t) { return curve(t).rotation(); }
-
-pointX_t se3returnTranslation(const SE3Curve_t& curve, const real t) { return pointX_t(curve(t).translation()); }
-
 /* End wrap SE3Curves */
 
 /* Wrap piecewiseSE3Curves */
@@ -360,13 +357,7 @@ pointX_t se3returnTranslation(const SE3Curve_t& curve, const real t) { return po
 typedef pinocchio::SE3Tpl<real, 0> SE3_t;
 typedef pinocchio::MotionTpl<real, 0> Motion_t;
 
-SE3_t piecewiseSE3ReturnPinocchio(const piecewise_SE3_curve_t& curve, const real t) { return SE3_t(curve(t).matrix()); }
-
-Motion_t piecewiseSE3ReturnDerivatePinocchio(const piecewise_SE3_curve_t& curve, const real t, const std::size_t order) {
-  return Motion_t(curve.derivate(t, order));
-}
-
-void addFinalSE3(piecewise_SE3_curve_t& self, const SE3_t& end, const real time) {
+void addFinalSE3(piecewise_SE3_t& self, const SE3_t& end, const real time) {
   if(self.num_curves() == 0)
     throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
   if (self.is_continuous(1) && self.num_curves()>1 )
@@ -379,14 +370,7 @@ void addFinalSE3(piecewise_SE3_curve_t& self, const SE3_t& end, const real time)
 
 #endif  // CURVES_WITH_PINOCCHIO_SUPPORT
 
-matrix4_t piecewiseSE3Return(const piecewise_SE3_curve_t& curve, const real t) { return curve(t).matrix(); }
-
-
-matrix3_t piecewiseSE3returnRotation(const piecewise_SE3_curve_t& curve, const real t) { return curve(t).rotation(); }
-
-pointX_t piecewiseSE3returnTranslation(const piecewise_SE3_curve_t& curve, const real t) { return pointX_t(curve(t).translation()); }
-
-void addFinalTransform(piecewise_SE3_curve_t& self, const matrix4_t& end, const real time) {
+void addFinalTransform(piecewise_SE3_t& self, const matrix4_t& end, const real time) {
   if(self.num_curves() == 0)
     throw std::runtime_error("Piecewise append : you need to add at least one curve before using append(finalPoint) method.");
   if (self.is_continuous(1) && self.num_curves()>1 )
@@ -409,7 +393,6 @@ BOOST_PYTHON_MODULE(curves) {
   ENABLE_SPECIFIC_MATRIX_TYPE(point6_t);
   ENABLE_SPECIFIC_MATRIX_TYPE(pointX_list_t);
   ENABLE_SPECIFIC_MATRIX_TYPE(coeff_t);
-  ENABLE_SPECIFIC_MATRIX_TYPE(point_list_t);
   ENABLE_SPECIFIC_MATRIX_TYPE(matrix3_t);
   ENABLE_SPECIFIC_MATRIX_TYPE(matrix4_t);
   // ENABLE_SPECIFIC_MATRIX_TYPE(quaternion_t);
@@ -422,6 +405,7 @@ BOOST_PYTHON_MODULE(curves) {
            args("self", "t"))
       .def("derivate", pure_virtual(&curve_abc_t::derivate), "Evaluate the derivative of order N of curve at time t.",
            args("self", "t", "N"))
+      .def("compute_derivate", pure_virtual(&curve_abc_t::compute_derivate_ptr),return_value_policy<manage_new_object>(), "Return the derivative of *this at the order N.",  args("self", "N"))
       .def("min", pure_virtual(&curve_abc_t::min), "Get the LOWER bound on interval definition of the curve.")
       .def("max", pure_virtual(&curve_abc_t::max), "Get the HIGHER bound on interval definition of the curve.")
       .def("dim", pure_virtual(&curve_abc_t::dim), "Get the dimension of the curve.")
@@ -443,6 +427,7 @@ BOOST_PYTHON_MODULE(curves) {
            args("self", "t"))
       .def("derivate", pure_virtual(&curve_3_t::derivate), "Evaluate the derivative of order N of curve at time t.",
            args("self", "t", "N"))
+      .def("compute_derivate", pure_virtual(&curve_3_t::compute_derivate_ptr),return_value_policy<manage_new_object>(), "Return the derivative of *this at the order N.",  args("self", "N"))
       .def("min", pure_virtual(&curve_3_t::min), "Get the LOWER bound on interval definition of the curve.")
       .def("max", pure_virtual(&curve_3_t::max), "Get the HIGHER bound on interval definition of the curve.")
       .def("dim", pure_virtual(&curve_3_t::dim), "Get the dimension of the curve.");
@@ -452,17 +437,40 @@ BOOST_PYTHON_MODULE(curves) {
            args("self", "t"))
       .def("derivate", pure_virtual(&curve_rotation_t::derivate),
            "Evaluate the derivative of order N of curve at time t.", args("self", "t", "N"))
+      .def("compute_derivate", pure_virtual(&curve_rotation_t::compute_derivate_ptr),return_value_policy<manage_new_object>(), "Return the derivative of *this at the order N.",  args("self", "N"))
       .def("min", pure_virtual(&curve_rotation_t::min), "Get the LOWER bound on interval definition of the curve.")
       .def("max", pure_virtual(&curve_rotation_t::max), "Get the HIGHER bound on interval definition of the curve.")
       .def("dim", pure_virtual(&curve_rotation_t::dim), "Get the dimension of the curve.");
 
+  class_<CurveSE3Wrapper, boost::noncopyable, bases<curve_abc_t> >("curve_SE3", no_init)
+      .def("__call__", &se3Return, "Evaluate the curve at the given time. Return as an homogeneous matrix.",
+           args("self", "t"))
+      .def("derivate", pure_virtual(&curve_SE3_t::derivate),
+           "Evaluate the derivative of order N of curve at time t. Return as a vector 6.", args("self", "t", "N"))
+      .def("compute_derivate", pure_virtual(&curve_rotation_t::compute_derivate_ptr),return_value_policy<manage_new_object>(), "Return the derivative of *this at the order N.",  args("self", "N"))
+      .def("min", pure_virtual(&curve_SE3_t::min), "Get the LOWER bound on interval definition of the curve.")
+      .def("max", pure_virtual(&curve_SE3_t::max), "Get the HIGHER bound on interval definition of the curve.")
+      .def("dim", pure_virtual(&curve_SE3_t::dim), "Get the dimension of the curve.")
+      .def("rotation", &se3returnRotation, "Output the rotation (as a 3x3 matrix) at the given time.",
+           args("self", "time"))
+      .def("translation", &se3returnTranslation, "Output the rotation (as a vector 3) at the given time.",
+           args("self", "time"))
+    #ifdef CURVES_WITH_PINOCCHIO_SUPPORT
+      .def("evaluateAsSE3", &se3ReturnPinocchio, "Evaluate the curve at the given time. Return as a pinocchio.SE3 object",
+           args("self", "t"))
+      .def("derivateAsMotion", &se3ReturnDerivatePinocchio,
+           "Evaluate the derivative of order N of curve at time t. Return as a pinocchio.Motion",
+           args("self", "t", "N"))
+    #endif  // CURVES_WITH_PINOCCHIO_SUPPORT
+      ;
+
+
   /** BEGIN bezier3 curve**/
   class_<bezier3_t, bases<curve_3_t> >("bezier3", init<>())
       .def("__init__", make_constructor(&wrapBezier3Constructor))
       .def("__init__", make_constructor(&wrapBezier3ConstructorBounds))
       .def("__init__", make_constructor(&wrapBezier3ConstructorConstraints))
       .def("__init__", make_constructor(&wrapBezier3ConstructorBoundsConstraints))
-      .def("compute_derivate", &bezier3_t::compute_derivate)
       .def("compute_primitive", &bezier3_t::compute_primitive)
       .def("waypointAtIndex", &bezier3_t::waypointAtIndex)
       .def_readonly("degree", &bezier3_t::degree_)
@@ -486,7 +494,6 @@ BOOST_PYTHON_MODULE(curves) {
       .def("__init__", make_constructor(&wrapBezierConstructorBounds))
       .def("__init__", make_constructor(&wrapBezierConstructorConstraints))
       .def("__init__", make_constructor(&wrapBezierConstructorBoundsConstraints))
-      .def("compute_derivate", &bezier_t::compute_derivate)
       .def("compute_primitive", &bezier_t::compute_primitive)
       .def("waypointAtIndex", &bezier_t::waypointAtIndex)
       .def_readonly("degree", &bezier_t::degree_)
@@ -536,7 +543,7 @@ BOOST_PYTHON_MODULE(curves) {
       .def("__call__", &bezier_linear_variable_t::operator())
       .def("evaluate", &bezier_linear_variable_t_evaluate, bp::return_value_policy<bp::manage_new_object>())
       .def("derivate", &bezier_linear_variable_t::derivate)
-      .def("compute_derivate", &bezier_linear_variable_t::compute_derivate)
+      .def("compute_derivate", &bezier_linear_variable_t::compute_derivate_ptr, return_value_policy<manage_new_object>())
       .def("compute_primitive", &bezier_linear_variable_t::compute_primitive)
       .def("split", split_py)
       .def("waypoints", &wayPointsToLists, return_value_policy<manage_new_object>())
@@ -583,7 +590,6 @@ BOOST_PYTHON_MODULE(curves) {
            " ddc(min) == dd_init and ddc(max) == dd_end")
       .def("coeffAtDegree", &polynomial_t::coeffAtDegree)
       .def("coeff", &polynomial_t::coeff)
-      .def("compute_derivate", &polynomial_t::compute_derivate, "Compute derivative of order N of curve at time t.")
       .def("saveAsText", &polynomial_t::saveAsText<polynomial_t>, bp::args("filename"),
            "Saves *this inside a text file.")
       .def("loadFromText", &polynomial_t::loadFromText<polynomial_t>, bp::args("filename"),
@@ -599,10 +605,10 @@ BOOST_PYTHON_MODULE(curves) {
 
   /** END polynomial function**/
   /** BEGIN piecewise curve function **/
-  class_<piecewise_polynomial_curve_t, bases<curve_abc_t> >("piecewise_polynomial_curve", init<>())
+  class_<piecewise_t, bases<curve_abc_t> >("piecewise", init<>())
       .def("__init__",
-           make_constructor(&wrapPiecewisePolynomialCurveConstructor, default_call_policies(), arg("curve")),
-           "Create a peicewise-polynomial curve containing the given polynomial curve.")
+           make_constructor(&wrapPiecewiseCurveConstructor, default_call_policies(), arg("curve")),
+           "Create a peicewise curve containing the given curve.")
       .def("FromPointsList", &discretPointToPolynomialC0,
            "Create a piecewise-polynomial connecting exactly all the given points at the given time. The created "
            "piecewise is C0 continuous.",
@@ -630,163 +636,67 @@ BOOST_PYTHON_MODULE(curves) {
            "and time and connecting exactly self(self.max()) and end. It guarantee C2 continuity and guarantee that "
            "self.derivate(time,1) == d_end and self.derivate(time,2) == dd_end",
            args("self", "end", "d_end", "d_end", "time"))
-      .def("compute_derivate", &piecewise_polynomial_curve_t::compute_derivate,
-           "Return a piecewise_polynomial curve which is the derivate of this.", args("self", "order"))
-      .def("append", &piecewise_polynomial_curve_t::add_curve,
+      .def("append", &piecewise_t::add_curve_ptr,
            "Add a new curve to piecewise curve, which should be defined in T_{min},T_{max}] "
            "where T_{min} is equal toT_{max} of the actual piecewise curve.")
-      .def("is_continuous", &piecewise_polynomial_curve_t::is_continuous,
+      .def("is_continuous", &piecewise_t::is_continuous,
            "Check if the curve is continuous at the given order.",args("self,order"))
+      .def("convert_piecewise_curve_to_polynomial",
+           &piecewise_t::convert_piecewise_curve_to_polynomial<polynomial_t>,
+           "Convert a piecewise curve to to a piecewise polynomial curve")
       .def("convert_piecewise_curve_to_bezier",
-           &piecewise_polynomial_curve_t::convert_piecewise_curve_to_bezier<bezier_t>,
-           "Convert a piecewise polynomial curve to to a piecewise bezier curve")
+           &piecewise_t::convert_piecewise_curve_to_bezier<bezier_t>,
+           "Convert a piecewise curve to to a piecewise bezier curve")
       .def("convert_piecewise_curve_to_cubic_hermite",
-           &piecewise_polynomial_curve_t::convert_piecewise_curve_to_cubic_hermite<cubic_hermite_spline_t>,
-           "Convert a piecewise polynomial curve to to a piecewise cubic hermite spline")
-      .def("curve_at_index", &piecewise_polynomial_curve_t::curve_at_index,
+           &piecewise_t::convert_piecewise_curve_to_cubic_hermite<cubic_hermite_spline_t>,
+           "Convert a piecewise curve to to a piecewise cubic hermite spline")
+      .def("curve_at_index", &piecewise_t::curve_at_index,
            return_value_policy<copy_const_reference>())
-      .def("curve_at_time", &piecewise_polynomial_curve_t::curve_at_time, return_value_policy<copy_const_reference>())
-      .def("num_curves", &piecewise_polynomial_curve_t::num_curves)
-      .def("saveAsText", &piecewise_polynomial_curve_t::saveAsText<piecewise_polynomial_curve_t>, bp::args("filename"),
+      .def("curve_at_time", &piecewise_t::curve_at_time, return_value_policy<copy_const_reference>())
+      .def("num_curves", &piecewise_t::num_curves)
+      .def("saveAsText", &piecewise_t::saveAsText<piecewise_t>, bp::args("filename"),
            "Saves *this inside a text file.")
-      .def("loadFromText", &piecewise_polynomial_curve_t::loadFromText<piecewise_polynomial_curve_t>,
+      .def("loadFromText", &piecewise_t::loadFromText<piecewise_t>,
            bp::args("filename"), "Loads *this from a text file.")
-      .def("saveAsXML", &piecewise_polynomial_curve_t::saveAsXML<piecewise_polynomial_curve_t>,
+      .def("saveAsXML", &piecewise_t::saveAsXML<piecewise_t>,
            bp::args("filename", "tag_name"), "Saves *this inside a XML file.")
-      .def("loadFromXML", &piecewise_polynomial_curve_t::loadFromXML<piecewise_polynomial_curve_t>,
+      .def("loadFromXML", &piecewise_t::loadFromXML<piecewise_t>,
            bp::args("filename", "tag_name"), "Loads *this from a XML file.")
-      .def("saveAsBinary", &piecewise_polynomial_curve_t::saveAsBinary<piecewise_polynomial_curve_t>,
+      .def("saveAsBinary", &piecewise_t::saveAsBinary<piecewise_t>,
            bp::args("filename"), "Saves *this inside a binary file.")
-      .def("loadFromBinary", &piecewise_polynomial_curve_t::loadFromBinary<piecewise_polynomial_curve_t>,
+      .def("loadFromBinary", &piecewise_t::loadFromBinary<piecewise_t>,
            bp::args("filename"), "Loads *this from a binary file.");
 
-  class_<piecewise_bezier_curve_t, bases<curve_abc_t> >("piecewise_bezier_curve", init<>())
-      .def("__init__", make_constructor(&wrapPiecewiseBezierCurveConstructor))
-      .def("compute_derivate", &piecewise_polynomial_curve_t::compute_derivate,
-           "Return a piecewise_polynomial curve which is the derivate of this.", args("self", "order"))
-      .def("append", &piecewise_bezier_curve_t::add_curve)
-      .def("is_continuous", &piecewise_bezier_curve_t::is_continuous)
-      .def("convert_piecewise_curve_to_polynomial",
-           &piecewise_bezier_curve_t::convert_piecewise_curve_to_polynomial<polynomial_t>,
-           "Convert a piecewise bezier curve to to a piecewise polynomial curve")
-      .def("convert_piecewise_curve_to_cubic_hermite",
-           &piecewise_bezier_curve_t::convert_piecewise_curve_to_cubic_hermite<cubic_hermite_spline_t>,
-           "Convert a piecewise bezier curve to to a piecewise cubic hermite spline")
-      .def("curve_at_index", &piecewise_bezier_curve_t::curve_at_index, return_value_policy<copy_const_reference>())
-      .def("curve_at_time", &piecewise_bezier_curve_t::curve_at_time, return_value_policy<copy_const_reference>())
-      .def("num_curves", &piecewise_bezier_curve_t::num_curves)
-      .def("saveAsText", &piecewise_bezier_curve_t::saveAsText<piecewise_bezier_curve_t>, bp::args("filename"),
-           "Saves *this inside a text file.")
-      .def("loadFromText", &piecewise_bezier_curve_t::loadFromText<piecewise_bezier_curve_t>, bp::args("filename"),
-           "Loads *this from a text file.")
-      .def("saveAsXML", &piecewise_bezier_curve_t::saveAsXML<piecewise_bezier_curve_t>,
-           bp::args("filename", "tag_name"), "Saves *this inside a XML file.")
-      .def("loadFromXML", &piecewise_bezier_curve_t::loadFromXML<piecewise_bezier_curve_t>,
-           bp::args("filename", "tag_name"), "Loads *this from a XML file.")
-      .def("saveAsBinary", &piecewise_bezier_curve_t::saveAsBinary<piecewise_bezier_curve_t>, bp::args("filename"),
-           "Saves *this inside a binary file.")
-      .def("loadFromBinary", &piecewise_bezier_curve_t::loadFromBinary<piecewise_bezier_curve_t>, bp::args("filename"),
-           "Loads *this from a binary file.");
-
-  class_<piecewise_cubic_hermite_curve_t, bases<curve_abc_t> >("piecewise_cubic_hermite_curve", init<>())
-      .def("__init__", make_constructor(&wrapPiecewiseCubicHermiteCurveConstructor))
-      .def("append", &piecewise_cubic_hermite_curve_t::add_curve)
-      .def("is_continuous", &piecewise_cubic_hermite_curve_t::is_continuous)
-      .def("convert_piecewise_curve_to_polynomial",
-           &piecewise_cubic_hermite_curve_t::convert_piecewise_curve_to_polynomial<polynomial_t>,
-           "Convert a piecewise cubic hermite spline to to a piecewise polynomial curve")
-      .def("convert_piecewise_curve_to_bezier",
-           &piecewise_cubic_hermite_curve_t::convert_piecewise_curve_to_bezier<bezier_t>,
-           "Convert a piecewise cubic hermite spline to to a piecewise bezier curve")
-      .def("curve_at_index", &piecewise_cubic_hermite_curve_t::curve_at_index,
-           return_value_policy<copy_const_reference>())
-      .def("curve_at_time", &piecewise_cubic_hermite_curve_t::curve_at_time,
-           return_value_policy<copy_const_reference>())
-      .def("num_curves", &piecewise_cubic_hermite_curve_t::num_curves)
-      .def("saveAsText", &piecewise_cubic_hermite_curve_t::saveAsText<piecewise_cubic_hermite_curve_t>,
-           bp::args("filename"), "Saves *this inside a text file.")
-      .def("loadFromText", &piecewise_cubic_hermite_curve_t::loadFromText<piecewise_cubic_hermite_curve_t>,
-           bp::args("filename"), "Loads *this from a text file.")
-      .def("saveAsXML", &piecewise_cubic_hermite_curve_t::saveAsXML<piecewise_cubic_hermite_curve_t>,
-           bp::args("filename", "tag_name"), "Saves *this inside a XML file.")
-      .def("loadFromXML", &piecewise_cubic_hermite_curve_t::loadFromXML<piecewise_cubic_hermite_curve_t>,
-           bp::args("filename", "tag_name"), "Loads *this from a XML file.")
-      .def("saveAsBinary", &piecewise_cubic_hermite_curve_t::saveAsBinary<piecewise_cubic_hermite_curve_t>,
-           bp::args("filename"), "Saves *this inside a binary file.")
-      .def("loadFromBinary", &piecewise_cubic_hermite_curve_t::loadFromBinary<piecewise_cubic_hermite_curve_t>,
-           bp::args("filename"), "Loads *this from a binary file.");
-
-  class_<piecewise_bezier_linear_curve_t, bases<curve_abc_t> >("piecewise_bezier_linear_curve_t", init<>())
-      .def("__init__", make_constructor(&wrapPiecewiseLinearBezierCurveConstructor))
-      .def("append", &piecewise_bezier_linear_curve_t::add_curve)
-      .def("is_continuous", &piecewise_bezier_linear_curve_t::is_continuous,
-           "Check if the curve is continuous at the given order.")
-      .def("curve_at_index", &piecewise_bezier_linear_curve_t::curve_at_index,
-           return_value_policy<copy_const_reference>())
-      .def("curve_at_time", &piecewise_bezier_linear_curve_t::curve_at_time,
-           return_value_policy<copy_const_reference>())
-      .def("num_curves", &piecewise_bezier_linear_curve_t::num_curves)
-      .def("saveAsText", &piecewise_bezier_linear_curve_t::saveAsText<piecewise_bezier_linear_curve_t>,
-           bp::args("filename"), "Saves *this inside a text file.")
-      .def("loadFromText", &piecewise_bezier_linear_curve_t::loadFromText<piecewise_bezier_linear_curve_t>,
-           bp::args("filename"), "Loads *this from a text file.")
-      .def("saveAsXML", &piecewise_bezier_linear_curve_t::saveAsXML<piecewise_bezier_linear_curve_t>,
-           bp::args("filename", "tag_name"), "Saves *this inside a XML file.")
-      .def("loadFromXML", &piecewise_bezier_linear_curve_t::loadFromXML<piecewise_bezier_linear_curve_t>,
-           bp::args("filename", "tag_name"), "Loads *this from a XML file.")
-      .def("saveAsBinary", &piecewise_bezier_linear_curve_t::saveAsBinary<piecewise_bezier_linear_curve_t>,
-           bp::args("filename"), "Saves *this inside a binary file.")
-      .def("loadFromBinary", &piecewise_bezier_linear_curve_t::loadFromBinary<piecewise_bezier_linear_curve_t>,
-           bp::args("filename"), "Loads *this from a binary file.");
-
-class_<piecewise_SE3_curve_t, bases<curve_abc_t> >("piecewise_SE3_curve", init<>())
+  class_<piecewise_SE3_t, bases<curve_SE3_t> >("piecewise_SE3", init<>())
       .def("__init__", make_constructor(&wrapPiecewiseSE3Constructor, default_call_policies(), arg("curve")),
       "Create a piecewise-se3 curve containing the given se3 curve.")
       .def("__init__", make_constructor(&wrapPiecewiseSE3EmptyConstructor),
       "Create an empty piecewise-se3 curve.")
-//      .def("compute_derivate", &piecewise_SE3_curve_t::compute_derivate,
-//           "Return a piecewise_polynomial curve which is the derivate of this.", args("self", "order"))
-      .def("append", &piecewise_SE3_curve_t::add_curve,
+      .def("append", &piecewise_SE3_t::add_curve_ptr,
            "Add a new curve to piecewise curve, which should be defined in T_{min},T_{max}] "
            "where T_{min} is equal toT_{max} of the actual piecewise curve.",
            args("self,curve"))
-      .def("is_continuous", &piecewise_SE3_curve_t::is_continuous, "Check if the curve is continuous at the given order.",args("self,order"))
-      .def("curve_at_index", &piecewise_SE3_curve_t::curve_at_index, return_value_policy<copy_const_reference>())
-      .def("curve_at_time", &piecewise_SE3_curve_t::curve_at_time, return_value_policy<copy_const_reference>())
-      .def("num_curves", &piecewise_SE3_curve_t::num_curves)
-      .def("rotation", &piecewiseSE3returnRotation, "Output the rotation (as a 3x3 matrix) at the given time.",
-           args("self", "t"))
-      .def("translation", &piecewiseSE3returnTranslation, "Output the translation (as a vector 3) at the given time.",
-           args("self", "t"))
-      .def("__call__", &piecewiseSE3Return, "Evaluate the curve at the given time. Return as an homogeneous matrix",
-           args("self", "t"))
-      .def("derivate", &piecewise_SE3_curve_t::derivate,
-           "Evaluate the derivative of order N of curve at time t. Return as a vector 6", args("self", "t", "N"))
-      .def("min", &piecewise_SE3_curve_t::min, "Get the LOWER bound on interval definition of the curve.")
-      .def("max", &piecewise_SE3_curve_t::max, "Get the HIGHER bound on interval definition of the curve.")
-      .def("dim", &piecewise_SE3_curve_t::dim, "Get the dimension of the curve.")
+      .def("is_continuous", &piecewise_SE3_t::is_continuous, "Check if the curve is continuous at the given order.",args("self,order"))
+      .def("curve_at_index", &piecewise_SE3_t::curve_at_index, return_value_policy<copy_const_reference>())
+      .def("curve_at_time", &piecewise_SE3_t::curve_at_time, return_value_policy<copy_const_reference>())
+      .def("num_curves", &piecewise_SE3_t::num_curves)
       .def("append", &addFinalTransform,
        "Append a new linear SE3 curve at the end of the piecewise curve, defined between self.max() "
        "and time and connecting exactly self(self.max()) and end",
        args("self", "end", "time"))
-      .def("saveAsText", &piecewise_SE3_curve_t::saveAsText<piecewise_SE3_curve_t>, bp::args("filename"),
+      .def("saveAsText", &piecewise_SE3_t::saveAsText<piecewise_SE3_t>, bp::args("filename"),
            "Saves *this inside a text file.")
-      .def("loadFromText", &piecewise_SE3_curve_t::loadFromText<piecewise_SE3_curve_t>, bp::args("filename"),
+      .def("loadFromText", &piecewise_SE3_t::loadFromText<piecewise_SE3_t>, bp::args("filename"),
            "Loads *this from a text file.")
-      .def("saveAsXML", &piecewise_SE3_curve_t::saveAsXML<piecewise_SE3_curve_t>,
+      .def("saveAsXML", &piecewise_SE3_t::saveAsXML<piecewise_SE3_t>,
            bp::args("filename", "tag_name"), "Saves *this inside a XML file.")
-      .def("loadFromXML", &piecewise_SE3_curve_t::loadFromXML<piecewise_SE3_curve_t>,
+      .def("loadFromXML", &piecewise_SE3_t::loadFromXML<piecewise_SE3_t>,
            bp::args("filename", "tag_name"), "Loads *this from a XML file.")
-      .def("saveAsBinary", &piecewise_SE3_curve_t::saveAsBinary<piecewise_SE3_curve_t>, bp::args("filename"),
+      .def("saveAsBinary", &piecewise_SE3_t::saveAsBinary<piecewise_SE3_t>, bp::args("filename"),
            "Saves *this inside a binary file.")
-      .def("loadFromBinary", &piecewise_SE3_curve_t::loadFromBinary<piecewise_SE3_curve_t>, bp::args("filename"),
+      .def("loadFromBinary", &piecewise_SE3_t::loadFromBinary<piecewise_SE3_t>, bp::args("filename"),
            "Loads *this from a binary file.")
         #ifdef CURVES_WITH_PINOCCHIO_SUPPORT
-          .def("evaluateAsSE3", &piecewiseSE3ReturnPinocchio, "Evaluate the curve at the given time. Return as a pinocchio.SE3 object",
-               args("self", "t"))
-          .def("derivateAsMotion", &piecewiseSE3ReturnDerivatePinocchio,
-               "Evaluate the derivative of order N of curve at time t. Return as a pinocchio.Motion",
-               args("self", "t", "N"))
           .def("append", &addFinalSE3,
            "Append a new linear SE3 curve at the end of the piecewise curve, defined between self.max() "
            "and time and connecting exactly self(self.max()) and end",
@@ -877,7 +787,7 @@ class_<piecewise_SE3_curve_t, bases<curve_abc_t> >("piecewise_SE3_curve", init<>
 
   /** END  SO3 Linear**/
   /** BEGIN SE3 Curve**/
-  class_<SE3Curve_t, bases<curve_abc_t> >("SE3Curve", init<>())
+  class_<SE3Curve_t, bases<curve_SE3_t> >("SE3Curve", init<>())
       .def("__init__",
            make_constructor(&wrapSE3CurveFromTransform, default_call_policies(),
                             args("init_transform", "end_transform", "min", "max")),
@@ -912,17 +822,6 @@ class_<piecewise_SE3_curve_t, bases<curve_abc_t> >("piecewise_SE3_curve", init<>
            "translation curve."
            "The orientation along the SE3Curve will be a slerp between the two given rotations."
            "The orientations should be represented as 3x3 rotation matrix")
-      .def("rotation", &se3returnRotation, "Output the rotation (as a 3x3 matrix) at the given time.",
-           args("self", "time"))
-      .def("translation", &se3returnTranslation, "Output the rotation (as a vector 3) at the given time.",
-           args("self", "time"))
-      .def("__call__", &se3Return, "Evaluate the curve at the given time. Return as an homogeneous matrix",
-           args("self", "t"))
-      .def("derivate", &se3ReturnDerivate,
-           "Evaluate the derivative of order N of curve at time t. Return as a vector 6", args("self", "t", "N"))
-      .def("min", &SE3Curve_t::min, "Get the LOWER bound on interval definition of the curve.")
-      .def("max", &SE3Curve_t::max, "Get the HIGHER bound on interval definition of the curve.")
-      .def("dim", &SE3Curve_t::dim, "Get the dimension of the curve.")
       .def("saveAsText", &SE3Curve_t::saveAsText<SE3Curve_t>,bp::args("filename"),
       "Saves *this inside a text file.")
       .def("loadFromText",&SE3Curve_t::loadFromText<SE3Curve_t>,bp::args("filename"),
@@ -941,22 +840,14 @@ class_<piecewise_SE3_curve_t, bases<curve_abc_t> >("piecewise_SE3_curve", init<>
                             args("init_SE3", "end_SE3", "min", "max")),
            "Create a SE3 curve between two SE3 objects from Pinocchio, defined for t in [min,max]."
            " Using linear interpolation for translation and slerp for rotation between init and end.")
-      .def("evaluateAsSE3", &se3ReturnPinocchio, "Evaluate the curve at the given time. Return as a pinocchio.SE3 object",
-           args("self", "t"))
-      .def("derivateAsMotion", &se3ReturnDerivatePinocchio,
-           "Evaluate the derivative of order N of curve at time t. Return as a pinocchio.Motion",
-           args("self", "t", "N"))
 #endif  // CURVES_WITH_PINOCCHIO_SUPPORT
       ;
 
   /** END SE3 Curve**/
   /** BEGIN curves conversion**/
-  def("polynomial_from_bezier", polynomial_from_curve<polynomial_t, bezier_t>);
-  def("polynomial_from_hermite", polynomial_from_curve<polynomial_t, cubic_hermite_spline_t>);
-  def("bezier_from_hermite", bezier_from_curve<bezier_t, cubic_hermite_spline_t>);
-  def("bezier_from_polynomial", bezier_from_curve<bezier_t, polynomial_t>);
-  def("hermite_from_bezier", hermite_from_curve<cubic_hermite_spline_t, bezier_t>);
-  def("hermite_from_polynomial", hermite_from_curve<cubic_hermite_spline_t, polynomial_t>);
+  def("convert_to_polynomial", polynomial_from_curve<polynomial_t>);
+  def("convert_to_bezier", bezier_from_curve<bezier_t>);
+  def("convert_to_hermite", hermite_from_curve<cubic_hermite_spline_t>);
   /** END curves conversion**/
 
   optimization::python::exposeOptimization();
diff --git a/python/python_definitions.h b/python/python_definitions.h
index d33b96380ee5d4719c8ca9d631338193b25ebf9f..02131a4ad25b0d927f4e52e93a052fec181bbe66 100644
--- a/python/python_definitions.h
+++ b/python/python_definitions.h
@@ -1,3 +1,4 @@
+#include "curves/fwd.h"
 #include "curves/bezier_curve.h"
 #include "curves/linear_variable.h"
 #include "curves/quadratic_variable.h"
@@ -8,24 +9,25 @@
 #define _DEFINITION_PYTHON_BINDINGS
 
 namespace curves {
+/*** TEMPLATE SPECIALIZATION FOR PYTHON ****/
 typedef double real;
-typedef Eigen::Vector3d point_t;
-typedef Eigen::Vector3d tangent_t;
-typedef Eigen::VectorXd vectorX_t;
-typedef std::pair<point_t, tangent_t> pair_point_tangent_t;
-typedef Eigen::Matrix<double, 6, 1, 0, 6, 1> point6_t;
-typedef Eigen::Matrix<double, 3, 1, 0, 3, 1> ret_point_t;
-typedef Eigen::Matrix<double, 6, 1, 0, 6, 1> ret_point6_t;
+typedef std::vector<real> t_time_t;
 typedef Eigen::VectorXd time_waypoints_t;
-typedef Eigen::Matrix<real, 3, Eigen::Dynamic> point_list_t;
+
+typedef Eigen::Matrix<double, Eigen::Dynamic, 1, 0, Eigen::Dynamic, 1> ret_pointX_t;
+typedef std::pair<pointX_t, pointX_t> pair_pointX_tangent_t;
+typedef Eigen::MatrixXd pointX_list_t;
+typedef std::vector<pair_pointX_tangent_t, Eigen::aligned_allocator<pair_pointX_tangent_t> > t_pair_pointX_tangent_t;
+typedef curves::curve_constraints<pointX_t> curve_constraints_t;
+typedef curves::curve_constraints<point3_t> curve_constraints3_t;
+typedef std::pair<real, pointX_t> waypoint_t;
+typedef std::vector<waypoint_t> t_waypoint_t;
+typedef Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> point_listX_t;
+typedef Eigen::Matrix<real, 3, Eigen::Dynamic> point_list3_t;
 typedef Eigen::Matrix<real, 6, Eigen::Dynamic> point_list6_t;
-typedef std::vector<real> t_time_t;
-typedef std::vector<point_t, Eigen::aligned_allocator<point_t> > t_point_t;
-typedef std::vector<point6_t, Eigen::aligned_allocator<point6_t> > t_point6_t;
-typedef std::pair<real, point_t> Waypoint;
-typedef std::vector<Waypoint> T_Waypoint;
-typedef std::pair<real, point6_t> Waypoint6;
-typedef std::vector<Waypoint6> T_Waypoint6;
+
+typedef polynomial_t::coeff_t coeff_t;
+typedef curves::Bern<double> bernstein_t;
 
 template <typename PointList, typename T_Point>
 T_Point vectorFromEigenArray(const PointList& array) {
diff --git a/python/python_variables.cpp b/python/python_variables.cpp
index 13e66c90d5ae1e9e4ed2a2bb9a4fcd47380458d9..c4fdc500a3b60e0bf42c579a03309961711351ec 100644
--- a/python/python_variables.cpp
+++ b/python/python_variables.cpp
@@ -4,7 +4,7 @@
 #include <Eigen/Core>
 
 namespace curves {
-std::vector<linear_variable_t> matrix3DFromEigenArray(const point_list_t& matrices, const point_list_t& vectors) {
+std::vector<linear_variable_t> matrix3DFromEigenArray(const point_list3_t& matrices, const point_list3_t& vectors) {
   assert(vectors.cols() * 3 == matrices.cols());
   std::vector<linear_variable_t> res;
   for (int i = 0; i < vectors.cols(); ++i) {
@@ -19,7 +19,7 @@ linear_variable_t fillWithZeros(const linear_variable_t& var, const std::size_t
   return linear_variable_t(B, var.c());
 }
 
-std::vector<linear_variable_t> computeLinearControlPoints(const point_list_t& matrices, const point_list_t& vectors) {
+std::vector<linear_variable_t> computeLinearControlPoints(const point_list3_t& matrices, const point_list3_t& vectors) {
   std::vector<linear_variable_t> res;
   std::vector<linear_variable_t> variables = matrix3DFromEigenArray(matrices, vectors);
   // now need to fill all this with zeros...
@@ -29,12 +29,12 @@ std::vector<linear_variable_t> computeLinearControlPoints(const point_list_t& ma
 }
 
 /*linear variable control points*/
-bezier_linear_variable_t* wrapBezierLinearConstructor(const point_list_t& matrices, const point_list_t& vectors) {
+bezier_linear_variable_t* wrapBezierLinearConstructor(const point_list3_t& matrices, const point_list3_t& vectors) {
   std::vector<linear_variable_t> asVector = computeLinearControlPoints(matrices, vectors);
   return new bezier_linear_variable_t(asVector.begin(), asVector.end());
 }
 
-bezier_linear_variable_t* wrapBezierLinearConstructorBounds(const point_list_t& matrices, const point_list_t& vectors,
+bezier_linear_variable_t* wrapBezierLinearConstructorBounds(const point_list3_t& matrices, const point_list3_t& vectors,
                                                             const real T_min, const real T_max) {
   std::vector<linear_variable_t> asVector = computeLinearControlPoints(matrices, vectors);
   return new bezier_linear_variable_t(asVector.begin(), asVector.end(), T_min, T_max);
diff --git a/python/python_variables.h b/python/python_variables.h
index 70ebfcbe6bcf94ef3e830dde7950262e60a188d3..9e4d2906debce8a76415560cc5ec6a38c1e37e8d 100644
--- a/python/python_variables.h
+++ b/python/python_variables.h
@@ -1,3 +1,4 @@
+#include "curves/fwd.h"
 #include "curves/linear_variable.h"
 #include "curves/bezier_curve.h"
 #include "curves/polynomial.h"
@@ -27,8 +28,8 @@ typedef quadratic_variable<real> quadratic_variable_t;
 typedef bezier_curve<real, real, true, linear_variable_t> bezier_linear_variable_t;
 
 /*linear variable control points*/
-bezier_linear_variable_t* wrapBezierLinearConstructor(const point_list_t& matrices, const point_list_t& vectors);
-bezier_linear_variable_t* wrapBezierLinearConstructorBounds(const point_list_t& matrices, const point_list_t& vectors,
+bezier_linear_variable_t* wrapBezierLinearConstructor(const point_list3_t& matrices, const point_list3_t& vectors);
+bezier_linear_variable_t* wrapBezierLinearConstructorBounds(const point_list3_t& matrices, const point_list3_t& vectors,
                                                             const real T_min, const real T_max);
 
 typedef Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic> matrix_x_t;
@@ -57,74 +58,29 @@ struct LinearBezierVector {
   }
 };
 
-/*** TEMPLATE SPECIALIZATION FOR PYTHON ****/
-typedef double real;
-typedef Eigen::VectorXd time_waypoints_t;
-
-typedef Eigen::VectorXd pointX_t;
-typedef Eigen::Matrix<double, 3, 1> point3_t;
-typedef Eigen::Matrix<double, Eigen::Dynamic, 1, 0, Eigen::Dynamic, 1> ret_pointX_t;
-typedef std::pair<pointX_t, pointX_t> pair_pointX_tangent_t;
-typedef Eigen::MatrixXd pointX_list_t;
-typedef std::vector<pointX_t, Eigen::aligned_allocator<pointX_t> > t_pointX_t;
-typedef std::vector<pointX_t, Eigen::aligned_allocator<point3_t> > t_point3_t;
-typedef std::vector<pair_pointX_tangent_t, Eigen::aligned_allocator<pair_pointX_tangent_t> > t_pair_pointX_tangent_t;
-typedef curves::curve_constraints<pointX_t> curve_constraints_t;
-typedef curves::curve_constraints<point3_t> curve_constraints3_t;
-typedef std::pair<real, pointX_t> waypoint_t;
-typedef std::vector<waypoint_t> t_waypoint_t;
-typedef Eigen::Matrix<real, 3, 3> matrix3_t;
-typedef Eigen::Matrix<real, 4, 4> matrix4_t;
-typedef Eigen::Transform<double, 3, Eigen::Affine> transform_t;
-typedef Eigen::Quaternion<real> quaternion_t;
-
-// Curves
-typedef curve_abc<real, real, true, pointX_t> curve_abc_t;  // generic class of curve
-typedef curve_abc<real, real, true, point3_t> curve_3_t;    // generic class of curve of size 3
-typedef curve_abc<real, real, true, matrix3_t, point3_t>
-    curve_rotation_t;  // templated class used for the rotation (return dimension are fixed)
-typedef boost::shared_ptr<curve_abc_t> curve_ptr_t;
-typedef boost::shared_ptr<curve_rotation_t> curve_rotation_ptr_t;
-typedef curves::cubic_hermite_spline<real, real, true, pointX_t> cubic_hermite_spline_t;
-typedef curves::bezier_curve<real, real, true, pointX_t> bezier_t;
-typedef curves::bezier_curve<real, real, true, Eigen::Vector3d> bezier3_t;
-typedef curves::polynomial<real, real, true, pointX_t, t_pointX_t> polynomial_t;
-typedef polynomial_t::coeff_t coeff_t;
-typedef curves::piecewise_curve<real, real, true, pointX_t, t_pointX_t, polynomial_t> piecewise_polynomial_curve_t;
-typedef curves::piecewise_curve<real, real, true, pointX_t, t_pointX_t, bezier_t> piecewise_bezier_curve_t;
-typedef curves::piecewise_curve<real, real, true, pointX_t, t_pointX_t, cubic_hermite_spline_t>
-    piecewise_cubic_hermite_curve_t;
-typedef curves::piecewise_curve<real, real, true, linear_variable_t,
-                                std::vector<linear_variable_t, Eigen::aligned_allocator<linear_variable_t> >,
-                                bezier_linear_variable_t>
-    piecewise_bezier_linear_curve_t;
-typedef curves::exact_cubic<real, real, true, pointX_t, t_pointX_t> exact_cubic_t;
-typedef SO3Linear<double, double, true> SO3Linear_t;
-typedef SE3Curve<double, double, true> SE3Curve_t;
-typedef curves::piecewise_curve<real, real, true, SE3Curve_t::point_t, t_pointX_t, SE3Curve_t,SE3Curve_t::point_derivate_t> piecewise_SE3_curve_t;
-typedef curves::Bern<double> bernstein_t;
 
 /*** TEMPLATE SPECIALIZATION FOR PYTHON ****/
 }  // namespace curves
-
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::bernstein_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::cubic_hermite_spline_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::bezier_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::bezier3_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::polynomial_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::curve_constraints_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_polynomial_curve_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_bezier_curve_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_cubic_hermite_curve_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_bezier_linear_curve_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::exact_cubic_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::SO3Linear_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::SE3Curve_t)
-EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_SE3_curve_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::matrix_x_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::pointX_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::linear_variable_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::bezier_linear_variable_t)
 EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::matrix_pair)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::polynomial_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::exact_cubic_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::bezier_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::cubic_hermite_spline_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::polynomial3_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::exact_cubic3_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::bezier3_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::cubic_hermite_spline3_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise3_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::SO3Linear_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::SE3Curve_t)
+EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(curves::piecewise_SE3_t)
+
 
 #endif  //_VARIABLES_PYTHON_BINDINGS
diff --git a/python/test/test.py b/python/test/test.py
index a7dc24149a95ed57dcfaab71117fd19ae245c536..a9de8c253e60d5d92d21ebcf16126e570b39a2fe 100644
--- a/python/test/test.py
+++ b/python/test/test.py
@@ -8,10 +8,8 @@ from numpy import array, array_equal, isclose, random, zeros
 from numpy.linalg import norm
 
 from curves import (CURVES_WITH_PINOCCHIO_SUPPORT, Quaternion, SE3Curve, SO3Linear, bezier, bezier3,
-                    bezier_from_hermite, bezier_from_polynomial, cubic_hermite_spline, curve_constraints, exact_cubic,
-                    hermite_from_bezier, hermite_from_polynomial, piecewise_bezier_curve,
-                    piecewise_cubic_hermite_curve, piecewise_polynomial_curve,piecewise_SE3_curve, polynomial, polynomial_from_bezier,
-                    polynomial_from_hermite)
+                    cubic_hermite_spline, curve_constraints, exact_cubic,polynomial,
+                    piecewise, piecewise_SE3, convert_to_polynomial,convert_to_bezier,convert_to_hermite)
 
 eigenpy.switchToNumpyArray()
 
@@ -28,13 +26,15 @@ class TestCurves(unittest.TestCase):
     def compareCurves(self,c1,c2):
         t_min = c1.min()
         t_max = c1.max()
-        self.assertEqual(t_min,c2.min())
-        self.assertEqual(t_max,c2.max())
-        self.assertTrue(norm(c1.derivate(t_min, 1) - c2.derivate(t_min, 1)) < 1e-10)
-        self.assertTrue(norm(c1.derivate(t_max, 1) - c2.derivate(t_max, 1)) < 1e-10)
+        self.assertEqual(t_min,c2.min(),"c1 min : "+str(t_min)+" ; c2 min : "+str(c2.min()))
+        self.assertEqual(t_max,c2.max(),"c1 max : "+str(t_max)+" ; c2 max : "+str(c2.max()))
+        self.assertTrue(norm(c1.derivate(t_min, 1) - c2.derivate(t_min, 1)) < 1e-10,
+        "dc1(tmin) = "+str(c1.derivate(t_min, 1))+" ; dc2(tmin) = "+str(c2.derivate(t_min, 1)))
+        self.assertTrue(norm(c1.derivate(t_max, 1) - c2.derivate(t_max, 1)) < 1e-10,
+        "dc1(tmax) = "+str(c1.derivate(t_max, 1))+" ; dc2(tmax) = "+str(c2.derivate(t_max, 1)))
         t = t_min
         while t < t_max:
-          self.assertTrue(norm(c1(t) - c2(t)) < 1e-10)
+          self.assertTrue(norm(c1(t) - c2(t)) < 1e-10," at t = "+str(t)+" c1 = "+str(c1(t))+" ; c2 = "+str(c2(t)))
           t = t+0.01
 
 
@@ -69,7 +69,6 @@ class TestCurves(unittest.TestCase):
         a.max()
         a(0.4)
         self.assertTrue((a(a.min()) == array([1., 2., 3.])).all())
-        self.assertTrue((a.derivate(0.4, 0) == a(0.4)).all())
         a.derivate(0.4, 2)
         a = a.compute_derivate(100)
         prim = a.compute_primitive(1)
@@ -161,7 +160,6 @@ class TestCurves(unittest.TestCase):
         a.max()
         a(0.4)
         self.assertTrue((a(a.min()) == array([1., 2., 3.])).all())
-        self.assertTrue((a.derivate(0.4, 0) == a(0.4)).all())
         a.derivate(0.4, 2)
         a = a.compute_derivate(100)
         prim = a.compute_primitive(1)
@@ -337,7 +335,7 @@ class TestCurves(unittest.TestCase):
         polynomial(waypoints0, 0., 0.1)
         a = polynomial(waypoints1, 0., 1.)
         b = polynomial(waypoints2, 1., 3.)
-        pc = piecewise_polynomial_curve(a)
+        pc = piecewise(a)
         pc.append(b)
         pc.min()
         pc.max()
@@ -349,7 +347,7 @@ class TestCurves(unittest.TestCase):
         pc.is_continuous(1)
         # Test serialization
         pc.saveAsText("serialization_pc.test")
-        pc_test = piecewise_polynomial_curve()
+        pc_test = piecewise()
         pc_test.loadFromText("serialization_pc.test")
         self.assertTrue((pc(0.4) == pc_test(0.4)).all())
         os.remove("serialization_pc.test")
@@ -361,7 +359,7 @@ class TestCurves(unittest.TestCase):
           pc.append(c)
 
         ### Test the different append methods :
-        pc = piecewise_polynomial_curve()
+        pc = piecewise()
         self.assertEqual(pc.num_curves(),0)
         end_point1 = array([1.,3.,5.,6.5,-2.])
         max1 = 2.5
@@ -371,7 +369,7 @@ class TestCurves(unittest.TestCase):
           pc.append(a)
           pc.append(end_point1,max1)
 
-        pc = piecewise_polynomial_curve()
+        pc = piecewise()
         d = polynomial(waypoints3, 0., 1.2)
         self.assertEqual(pc.num_curves(),0)
         pc.append(d)
@@ -393,7 +391,7 @@ class TestCurves(unittest.TestCase):
         points_second_derivative = array(random.rand(3, N))
         time_points = array(random.rand(1, N)).T
         time_points.sort(0)
-        polC0 = piecewise_polynomial_curve.FromPointsList(points, time_points)
+        polC0 = piecewise.FromPointsList(points, time_points)
         self.assertEqual(polC0.min(), time_points[0, 0])
         self.assertEqual(polC0.max(), time_points[-1, 0])
         self.assertTrue(polC0.is_continuous(0))
@@ -401,7 +399,7 @@ class TestCurves(unittest.TestCase):
         for i in range(N):
             self.assertTrue(isclose(polC0(time_points[i, 0]), points[:, i]).all())
 
-        polC1 = piecewise_polynomial_curve.FromPointsList(points, points_derivative, time_points)
+        polC1 = piecewise.FromPointsList(points, points_derivative, time_points)
         self.assertEqual(polC1.min(), time_points[0, 0])
         self.assertEqual(polC1.max(), time_points[-1, 0])
         self.assertTrue(polC1.is_continuous(0))
@@ -411,7 +409,7 @@ class TestCurves(unittest.TestCase):
             self.assertTrue(isclose(polC1(time_points[i, 0]), points[:, i]).all())
             self.assertTrue(isclose(polC1.derivate(time_points[i, 0], 1), points_derivative[:, i]).all())
 
-        polC2 = piecewise_polynomial_curve.FromPointsList(points, points_derivative, points_second_derivative,
+        polC2 = piecewise.FromPointsList(points, points_derivative, points_second_derivative,
                                                           time_points)
         self.assertEqual(polC2.min(), time_points[0, 0])
         self.assertEqual(polC2.max(), time_points[-1, 0])
@@ -428,13 +426,13 @@ class TestCurves(unittest.TestCase):
         time_points[0, 0] = 1
         time_points[1, 0] = 0.5
         with self.assertRaises(ValueError):
-            polC0 = piecewise_polynomial_curve.FromPointsList(points, time_points)
+            polC0 = piecewise.FromPointsList(points, time_points)
 
         with self.assertRaises(ValueError):
-            polC1 = piecewise_polynomial_curve.FromPointsList(points, points_derivative, time_points)
+            polC1 = piecewise.FromPointsList(points, points_derivative, time_points)
 
         with self.assertRaises(ValueError):
-            polC2 = piecewise_polynomial_curve.FromPointsList(points, points_derivative, points_second_derivative,
+            polC2 = piecewise.FromPointsList(points, points_derivative, points_second_derivative,
                                                               time_points)
 
     def test_piecewise_bezier_curve(self):
@@ -443,7 +441,7 @@ class TestCurves(unittest.TestCase):
         waypoints = array([[1., 2., 3.], [4., 5., 6.]]).transpose()
         a = bezier(waypoints, 0., 1.)
         b = bezier(waypoints, 1., 2.)
-        pc = piecewise_bezier_curve(a)
+        pc = piecewise(a)
         pc.append(b)
         pc.min()
         pc.max()
@@ -455,7 +453,7 @@ class TestCurves(unittest.TestCase):
         pc.is_continuous(1)
         # Test serialization
         pc.saveAsText("serialization_pc.test")
-        pc_test = piecewise_bezier_curve()
+        pc_test = piecewise()
         pc_test.loadFromText("serialization_pc.test")
         self.assertTrue((pc(0.4) == pc_test(0.4)).all())
         os.remove("serialization_pc.test")
@@ -471,7 +469,7 @@ class TestCurves(unittest.TestCase):
         time_points1 = array([[1., 2.]]).transpose()
         a = cubic_hermite_spline(points, tangents, time_points0)
         b = cubic_hermite_spline(points, tangents, time_points1)
-        pc = piecewise_cubic_hermite_curve(a)
+        pc = piecewise(a)
         pc.append(b)
         pc.min()
         pc.max()
@@ -483,7 +481,7 @@ class TestCurves(unittest.TestCase):
         pc.is_continuous(1)
         # Test serialization
         pc.saveAsText("serialization_pc.test")
-        pc_test = piecewise_cubic_hermite_curve()
+        pc_test = piecewise()
         pc_test.loadFromText("serialization_pc.test")
         self.assertTrue((pc(0.4) == pc_test(0.4)).all())
         os.remove("serialization_pc.test")
@@ -550,23 +548,23 @@ class TestCurves(unittest.TestCase):
         waypoints = array([[1., 2., 3.], [4., 5., 6.]]).transpose()
         a = bezier(waypoints)
         # converting bezier to polynomial
-        a_pol = polynomial_from_bezier(a)
+        a_pol = convert_to_polynomial(a)
         self.assertTrue(norm(a(0.3) - a_pol(0.3)) < __EPS)
         # converting polynomial to hermite
-        a_chs = hermite_from_polynomial(a_pol)
+        a_chs = convert_to_hermite(a_pol)
         self.assertTrue(norm(a_chs(0.3) - a_pol(0.3)) < __EPS)
         # converting hermite to bezier
-        a_bc = bezier_from_hermite(a_chs)
+        a_bc = convert_to_bezier(a_chs)
         self.assertTrue(norm(a_chs(0.3) - a_bc(0.3)) < __EPS)
         self.assertTrue(norm(a(0.3) - a_bc(0.3)) < __EPS)
         # converting bezier to hermite
-        a_chs = hermite_from_bezier(a)
+        a_chs = convert_to_hermite(a)
         self.assertTrue(norm(a(0.3) - a_chs(0.3)) < __EPS)
         # converting hermite to polynomial
-        a_pol = polynomial_from_hermite(a_chs)
+        a_pol = convert_to_polynomial(a_chs)
         self.assertTrue(norm(a_pol(0.3) - a_chs(0.3)) < __EPS)
         # converting polynomial to bezier
-        a_bc = bezier_from_polynomial(a_pol)
+        a_bc = convert_to_bezier(a_pol)
         self.assertTrue(norm(a_bc(0.3) - a_pol(0.3)) < __EPS)
         self.assertTrue(norm(a(0.3) - a_bc(0.3)) < __EPS)
         return
@@ -582,7 +580,7 @@ class TestCurves(unittest.TestCase):
       translation = bezier(waypoints, min, max)
       # test with bezier
       se3 = SE3Curve(translation, init_rot, end_rot)
-      pc = piecewise_SE3_curve(se3)
+      pc = piecewise_SE3(se3)
       self.assertEqual(pc.num_curves(),1)
       self.assertEqual(pc.min(), min)
       self.assertEqual(pc.max(), max)
@@ -616,17 +614,17 @@ class TestCurves(unittest.TestCase):
         pc.append(se3_3)
 
       pc.saveAsText("serialization_curve.txt")
-      pc_txt = piecewise_SE3_curve()
+      pc_txt = piecewise_SE3()
       pc_txt.loadFromText("serialization_curve.txt")
       self.compareCurves(pc,pc_txt)
 
       pc.saveAsXML("serialization_curve.xml","pc")
-      pc_xml = piecewise_SE3_curve()
+      pc_xml = piecewise_SE3()
       pc_xml.loadFromXML("serialization_curve.xml","pc")
       self.compareCurves(pc,pc_xml)
 
       pc.saveAsBinary("serialization_curve")
-      pc_bin = piecewise_SE3_curve()
+      pc_bin = piecewise_SE3()
       pc_bin.loadFromBinary("serialization_curve")
       self.compareCurves(pc,pc_bin)
 
@@ -646,7 +644,7 @@ class TestCurves(unittest.TestCase):
       translation = bezier(waypoints, min, max)
       # test with bezier
       se3 = SE3Curve(translation, init_rot, end_rot)
-      pc = piecewise_SE3_curve()
+      pc = piecewise_SE3()
       self.assertEqual(pc.num_curves(),0)
       pc.append(se3)
       self.assertEqual(pc.num_curves(),1)
@@ -696,7 +694,7 @@ class TestCurves(unittest.TestCase):
         self.assertTrue(isclose(pmin[0:3, 3], translation(min)).all())
         self.assertTrue(isclose(pmax[0:3, 3], end_translation).all())
         self.assertTrue(pc.is_continuous(0))
-      pc = piecewise_SE3_curve()
+      pc = piecewise_SE3()
       with self.assertRaises(RuntimeError):
         pc.append(end_pose,max)
 
@@ -719,7 +717,7 @@ class TestCurves(unittest.TestCase):
             min = 0.7
             max = 12.
             se3 = SE3Curve(init_pose, end_pose, min, max)
-            pc = piecewise_SE3_curve(se3)
+            pc = piecewise_SE3(se3)
             self.assertEqual(pc.num_curves(),1)
             p = pc.evaluateAsSE3(min)
             self.assertTrue(isinstance(p, SE3))
@@ -754,17 +752,17 @@ class TestCurves(unittest.TestCase):
         waypoints = array([[1., 2., 3.], [4., 5., 6.]]).transpose()
         a = bezier(waypoints, 0., 1.)
         b = bezier(waypoints, 1., 2.)
-        pc = piecewise_bezier_curve(a)
+        pc = piecewise(a)
         pc.append(b)
         # Convert to piecewise polynomial
         pc_pol = pc.convert_piecewise_curve_to_polynomial()
-        self.assertTrue(norm(pc_pol(0.3) - pc(0.3)) < __EPS)
+        self.compareCurves(pc_pol, pc)
         # Convert to piecewise cubic hermite
         pc_chs = pc.convert_piecewise_curve_to_cubic_hermite()
-        self.assertTrue(norm(pc_chs(0.3) - pc(0.3)) < __EPS)
+        self.compareCurves(pc_chs, pc)
         # Convert to piecewise bezier
         pc_bc = pc_chs.convert_piecewise_curve_to_bezier()
-        self.assertTrue(norm(pc_bc(0.3) - pc(0.3)) < __EPS)
+        self.compareCurves(pc_bc, pc)
         return
 
     def test_so3_linear(self):
@@ -992,7 +990,7 @@ class TestCurves(unittest.TestCase):
         # points_second_derivative = array(random.rand(3, N))
         time_points = array(random.rand(1, N)).T
         time_points.sort(0)
-        translation = piecewise_polynomial_curve.FromPointsList(points, time_points)
+        translation = piecewise.FromPointsList(points, time_points)
         min = translation.min()
         max = translation.max()
         se3 = SE3Curve(translation, init_rot, end_rot)
diff --git a/tests/Main.cpp b/tests/Main.cpp
index 5c513e755dc0a02235ea33a59829b85cfd8dcb13..5f2621949c640b91130bd9b14d7a672a07e2a8d7 100644
--- a/tests/Main.cpp
+++ b/tests/Main.cpp
@@ -1,4 +1,4 @@
-
+#include "curves/fwd.h"
 #include "curves/exact_cubic.h"
 #include "curves/bezier_curve.h"
 #include "curves/polynomial.h"
@@ -15,29 +15,14 @@
 #include <iostream>
 #include <cmath>
 #include <ctime>
+#include <boost/smart_ptr/shared_ptr.hpp>
 
 using namespace std;
 
 namespace curves {
-typedef Eigen::Vector3d point3_t;
-typedef Eigen::VectorXd pointX_t;
-typedef Eigen::Matrix<double, 3, 3> matrix3_t;
-typedef Eigen::Quaternion<double> quaternion_t;
-typedef std::vector<pointX_t, Eigen::aligned_allocator<pointX_t> > t_pointX_t;
-typedef curve_abc<double, double, true, pointX_t> curve_abc_t;
-typedef curve_abc<double, double, true, matrix3_t, point3_t> curve_rotation_t;  // templated class used for the rotation (return dimension are fixed)
-typedef boost::shared_ptr<curve_abc_t> curve_ptr_t;
-typedef boost::shared_ptr<curve_rotation_t> curve_rotation_ptr_t;
-typedef polynomial<double, double, true, pointX_t, t_pointX_t> polynomial_t;
-typedef exact_cubic<double, double, true, pointX_t> exact_cubic_t;
 typedef exact_cubic<double, double, true, Eigen::Matrix<double, 1, 1> > exact_cubic_one;
-typedef bezier_curve<double, double, true, pointX_t> bezier_curve_t;
-typedef cubic_hermite_spline<double, double, true, pointX_t> cubic_hermite_spline_t;
-typedef piecewise_curve<double, double, true, pointX_t, t_pointX_t, polynomial_t> piecewise_polynomial_curve_t;
-typedef piecewise_curve<double, double, true, pointX_t, t_pointX_t, bezier_curve_t> piecewise_bezier_curve_t;
-typedef piecewise_curve<double, double, true, pointX_t, t_pointX_t, cubic_hermite_spline_t>
-    piecewise_cubic_hermite_curve_t;
 typedef exact_cubic_t::spline_constraints spline_constraints_t;
+
 typedef std::pair<double, pointX_t> Waypoint;
 typedef std::vector<Waypoint> T_Waypoint;
 typedef Eigen::Matrix<double, 1, 1> point_one;
@@ -45,9 +30,7 @@ typedef std::pair<double, point_one> WaypointOne;
 typedef std::vector<WaypointOne> T_WaypointOne;
 typedef std::pair<pointX_t, pointX_t> pair_point_tangent_t;
 typedef std::vector<pair_point_tangent_t, Eigen::aligned_allocator<pair_point_tangent_t> > t_pair_point_tangent_t;
-typedef SO3Linear<double, double, true> SO3Linear_t;
-typedef SE3Curve<double, double, true> SE3Curve_t;
-typedef Eigen::Transform<double, 3, Eigen::Affine> transform_t;
+
 
 
 const double margin = 1e-3;
@@ -85,11 +68,11 @@ void ComparePoints(const Eigen::MatrixXd& pt1, const Eigen::MatrixXd& pt2, const
 }
 
 template <typename curve1, typename curve2>
-void CompareCurves(curve1 c1, curve2 c2, const std::string& errMsg, bool& error ,double prec = Eigen::NumTraits<double>::dummy_precision()) {
+void CompareCurves(const curve1& c1,const curve2& c2, const std::string& errMsg, bool& error ,double prec = Eigen::NumTraits<double>::dummy_precision()) {
   double T_min = c1.min();
   double T_max = c1.max();
   if (!QuasiEqual(T_min, c2.min()) || !QuasiEqual(T_max, c2.max())) {
-    std::cout << "CompareCurves, ERROR, time min and max of curves do not match [" << T_min << "," << T_max << "] "
+    std::cout << errMsg<<"CompareCurves, ERROR, time min and max of curves do not match [" << T_min << "," << T_max << "] "
               << " and [" << c2.min() << "," << c2.max() << "] " << std::endl;
     error = true;
   } else {
@@ -162,17 +145,17 @@ void PolynomialCubicFunctionTest(bool& error) {
   }
   // Test derivate and compute_derivative
   // Order 1
-  polynomial_t cf_derivated = cf.compute_derivate(1);
-  ComparePoints(cf.derivate(0, 1), cf_derivated(0), errMsg + " - derivate order 1 : ", error);
-  ComparePoints(cf.derivate(0.3, 1), cf_derivated(0.3), errMsg + " - derivate order 1 : ", error);
-  ComparePoints(cf.derivate(0.5, 1), cf_derivated(0.5), errMsg + " - derivate order 1 : ", error);
-  ComparePoints(cf.derivate(1, 1), cf_derivated(1), errMsg + " - derivate order 1 : ", error);
+  curve_abc_t* cf_derivated = cf.compute_derivate_ptr(1);
+  ComparePoints(cf.derivate(0, 1), (*cf_derivated)(0), errMsg + " - derivate order 1 : ", error);
+  ComparePoints(cf.derivate(0.3, 1), (*cf_derivated)(0.3), errMsg + " - derivate order 1 : ", error);
+  ComparePoints(cf.derivate(0.5, 1), (*cf_derivated)(0.5), errMsg + " - derivate order 1 : ", error);
+  ComparePoints(cf.derivate(1, 1), (*cf_derivated)(1), errMsg + " - derivate order 1 : ", error);
   // Order 2
   polynomial_t cf_derivated_2 = cf.compute_derivate(2);
-  ComparePoints(cf.derivate(0, 2), cf_derivated_2(0), errMsg + " - derivate order 1 : ", error);
-  ComparePoints(cf.derivate(0.3, 2), cf_derivated_2(0.3), errMsg + " - derivate order 1 : ", error);
-  ComparePoints(cf.derivate(0.5, 2), cf_derivated_2(0.5), errMsg + " - derivate order 1 : ", error);
-  ComparePoints(cf.derivate(1, 2), cf_derivated_2(1), errMsg + " - derivate order 1 : ", error);
+  ComparePoints(cf.derivate(0, 2), (cf_derivated_2)(0), errMsg + " - derivate order 1 : ", error);
+  ComparePoints(cf.derivate(0.3, 2), (cf_derivated_2)(0.3), errMsg + " - derivate order 1 : ", error);
+  ComparePoints(cf.derivate(0.5, 2), (cf_derivated_2)(0.5), errMsg + " - derivate order 1 : ", error);
+  ComparePoints(cf.derivate(1, 2), (cf_derivated_2)(1), errMsg + " - derivate order 1 : ", error);
 }
 
 /*bezier_curve Function tests*/
@@ -185,7 +168,7 @@ void BezierCurveTest(bool& error) {
   std::vector<point3_t> params;
   params.push_back(a);
   // 1d curve in [0,1]
-  bezier_curve_t cf1(params.begin(), params.end());
+  bezier_t cf1(params.begin(), params.end());
   point3_t res1;
   res1 = cf1(0);
   point3_t x10 = a;
@@ -194,7 +177,7 @@ void BezierCurveTest(bool& error) {
   ComparePoints(x10, res1, errMsg + "1(1) ", error);
   // 2d curve in [0,1]
   params.push_back(b);
-  bezier_curve_t cf(params.begin(), params.end());
+  bezier_t cf(params.begin(), params.end());
   res1 = cf(0);
   point3_t x20 = a;
   ComparePoints(x20, res1, errMsg + "2(0) ", error);
@@ -203,22 +186,26 @@ void BezierCurveTest(bool& error) {
   ComparePoints(x21, res1, errMsg + "2(1) ", error);
   // 3d curve in [0,1]
   params.push_back(c);
-  bezier_curve_t cf3(params.begin(), params.end());
+  bezier_t cf3(params.begin(), params.end());
   res1 = cf3(0);
   ComparePoints(a, res1, errMsg + "3(0) ", error);
   res1 = cf3(1);
   ComparePoints(c, res1, errMsg + "3(1) ", error);
   // 4d curve in [1,2]
   params.push_back(d);
-  bezier_curve_t cf4(params.begin(), params.end(), 1., 2.);
+  bezier_t cf4(params.begin(), params.end(), 1., 2.);
   // testing bernstein polynomials
-  bezier_curve_t cf5(params.begin(), params.end(), 1., 2.);
+  bezier_t cf5(params.begin(), params.end(), 1., 2.);
   std::string errMsg2("In test BezierCurveTest ; Bernstein polynomials do not evaluate as analytical evaluation");
+  bezier_t cf5_derivated = cf5.compute_derivate(1);
+
   for (double d = 1.; d < 2.; d += 0.1) {
     ComparePoints(cf5.evalBernstein(d), cf5(d), errMsg2, error);
     ComparePoints(cf5.evalHorner(d), cf5(d), errMsg2, error);
-    ComparePoints(cf5.compute_derivate(1).evalBernstein(d), cf5.compute_derivate(1)(d), errMsg2, error);
-    ComparePoints(cf5.compute_derivate(1).evalHorner(d), cf5.compute_derivate(1)(d), errMsg2, error);
+    ComparePoints(cf5_derivated.evalBernstein(d), cf5_derivated(d), errMsg2, error);
+    ComparePoints(cf5_derivated.evalHorner(d), cf5_derivated(d), errMsg2, error);
+    ComparePoints(cf5.derivate(d,1), cf5_derivated(d), errMsg2, error);
+
   }
   bool error_in(true);
   try {
@@ -272,7 +259,7 @@ void BezierCurveTestCompareHornerAndBernstein(bool&)  // error
   params.push_back(b);
   params.push_back(c);
   // 3d curve
-  bezier_curve_t cf(params.begin(), params.end());  // defined in [0,1]
+  bezier_t cf(params.begin(), params.end());  // defined in [0,1]
   // Check all evaluation of bezier curve
   clock_t s0, e0, s1, e1, s2, e2, s3, e3;
   s0 = clock();
@@ -307,7 +294,7 @@ void BezierCurveTestCompareHornerAndBernstein(bool&)  // error
   params.push_back(g);
   params.push_back(h);
   params.push_back(i);
-  bezier_curve_t cf2(params.begin(), params.end());
+  bezier_t cf2(params.begin(), params.end());
   s1 = clock();
   for (std::vector<double>::const_iterator cit = values.begin(); cit != values.end(); ++cit) {
     cf2.evalBernstein(*cit);
@@ -343,8 +330,7 @@ void BezierDerivativeCurveTest(bool& error) {
   params.push_back(a);
   params.push_back(b);
   params.push_back(c);
-  bezier_curve_t cf3(params.begin(), params.end());
-  ComparePoints(cf3(0), cf3.derivate(0., 0), errMsg, error);
+  bezier_t cf3(params.begin(), params.end());
   ComparePoints(cf3(0), cf3.derivate(0., 1), errMsg, error, true);
   ComparePoints(point3_t::Zero(), cf3.derivate(0., 100), errMsg, error);
 }
@@ -368,8 +354,8 @@ void BezierDerivativeCurveTimeReparametrizationTest(bool& error) {
   double Tmin = 0.;
   double Tmax = 2.;
   double diffT = Tmax - Tmin;
-  bezier_curve_t cf(params.begin(), params.end());
-  bezier_curve_t cfT(params.begin(), params.end(), Tmin, Tmax);
+  bezier_t cf(params.begin(), params.end());
+  bezier_t cfT(params.begin(), params.end(), Tmin, Tmax);
   ComparePoints(cf(0.5), cfT(1), errMsg, error);
   ComparePoints(cf.derivate(0.5, 1), cfT.derivate(1, 1) * (diffT), errMsg, error);
   ComparePoints(cf.derivate(0.5, 2), cfT.derivate(1, 2) * diffT * diffT, errMsg, error);
@@ -380,7 +366,7 @@ void BezierDerivativeCurveConstraintTest(bool& error) {
   point3_t a(1, 2, 3);
   point3_t b(2, 3, 4);
   point3_t c(3, 4, 5);
-  bezier_curve_t::curve_constraints_t constraints(3);
+  bezier_t::curve_constraints_t constraints(3);
   constraints.init_vel = point3_t(-1, -1, -1);
   constraints.init_acc = point3_t(-2, -2, -2);
   constraints.end_vel = point3_t(-10, -10, -10);
@@ -389,9 +375,9 @@ void BezierDerivativeCurveConstraintTest(bool& error) {
   params.push_back(a);
   params.push_back(b);
   params.push_back(c);
-  bezier_curve_t::num_t T_min = 1.0;
-  bezier_curve_t::num_t T_max = 3.0;
-  bezier_curve_t cf(params.begin(), params.end(), constraints, T_min, T_max);
+  bezier_t::num_t T_min = 1.0;
+  bezier_t::num_t T_max = 3.0;
+  bezier_t cf(params.begin(), params.end(), constraints, T_min, T_max);
   ComparePoints(a, cf(T_min), errMsg0, error);
   ComparePoints(c, cf(T_max), errMsg0, error);
   ComparePoints(constraints.init_vel, cf.derivate(T_min, 1), errMsg0, error);
@@ -435,11 +421,11 @@ void toPolynomialConversionTest(bool& error) {
   control_points.push_back(g);
   control_points.push_back(h);
   control_points.push_back(i);
-  bezier_curve_t::num_t T_min = 1.0;
-  bezier_curve_t::num_t T_max = 3.0;
-  bezier_curve_t bc(control_points.begin(), control_points.end(), T_min, T_max);
-  polynomial_t pol = polynomial_from_curve<polynomial_t, bezier_curve_t>(bc);
-  CompareCurves<polynomial_t, bezier_curve_t>(pol, bc, errMsg, error);
+  bezier_t::num_t T_min = 1.0;
+  bezier_t::num_t T_max = 3.0;
+  bezier_t bc(control_points.begin(), control_points.end(), T_min, T_max);
+  polynomial_t pol = polynomial_from_curve<polynomial_t>(bc);
+  CompareCurves<polynomial_t, bezier_t>(pol, bc, errMsg, error);
 }
 
 void cubicConversionTest(bool& error) {
@@ -468,38 +454,38 @@ void cubicConversionTest(bool& error) {
   // hermite to bezier
   // std::cout<<"======================= \n";
   // std::cout<<"hermite to bezier \n";
-  bezier_curve_t bc0 = bezier_from_curve<bezier_curve_t, cubic_hermite_spline_t>(chs0);
-  CompareCurves<cubic_hermite_spline_t, bezier_curve_t>(chs0, bc0, errMsg0, error);
+  bezier_t bc0 = bezier_from_curve<bezier_t>(chs0);
+  CompareCurves<cubic_hermite_spline_t, bezier_t>(chs0, bc0, errMsg0, error);
   // hermite to pol
   // std::cout<<"======================= \n";
   // std::cout<<"hermite to polynomial \n";
-  polynomial_t pol0 = polynomial_from_curve<polynomial_t, cubic_hermite_spline_t>(chs0);
+  polynomial_t pol0 = polynomial_from_curve<polynomial_t>(chs0);
   CompareCurves<cubic_hermite_spline_t, polynomial_t>(chs0, pol0, errMsg0, error);
   // pol to hermite
   // std::cout<<"======================= \n";
   // std::cout<<"polynomial to hermite \n";
-  cubic_hermite_spline_t chs1 = hermite_from_curve<cubic_hermite_spline_t, polynomial_t>(pol0);
+  cubic_hermite_spline_t chs1 = hermite_from_curve<cubic_hermite_spline_t>(pol0);
   CompareCurves<polynomial_t, cubic_hermite_spline_t>(pol0, chs1, errMsg2, error);
   // pol to bezier
   // std::cout<<"======================= \n";
   // std::cout<<"polynomial to bezier \n";
-  bezier_curve_t bc1 = bezier_from_curve<bezier_curve_t, polynomial_t>(pol0);
-  CompareCurves<bezier_curve_t, polynomial_t>(bc1, pol0, errMsg2, error);
+  bezier_t bc1 = bezier_from_curve<bezier_t>(pol0);
+  CompareCurves<bezier_t, polynomial_t>(bc1, pol0, errMsg2, error);
   // Bezier to pol
   // std::cout<<"======================= \n";
   // std::cout<<"bezier to polynomial \n";
-  polynomial_t pol1 = polynomial_from_curve<polynomial_t, bezier_curve_t>(bc0);
-  CompareCurves<bezier_curve_t, polynomial_t>(bc0, pol1, errMsg1, error);
+  polynomial_t pol1 = polynomial_from_curve<polynomial_t>(bc0);
+  CompareCurves<bezier_t, polynomial_t>(bc0, pol1, errMsg1, error);
   // bezier => hermite
   // std::cout<<"======================= \n";
   // std::cout<<"bezier to hermite \n";
-  cubic_hermite_spline_t chs2 = hermite_from_curve<cubic_hermite_spline_t, bezier_curve_t>(bc0);
-  CompareCurves<bezier_curve_t, cubic_hermite_spline_t>(bc0, chs2, errMsg1, error);
+  cubic_hermite_spline_t chs2 = hermite_from_curve<cubic_hermite_spline_t>(bc0);
+  CompareCurves<bezier_t, cubic_hermite_spline_t>(bc0, chs2, errMsg1, error);
 
   // Test : compute derivative of bezier => Convert it to polynomial
-  bezier_curve_t bc_der = bc0.compute_derivate(1);
-  polynomial_t pol_test = polynomial_from_curve<polynomial_t, bezier_curve_t>(bc_der);
-  CompareCurves<bezier_curve_t, polynomial_t>(bc_der, pol_test, errMsg1, error);
+  curve_abc_t* bc_der = bc0.compute_derivate_ptr(1);
+  polynomial_t pol_test = polynomial_from_curve<polynomial_t>(*bc_der);
+  CompareCurves<curve_abc_t, polynomial_t>(*bc_der, pol_test, errMsg1, error);
 }
 
 /*Exact Cubic Function tests*/
@@ -861,7 +847,7 @@ void BezierEvalDeCasteljau(bool& error) {
   params.push_back(b);
   params.push_back(c);
   // 3d curve
-  bezier_curve_t cf(params.begin(), params.end());
+  bezier_t cf(params.begin(), params.end());
   std::string errmsg("Error in BezierEvalDeCasteljau; while comparing actual bezier evaluation and de Casteljau : ");
   for (std::vector<double>::const_iterator cit = values.begin(); cit != values.end(); ++cit) {
     ComparePoints(cf.evalDeCasteljau(*cit), cf(*cit), errmsg, error);
@@ -872,7 +858,7 @@ void BezierEvalDeCasteljau(bool& error) {
   params.push_back(g);
   params.push_back(h);
   params.push_back(i);
-  bezier_curve_t cf2(params.begin(), params.end());
+  bezier_t cf2(params.begin(), params.end());
   for (std::vector<double>::const_iterator cit = values.begin(); cit != values.end(); ++cit) {
     ComparePoints(cf.evalDeCasteljau(*cit), cf(*cit), errmsg, error);
   }
@@ -908,8 +894,8 @@ void BezierSplitCurve(bool& error) {
     double t0 = (rand() / (double)RAND_MAX) * (t_max - t_min) + t_min;
     double t1 = (rand() / (double)RAND_MAX) * (t_max - t0) + t0;
     double ts = (rand() / (double)RAND_MAX) * (t1 - t0) + t0;
-    bezier_curve_t c(wps.begin(), wps.end(), t0, t1);
-    std::pair<bezier_curve_t, bezier_curve_t> cs = c.split(ts);
+    bezier_t c(wps.begin(), wps.end(), t0, t1);
+    std::pair<bezier_t, bezier_t> cs = c.split(ts);
     // test on splitted curves :
     if (!((c.degree_ == cs.first.degree_) && (c.degree_ == cs.second.degree_))) {
       error = true;
@@ -939,19 +925,19 @@ void BezierSplitCurve(bool& error) {
       ti += 0.01;
     }
     // Test extract function
-    bezier_curve_t bezier_extracted0 = c.extract(t0 + 0.01, t1 - 0.01);  // T_min < t0 < t1 < T_max
+    bezier_t bezier_extracted0 = c.extract(t0 + 0.01, t1 - 0.01);  // T_min < t0 < t1 < T_max
     for (double t = bezier_extracted0.min(); t < bezier_extracted0.max(); t += 0.01) {
       ComparePoints(bezier_extracted0(t), c(t), errMsg6, error);
     }
-    bezier_curve_t bezier_extracted1 = c.extract(t0, t1 - 0.01);  // T_min = t0 < t1 < T_max
+    bezier_t bezier_extracted1 = c.extract(t0, t1 - 0.01);  // T_min = t0 < t1 < T_max
     for (double t = bezier_extracted1.min(); t < bezier_extracted1.max(); t += 0.01) {
       ComparePoints(bezier_extracted1(t), c(t), errMsg6, error);
     }
-    bezier_curve_t bezier_extracted2 = c.extract(t0 + 0.01, t1);  // T_min < t0 < t1 = T_max
+    bezier_t bezier_extracted2 = c.extract(t0 + 0.01, t1);  // T_min < t0 < t1 = T_max
     for (double t = bezier_extracted2.min(); t < bezier_extracted2.max(); t += 0.01) {
       ComparePoints(bezier_extracted2(t), c(t), errMsg6, error);
     }
-    bezier_curve_t bezier_extracted3 = c.extract(t0, t1);  // T_min = t0 < t1 = T_max
+    bezier_t bezier_extracted3 = c.extract(t0, t1);  // T_min = t0 < t1 = T_max
     for (double t = bezier_extracted3.min(); t < bezier_extracted3.max(); t += 0.01) {
       ComparePoints(bezier_extracted3(t), c(t), errMsg6, error);
     }
@@ -1069,16 +1055,16 @@ void piecewiseCurveTest(bool& error) {
     vec2.push_back(b);  // x=2, y=1, z=1
     vec3.push_back(c);  // x=3, y=1, z=1
     // Create three polynomials of constant value in the interval of definition
-    polynomial_t pol1(vec1.begin(), vec1.end(), 0, 1);
-    polynomial_t pol2(vec2.begin(), vec2.end(), 1, 2);
-    polynomial_t pol3(vec3.begin(), vec3.end(), 2, 3);
+    boost::shared_ptr<polynomial_t> pol1_ptr (new polynomial_t(vec1.begin(), vec1.end(), 0, 1));
+    boost::shared_ptr<polynomial_t> pol2_ptr (new polynomial_t(vec2.begin(), vec2.end(), 1, 2));
+    boost::shared_ptr<polynomial_t> pol3_ptr (new polynomial_t(vec3.begin(), vec3.end(), 2, 3));
     // 1 polynomial in curve
-    piecewise_polynomial_curve_t pc(pol1);
+    piecewise_t pc(pol1_ptr);
     res = pc(0.5);
     ComparePoints(a, res, errmsg1, error);
     // 3 polynomials in curve
-    pc.add_curve(pol2);
-    pc.add_curve(pol3);
+    pc.add_curve_ptr(pol2_ptr);
+    pc.add_curve_ptr(pol3_ptr);
     // Check values on piecewise curve
     // t in [0,1[ -> res=a
     res = pc(0.);
@@ -1110,10 +1096,10 @@ void piecewiseCurveTest(bool& error) {
     params1.push_back(c0);
     params1.push_back(b0);
     params1.push_back(a0);
-    bezier_curve_t bc0(params0.begin(), params0.end(), 0., 1.);
-    bezier_curve_t bc1(params1.begin(), params1.end(), 1., 2.);
-    piecewise_bezier_curve_t pc_C0(bc0);
-    pc_C0.add_curve(bc1);
+    boost::shared_ptr<bezier_t> bc0_ptr(new bezier_t(params0.begin(), params0.end(), 0., 1.));
+    boost::shared_ptr<bezier_t> bc1_ptr(new bezier_t(params1.begin(), params1.end(), 1., 2.));
+    piecewise_t pc_C0(bc0_ptr);
+    pc_C0.add_curve_ptr(bc1_ptr);
     // Check value in t=0.5 and t=1.5
     res = pc_C0(0.0);
     ComparePoints(a0, res, errmsg1, error);
@@ -1139,10 +1125,10 @@ void piecewiseCurveTest(bool& error) {
     time_control_points0.push_back(1.);  // hermite 0 between [0,1]
     time_control_points1.push_back(1.);
     time_control_points1.push_back(3.);  // hermite 1 between [1,3]
-    cubic_hermite_spline_t chs0(control_points_0.begin(), control_points_0.end(), time_control_points0);
-    cubic_hermite_spline_t chs1(control_points_1.begin(), control_points_1.end(), time_control_points1);
-    piecewise_cubic_hermite_curve_t pc_C1(chs0);
-    pc_C1.add_curve(chs1);
+    boost::shared_ptr<cubic_hermite_spline_t> chs0_ptr(new cubic_hermite_spline_t(control_points_0.begin(), control_points_0.end(), time_control_points0));
+    boost::shared_ptr<cubic_hermite_spline_t> chs1_ptr(new cubic_hermite_spline_t(control_points_1.begin(), control_points_1.end(), time_control_points1));
+    piecewise_t pc_C1(chs0_ptr);
+    pc_C1.add_curve_ptr(chs1_ptr);
     // Create piecewise curve C2
     point3_t a1(0, 0, 0);
     point3_t b1(1, 1, 1);
@@ -1153,10 +1139,10 @@ void piecewiseCurveTest(bool& error) {
     // in [1,2]
     vecb.push_back(b1);
     vecb.push_back(b1);  // x=(t-1)+1, y=(t-1)+1, z=(t-1)+1
-    polynomial_t pola(veca.begin(), veca.end(), 0, 1);
-    polynomial_t polb(vecb.begin(), vecb.end(), 1, 2);
-    piecewise_polynomial_curve_t pc_C2(pola);
-    pc_C2.add_curve(polb);
+    boost::shared_ptr<polynomial_t> pola_ptr(new polynomial_t(veca.begin(), veca.end(), 0, 1));
+    boost::shared_ptr<polynomial_t> polb_ptr(new polynomial_t(vecb.begin(), vecb.end(), 1, 2));
+    piecewise_t pc_C2(pola_ptr);
+    pc_C2.add_curve_ptr(polb_ptr);
     // check C0 continuity
     std::string errmsg2("in piecewise polynomial curve test, Error while checking continuity C0 on ");
     std::string errmsg3("in piecewise polynomial curve test, Error while checking continuity C1 on ");
@@ -1199,40 +1185,49 @@ void piecewiseCurveTest(bool& error) {
     }
     // CONVERT PIECEWISE POLYNOMIAL CURVES TO BEZIER AND HERMITE
     std::string errmsg5("in piecewise polynomial curve test, Error while checking piecewise curve conversion");
-    piecewise_bezier_curve_t pc_bezier = pc.convert_piecewise_curve_to_bezier<bezier_curve_t>();
-    CompareCurves<piecewise_polynomial_curve_t, piecewise_bezier_curve_t>(pc, pc_bezier, errmsg5, error);
-    piecewise_cubic_hermite_curve_t pc_hermite = pc.convert_piecewise_curve_to_cubic_hermite<cubic_hermite_spline_t>();
-    CompareCurves<piecewise_polynomial_curve_t, piecewise_cubic_hermite_curve_t>(pc, pc_hermite, errmsg5, error);
-    piecewise_polynomial_curve_t pc_polynomial_same = pc.convert_piecewise_curve_to_polynomial<polynomial_t>();
-    CompareCurves<piecewise_polynomial_curve_t, piecewise_polynomial_curve_t>(pc, pc_polynomial_same, errmsg5, error);
+    piecewise_t pc_bezier = pc.convert_piecewise_curve_to_bezier<bezier_t>();
+    CompareCurves<piecewise_t, piecewise_t>(pc, pc_bezier, errmsg5, error);
+    piecewise_t pc_hermite = pc.convert_piecewise_curve_to_cubic_hermite<cubic_hermite_spline_t>();
+    CompareCurves<piecewise_t, piecewise_t>(pc, pc_hermite, errmsg5, error);
+    piecewise_t pc_polynomial_same = pc.convert_piecewise_curve_to_polynomial<polynomial_t>();
+    CompareCurves<piecewise_t, piecewise_t>(pc, pc_polynomial_same, errmsg5, error);
+    // CONVERT PIECEWISE BEZIER TO POLYNOMIAL AND HERMITE
+
+    std::string errmsg6("in piecewise bezier curve test, Error while checking piecewise curve conversion");
+    piecewise_t pc_bezier1 = pc_C0.convert_piecewise_curve_to_bezier<bezier_t>();
+    CompareCurves<piecewise_t, piecewise_t>(pc_C0, pc_bezier1, errmsg6, error);
+    piecewise_t pc_hermite1 = pc_C0.convert_piecewise_curve_to_cubic_hermite<cubic_hermite_spline_t>();
+    CompareCurves<piecewise_t, piecewise_t>(pc_C0, pc_hermite1, errmsg6, error);
+    piecewise_t pc_polynomial1 = pc_C0.convert_piecewise_curve_to_polynomial<polynomial_t>();
+    CompareCurves<piecewise_t, piecewise_t>(pc_C0, pc_polynomial1, errmsg6, error);
 
     // compare compute_derivate and derivate results :
 
-    piecewise_polynomial_curve_t pc_C2_derivate = pc_C2.compute_derivate(1);
-    piecewise_polynomial_curve_t pc_C2_derivate2 = pc_C2.compute_derivate(2);
-    if (pc_C2.min() != pc_C2_derivate.min()) {
+    curve_abc_t* pc_C2_derivate = pc_C2.compute_derivate_ptr(1);
+    curve_abc_t* pc_C2_derivate2 = pc_C2.compute_derivate_ptr(2);
+    if (pc_C2.min() != pc_C2_derivate->min()) {
       error = true;
       std::cout << "min bounds for curve and it's derivate are not equals." << std::endl;
     }
-    if (pc_C2.min() != pc_C2_derivate2.min()) {
+    if (pc_C2.min() != pc_C2_derivate2->min()) {
       error = true;
       std::cout << "min bounds for curve and it's second derivate are not equals." << std::endl;
     }
-    if (pc_C2.max() != pc_C2_derivate.max()) {
+    if (pc_C2.max() != pc_C2_derivate->max()) {
       error = true;
       std::cout << "max bounds for curve and it's derivate are not equals." << std::endl;
     }
-    if (pc_C2.max() != pc_C2_derivate2.max()) {
+    if (pc_C2.max() != pc_C2_derivate2->max()) {
       error = true;
       std::cout << "max bounds for curve and it's second derivate are not equals." << std::endl;
     }
     double t = 0.;
     while (t < pc_C2.max()) {
-      if (!QuasiEqual(pc_C2.derivate(t, 1), pc_C2_derivate(t))) {
+      if (!QuasiEqual(pc_C2.derivate(t, 1), (*pc_C2_derivate)(t))) {
         error = true;
         std::cout << "value not equal between derivate and compute_derivate (order 1) at t = " << t << std::endl;
       }
-      if (!QuasiEqual(pc_C2.derivate(t, 2), pc_C2_derivate2(t))) {
+      if (!QuasiEqual(pc_C2.derivate(t, 2), (*pc_C2_derivate2)(t))) {
         error = true;
         std::cout << "value not equal between derivate and compute_derivate (order 2) at t = " << t << std::endl;
       }
@@ -1250,7 +1245,7 @@ void curveAbcDimDynamicTest(bool& error) {
   typedef polynomial<double, double, true> polynomial_test_t;
   typedef exact_cubic<double, double, true> exact_cubic_test_t;
   typedef exact_cubic_test_t::spline_constraints spline_constraints_test_t;
-  typedef bezier_curve<double, double, true> bezier_curve_test_t;
+  typedef bezier_curve<double, double, true> bezier_test_t;
   typedef cubic_hermite_spline<double, double, true> cubic_hermite_spline_test_t;
   curve_abc_test_t* pt_curve_abc;
   // POLYNOMIAL
@@ -1267,7 +1262,7 @@ void curveAbcDimDynamicTest(bool& error) {
     error = false;
   }
   // BEZIER
-  bezier_curve_test_t bc = bezier_from_curve<bezier_curve_test_t, polynomial_test_t>(pol);
+  bezier_test_t bc = bezier_from_curve<bezier_test_t>(pol);
   try {
     bc(0);
     bc(1);
@@ -1275,7 +1270,7 @@ void curveAbcDimDynamicTest(bool& error) {
     error = false;
   }
   // CUBIC HERMITE
-  cubic_hermite_spline_test_t chs = hermite_from_curve<cubic_hermite_spline_test_t, polynomial_test_t>(pol);
+  cubic_hermite_spline_test_t chs = hermite_from_curve<cubic_hermite_spline_test_t>(pol);
   try {
     chs(0);
     chs(1);
@@ -1361,10 +1356,11 @@ void PiecewisePolynomialCurveFromDiscretePoints(bool& error) {
   time_points.push_back(t3);
 
   // Piecewise polynomial curve C0 => Linear interpolation between points
-  piecewise_polynomial_curve_t ppc_C0 =
-      piecewise_polynomial_curve_t::convert_discrete_points_to_polynomial<polynomial_t>(points, time_points);
-  if (!ppc_C0.is_continuous(0)) {
-    std::cout << "PiecewisePolynomialCurveFromDiscretePoints, Error, piecewise curve is not C0" << std::endl;
+  piecewise_t ppc_C0 =  piecewise_t::
+    convert_discrete_points_to_polynomial<polynomial_t>(points,time_points);
+  if (!ppc_C0.is_continuous(0))
+  {
+    std::cout<<"PiecewisePolynomialCurveFromDiscretePoints, Error, piecewise curve is not C0"<<std::endl;
     error = true;
   }
   for (std::size_t i = 0; i < points.size(); i++) {
@@ -1375,11 +1371,13 @@ void PiecewisePolynomialCurveFromDiscretePoints(bool& error) {
   ComparePoints(pos_between_po_and_p1, ppc_C0(time_between_po_and_p1), errMsg, error);
 
   // Piecewise polynomial curve C1
-  piecewise_polynomial_curve_t ppc_C1 =
-      piecewise_polynomial_curve_t::convert_discrete_points_to_polynomial<polynomial_t>(points, points_derivative,
-                                                                                        time_points);
-  if (!ppc_C1.is_continuous(1)) {
-    std::cout << "PiecewisePolynomialCurveFromDiscretePoints, Error, piecewise curve is not C1" << std::endl;
+  piecewise_t ppc_C1 =  piecewise_t::
+    convert_discrete_points_to_polynomial<polynomial_t>(points,
+                                                        points_derivative,
+                                                        time_points);
+  if (!ppc_C1.is_continuous(1))
+  {
+    std::cout<<"PiecewisePolynomialCurveFromDiscretePoints, Error, piecewise curve is not C1"<<std::endl;
     error = true;
   }
   for (std::size_t i = 0; i < points.size(); i++) {
@@ -1388,14 +1386,18 @@ void PiecewisePolynomialCurveFromDiscretePoints(bool& error) {
   }
 
   // Piecewise polynomial curve C2
-  piecewise_polynomial_curve_t ppc_C2 =
-      piecewise_polynomial_curve_t::convert_discrete_points_to_polynomial<polynomial_t>(
-          points, points_derivative, points_second_derivative, time_points);
-  if (!ppc_C2.is_continuous(2)) {
-    std::cout << "PiecewisePolynomialCurveFromDiscretePoints, Error, piecewise curve is not C1" << std::endl;
-    error = true;
-  }
-  for (std::size_t i = 0; i < points.size(); i++) {
+  piecewise_t ppc_C2 =  piecewise_t::
+    convert_discrete_points_to_polynomial<polynomial_t>(points,
+                                                        points_derivative,
+                                                        points_second_derivative,
+                                                        time_points);
+  if (!ppc_C2.is_continuous(2))
+  {
+    std::cout<<"PiecewisePolynomialCurveFromDiscretePoints, Error, piecewise curve is not C1"<<std::endl;
+    error = true;
+  }
+  for (std::size_t i=0; i<points.size(); i++)
+  {
     ComparePoints(points[i], ppc_C2(time_points[i]), errMsg, error);
     ComparePoints(points_derivative[i], ppc_C2.derivate(time_points[i], 1), errMsg, error);
     ComparePoints(points_second_derivative[i], ppc_C2.derivate(time_points[i], 2), errMsg, error);
@@ -1421,9 +1423,10 @@ void serializationCurvesTest(bool& error) {
     polynomial_t pol1(vec1.begin(), vec1.end(), 0, 1);
     polynomial_t pol2(vec2.begin(), vec2.end(), 1, 2);
     polynomial_t pol3(vec3.begin(), vec3.end(), 2, 3);
-    piecewise_polynomial_curve_t ppc(pol1);
-    ppc.add_curve(pol2);
-    ppc.add_curve(pol3);
+    piecewise_t ppc;
+    ppc.add_curve<polynomial_t>(pol1);
+    ppc.add_curve<polynomial_t>(pol2);
+    ppc.add_curve<polynomial_t>(pol3);
     std::string fileName("fileTest.test");
     std::string fileName1("fileTest1.test");
     // Simple curves
@@ -1433,35 +1436,39 @@ void serializationCurvesTest(bool& error) {
     pol_test.loadFromText<polynomial_t>(fileName1);
     CompareCurves<polynomial_t, polynomial_t>(pol1, pol_test, errMsg1, error);
     // Test serialization on Bezier
-    bezier_curve_t bc = bezier_from_curve<bezier_curve_t, polynomial_t>(pol1);
-    bc.saveAsText<bezier_curve_t>(fileName);
-    bezier_curve_t bc_test;
-    bc_test.loadFromText<bezier_curve_t>(fileName);
-    CompareCurves<polynomial_t, bezier_curve_t>(pol1, bc_test, errMsg2, error);
+    bezier_t bc = bezier_from_curve<bezier_t>(pol1);
+    bc.saveAsText<bezier_t>(fileName);
+    bezier_t bc_test;
+    bc_test.loadFromText<bezier_t>(fileName);
+    CompareCurves<polynomial_t, bezier_t>(pol1, bc_test, errMsg2, error);
     // Test serialization on Cubic Hermite
-    cubic_hermite_spline_t chs = hermite_from_curve<cubic_hermite_spline_t, polynomial_t>(pol1);
+    cubic_hermite_spline_t chs = hermite_from_curve<cubic_hermite_spline_t>(pol1);
     chs.saveAsText<cubic_hermite_spline_t>(fileName);
     cubic_hermite_spline_t chs_test;
     chs_test.loadFromText<cubic_hermite_spline_t>(fileName);
     CompareCurves<polynomial_t, cubic_hermite_spline_t>(pol1, chs_test, errMsg3, error);
     // Piecewise curves
     // Test serialization on Piecewise Polynomial curve
-    ppc.saveAsText<piecewise_polynomial_curve_t>(fileName);
-    piecewise_polynomial_curve_t ppc_test;
-    ppc_test.loadFromText<piecewise_polynomial_curve_t>(fileName);
-    CompareCurves<piecewise_polynomial_curve_t, piecewise_polynomial_curve_t>(ppc, ppc_test, errMsg4, error);
+    ppc.saveAsText<piecewise_t>(fileName);
+    piecewise_t ppc_test,ppc_test_binary;
+    ppc_test.loadFromText<piecewise_t>(fileName);
+    CompareCurves<piecewise_t, piecewise_t>(ppc, ppc_test, errMsg4, error);
+    ppc.saveAsBinary<piecewise_t>(fileName);
+    ppc_test_binary.loadFromBinary<piecewise_t>(fileName);
+    CompareCurves<piecewise_t, piecewise_t>(ppc, ppc_test_binary, errMsg4, error);
+
     // Test serialization on Piecewise Bezier curve
-    piecewise_bezier_curve_t pbc = ppc.convert_piecewise_curve_to_bezier<bezier_curve_t>();
-    pbc.saveAsText<piecewise_bezier_curve_t>(fileName);
-    piecewise_bezier_curve_t pbc_test;
-    pbc_test.loadFromText<piecewise_bezier_curve_t>(fileName);
-    CompareCurves<piecewise_polynomial_curve_t, piecewise_bezier_curve_t>(ppc, pbc_test, errMsg4, error);
+    piecewise_t pbc = ppc.convert_piecewise_curve_to_bezier<bezier_t>();
+    pbc.saveAsText<piecewise_t>(fileName);
+    piecewise_t pbc_test;
+    pbc_test.loadFromText<piecewise_t>(fileName);
+    CompareCurves<piecewise_t, piecewise_t>(ppc, pbc_test, errMsg4, error);
     // Test serialization on Piecewise Cubic Hermite curve
-    piecewise_cubic_hermite_curve_t pchc = ppc.convert_piecewise_curve_to_cubic_hermite<cubic_hermite_spline_t>();
-    pchc.saveAsText<piecewise_cubic_hermite_curve_t>(fileName);
-    piecewise_cubic_hermite_curve_t pchc_test;
-    pchc_test.loadFromText<piecewise_cubic_hermite_curve_t>(fileName);
-    CompareCurves<piecewise_polynomial_curve_t, piecewise_cubic_hermite_curve_t>(ppc, pchc_test, errMsg4, error);
+    piecewise_t pchc = ppc.convert_piecewise_curve_to_cubic_hermite<cubic_hermite_spline_t>();
+    pchc.saveAsText<piecewise_t>(fileName);
+    piecewise_t pchc_test;
+    pchc_test.loadFromText<piecewise_t>(fileName);
+    CompareCurves<piecewise_t, piecewise_t>(ppc, pchc_test, errMsg4, error);
     // Test serialization on exact cubic
     curves::T_Waypoint waypoints;
     for (double i = 0; i <= 1; i = i + 0.2) {
@@ -1490,13 +1497,13 @@ void serializationCurvesTest(bool& error) {
     // Piecewise Polynomial
     pt_0 = NULL;
     pt_1 = NULL;
-    ppc_test = piecewise_polynomial_curve_t();
+    ppc_test = piecewise_t();
     pt_0 = &ppc;
     pt_1 = &ppc_test;
-    (*pt_0).saveAsText<piecewise_polynomial_curve_t>(fileName);
-    (*pt_1).loadFromText<piecewise_polynomial_curve_t>(fileName);
-    CompareCurves<piecewise_polynomial_curve_t, piecewise_polynomial_curve_t>(
-        ppc, (*dynamic_cast<piecewise_polynomial_curve_t*>(pt_1)), errMsg6, error);
+    (*pt_0).saveAsText<piecewise_t>(fileName);
+    (*pt_1).loadFromText<piecewise_t>(fileName);
+    CompareCurves<piecewise_t, piecewise_t>(
+        ppc, (*dynamic_cast<piecewise_t*>(pt_1)), errMsg6, error);
   } catch (...) {
     error = true;
     std::cout << "Error in serializationCurvesTest" << std::endl;
@@ -1780,7 +1787,7 @@ void se3CurveTest(bool& error) {
     params.push_back(b);
     params.push_back(c);
     params.push_back(d);
-    boost::shared_ptr<bezier_curve_t> translation_bezier(new bezier_curve_t(params.begin(), params.end(), min, max));
+    boost::shared_ptr<bezier_t> translation_bezier(new bezier_t(params.begin(), params.end(), min, max));
     cBezier = SE3Curve_t(translation_bezier, q0.toRotationMatrix(), q1.toRotationMatrix());
     p0 = (*translation_bezier)(min);
     p1 = (*translation_bezier)(max);
@@ -1918,7 +1925,7 @@ void Se3serializationTest(bool &error){
     params.push_back(b);
     params.push_back(c);
     params.push_back(d);
-    boost::shared_ptr<bezier_curve_t> translation_bezier(new bezier_curve_t(params.begin(), params.end(), min, max));
+    boost::shared_ptr<bezier_t> translation_bezier(new bezier_t(params.begin(), params.end(), min, max));
     cBezier = SE3Curve_t(translation_bezier, q0, q1);
   }