diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f234adeb92febac8b0e30b822ad211861e35c865..4dc1a387384f8fed8645059b9846281f831a914c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -61,6 +61,12 @@ IF(OpenCV_FOUND)
     MESSAGE("OpenCV Library FOUND: OpenCV related sources will be built.")
 ENDIF(OpenCV_FOUND)
 
+# Cereal
+FIND_PACKAGE(cereal QUIET)
+IF(cereal_FOUND)
+    MESSAGE("cereal Library FOUND: cereal related sources will be built.")
+ENDIF(cereal_FOUND)
+
 # YAML with yaml-cpp
 INCLUDE (${PROJECT_SOURCE_DIR}/cmake_modules/FindYamlCpp.cmake)
 IF(YAMLCPP_FOUND)
@@ -143,6 +149,11 @@ IF(OpenCV_FOUND)
     INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
 ENDIF(OpenCV_FOUND)
 
+# cereal
+IF(cereal_FOUND)
+    INCLUDE_DIRECTORIES(${cereal_INCLUDE_DIRS})
+ENDIF(cereal_FOUND)
+
 IF(Suitesparse_FOUND)
     INCLUDE_DIRECTORIES(${Suitesparse_INCLUDE_DIRS})
 ENDIF(Suitesparse_FOUND)
@@ -388,6 +399,10 @@ IF (OpenCV_FOUND)
         )
 ENDIF(OpenCV_FOUND)
 
+IF (cereal_FOUND)
+  ADD_SUBDIRECTORY(io/cereal)
+ENDIF(cereal_FOUND)
+
 IF (Suitesparse_FOUND)
     ADD_SUBDIRECTORY(solver)
 ENDIF(Suitesparse_FOUND)
@@ -472,6 +487,8 @@ INSTALL(FILES ${HDRS_WRAPPER}
     DESTINATION include/iri-algorithms/wolf/ceres_wrapper)
 INSTALL(FILES ${HDRS_SOLVER}
     DESTINATION include/iri-algorithms/wolf/solver)
+INSTALL(FILES ${HDRS_CEREAL}
+    DESTINATION include/iri-algorithms/wolf/io/cereal)
 
 INSTALL(FILES "${CMAKE_SOURCE_DIR}/cmake_modules/Findwolf.cmake"
     DESTINATION "lib/cmake/${PROJECT_NAME}")
