diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 733ae9a3c56060fb942eb9c06377a4f00d9f2fcb..d8aa740acd8b9fbc3f1e0e87e40af15e0c60f26a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -69,6 +69,12 @@ else(OpenCV_FOUND)
     message("[WARN] OpenCV not found. Related sources will NOT 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)
@@ -161,6 +167,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)
@@ -413,6 +424,10 @@ IF (OpenCV_FOUND)
         )
 ENDIF(OpenCV_FOUND)
 
+IF (cereal_FOUND)
+  ADD_SUBDIRECTORY(serialization/cereal)
+ENDIF(cereal_FOUND)
+
 IF (Suitesparse_FOUND)
     ADD_SUBDIRECTORY(solver)
 ENDIF(Suitesparse_FOUND)
@@ -502,6 +517,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_SERIALIZATION}
+    DESTINATION include/iri-algorithms/wolf/serialization)
 
 INSTALL(FILES "${CMAKE_SOURCE_DIR}/cmake_modules/Findwolf.cmake"
     DESTINATION "lib/cmake/${PROJECT_NAME}")
diff --git a/src/serialization/CMakeLists.txt b/src/serialization/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a853ba8ec5158727fcd4bfd9752d6de398c5aefa
--- /dev/null
+++ b/src/serialization/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(cereal)
diff --git a/src/serialization/cereal/CMakeLists.txt b/src/serialization/cereal/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f2c1ee7a067ab1e82692c2c447ee1e97000c3104
--- /dev/null
+++ b/src/serialization/cereal/CMakeLists.txt
@@ -0,0 +1,7 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+SET(HDRS_SERIALIZATION ${HDRS_SERIALIZATION}
+    ${CMAKE_CURRENT_SOURCE_DIR}/archives.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/io.h
+
+    PARENT_SCOPE)
diff --git a/src/serialization/cereal/archives.h b/src/serialization/cereal/archives.h
new file mode 100644
index 0000000000000000000000000000000000000000..d8c16fd180ef04049ceedaf268fa33782790d27a
--- /dev/null
+++ b/src/serialization/cereal/archives.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/serialization/cereal/io.h b/src/serialization/cereal/io.h
new file mode 100644
index 0000000000000000000000000000000000000000..afd32843878e43a66674970a69df37dbf6429fe2
--- /dev/null
+++ b/src/serialization/cereal/io.h
@@ -0,0 +1,216 @@
+#ifndef _WOLF_SERIALIZATION_CEREAL_IO_H_
+#define _WOLF_SERIALIZATION_CEREAL_IO_H_
+
+#include <stdexcept>
+#include "archives.h"
+
+//#include <cereal/types/tuple.hpp>
+
+namespace wolf {
+namespace serialization {
+
+inline std::string extension(const std::string& file)
+{
+  const std::size_t p = file.find_last_of(".");
+  return (p != std::string::npos) ? file.substr(p) : "";
+}
+
+//struct Extensions
+//{
+//  constexpr static const char* bin  = ".bin";
+//  constexpr static const char* json = ".json";
+//  constexpr static const char* xml  = ".xml";
+
+//  constexpr static const char* fall_back = json;
+//};
+
+//enum class Extensions2 : std::size_t
+//{
+//  BIN = 0,
+////  CBIN,
+//  JSON,
+////  TEXT,
+//  XML,
+//};
+
+//template <char... Chars>
+//struct constexp_str
+//{
+//  using type = constexp_str<Chars...>;
+
+//  virtual ~constexp_str() = default;
+
+//  constexpr static const char value[sizeof...(Chars)+1] = {Chars..., '\0'};
+
+//  constexpr static std::size_t size() { return sizeof...(Chars); }
+
+//  constexpr static const char* c_str() { return &value[0]; }
+
+////  constexpr static bool comp(const std::string& s) { return s == value; }
+
+//  /*constexpr*/ bool operator == (const std::string& s) { return s == value; }
+
+//  constexpr /*static*/ operator const char* ()  { return c_str(); }
+//  constexpr /*static*/ operator std::string& () { return c_str(); }
+//};
+
+struct Extensions
+{
+//  template <char... Chars>
+//  struct EXT : constexp_str<Chars...>
+//  {
+//    //
+//  };
+
+//  struct BIN  : EXT<'.','b','i','n'> { };
+//  struct XML  : EXT<'.','x','m','l'> { };
+//  struct JSON : EXT<'.','j','s','o','n'> { };
+
+  struct EXT { virtual ~EXT() = default; };
+
+  struct BIN : EXT
+  {
+    constexpr static const char* value  = ".bin";
+    bool operator == (const std::string& s) { return value == s; }
+  };
+
+  struct XML : EXT
+  {
+    constexpr static const char* value  = ".xml";
+    bool operator == (const std::string& s) { return value == s; }
+  };
+
+  struct JSON : EXT
+  {
+    constexpr static const char* value  = ".json";
+    bool operator == (const std::string& s) { return value == s; }
+  };
+};
+
+template <typename Ar, typename S, typename T, typename... Args>
+void serialize(S& stream, T&& object, Args&&... args)
+{
+  Ar archive(stream);
+
+  archive( cereal::make_nvp("object", std::forward<T>(object)) );
+  archive( cereal::make_nvp("object", std::forward<Args>(args))... );
+}
+
+template <typename Ar, typename S, typename T>
+void serialize(S& stream, T&& object)
+{
+  Ar archive(stream);
+  archive( cereal::make_nvp("object", std::forward<T>(object)) );
+}
+
+template <typename EXT, typename InAr, typename OutAr>
+struct Serializer
+{
+  template <typename S, typename... T>
+  static void serialize_in(S& stream, T&... object)
+  {
+    serialize<InAr>(stream, object...);
+  }
+
+  template <typename S, typename... T>
+  static void serialize_out(S& stream, T&&... object)
+  {
+    serialize<OutAr>(stream, std::forward<T>(object)...);
+  }
+
+  template <typename... T>
+  static void save(std::string filename, T&&... o)
+  {
+    const std::string ext = serialization::extension(filename);
+
+    if (ext != EXT::value) filename += EXT::value;
+
+    std::ofstream os(filename);
+    serialize_out(os, std::forward<T>(o)...);
+  }
+
+  template <typename... T>
+  static void load(std::string filename, T&... o)
+  {
+    const std::string ext = serialization::extension(filename);
+
+    if (ext != EXT::value) filename += EXT::value;
+
+    std::ifstream is(filename);
+    serialize_in(is, o...);
+  }
+};
+
+using SerializerBin = Serializer<Extensions::BIN,
+                                 cereal::BinaryInputArchive,
+                                 cereal::BinaryOutputArchive>;
+
+using SerializerXML = Serializer<Extensions::XML,
+                                 cereal::XMLInputArchive,
+                                 cereal::XMLOutputArchive>;
+
+using SerializerJSON = Serializer<Extensions::JSON,
+                                  cereal::JSONInputArchive,
+                                  cereal::JSONOutputArchive>;
+
+
+} /* namespace serialization */
+
+template <typename... T>
+void save(const std::string& filename, T&&... o)
+throw(std::runtime_error)
+{
+  const std::string ext = serialization::extension(filename);
+
+  if (ext == serialization::Extensions::BIN::value)
+  {
+    serialization::SerializerBin::save(filename, std::forward<T>(o)...);
+  }
+  else if (ext == serialization::Extensions::JSON::value)
+  {
+    serialization::SerializerJSON::save(filename, std::forward<T>(o)...);
+  }
+  else if (ext == serialization::Extensions::XML::value)
+  {
+    serialization::SerializerXML::save(filename, std::forward<T>(o)...);
+  }
+  else if (ext == "") // falback is json
+  {
+    serialization::SerializerJSON::save(filename, std::forward<T>(o)...);
+  }
+  else
+  {
+    throw std::runtime_error("Unknown file extension : " + filename);
+  }
+}
+
+template <typename... T>
+void load(const std::string& filename, T&... o)
+{
+  const std::string ext = serialization::extension(filename);
+
+  if (ext == serialization::Extensions::BIN::value)
+  {
+    serialization::SerializerBin::load(filename, o...);
+  }
+  else if (ext == serialization::Extensions::XML::value)
+  {
+    serialization::SerializerXML::load(filename, o...);
+  }
+  else if (ext == serialization::Extensions::JSON::value)
+  {
+    serialization::SerializerJSON::load(filename, o...);
+  }
+  else if (ext == "") // falback is json
+  {
+    serialization::SerializerJSON::load(filename, o...);
+  }
+  else
+  {
+    throw std::runtime_error("Unknown file extension : " + filename);
+  }
+}
+
+} /* namespace wolf */
+
+#endif /* _WOLF_SERIALIZATION_CEREAL_IO_H_ */