diff --git a/include/spline/cubic_function.h b/include/spline/cubic_function.h
index 61f9c45d48731fa0921922cd21c23d7ad5dcc8e4..8705375b63765d3e64f421306650adba74b75f02 100644
--- a/include/spline/cubic_function.h
+++ b/include/spline/cubic_function.h
@@ -40,7 +40,7 @@ struct cubic_function : public curve_abc<Time, Numeric, Dim, Safe, Point>
 	cubic_function(point_t const& a, point_t const& b, point_t const& c, point_t const &d, time_t min, time_t max)
 		:a_(a), b_(b), c_(c), d_(d), t_min_(min), t_max_(max)
 	{
-		if(t_min_ >= t_max_ & Safe)
+		if(t_min_ >= t_max_ && Safe)
 		{
 			std::out_of_range("TODO");
 		}
diff --git a/include/spline/optimization/OptimizeSpline.h b/include/spline/optimization/OptimizeSpline.h
new file mode 100644
index 0000000000000000000000000000000000000000..0f3aef41dcc3278aa136e0ac8f5cb8a83dd464a1
--- /dev/null
+++ b/include/spline/optimization/OptimizeSpline.h
@@ -0,0 +1,520 @@
+/**
+* \file OptimizeSpline.h
+* \brief Optimization loop for cubic spline generations
+* \author Steve T.
+* \version 0.1
+* \date 06/17/2013
+*
+* This file uses the mosek library to optimize the waypoints location
+* to generate exactCubic spline
+*/
+
+#ifndef _CLASS_SPLINEOPTIMIZER
+#define _CLASS_SPLINEOPTIMIZER
+
+#include "spline/MathDefs.h" 
+#include "spline/exact_cubic.h"
+
+#include "mosek/mosek.h" 
+#include <Eigen/SparseCore>
+
+#include <utility>
+
+namespace spline
+{
+/// \class SplineOptimizer
+/// \brief Mosek connection to produce optimized splines
+template<typename Time= double, typename Numeric=Time, int Dim=3, bool Safe=false
+, typename Point= Eigen::Matrix<Numeric, Dim, 1> >
+struct SplineOptimizer
+{
+typedef Eigen::Matrix<Numeric, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
+typedef Point point_t;
+typedef Time time_t;
+typedef Numeric num_t;
+typedef exact_cubic<time_t, Numeric, Dim, Safe, Point> exact_cubic_t; 
+typedef SplineOptimizer<time_t, Numeric, Dim, Safe, Point> splineOptimizer_t; 
+
+/* Constructors - destructors */
+public:
+	///\brief Initializes optimizer environment
+	SplineOptimizer()
+	{
+		MSKrescodee  r_ = MSK_makeenv(&env_,NULL);
+		assert(r_ == MSK_RES_OK);
+	}
+
+	///\brief Destructor
+	~SplineOptimizer()
+	{
+		MSK_deleteenv(&env_);
+	}
+
+private:
+	SplineOptimizer(const SplineOptimizer&);
+	SplineOptimizer& operator=(const SplineOptimizer&);
+/* Constructors - destructors */
+
+/*Operations*/
+public:
+	/// \brief Starts an optimization loop to create curve
+	///	\param waypoints : a list comprising at least 2 waypoints in ascending time order
+	/// \return An Optimised curve
+	template<typename In>
+	exact_cubic_t* GenerateOptimizedCurve(In wayPointsBegin, In wayPointsEnd) const;
+/*Operations*/
+
+private:
+	template<typename In>
+	void ComputeHMatrices(In wayPointsBegin, In wayPointsEnd, 
+	MatrixX& h1, MatrixX& h2, MatrixX& h3, MatrixX& h4) const;
+	
+/*Attributes*/
+private:
+	MSKenv_t env_;
+/*Attributes*/
+	
+private:
+	typedef std::pair<time_t, Point> waypoint_t; 
+	typedef std::vector<waypoint_t> T_waypoints_t; 
+};
+
+template<typename Time, typename Numeric, int Dim, bool Safe, typename Point>
+template<typename In>
+inline void SplineOptimizer<Time, Numeric, Dim, Safe, Point>::ComputeHMatrices(In wayPointsBegin, In wayPointsEnd, 
+	MatrixX& h1, MatrixX& h2, MatrixX& h3, MatrixX& h4) const
+{
+	std::size_t const size(std::distance(wayPointsBegin, wayPointsEnd));
+	assert((!Safe) || (size > 1));
+	
+	In it(wayPointsBegin), next(wayPointsBegin);
+	++next;
+	Numeric t_previous((*it).first);
+
+	for(std::size_t i(0); next != wayPointsEnd; ++next, ++it, ++i)
+	{
+		num_t const dTi((*next).first  - (*it).first);
+		num_t const dTi_sqr(dTi * dTi);
+		// filling matrices values
+		h3(i,i)   = -3 / dTi_sqr;
+		h3(i,i+1) =  3 / dTi_sqr;
+		h4(i,i)   = -2 / dTi;
+		h4(i,i+1) = -1 / dTi;
+		if( i+2 < size)
+		{
+			In it2(next); ++ it2;
+			num_t const dTi_1(1/((*it2).first - (*next).first));
+			num_t const dTi_1sqr(dTi_1 * dTi_1);
+			// this can be optimized but let's focus on clarity as long as not needed
+			h1(i+1, i)   =  2 / dTi;
+			h1(i+1, i+1) =  4 / dTi + 4 / dTi_1;
+			h1(i+1, i+2) =  2 / dTi_1;
+			h2(i+1, i)   = -6 / dTi_sqr;
+			h2(i+1, i+1) = (6 / dTi_1sqr) - (6 / dTi_sqr);
+			h2(i+1, i+2) =  6 / dTi_1sqr;
+		}
+	}
+}
+
+template<typename Time, typename Numeric, int Dim, bool Safe, typename Point>
+template<typename In>
+inline exact_cubic<Time, Numeric, Dim, Safe, Point>*
+	SplineOptimizer<Time, Numeric, Dim, Safe, Point>::GenerateOptimizedCurve(In wayPointsBegin, In wayPointsEnd) const
+{
+	exact_cubic_t* res = 0;
+	int const size((int)std::distance(wayPointsBegin, wayPointsEnd));
+	if(Safe && size < 1)
+	{
+		throw; // TODO
+	}
+	// refer to the paper to understand all this.
+	MatrixX h1 = MatrixX::Zero(size, size);
+	MatrixX h2 = MatrixX::Zero(size, size);
+	MatrixX h3 = MatrixX::Zero(size, size);
+	MatrixX h4 = MatrixX::Zero(size, size);
+
+	// remove this for the time being
+	/*MatrixX g1 = MatrixX::Zero(size, size);
+	MatrixX g2 = MatrixX::Zero(size, size);
+	MatrixX g3 = MatrixX::Zero(size, size);
+	MatrixX g4 = MatrixX::Zero(size, size);*/
+
+	ComputeHMatrices(wayPointsBegin, wayPointsEnd, h1, h2, h3, h4);
+
+	// number of Waypoints : T + 1 => T mid points. Dim variables per points, + acceleration + derivations
+	// (T * t+ 1 ) * Dim * 3 = nb var 
+
+// NOG const MSKint32t numvar = ( size + size - 1) * 3 * 3;
+	const MSKint32t numvar = (size) * Dim * 3;
+	/*
+	We store the variables in that order to simplifly matrix computation ( see later )
+// NOG [ x0  x1 --- xn y0 --- y z0 --- zn x0. --- zn. x0..--- zn.. x0' --- zn..' ] T
+	   [ x0  x1 --- xn y0 --- y z0 --- zn x0. --- zn. x0..--- zn..] T
+	*/
+	
+	/*the first constraint is H1x. = H2x => H2x - H1x. = 0
+	this will give us size * 3 inequalities constraints
+	So this line of A will be writen
+	H2 -H1 0 0 0 0
+	*/
+
+	int ptOff     = (int) Dim * size; // . offest
+	int ptptOff   = (int) Dim * 2 * size; // .. offest
+	int prOff     = (int) 3 * ptOff; // ' offest
+// NOG int prptOff   = (int) prOff + ptOff; // '. offest
+// NOG int prptptOff = (int) prptOff + ptOff; // '.. offest
+
+	MatrixX h2x_h1x = MatrixX::Zero(size * Dim, numvar);
+	/**A looks something like that : (n = size)
+	[H2(0)  0      0     -H1(0) 0-------------------0]
+	[ 0  0  H2(0)  0       0   -H1(0)---------------0]
+	[ 0  0  0      H2(0)   0     0     H1(0)--------0]
+	...
+	[ 0  0  0      0   H2(n)   0    0      0     -H1(n)-0] // row n
+
+	Overall it's fairly easy to fill	
+	*/
+	for(int i = 0; i < size*Dim; i = i + 3)
+	{
+		for(int j = 0; j<Dim; ++j)
+		{
+			int id = i + j;
+			h2x_h1x.block(id, j*size    , 1, size)  = h2.row(i%3);
+			h2x_h1x.block(id, j*size + ptOff, 1, size) -= h1.row(i%3);
+		}
+	}
+
+	
+	/*the second constraint is x' = G1x + G2x. => G1x + G2x. - x' = 0
+	this will give us size * 3 inequalities constraints
+	So this line of A will be writen
+	H2 -H1 0 0 0 0
+	*/MatrixX g1x_g2x = MatrixX::Zero(size * Dim, numvar);
+	/**A looks something like that : (n = size)
+	[G1(0)  0      0     G2(0) 0-----------------------0 -1 0]
+	[ 0  0  G1(0)  0       0   G2(0)-------------------0 -1 0]
+	[ 0  0  0      G1(0)   0     0     G2(0)-----------0 -1 0]
+	...
+	[ 0  0  0      0   G1(n)   0    0      0     G2(n)-0 -1 0] // row n
+
+	Overall it's fairly easy to fill	
+	*/
+// NOG 
+	/*for(int j = 0; j<3; ++j)
+	{
+		for(int j =0; j<3; ++j)
+		{
+			int id = i + j;
+			g1x_g2x.block(id, j*size	    , 1, size)   = g1.row(i);
+			g1x_g2x.block(id, j*size + ptOff, 1, size)   = g2.row(i);
+			g1x_g2x.block(id, j*size + prOff, 1, size)  -= MatrixX::Ones(1, size);
+		}
+	}*/
+
+	/*the third constraint is x.' = G3x + G4x. => G3x + G4x. - x.' = 0
+	this will give us size * 3 inequalities constraints
+	So this line of A will be writen
+	H2 -H1 0 0 0 0
+	*/MatrixX g3x_g4x = MatrixX::Zero(size * Dim, numvar);
+	/**A looks something like that : (n = size)
+	[G3(0)  0      0     G4(0) 0-------------------0 -1 0]
+	[ 0  0  G3(0)  0       0   G4(0)---------------0 -1 0]
+	[ 0  0  0      G3(0)   0     0     G4(0)--------0 -1 0]
+	...
+	[ 0  0  0      0   G3(n)   0    0      0     G4(n)-0 -1 0] // row n
+
+	Overall it's fairly easy to fill	
+	*/
+// NOG 
+	/*for(int j = 0; j<3; ++j)
+	{
+		for(int j =0; j<3; ++j)
+		{
+			int id = i + j;
+			g3x_g4x.block(id, j*size		 , 1, size)   = g3.row(i);
+			g3x_g4x.block(id, j*size + ptOff, 1, size)   = g4.row(i);
+			g3x_g4x.block(id, j*size + prptOff, 1, size)  -= MatrixX::Ones(1, size);
+		}
+	}
+*/
+	/*the fourth constraint is x.. = 1/2(H3x + H4x.) => 1/2(H3x + H4x.) - x.. = 0
+	=> H3x + H4x. - 2x.. = 0
+	this will give us size * 3 inequalities constraints
+	So this line of A will be writen
+	H2 -H1 0 0 0 0
+	*/
+	MatrixX h3x_h4x = MatrixX::Zero(size * Dim, numvar);
+	/**A looks something like that : (n = size)
+	[H3(0)  0      0     H4(0) 0-------------------0 -2 0]
+	[ 0  0  H3(0)  0       0   H4(0)---------------0 -2 0]
+	[ 0  0  0      H3(0)   0     0     H4(0)-------0 -2 0]
+	...
+	[ 0  0  0      0   H3(n)   0    0      0     H4(n)-0 -2 0] // row n
+
+	Overall it's fairly easy to fill	
+	*/
+	for(int i = 0; i < size*Dim; i = i + Dim)
+	{
+		for(int j = 0; j<Dim; ++j)
+		{
+			int id = i + j;
+			h3x_h4x.block(id, j*size		   , 1, size) = h3.row(i%3);
+			h3x_h4x.block(id, j*size + ptOff  , 1, size) = h4.row(i%3);
+			h3x_h4x.block(id, j*size + ptptOff, 1, size) = MatrixX::Ones(1, size) * -2;
+		}
+	}
+
+	/*the following constraints are easy to understand*/
+
+	/*x0,: = x^0*/
+	MatrixX x0_x0 = MatrixX::Zero(Dim, numvar);
+	for(int j = 0; j<Dim; ++j)
+	{
+		x0_x0(0, 0)		   = 1;
+		x0_x0(1, size)	   = 1;
+		x0_x0(2, size * 2) = 1;
+	}
+
+	/*x0.,: = 0*/
+	MatrixX x0p_0 = MatrixX::Zero(Dim, numvar);
+	for(int j = 0; j<Dim; ++j)
+	{
+		x0p_0(0, ptOff)	   = 1;
+		x0p_0(1, ptOff + size) = 1;
+		x0p_0(2, ptOff + size * 2) = 1;
+	}
+		
+	/*xt,: = x^t*/
+	MatrixX xt_xt = MatrixX::Zero(Dim, numvar);
+	for(int j = 0; j<Dim; ++j)
+	{
+		xt_xt(0, size - 1)	   = 1;
+		xt_xt(1, 2 * size - 1) = 1;
+		xt_xt(2, 3* size  - 1) = 1;
+	}
+
+	/*xT.,: = 0*/
+	MatrixX xtp_0 = MatrixX::Zero(Dim, numvar);
+	for(int j = 0; j<Dim; ++j)
+	{
+		xtp_0(0, ptOff + size - 1)	         = 1;
+		xtp_0(1, ptOff + size + size - 1)    = 1;
+		xtp_0(2, ptOff + size * 2 + size - 1)= 1;
+	}
+
+	//skipping constraints on x and y accelerations for the time being
+	// to compute A i'll create an eigen matrix, then i'll convert it to a sparse one and fill those tables
+
+	//total number of constraints
+// NOG h2x_h1x (size * Dim) + h3x_h4x (size * Dim ) + g1x_g2x (size * Dim ) + g3x_g4x (size*Dim) 
+// NOG + x0_x0 (Dim ) + x0p_0 (Dim) + xt_xt (Dim)  + xtp_0 (Dim) = 4 * Dim * size + 4 * Dim
+	// h2x_h1x (size * Dim) + h3x_h4x (size * Dim )
+	// + x0_x0 (Dim ) + x0p_0 (Dim) + xt_xt (Dim)  + xtp_0 (Dim) = 2 * Dim * size + 4 * Dim
+// NOG const MSKint32t numcon = 12 * size + 12;
+	const MSKint32t numcon =  Dim * 2 * size + 4 * Dim; // TODO
+
+	//this gives us the matrix A of size numcon * numvaar
+	MatrixX a = MatrixX::Zero(numcon, numvar);
+	a.block(0							, 0, size * Dim, numvar) = h2x_h1x;
+	a.block(size * Dim					, 0, size * Dim, numvar) = h3x_h4x;
+	a.block(size * Dim * 2				, 0,        Dim, numvar) = x0p_0  ;
+	a.block(size * Dim * 2 + Dim		, 0,        Dim, numvar) = xtp_0  ;
+	a.block(size * Dim * 2 + Dim * 2	, 0,        Dim, numvar) = x0_x0  ;
+	a.block(size * Dim * 2 + Dim * 3	, 0,        Dim, numvar) = xt_xt  ;
+
+	//convert to sparse representation
+	Eigen::SparseMatrix<Numeric> spA;
+	spA = a.sparseView();
+
+	//convert to sparse representation using column
+	// http://docs.mosek.com/7.0/capi/Conventions_employed_in_the_API.html#sec-intro-subsubsec-cmo-rmo-matrix
+
+	int nonZeros = spA.nonZeros();
+	
+	/* Below is the sparse representation of the A
+	matrix stored by column. */
+	double*		aval  = new double[nonZeros];
+	MSKint32t*  asub  = new MSKint32t[nonZeros];
+	MSKint32t*  aptrb = new MSKint32t[numvar];
+	MSKint32t*  aptre = new MSKint32t[numvar];
+
+	int currentIndex = 0;
+	for(int j=0; j<numvar; ++j)
+	{
+		bool nonZeroAtThisCol = false;
+		for(int i=0; i<numcon; ++i)
+		{
+			if(a(i,j) != 0)
+			{
+				if(!nonZeroAtThisCol)
+				{
+					aptrb[j] = currentIndex;
+					nonZeroAtThisCol = true;
+				}
+				aval[currentIndex] = a(i,j);
+				asub[currentIndex] = i;
+				aptre[j] = currentIndex + 1; //overriding previous value
+				++currentIndex;
+			}
+		}
+	}
+
+	/*Q looks like this
+	0 0 0 0 0 0  | -> size * 3
+	0 0 2 0 0 0  | -> size *3
+	0 0 0 0 0 0
+	0 0 0 0 2 0
+	0 0 0 0 0 0	
+	*/
+	/* Number of non-zeros in Q.*/
+	const MSKint32t  numqz = size * Dim * 2;
+	MSKint32t* qsubi = new MSKint32t[numqz]; 
+	MSKint32t* qsubj = new MSKint32t[numqz]; 
+	double*	   qval  = new double   [numqz];
+	for(int id = 0; id < numqz; ++id)
+	{
+		qsubi[id] = id + ptOff; // we want the x.
+		qsubj[id] = id + ptOff;
+		 qval[id] = 2;
+	}
+	
+	 /* Bounds on constraints. */
+	MSKboundkeye* bkc  = new MSKboundkeye[numcon];
+	  
+	double*   blc = new double[numcon];
+	double*   buc = new double[numcon];
+
+	for(int i = 0; i < numcon - Dim * 2 ; ++i)
+	{
+		bkc[i] = MSK_BK_FX;
+		blc[i] = 0;
+		buc[i] = 0;
+	}
+	for(int i = numcon - Dim * 2; i < numcon - Dim ; ++i) // x0 = x^0
+	{
+		bkc[i] = MSK_BK_FX;
+		blc[i] = wayPointsBegin->second(i - (numcon - Dim * 2) );
+		buc[i] = wayPointsBegin->second(i - (numcon - Dim * 2) );
+	}
+	In last(wayPointsEnd);
+	--last;
+	for(int i = numcon - 3; i < numcon ; ++i) // xT = x^T
+	{
+		bkc[i] = MSK_BK_FX;
+		blc[i] = last->second(i - (numcon - Dim) );
+		buc[i] = last->second(i - (numcon - Dim) );
+	}
+
+	///*No Bounds on variables. */
+	MSKboundkeye* bkx  = new MSKboundkeye[numvar];
+	  
+	double*   blx = new double[numvar];
+	double*   bux = new double[numvar];
+
+	for(int i = 0; i < numvar; ++i)
+	{
+		bkx[i] = MSK_BK_FR;
+		blx[i] = -MSK_INFINITY;
+		bux[i] = +MSK_INFINITY;
+	}
+
+	MSKrescodee  r;
+	MSKtask_t    task = NULL;
+	/* Create the optimization task. */
+	r = MSK_maketask(env_,numcon,numvar,&task);
+
+	/* Directs the log task stream to the 'printstr' function. */
+	/*if ( r==MSK_RES_OK )
+		r = MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr);*/
+
+	/* Append 'numcon' empty constraints.
+		The constraints will initially have no bounds. */
+	if ( r == MSK_RES_OK )
+		r = MSK_appendcons(task,numcon);
+
+	/* Append 'numvar' variables.
+		The variables will initially be fixed at zero (x=0). */
+	if ( r == MSK_RES_OK )
+		r = MSK_appendvars(task,numvar);
+
+	for(int j=0; j<numvar && r == MSK_RES_OK; ++j)
+	{
+	/* Set the linear term c_j in the objective.*/   
+      if(r == MSK_RES_OK) 
+        r = MSK_putcj(task,j,0); 
+
+		/* Set the bounds on variable j.
+		blx[j] <= x_j <= bux[j] */
+		if(r == MSK_RES_OK)
+		r = MSK_putvarbound(task,
+							j,           /* Index of variable.*/
+							bkx[j],      /* Bound key.*/
+							blx[j],      /* Numerical value of lower bound.*/
+							bux[j]);     /* Numerical value of upper bound.*/
+
+		/* Input column j of A */   
+		if(r == MSK_RES_OK)
+		r = MSK_putacol(task,
+						j,                 /* Variable (column) index.*/
+						aptre[j]-aptrb[j], /* Number of non-zeros in column j.*/
+						asub+aptrb[j],     /* Pointer to row indexes of column j.*/
+						aval+aptrb[j]);    /* Pointer to Values of column j.*/
+	}
+
+	/* Set the bounds on constraints.
+		for i=1, ...,numcon : blc[i] <= constraint i <= buc[i] */
+	for(int i=0; i<numcon && r == MSK_RES_OK; ++i)
+		r = MSK_putconbound(task,
+							i,           /* Index of constraint.*/
+							bkc[i],      /* Bound key.*/
+							blc[i],      /* Numerical value of lower bound.*/
+							buc[i]);     /* Numerical value of upper bound.*/
+
+	/* Maximize objective function. */
+	if (r == MSK_RES_OK)
+		r = MSK_putobjsense(task, MSK_OBJECTIVE_SENSE_MINIMIZE);
+
+
+	if ( r==MSK_RES_OK ) 
+    {  
+    /* Input the Q for the objective. */ 
+ 
+    r = MSK_putqobj(task,numqz,qsubi,qsubj,qval); 
+    } 
+
+	if ( r==MSK_RES_OK )
+	{
+		MSKrescodee trmcode;
+    
+		/* Run optimizer */
+		r = MSK_optimizetrm(task,&trmcode);
+		if ( r==MSK_RES_OK )
+		{
+			double *xx = (double*) calloc(numvar,sizeof(double));
+			if ( xx )
+			{
+				/* Request the interior point solution. */
+				MSK_getxx(task,	MSK_SOL_ITR, xx);
+				T_waypoints_t nwaypoints;
+				In begin(wayPointsBegin);
+				for(int i=0; i< size; i = ++i, ++begin)
+				{
+					point_t target;
+					for(int j=0; j< Dim; ++ j)
+					{
+						target(j) = xx[i + j*size];
+					}
+					nwaypoints.push_back(std::make_pair(begin->first, target));
+				}
+				res = new exact_cubic_t(nwaypoints.begin(), nwaypoints.end());
+				free(xx);
+			}
+		}
+	}
+	/* Delete the task and the associated data. */
+	MSK_deletetask(&task);
+	return res;
+}
+
+} // namespace spline
+#endif //_CLASS_SPLINEOPTIMIZER
diff --git a/src/tests/spline_test/Main.cpp b/src/tests/spline_test/Main.cpp
index 7f9da71e92274bfcfd9ca5481d0f84d75410e935..3fef0ca27ea228bb8b04394e7fde678195f6d5aa 100644
--- a/src/tests/spline_test/Main.cpp
+++ b/src/tests/spline_test/Main.cpp
@@ -15,8 +15,8 @@ typedef Eigen::Vector3d point_t;
 typedef cubic_function<double, double, 3, true, point_t> cubic_function_t;
 typedef exact_cubic   <double, double, 3, true, point_t> exact_cubic_t;
 typedef bezier_curve  <double, double, 3, true, point_t> bezier_curve_t;
-typedef typename std::pair<double, point_t> Waypoint;
-typedef typename std::vector<Waypoint> T_Waypoint;
+typedef std::pair<double, point_t> Waypoint;
+typedef std::vector<Waypoint> T_Waypoint;
 
 bool QuasiEqual(const double a, const double b, const float margin)
 {