diff --git a/src/io/CMakeLists.txt b/src/io/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a853ba8ec5158727fcd4bfd9752d6de398c5aefa
--- /dev/null
+++ b/src/io/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(cereal)
diff --git a/src/io/cereal/CMakeLists.txt b/src/io/cereal/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8f5bba88a1cd462911b5ae8abb72869075bfac39
--- /dev/null
+++ b/src/io/cereal/CMakeLists.txt
@@ -0,0 +1,4 @@
+SET(HDRS_CEREAL
+    serialization_node_base.h)
+
+SET(SRCS_CEREAL)
diff --git a/src/io/cereal/archive.h b/src/io/cereal/archive.h
new file mode 100644
index 0000000000000000000000000000000000000000..d8c16fd180ef04049ceedaf268fa33782790d27a
--- /dev/null
+++ b/src/io/cereal/archive.h
@@ -0,0 +1,9 @@
+#ifndef _WOLF_IO_CEREAL_ARCHIVE_H_
+#define _WOLF_IO_CEREAL_ARCHIVE_H_
+
+#include <cereal/archives/binary.hpp>
+#include <cereal/archives/json.hpp>
+#include <cereal/archives/portable_binary.hpp>
+#include <cereal/archives/xml.hpp>
+
+#endif /* _WOLF_IO_CEREAL_ARCHIVE_H_ */
diff --git a/src/io/cereal/serialization_node_base.h b/src/io/cereal/serialization_node_base.h
new file mode 100644
index 0000000000000000000000000000000000000000..f5b67cd2e55ecf20b60bea3cf76d11efa92b13e1
--- /dev/null
+++ b/src/io/cereal/serialization_node_base.h
@@ -0,0 +1,75 @@
+#ifndef _WOLF_IO_CEREAL_NODE_BASE_H_
+#define _WOLF_IO_CEREAL_NODE_BASE_H_
+
+// Wolf includes
+#include "../../node_base.h"
+
+#include <cereal/cereal.hpp>
+
+namespace wolf {
+
+struct NodeBase::Serializer {
+
+  template <class Archive>
+  static void serialize(Archive& ar, NodeBase& o, std::uint32_t const /*version*/)
+  {
+    ar( cereal::make_nvp("node_class_", o.node_class_) );
+    ar( cereal::make_nvp("node_type_",  o.node_type_)  );
+    ar( cereal::make_nvp("node_name_",  o.node_name_)  );
+    ar( cereal::make_nvp("node_id_",    o.node_id_)    );
+
+//    ar( cereal::make_nvp("problem_ptr_", o.problem_ptr_) );
+
+    // Not sure what to do with this guy ...
+    //ar( cereal::make_nvp("node_id_count_",    o.node_id_count_)    );
+  }
+
+  template <class Archive>
+  static void load_and_construct( Archive& ar, cereal::construct<wolf::NodeBase>& construct,
+                                  std::uint32_t const /*version*/ )
+  {
+    decltype(std::declval<wolf::NodeBase>().getClass()) nb_class;
+    decltype(std::declval<wolf::NodeBase>().getType())  nb_type;
+    decltype(std::declval<wolf::NodeBase>().getName())  nb_name;
+
+    ar( cereal::make_nvp("node_class_", nb_class) );
+    ar( cereal::make_nvp("node_type_",  nb_type) );
+    ar( cereal::make_nvp("node_name_",  nb_name) );
+
+    construct( nb_class, nb_type, nb_name );
+
+    ar( cereal::make_nvp("node_id_", construct->node_id_) );
+
+//    ar( cereal::make_nvp("problem_ptr_", construct->problem_ptr_) );
+
+    // Not sure what to do with this guy ...
+    //ar( cereal::make_nvp("node_id_count_", construct->node_id_count_)    );
+  }
+
+};
+
+} // namespace wolf
+
+namespace cereal {
+
+template <>
+struct LoadAndConstruct<wolf::NodeBase>
+{
+  template <class Archive>
+  static void load_and_construct( Archive& ar,
+                                  cereal::construct<wolf::NodeBase>& construct,
+                                  std::uint32_t const version )
+  {
+    wolf::NodeBase::Serializer::load_and_construct(ar, construct, version);
+  }
+};
+
+template <class Archive>
+void serialize(Archive& ar, wolf::NodeBase& o, std::uint32_t const version)
+{
+  wolf::NodeBase::Serializer::serialize(ar, o, version);
+}
+
+} // namespace cereal
+
+#endif /* _WOLF_IO_CEREAL_NODE_BASE_H_ */
diff --git a/src/node_base.h b/src/node_base.h
index 96ad0ff73e3ea16165c5d537eb95713e3d8e48e3..e404eedf839085510b2595de1a606facdb75424c 100644
--- a/src/node_base.h
+++ b/src/node_base.h
@@ -56,6 +56,8 @@ class NodeBase
     private:
         static unsigned int node_id_count_; ///< Object counter (acts as simple ID factory)
 
+        struct Serializer;
+
     protected:
         ProblemWPtr problem_ptr_;
 
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 7680d9f62e59ac0f1e0a3e36e7e694b4371a9321..bd1317227b8e7f4d069396d26dfc6054ae7c2803 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -115,3 +115,7 @@ IF(OpenCV_FOUND)
   wolf_add_gtest(gtest_roi_ORB gtest_roi_ORB.cpp)
   target_link_libraries(gtest_roi_ORB ${PROJECT_NAME})
 ENDIF(OpenCV_FOUND)
