diff --git a/CMakeLists.txt b/CMakeLists.txt
index db87f133768c57cf108f64290f083ddf07651337..c9ade9be5108a99f84175f60c8802681c790aeff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,11 +37,14 @@ INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS})
 SET(${PROJECT_NAME}_HEADERS
   src/eigenpy.hpp
   src/exception.hpp
+  src/details.hpp
+  src/fwd.hpp
   src/map.hpp
-  src/simple.hpp
   src/geometry.hpp
   src/angle-axis.hpp
   src/quaternion.hpp
+  # Deprec
+  src/simple.hpp
 )
 MAKE_DIRECTORY("${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy")
 INCLUDE_DIRECTORIES(${${PROJECT_NAME}_BINARY_DIR}/include/eigenpy)
@@ -68,7 +71,8 @@ ENDFOREACH(header)
 
 ADD_LIBRARY(eigenpy SHARED
   src/exception.cpp
-  src/simple.cpp
+  src/eigenpy.cpp
+  src/details.cpp
   src/angle-axis.cpp
   src/quaternion.cpp
   )
diff --git a/python/alpha.py b/python/alpha.py
deleted file mode 100644
index 55e67fee6959092e370740226d2fb8c6c56b637c..0000000000000000000000000000000000000000
--- a/python/alpha.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/python
-
-import numpy as np
-
-'''
-import libsimple
-
-print libsimple.char()
-print libsimple.str()
-try:
-    a = libsimple.eigenvec()
-    print a
-except:
-    print "Error when calling simple eigenvec"
-
-import libmystring
-print libmystring.hello()
-print libmystring.size("toto+5")
-
-import libeigen
-print libeigen.test()
-a = np.matrix([11,2,3,4,5]).T
-
-b = np.array([11,2,3,4,5])
-#b = np.array([[15,],[1,],[1,],[1,],[1,],])
-#b = np.array([ [[10,2],[3,4]],[[10,2],[3,4]] ])
-
-print "matrix ===> "
-libeigen.test2(a)
-print "array ===> "
-libeigen.test2(b)
-'''
-
-import libeigenpy
-# print "===> From C++ to Py"
-# print libeigentemplate.test()
-# print "===> From Vec C++ to Py"
-# print libeigentemplate.testVec()
-# print "===> From Py to C++"
-a = np.random.random([5,5])
-for i in range(5):
-    for j in range(5):
-        a[i,j] = i*5+j
-#a = np.random.random([
-print a
-libeigentemplate.test2(a)
-# print "===> From Py::slice to C++"
-# b=a[1:5,1:3]
-# print b
-# libeigentemplate.test2(b)
-
-# print "===> From Py::transpose to C++"
-# b=a[1:5,1:3].T
-# print b
-# libeigentemplate.test2(b)
-
-print "===> From py::vec to C++ Vec"
-v = np.array([range(5),],np.float64).T
-print v
-libeigentemplate.test2Vec(v)
-
-
-v = np.array(range(5),np.float64)
-print "v = ", v
-libeigentemplate.test2Vec(v)
-
-v = np.array(range(10),np.float64)
-v2 = v[0:10:5]
-print "v2 = ", v2
-libeigentemplate.test2Vec(v2)
-
-'''
-import libbnpy
-a=libbnpy.array()
-print a.__class__
-b=libbnpy.matrix()
-print b.__class__
-'''
diff --git a/python/test_unit.py b/python/test_unit/eigenpy.py
similarity index 100%
rename from python/test_unit.py
rename to python/test_unit/eigenpy.py
diff --git a/python/tgeometry.py b/python/test_unit/geometry.py
similarity index 90%
rename from python/tgeometry.py
rename to python/test_unit/geometry.py
index 211d23e0024ac0761cd97832ef410f7553a1fd63..1f2642a4fbedbb3af023abdef368dcc67804acaa 100644
--- a/python/tgeometry.py
+++ b/python/test_unit/geometry.py
@@ -2,10 +2,10 @@ from geometry import *
 import numpy as np
 from numpy import cos,sin
 
-verbose = True
+verbose = False
 
 def isapprox(a,b,epsilon=1e-6):
-    if a.__class__ == b.__class__ == np.ndarray:
+    if issubclass(a.__class__,np.ndarray) and issubclass(b.__class__,np.ndarray):
         return np.allclose(a,b,epsilon)
     else:
         return abs(a-b)<epsilon
@@ -23,7 +23,7 @@ assert(isapprox(q.coeffs(),q2.coeffs()))
 
 Rq = q.matrix()
 Rr = r.matrix()
-assert(isapprox(np.dot(Rq,Rq.T),np.eye(3)))
+assert(isapprox(Rq*Rq.T,np.eye(3)))
 assert(isapprox(Rr,Rq))
 
 qR = Quaternion(Rr)
@@ -41,7 +41,7 @@ except Exception,e:
 r = AngleAxis(.1,np.array([1,0,0],np.double))
 if verbose: print "Rx(.1) = \n\n",r.matrix(),"\n"
 assert( isapprox(r.matrix()[2,2],cos(r.angle)))
-assert( isapprox(r.axis,np.array([[1,0,0],],np.double).T) )
+assert( isapprox(r.axis,np.matrix("1;0;0")) )
 assert( isapprox(r.angle,0.1) )
 
 r.axis = np.array([0,1,0],np.double)
diff --git a/src/angle-axis.cpp b/src/angle-axis.cpp
index 988f1651fa159ebb96251ee563771e4a623ef4f8..4508ed7bbe10fe33a5b168208f85afc049731e3b 100644
--- a/src/angle-axis.cpp
+++ b/src/angle-axis.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2014, Nicolas Mansard, LAAS-CNRS
+ *
+ * This file is part of eigenpy.
+ * eigenpy is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ * eigenpy is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.  You should
+ * have received a copy of the GNU Lesser General Public License along
+ * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 #include "eigenpy/angle-axis.hpp"
 #include "eigenpy/geometry.hpp"
 