+
+# ------- Now Core classes Serialization ----------
+
+add_subdirectory(io)
diff --git a/src/test/io/CMakeLists.txt b/src/test/io/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6902132bd458245e2e45012662fdcf0b348b7d4a
--- /dev/null
+++ b/src/test/io/CMakeLists.txt
@@ -0,0 +1,4 @@
+# cereal
+IF(cereal_FOUND)
+  add_subdirectory(cereal)
+ENDIF(cereal_FOUND)
diff --git a/src/test/io/cereal/CMakeLists.txt b/src/test/io/cereal/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4ee6450dd4546e8e57bdb730c1f1bc83ff28d085
--- /dev/null
+++ b/src/test/io/cereal/CMakeLists.txt
@@ -0,0 +1,3 @@
+# NodeBase serialization class test
+wolf_add_gtest(gtest_cereal_serialization_node_base gtest_serialization_node_base.cpp)
+target_link_libraries(gtest_cereal_serialization_node_base ${PROJECT_NAME})
diff --git a/src/test/io/cereal/gtest_serialization_local_parametrization.cpp b/src/test/io/cereal/gtest_serialization_local_parametrization.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ceb8fff3062da32e62d97f7b78524bde860a0c5
--- /dev/null
+++ b/src/test/io/cereal/gtest_serialization_local_parametrization.cpp
@@ -0,0 +1,575 @@
+/*
+ * gtest_node_base_serialization.cpp
+ *
+ *  Created on: Jul 16, 2017
+ *      Author: Jeremie Deray
+ */
+
+#include "../../utils_gtest.h"
+
+#include "../../../io/cereal/serialization_local_parametrization_quaternion.h"
+#include "../../../io/cereal/serialization_local_parametrization_homogeneous.h"
+
+#include <cereal/archives/binary.hpp>
+#include <cereal/archives/json.hpp>
+#include <cereal/archives/portable_binary.hpp>
+#include <cereal/archives/xml.hpp>
+
+#include <cereal/types/memory.hpp>
+#include <fstream>
+
+///////////////////////////////////////
+/// LocalParametrizationHomogeneous ///
+///////////////////////////////////////
+
+const std::string path_to_io = "/tmp/";
+
+TEST(TestSerialization, SerializationLocalParametrizationHomogeneousXML)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_serialization.xml");
+    cereal::XMLOutputArchive archive(os);
+
+    wolf::LocalParametrizationHomogeneous local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_serialization.xml");
+    cereal::XMLInputArchive archive(is);
+
+    wolf::LocalParametrizationHomogeneous local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationHomogeneousXML !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationHomogeneousPtrXML)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_ptr_serialization.xml");
+    cereal::XMLOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationHomogeneous>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_ptr_serialization.xml");
+    cereal::XMLInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationHomogeneous>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationHomogeneousPtrXML !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationHomogeneousJSON)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_serialization.json");
+    cereal::JSONOutputArchive archive(os);
+
+    wolf::LocalParametrizationHomogeneous local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_serialization.json");
+    cereal::JSONInputArchive archive(is);
+
+    wolf::LocalParametrizationHomogeneous local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationHomogeneousJSON !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationHomogeneousPtrJSON)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_ptr_serialization.json");
+    cereal::JSONOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationHomogeneous>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_ptr_serialization.json");
+    cereal::JSONInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationHomogeneous>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationHomogeneousPtrJSON !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationHomogeneousBIN)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_serialization.bin");
+    cereal::BinaryOutputArchive archive(os);
+
+    wolf::LocalParametrizationHomogeneous local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_serialization.bin");
+    cereal::BinaryInputArchive archive(is);
+
+    wolf::LocalParametrizationHomogeneous local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationHomogeneousBIN !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationHomogeneousPtrBIN)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_ptr_serialization.bin");
+    cereal::BinaryOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationHomogeneous>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_ptr_serialization.bin");
+    cereal::BinaryInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationHomogeneous>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationHomogeneousPtrBIN !\n");
+}
+
+
+//////////////////////////////////////
+/// LocalParametrizationQuaternion ///
+//////////////////////////////////////
+
+//////////////////////////////////////
+///           LOCAL                ///
+//////////////////////////////////////
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionXML)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quat_serialization.xml");
+    cereal::XMLOutputArchive archive(os);
+
+    wolf::LocalParametrizationQuaternionLocal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quat_serialization.xml");
+    cereal::XMLInputArchive archive(is);
+
+    wolf::LocalParametrizationQuaternionLocal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionXML !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionPtrXML)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quat_ptr_serialization.xml");
+    cereal::XMLOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationQuaternionLocal>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quat_ptr_serialization.xml");
+    cereal::XMLInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationQuaternionLocal>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionPtrXML !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionJSON)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quat_serialization.json");
+    cereal::JSONOutputArchive archive(os);
+
+    wolf::LocalParametrizationQuaternionLocal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quat_serialization.json");
+    cereal::JSONInputArchive archive(is);
+
+    wolf::LocalParametrizationQuaternionLocal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionJSON !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionPtrJSON)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quat_ptr_serialization.json");
+    cereal::JSONOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationQuaternionLocal>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quat_ptr_serialization.json");
+    cereal::JSONInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationQuaternionLocal>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionPtrJSON !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionBIN)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quat_serialization.bin");
+    cereal::BinaryOutputArchive archive(os);
+
+    wolf::LocalParametrizationQuaternionLocal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quat_serialization.bin");
+    cereal::BinaryInputArchive archive(is);
+
+    wolf::LocalParametrizationQuaternionLocal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionBIN !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionPtrBIN)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quat_ptr_serialization.bin");
+    cereal::BinaryOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationQuaternionLocal>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quat_ptr_serialization.bin");
+    cereal::BinaryInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationQuaternionLocal>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionPtrBIN !\n");
+}
+
+//////////////////////////////////////
+///           GLOBAL               ///
+//////////////////////////////////////
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionGlobalXML)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quatg_serialization.xml");
+    cereal::XMLOutputArchive archive(os);
+
+    wolf::LocalParametrizationQuaternionGlobal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quatg_serialization.xml");
+    cereal::XMLInputArchive archive(is);
+
+    wolf::LocalParametrizationQuaternionGlobal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionGlobalXML !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionGlobalPtrXML)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quatg_ptr_serialization.xml");
+    cereal::XMLOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationQuaternionGlobal>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quatg_ptr_serialization.xml");
+    cereal::XMLInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationQuaternionGlobal>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionGlobalPtrXML !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionGlobalJSON)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quatg_serialization.json");
+    cereal::JSONOutputArchive archive(os);
+
+    wolf::LocalParametrizationQuaternionGlobal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quatg_serialization.json");
+    cereal::JSONInputArchive archive(is);
+
+    wolf::LocalParametrizationQuaternionGlobal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionGlobalJSON !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionGlobalPtrJSON)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quatg_ptr_serialization.json");
+    cereal::JSONOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationQuaternionGlobal>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quatg_ptr_serialization.json");
+    cereal::JSONInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationQuaternionGlobal>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionGlobalPtrJSON !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionGlobalBIN)
+{
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quatg_serialization.bin");
+    cereal::BinaryOutputArchive archive(os);
+
+    wolf::LocalParametrizationQuaternionGlobal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quatg_serialization.bin");
+    cereal::BinaryInputArchive archive(is);
+
+    wolf::LocalParametrizationQuaternionGlobal local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h.getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h.getLocalSize(),  3);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionGlobalBIN !\n");
+}
+
+TEST(TestSerialization, SerializationLocalParametrizationQuaternionGlobalPtrBIN)
+{
+  using LocalParametrizationPtr = std::shared_ptr<wolf::LocalParametrizationBase> ;
+
+  {
+    std::ofstream os(path_to_io + "local_parametrization_quatg_ptr_serialization.bin");
+    cereal::BinaryOutputArchive archive(os);
+
+    LocalParametrizationPtr local_param_h =
+        std::make_shared<wolf::LocalParametrizationQuaternionGlobal>();
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "local_parametrization_quatg_ptr_serialization.bin");
+    cereal::BinaryInputArchive archive(is);
+
+    LocalParametrizationPtr local_param_h;
+
+    ASSERT_NO_THROW( archive( local_param_h ) );
+
+    ASSERT_EQ(local_param_h->getGlobalSize(), 4);
+    ASSERT_EQ(local_param_h->getLocalSize(),  3);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::LocalParametrizationQuaternionGlobal>(local_param_h) != nullptr);
+  }
+
+  PRINTF("All good at TestSerialization::SerializationLocalParametrizationQuaternionGlobalPtrBIN !\n");
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/src/test/io/cereal/gtest_serialization_node_base.cpp b/src/test/io/cereal/gtest_serialization_node_base.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..820e1b1d3d6b86ebcf3357868959c7c5ce63b7f5
--- /dev/null
+++ b/src/test/io/cereal/gtest_serialization_node_base.cpp
@@ -0,0 +1,250 @@
+/*
+ * gtest_node_base_serialization.cpp
+ *
+ *  Created on: Jul 16, 2017
+ *      Author: Jeremie Deray
+ */
+
+#include "../../utils_gtest.h"
+
+#include "../../../io/cereal/serialization_node_base.h"
+
+#include <cereal/archives/binary.hpp>
+#include <cereal/archives/json.hpp>
+#include <cereal/archives/portable_binary.hpp>
+#include <cereal/archives/xml.hpp>
+
+#include <cereal/types/memory.hpp>
+#include <fstream>
+
+class WolfTestCerealSerializationNodeBase : public testing::Test
+{
+public:
+
+    WolfTestCerealSerializationNodeBase() /*:
+      nb(nb_class),
+      nb_ptr(std::make_shared<wolf::NodeBase>(nb_class))*/
+    {
+      //
+    }
+
+    const std::string path_to_io = "/tmp/";
+
+    decltype(std::declval<wolf::NodeBase>().getClass()) nb_class = "Foo";
+    decltype(std::declval<wolf::NodeBase>().getClass()) nb_type  = "Bar";
+    decltype(std::declval<wolf::NodeBase>().getClass()) nb_name  = "Dummy";
+
+    decltype(std::declval<wolf::NodeBase>().nodeId()) id;
+
+//    wolf::NodeBase nb;
+//    wolf::NodeBasePtr nb_ptr;
+};
+
+TEST_F(WolfTestCerealSerializationNodeBase, CerealSerializationNodeBaseXML)
+{
+  {
+    // This guy has node_id = 1
+    wolf::NodeBase nb(nb_class, nb_type, nb_name);
+
+    id = nb.nodeId();
+
+    std::ofstream os(path_to_io + "node_base_serialization.xml");
+    cereal::XMLOutputArchive xml_archive(os);
+
+    ASSERT_NO_THROW( xml_archive( nb ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "node_base_serialization.xml");
+    cereal::XMLInputArchive xml_archive(is);
+
+    // This guy has node_id = 2
+    wolf::NodeBase nb("SuperDummy");
+
+    ASSERT_NO_THROW( xml_archive( nb ) );
+
+    ASSERT_EQ(nb.getClass(), nb_class);
+    ASSERT_EQ(nb.getType(),  nb_type);
+    ASSERT_EQ(nb.getName(),  nb_name);
+    ASSERT_EQ(nb.nodeId(),   id);
+  }
+
+  PRINTF("All good at "
+         "WolfTestCerealSerializationNodeBase::CerealSerializationNodeBaseXML !\n");
+}
+
+TEST_F(WolfTestCerealSerializationNodeBase, CerealSerializationNodeBasePtrXML)
+{
+  {
+    // This guy has node_id = 3
+    wolf::NodeBasePtr nb = std::make_shared<wolf::NodeBase>(nb_class, nb_type, nb_name);
+
+    id = nb->nodeId();
+
+    std::ofstream os(path_to_io + "node_base_ptr_serialization.xml");
+    cereal::XMLOutputArchive xml_archive(os);
+
+    ASSERT_NO_THROW( xml_archive( nb ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "node_base_ptr_serialization.xml");
+    cereal::XMLInputArchive xml_archive(is);
+
+    wolf::NodeBasePtr nb;
+
+    ASSERT_NO_THROW( xml_archive( nb ) );
+
+    ASSERT_EQ(nb->getClass(), nb_class);
+    ASSERT_EQ(nb->getType(),  nb_type);
+    ASSERT_EQ(nb->getName(),  nb_name);
+    ASSERT_EQ(nb->nodeId(),   id);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::NodeBase>(nb) != nullptr);
+  }
+
+  PRINTF("All good at "
+         "WolfTestCerealSerializationNodeBase::CerealSerializationNodeBasePtrXML !\n");
+}
+
+TEST_F(WolfTestCerealSerializationNodeBase, CerealSerializationNodeBaseJSON)
+{
+  {
+    wolf::NodeBase nb(nb_class, nb_type, nb_name);
+
+    id = nb.nodeId();
+
+    std::ofstream os(path_to_io + "node_base_serialization.json");
+    cereal::JSONOutputArchive json_archive(os);
+
+    ASSERT_NO_THROW( json_archive( nb ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "node_base_serialization.json");
+    cereal::JSONInputArchive json_archive(is);
+
+    wolf::NodeBase blank("This guy has node_id = 1");
+    wolf::NodeBase nb("SuperDummy");
+
+    ASSERT_NO_THROW( json_archive( nb ) );
+
+    ASSERT_EQ(nb.getClass(), nb_class);
+    ASSERT_EQ(nb.getType(),  nb_type);
+    ASSERT_EQ(nb.getName(),  nb_name);
+    ASSERT_EQ(nb.nodeId(),   id);
+  }
+
+  PRINTF("All good at "
+         "WolfTestCerealSerializationNodeBase::CerealSerializationNodeBaseJSON !\n");
+}
+
+TEST_F(WolfTestCerealSerializationNodeBase, CerealSerializationNodeBasePtrJSON)
+{
+  {
+    wolf::NodeBasePtr nb = std::make_shared<wolf::NodeBase>(nb_class, nb_type, nb_name);
+
+    id = nb->nodeId();
+
+    std::ofstream os(path_to_io + "node_base_ptr_serialization.json");
+    cereal::JSONOutputArchive json_archive(os);
+
+    ASSERT_NO_THROW( json_archive( nb ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "node_base_ptr_serialization.json");
+    cereal::JSONInputArchive json_archive(is);
+
+    wolf::NodeBasePtr nb;
+
+    ASSERT_NO_THROW( json_archive( nb ) );
+
+    ASSERT_EQ(nb->getClass(), nb_class);
+    ASSERT_EQ(nb->getType(),  nb_type);
+    ASSERT_EQ(nb->getName(),  nb_name);
+    ASSERT_EQ(nb->nodeId(),   id);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::NodeBase>(nb) != nullptr);
+  }
+
+  PRINTF("All good at "
+         "WolfTestCerealSerializationNodeBase::CerealSerializationNodeBasePtrJSON !\n");
+}
+
+TEST_F(WolfTestCerealSerializationNodeBase, CerealSerializationNodeBaseBinary)
+{
+  {
+    wolf::NodeBase nb(nb_class, nb_type, nb_name);
+
+    id = nb.nodeId();
+
+    std::ofstream os(path_to_io + "node_base_serialization.bin");
+    cereal::BinaryOutputArchive bin_archive(os);
+
+    ASSERT_NO_THROW( bin_archive( nb ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "node_base_serialization.bin");
+    cereal::BinaryInputArchive bin_archive(is);
+
+    wolf::NodeBase blank("This guy has node_id = 1");
+    wolf::NodeBase nb("SuperDummy");
+
+    ASSERT_NO_THROW( bin_archive( nb ) );
+
+    ASSERT_EQ(nb.getClass(), nb_class);
+    ASSERT_EQ(nb.getType(),  nb_type);
+    ASSERT_EQ(nb.getName(),  nb_name);
+    ASSERT_EQ(nb.nodeId(),   id);
+  }
+
+  PRINTF("All good at "
+         "WolfTestCerealSerializationNodeBase::CerealSerializationNodeBaseBinary !\n");
+}
+
+TEST_F(WolfTestCerealSerializationNodeBase, CerealSerializationNodeBasePtrBinary)
+{
+  {
+    wolf::NodeBasePtr nb = std::make_shared<wolf::NodeBase>(nb_class, nb_type, nb_name);
+
+    id = nb->nodeId();
+
+    std::ofstream os(path_to_io + "node_base_ptr_serialization.bin");
+    cereal::BinaryOutputArchive bin_archive(os);
+
+    ASSERT_NO_THROW( bin_archive( nb ) );
+  }
+
+  {
+    std::ifstream is(path_to_io + "node_base_ptr_serialization.bin");
+    cereal::BinaryInputArchive bin_archive(is);
+
+    wolf::NodeBasePtr nb;
+
+    ASSERT_NO_THROW( bin_archive( nb ) );
+
+    ASSERT_EQ(nb->getClass(), nb_class);
+    ASSERT_EQ(nb->getType(),  nb_type);
+    ASSERT_EQ(nb->getName(),  nb_name);
+    ASSERT_EQ(nb->nodeId(),   id);
+
+    ASSERT_TRUE(
+          std::dynamic_pointer_cast<
+          wolf::NodeBase>(nb) != nullptr);
+  }
+
+  PRINTF("All good at "
+         "WolfTestCerealSerializationNodeBase::CerealSerializationNodeBasePtrBinary !\n");
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}