diff --git a/src/angle-axis.hpp b/src/angle-axis.hpp
index 7cb2a5d5937666e25c241f263f97f24a46d1e772..764001a2a4128a9919ebfa6b6632002ee6caeadd 100644
--- a/src/angle-axis.hpp
+++ b/src/angle-axis.hpp
@@ -1,10 +1,26 @@
-#ifndef __eigenpy_Angle_Axis_hpp__
-#define __eigenpy_Angle_Axis_hpp__
+/*
+ * Copyright 2014, Nicolas Mansard, LAAS-CNRS
+ *
+ * This file is part of eigenpy.
+ * eigenpy is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ * eigenpy is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.  You should
+ * have received a copy of the GNU Lesser General Public License along
+ * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __eigenpy_angle_axis_hpp__
+#define __eigenpy_angle_axis_hpp__
 
 #include <Eigen/Core>
 #include <Eigen/Geometry>
 #include <boost/python.hpp>
-#include "eigenpy/simple.hpp"
+#include "eigenpy/eigenpy.hpp"
 
 namespace eigenpy
 {
@@ -127,5 +143,4 @@ namespace eigenpy
 
 } // namespace eigenpy
 
-
-#endif //ifndef __eigenpy_Angle_Axis_hpp__
+#endif //ifndef __eigenpy_angle_axis_hpp__
diff --git a/src/details.cpp b/src/details.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d77c6c0c7287d6b0a8768726d7e6ddedeb239ffa
--- /dev/null
+++ b/src/details.cpp
@@ -0,0 +1,6 @@
+#include "eigenpy/details.hpp"
+
+namespace eigenpy
+{
+  PyMatrixType pyMatrixType = PyMatrixType();
+} // namespace eigenpy
diff --git a/src/details.hpp b/src/details.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3b71439742eda7016202d15333ae8090448c3b1f
--- /dev/null
+++ b/src/details.hpp
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2014, Nicolas Mansard, LAAS-CNRS
+ *
+ * This file is part of eigenpy.
+ * eigenpy is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ * eigenpy is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.  You should
+ * have received a copy of the GNU Lesser General Public License along
+ * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __eigenpy_details_hpp__
+#define __eigenpy_details_hpp__
+
+#include <Eigen/Core>
+#include <boost/python.hpp>
+#include <numpy/arrayobject.h>
+#include <iostream>
+
+#include "eigenpy/eigenpy.hpp"
+#include "eigenpy/exception.hpp"
+#include "eigenpy/map.hpp"
+
+
+namespace eigenpy
+{
+  template <typename SCALAR>  struct NumpyEquivalentType {};
+  template <> struct NumpyEquivalentType<double>  { enum { type_code = NPY_DOUBLE };};
+  template <> struct NumpyEquivalentType<int>     { enum { type_code = NPY_INT    };};
+  template <> struct NumpyEquivalentType<float>   { enum { type_code = NPY_FLOAT  };};
+
+  struct PyMatrixType
+  {
+    boost::python::object pyMatrixType;
+    boost::python::object pyModule;
+
+    PyMatrixType() 
+    {
+      pyModule = boost::python::import("numpy");
+      pyMatrixType = pyModule.attr("matrix");
+    }
+    operator boost::python::object () { return pyMatrixType; }
+
+    boost::python::object make(PyArrayObject* pyArray, bool copy = false)
+    { return make((PyObject*)pyArray,copy); }
+    boost::python::object make(PyObject* pyObj, bool copy = false)
+    {
+      boost::python::object m
+	= pyMatrixType( boost::python::object(boost::python::handle<>(pyObj)), 
+			boost::python::object(), copy );
+      Py_INCREF(m.ptr());
+      return m;
+    }
+  };
+
+  extern PyMatrixType pyMatrixType;
+
+  /* --- TO PYTHON -------------------------------------------------------------- */
+  template< typename MatType,typename EquivalentEigenType >
+  struct EigenToPy
+  {
+    static PyObject* convert(MatType const& mat)
+    {
+      typedef typename MatType::Scalar T;
+      assert( (mat.rows()<INT_MAX) && (mat.cols()<INT_MAX) 
+	      && "Matrix range larger than int ... should never happen." );
+      const int R  = (int)mat.rows(), C = (int)mat.cols();
+
+      npy_intp shape[2] = { R,C };
+      PyArrayObject* pyArray = (PyArrayObject*)
+	PyArray_SimpleNew(2, shape, NumpyEquivalentType<T>::type_code);
+
+      MapNumpy<EquivalentEigenType>::map(pyArray) = mat;
+
+      return pyMatrixType.make(pyArray).ptr();
+    }
+  };
+  
+  /* --- FROM PYTHON ------------------------------------------------------------ */
+  namespace bp = boost::python;
+
+  template<typename MatType, int ROWS,int COLS>
+  struct TraitsMatrixConstructor
+  {
+    static MatType & construct(void*storage,int /*r*/,int /*c*/)
+    {
+      return * new(storage) MatType();
+    }
+  };
+
+  template<typename MatType>
+  struct TraitsMatrixConstructor<MatType,Eigen::Dynamic,Eigen::Dynamic>
+  {
+    static MatType & construct(void*storage,int r,int c)
+    {
+      return * new(storage) MatType(r,c);
+    }
+  };
+
+  template<typename MatType,int R>
+  struct TraitsMatrixConstructor<MatType,R,Eigen::Dynamic>
+  {
+    static MatType & construct(void*storage,int /*r*/,int c)
+    {
+      return * new(storage) MatType(c);
+    }
+  };
+
+  template<typename MatType,int C>
+  struct TraitsMatrixConstructor<MatType,Eigen::Dynamic,C>
+  {
+    static MatType & construct(void*storage,int r,int /*c*/)
+    {
+      return * new(storage) MatType(r);
+    }
+  };
+
+
+  template<typename MatType,typename EquivalentEigenType>
+  struct EigenFromPy
+  {
+    EigenFromPy()
+    {
+      bp::converter::registry::push_back
+	(&convertible,&construct,bp::type_id<MatType>());
+    }
+ 
+    // Determine if obj_ptr can be converted in a Eigenvec
+    static void* convertible(PyObject* obj_ptr)
+    {
+      typedef typename MatType::Scalar T;
+
+      if (!PyArray_Check(obj_ptr)) 
+	{
+	  std::cerr << "The python object is not a numpy array." << std::endl;
+	  return 0;
+	}
+
+      if (PyArray_NDIM(obj_ptr) != 2)
+	if ( (PyArray_NDIM(obj_ptr) !=1) || (! MatType::IsVectorAtCompileTime) )
+	  {
+	    std::cerr << "The number of dimension of the object is not correct." << std::endl;
+	    return 0;
+	  }
+
+      if ((PyArray_ObjectType(obj_ptr, 0)) != NumpyEquivalentType<T>::type_code)
+	{
+	  std::cerr << "The internal type as no Eigen equivalent." << std::endl;
+	  return 0;
+	}
+
+      if (!(PyArray_FLAGS(obj_ptr) & NPY_ALIGNED))
+	{
+	  std::cerr << "NPY non-aligned matrices are not implemented." << std::endl;
+	  return 0;
+	}
+      
+      return obj_ptr;
+    }
+ 
+    // Convert obj_ptr into a Eigenvec
+    static void construct(PyObject* pyObj,
+			  bp::converter::rvalue_from_python_stage1_data* memory)
+    {
+      typedef typename MatType::Scalar T;
+      using namespace Eigen;
+
+      PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
+      typename MapNumpy<EquivalentEigenType>::EigenMap numpyMap = MapNumpy<EquivalentEigenType>::map(pyArray);
+
+      void* storage = ((bp::converter::rvalue_from_python_storage<MatType>*)
+		       (memory))->storage.bytes;
+      assert( (numpyMap.rows()<INT_MAX) && (numpyMap.cols()<INT_MAX) 
+	      && "Map range larger than int ... can never happen." );
+      int r=(int)numpyMap.rows(),c=(int)numpyMap.cols();
+      EquivalentEigenType & eigenMatrix = //* new(storage) MatType(numpyMap.rows(),numpyMap.cols());
+	TraitsMatrixConstructor<MatType,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime>::construct (storage,r,c);
+      memory->convertible = storage;
+
+      eigenMatrix = numpyMap;
+    }
+  };
+
+  template<typename MatType,typename EigenEquivalentType>
+  void enableEigenPySpecific()
+  {
+    import_array();
+
+ #ifdef EIGEN_DONT_VECTORIZE
+    boost::python::to_python_converter<MatType,
+				       eigenpy::EigenToPy<MatType,MatType> >();
+    eigenpy::EigenFromPy<MatType,MatType>();
+ #else 
+    typedef typename eigenpy::UnalignedEquivalent<MatType>::type MatTypeDontAlign;
+    
+    boost::python::to_python_converter<MatType,
+				       eigenpy::EigenToPy<MatType,MatType> >();
+    boost::python::to_python_converter<MatTypeDontAlign,
+				       eigenpy::EigenToPy<MatTypeDontAlign,MatTypeDontAlign> >();
+    eigenpy::EigenFromPy<MatTypeDontAlign,MatTypeDontAlign>();
+#endif
+
+  }
+
+} // namespace eigenpy
+
+#endif // ifndef __eigenpy_details_hpp__
diff --git a/src/eigenpy.cpp b/src/eigenpy.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fa6d2984a97b627403b4e11fb70efe653ee732eb
--- /dev/null
+++ b/src/eigenpy.cpp
@@ -0,0 +1,24 @@
+
+#include "eigenpy/eigenpy.hpp"
+#include "eigenpy/simple.hpp"
+
+namespace eigenpy
+{
+
+  /* Enable Eigen-Numpy serialization for a set of standard MatrixBase instance. */
+  void enableEigenPy()
+  {
+    Exception::registerException();
+
+    enableEigenPySpecific<Eigen::MatrixXd,Eigen::MatrixXd>();
+    enableEigenPySpecific<Eigen::Matrix2d,Eigen::Matrix2d>();
+    enableEigenPySpecific<Eigen::Matrix3d,Eigen::Matrix3d>();
+    enableEigenPySpecific<Eigen::Matrix4d,Eigen::Matrix4d>();
+
+    enableEigenPySpecific<Eigen::VectorXd,Eigen::VectorXd>();
+    enableEigenPySpecific<Eigen::Vector2d,Eigen::Vector2d>();
+    enableEigenPySpecific<Eigen::Vector3d,Eigen::Vector3d>();
+    enableEigenPySpecific<Eigen::Vector4d,Eigen::Vector4d>();
+  }
+
+} // namespace eigenpy
diff --git a/src/eigenpy.hpp b/src/eigenpy.hpp
index 873af25f699a789625234ffb1367085b29ae55b2..97d26c70cd02a7f3fa00f725a2e4258a0ce96a9d 100644
--- a/src/eigenpy.hpp
+++ b/src/eigenpy.hpp
@@ -14,205 +14,32 @@
  * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <Eigen/Core>
-#include <boost/python.hpp>
-#include <numpy/arrayobject.h>
-#include <iostream>
-#include <eigenpy/exception.hpp>
-#include <eigenpy/simple.hpp>
-#include <eigenpy/map.hpp>
+#ifndef __eigenpy_eigenpy_hpp__
+#define __eigenpy_eigenpy_hpp__
+
+#include "eigenpy/fwd.hpp"
 
 namespace eigenpy
 {
-
-  /* Enable the Eigen--Numpy serialization for the templated MatrixBase class. */
+  typedef UnalignedEquivalent<Eigen::MatrixXd>::type MatrixXd_fx;
+  typedef UnalignedEquivalent<Eigen::Matrix3d>::type Matrix3d_fx;
+  typedef UnalignedEquivalent<Eigen::Matrix4d>::type Matrix4d_fx;
+  typedef UnalignedEquivalent<Eigen::VectorXd>::type VectorXd_fx;
+  typedef UnalignedEquivalent<Eigen::Vector3d>::type Vector3d_fx;
+  typedef UnalignedEquivalent<Eigen::Vector4d>::type Vector4d_fx;
+
+  /* Enable Eigen-Numpy serialization for a set of standard MatrixBase instance. */
+  void enableEigenPy();
+
+  /* Enable the Eigen--Numpy serialization for the templated MatrixBase class.
+   * The second template argument is used for inheritance of Eigen classes. If
+   * using a native Eigen::MatrixBase, simply repeat the same arg twice. */
   template<typename MatType,typename EigenEquivalentType>
   void enableEigenPySpecific();
 
-}
-
-/* --- DETAILS ------------------------------------------------------------------ */
-/* --- DETAILS ------------------------------------------------------------------ */
-/* --- DETAILS ------------------------------------------------------------------ */
-
-namespace eigenpy
-{
-  template <typename SCALAR>  struct NumpyEquivalentType {};
-  template <> struct NumpyEquivalentType<double>  { enum { type_code = NPY_DOUBLE };};
-  template <> struct NumpyEquivalentType<int>     { enum { type_code = NPY_INT    };};
-  template <> struct NumpyEquivalentType<float>   { enum { type_code = NPY_FLOAT  };};
-
-  struct PyMatrixType
-  {
-    boost::python::object pyMatrixType;
-    boost::python::object pyModule;
-
-    PyMatrixType() 
-    {
-      pyModule = boost::python::import("numpy");
-      pyMatrixType = pyModule.attr("matrix");
-    }
-    operator boost::python::object () { return pyMatrixType; }
-
-    boost::python::object make(PyArrayObject* pyArray, bool copy = false)
-    { return make((PyObject*)pyArray,copy); }
-    boost::python::object make(PyObject* pyObj, bool copy = false)
-    {
-      boost::python::object m
-	= pyMatrixType( boost::python::object(boost::python::handle<>(pyObj)), 
-			boost::python::object(), copy );
-      Py_INCREF(m.ptr());
-      return m;
-    }
-  };
-
-  static PyMatrixType pyMatrixType = PyMatrixType();
-
-  /* --- TO PYTHON -------------------------------------------------------------- */
-  template< typename MatType,typename EquivalentEigenType >
-  struct EigenToPy
-  {
-    static PyObject* convert(MatType const& mat)
-    {
-      typedef typename MatType::Scalar T;
-      assert( (mat.rows()<INT_MAX) && (mat.cols()<INT_MAX) 
-	      && "Matrix range larger than int ... should never happen." );
-      const int R  = (int)mat.rows(), C = (int)mat.cols();
-
-      npy_intp shape[2] = { R,C };
-      PyArrayObject* pyArray = (PyArrayObject*)
-	PyArray_SimpleNew(2, shape, NumpyEquivalentType<T>::type_code);
-
-      MapNumpy<EquivalentEigenType>::map(pyArray) = mat;
-
-      return pyMatrixType.make(pyArray).ptr();
-    }
-  };
-  
-  /* --- FROM PYTHON ------------------------------------------------------------ */
-  namespace bp = boost::python;
-
-  template<typename MatType, int ROWS,int COLS>
-  struct TraitsMatrixConstructor
-  {
-    static MatType & construct(void*storage,int /*r*/,int /*c*/)
-    {
-      return * new(storage) MatType();
-    }
-  };
-
-  template<typename MatType>
-  struct TraitsMatrixConstructor<MatType,Eigen::Dynamic,Eigen::Dynamic>
-  {
-    static MatType & construct(void*storage,int r,int c)
-    {
-      return * new(storage) MatType(r,c);
-    }
-  };
-
-  template<typename MatType,int R>
-  struct TraitsMatrixConstructor<MatType,R,Eigen::Dynamic>
-  {
-    static MatType & construct(void*storage,int /*r*/,int c)
-    {
-      return * new(storage) MatType(c);
-    }
-  };
-
-  template<typename MatType,int C>
-  struct TraitsMatrixConstructor<MatType,Eigen::Dynamic,C>
-  {
-    static MatType & construct(void*storage,int r,int /*c*/)
-    {
-      return * new(storage) MatType(r);
-    }
-  };
-
-
-  template<typename MatType,typename EquivalentEigenType>
-  struct EigenFromPy
-  {
-    EigenFromPy()
-    {
-      bp::converter::registry::push_back
-	(&convertible,&construct,bp::type_id<MatType>());
-    }
- 
-    // Determine if obj_ptr can be converted in a Eigenvec
-    static void* convertible(PyObject* obj_ptr)
-    {
-      typedef typename MatType::Scalar T;
-
-      if (!PyArray_Check(obj_ptr)) 
-	{
-	  std::cerr << "The python object is not a numpy array." << std::endl;
-	  return 0;
-	}
-
-      if (PyArray_NDIM(obj_ptr) != 2)
-	if ( (PyArray_NDIM(obj_ptr) !=1) || (! MatType::IsVectorAtCompileTime) )
-	  {
-	    std::cerr << "The number of dimension of the object is not correct." << std::endl;
-	    return 0;
-	  }
-
-      if ((PyArray_ObjectType(obj_ptr, 0)) != NumpyEquivalentType<T>::type_code)
-	{
-	  std::cerr << "The internal type as no Eigen equivalent." << std::endl;
-	  return 0;
-	}
-
-      if (!(PyArray_FLAGS(obj_ptr) & NPY_ALIGNED))
-	{
-	  std::cerr << "NPY non-aligned matrices are not implemented." << std::endl;
-	  return 0;
-	}
-      
-      return obj_ptr;
-    }
- 
-    // Convert obj_ptr into a Eigenvec
-    static void construct(PyObject* pyObj,
-			  bp::converter::rvalue_from_python_stage1_data* memory)
-    {
-      typedef typename MatType::Scalar T;
-      using namespace Eigen;
-
-      PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
-      typename MapNumpy<EquivalentEigenType>::EigenMap numpyMap = MapNumpy<EquivalentEigenType>::map(pyArray);
-
-      void* storage = ((bp::converter::rvalue_from_python_storage<MatType>*)
-		       (memory))->storage.bytes;
-      assert( (numpyMap.rows()<INT_MAX) && (numpyMap.cols()<INT_MAX) 
-	      && "Map range larger than int ... can never happen." );
-      int r=(int)numpyMap.rows(),c=(int)numpyMap.cols();
-      EquivalentEigenType & eigenMatrix = //* new(storage) MatType(numpyMap.rows(),numpyMap.cols());
-	TraitsMatrixConstructor<MatType,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime>::construct (storage,r,c);
-      memory->convertible = storage;
-
-      eigenMatrix = numpyMap;
-    }
-  };
-
-  template<typename MatType,typename EigenEquivalentType>
-  void enableEigenPySpecific()
-  {
-    import_array();
+} // namespace eigenpy
 
- #ifdef EIGEN_DONT_VECTORIZE
-    boost::python::to_python_converter<MatType,
-				       eigenpy::EigenToPy<MatType,MatType> >();
-    eigenpy::EigenFromPy<MatType,MatType>();
- #else 
-    typedef typename eigenpy::UnalignedEquivalent<MatType>::type MatTypeDontAlign;
-    
-    boost::python::to_python_converter<MatType,
-				       eigenpy::EigenToPy<MatType,MatType> >();
-    boost::python::to_python_converter<MatTypeDontAlign,
-				       eigenpy::EigenToPy<MatTypeDontAlign,MatTypeDontAlign> >();
-    eigenpy::EigenFromPy<MatTypeDontAlign,MatTypeDontAlign>();
-#endif
+#include "eigenpy/details.hpp"
 
-  }
+#endif // ifndef __eigenpy_eigenpy_hpp__
 
-} // namespace eigenpy
diff --git a/src/fwd.hpp b/src/fwd.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7622f518ccc9e873cf90533c47b3d2be1d4e1209
--- /dev/null
+++ b/src/fwd.hpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2014, Nicolas Mansard, LAAS-CNRS
+ *
+ * This file is part of eigenpy.
+ * eigenpy is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ * eigenpy is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.  You should
+ * have received a copy of the GNU Lesser General Public License along
+ * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __eigenpy_fwd_hpp__
+#define __eigenpy_fwd_hpp__
+
+#include <Eigen/Core>
+#include <boost/python.hpp>
+
+namespace eigenpy
+{
+  template<typename D>
+  struct UnalignedEquivalent
+  {
+    typedef Eigen::MatrixBase<D> MatType;
+    typedef Eigen::Matrix<typename D::Scalar,
+			  D::RowsAtCompileTime,
+			  D::ColsAtCompileTime,
+			  D::Options | Eigen::DontAlign,
+			  D::MaxRowsAtCompileTime,
+			  D::MaxColsAtCompileTime>      type;
+  };
+
+} // namespace eigenpy
+
+#endif // ifndef __eigenpy_fwd_hpp__
diff --git a/src/geometry.hpp b/src/geometry.hpp
index b2b887617c8d26716f1a936950c1e8d0ea40c1fe..bdb7752a6068913fd16d7880efa77eaf3e11b89d 100644
--- a/src/geometry.hpp
+++ b/src/geometry.hpp
@@ -1,3 +1,26 @@
+/*
+ * Copyright 2014, Nicolas Mansard, LAAS-CNRS
+ *
+ * This file is part of eigenpy.
+ * eigenpy is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ * eigenpy is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.  You should
+ * have received a copy of the GNU Lesser General Public License along
+ * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __eigenpy_geometry_hpp__
+#define __eigenpy_geometry_hpp__
+
+#include "eigenpy/eigenpy.hpp"
+#include "eigenpy/quaternion.hpp"
+#include "eigenpy/angle-axis.hpp"
+
 namespace eigenpy
 {
   typedef Eigen::Quaternion<double,Eigen::DontAlign> Quaterniond_fx;
@@ -5,4 +28,7 @@ namespace eigenpy
 
   void exposeQuaternion();
   void exposeAngleAxis();
+
 } // namespace eigenpy
+
+#endif // define __eigenpy_geometry_hpp__
diff --git a/src/quaternion.cpp b/src/quaternion.cpp
index 90b5922ea2d757d59750f4ba0ced4fd45fc2861c..6e1360a3c53168ce7dd40318d0dd9f0aeade8b53 100644
--- a/src/quaternion.cpp
+++ b/src/quaternion.cpp
@@ -1,10 +1,25 @@
-#include "eigenpy/quaternion.hpp"
+/*
+ * Copyright 2014, Nicolas Mansard, LAAS-CNRS
+ *
+ * This file is part of eigenpy.
+ * eigenpy is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ * eigenpy is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.  You should
+ * have received a copy of the GNU Lesser General Public License along
+ * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 #include "eigenpy/geometry.hpp"
 
 namespace eigenpy
 {
   void exposeQuaternion()
   {
-      QuaternionVisitor<Eigen::Quaterniond>::expose();
+    QuaternionVisitor<Eigen::Quaterniond>::expose();
   }
 } // namespace eigenpy
diff --git a/src/quaternion.hpp b/src/quaternion.hpp
index 95e8bcb7174e16e1a18c3dc43a47262b6e415a89..e0f01fc25671cd91b28be628c5d162d2d068e59e 100644
--- a/src/quaternion.hpp
+++ b/src/quaternion.hpp
@@ -1,10 +1,26 @@
-#ifndef __eigenpy_Quaternion_hpp__
-#define __eigenpy_Quaternion_hpp__
+/*
+ * Copyright 2014, Nicolas Mansard, LAAS-CNRS
+ *
+ * This file is part of eigenpy.
+ * eigenpy is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ * eigenpy is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.  You should
+ * have received a copy of the GNU Lesser General Public License along
+ * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __eigenpy_quaternion_hpp__
+#define __eigenpy_quaternion_hpp__
 
-#include "eigenpy/exception.hpp"
 #include <Eigen/Core>
 #include <Eigen/Geometry>
-#include "eigenpy/simple.hpp"
+#include "eigenpy/eigenpy.hpp"
+#include "eigenpy/exception.hpp"
 
 namespace eigenpy
 {
@@ -160,4 +176,4 @@ namespace eigenpy
 
 } // namespace eigenpy
 
-#endif // ifndef __eigenpy_Quaternion_hpp__
+#endif // ifndef __eigenpy_quaternion_hpp__
diff --git a/src/simple.cpp b/src/simple.cpp
index 01aaf10b4e2c364764893d03c828672f9cdcc5f7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/src/simple.cpp
+++ b/src/simple.cpp
@@ -1,24 +0,0 @@
-
-#include <eigenpy/eigenpy.hpp>
-#include <eigenpy/simple.hpp>
-
-namespace eigenpy
-{
-
-  /* Enable Eigen-Numpy serialization for a set of standard MatrixBase instance. */
-  void enableEigenPy()
-  {
-    Exception::registerException();
-
-    enableEigenPySpecific<Eigen::MatrixXd,Eigen::MatrixXd>();
-    enableEigenPySpecific<Eigen::Matrix2d,Eigen::Matrix2d>();
-    enableEigenPySpecific<Eigen::Matrix3d,Eigen::Matrix3d>();
-    enableEigenPySpecific<Eigen::Matrix4d,Eigen::Matrix4d>();
-
-    enableEigenPySpecific<Eigen::VectorXd,Eigen::VectorXd>();
-    enableEigenPySpecific<Eigen::Vector2d,Eigen::Vector2d>();
-    enableEigenPySpecific<Eigen::Vector3d,Eigen::Vector3d>();
-    enableEigenPySpecific<Eigen::Vector4d,Eigen::Vector4d>();
-  }
-
-} // namespace eigenpy
diff --git a/src/simple.hpp b/src/simple.hpp
index 62415671e041ddbbce4088f8e30f87323abccddf..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/src/simple.hpp
+++ b/src/simple.hpp
@@ -1,51 +0,0 @@
-/*
- * Copyright 2014, Nicolas Mansard, LAAS-CNRS
- *
- * This file is part of eigenpy.
- * eigenpy is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- * eigenpy is distributed in the hope that it will be
- * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Lesser General Public License for more details.  You should
- * have received a copy of the GNU Lesser General Public License along
- * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __eigenpy_Simple_hpp__
-#define __eigenpy_Simple_hpp__
-
-#include <Eigen/Core>
-#include <boost/python.hpp>
-
-namespace eigenpy
-{
-
-  /* Enable Eigen-Numpy serialization for a set of standard MatrixBase instance. */
-  void enableEigenPy();
-
-
-  template<typename D>
-  struct UnalignedEquivalent
-  {
-    typedef Eigen::MatrixBase<D> MatType;
-    typedef Eigen::Matrix<typename D::Scalar,
-			  D::RowsAtCompileTime,
-			  D::ColsAtCompileTime,
-			  D::Options | Eigen::DontAlign,
-			  D::MaxRowsAtCompileTime,
-			  D::MaxColsAtCompileTime>      type;
-  };
-
-  typedef UnalignedEquivalent<Eigen::MatrixXd> MatrixXd_fx;
-  typedef UnalignedEquivalent<Eigen::Matrix3d> Matrix3d_fx;
-  typedef UnalignedEquivalent<Eigen::Matrix4d> Matrix4d_fx;
-  typedef UnalignedEquivalent<Eigen::VectorXd> VectorXd_fx;
-  typedef UnalignedEquivalent<Eigen::Vector3d> Vector3d_fx;
-  typedef UnalignedEquivalent<Eigen::Vector4d> Vector4d_fx;
-
-} // namespace eigenpy
-
-#endif // ifndef __eigenpy_Simple_hpp__
diff --git a/unittest/geometry.cpp b/unittest/geometry.cpp
index 65dd0982006b870e0e943c345937e7fdeca2823d..0490eb5969144c75fc0ed35c053e05071ba40813 100644
--- a/unittest/geometry.cpp
+++ b/unittest/geometry.cpp
@@ -1,7 +1,5 @@
-//#define EIGEN_DONT_VECTORIZE 
-//#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
 
-#include "eigenpy/simple.hpp"
+#include "eigenpy/eigenpy.hpp"
 #include "eigenpy/geometry.hpp"
 #include <Eigen/Core>
 #include <Eigen/Geometry>
diff --git a/unittest/matrix.cpp b/unittest/matrix.cpp
index 908b7dde12335e4aaa196825fb08819ce2ece617..a1f30d5f594f3c1247a7a64c636899849b748bfa 100644
--- a/unittest/matrix.cpp
+++ b/unittest/matrix.cpp
@@ -14,7 +14,7 @@
  * with eigenpy.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "eigenpy/simple.hpp"
+#include "eigenpy/eigenpy.hpp"
 #include <iostream>
 
 Eigen::MatrixXd naturals(int R,int C,bool verbose)