diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 16551ab17572d474b889779b30d790fa98a99c65..8e0fbc786908a51c33b4612dc7930e31dc4e4fce 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -357,6 +357,9 @@ SET(SRCS_DTASSC
     data_association/association_nnls.cpp
     )
 
+# Add the solver sub-directory
+add_subdirectory(solver)
+
 #optional HDRS and SRCS
 IF (Ceres_FOUND)
     SET(HDRS_WRAPPER
@@ -470,7 +473,8 @@ ADD_LIBRARY(${PROJECT_NAME}
             SHARED 
             ${SRCS_BASE} 
             ${SRCS} 
-            #${SRCS_DTASSC} 
+            #${SRCS_DTASSC}
+            ${SRCS_SOLVER}
             ${SRCS_WRAPPER}
             )
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${CMAKE_THREAD_LIBS_INIT})
@@ -521,7 +525,7 @@ INSTALL(FILES ${HDRS}
 #    DESTINATION include/iri-algorithms/wolf/data_association)
 INSTALL(FILES ${HDRS_WRAPPER}
     DESTINATION include/iri-algorithms/wolf/ceres_wrapper)
-INSTALL(FILES ${HDRS_SOLVER_SUITESPARSE}
+INSTALL(FILES ${HDRS_SOLVER}
     DESTINATION include/iri-algorithms/wolf/solver)
 INSTALL(FILES ${HDRS_SERIALIZATION}
     DESTINATION include/iri-algorithms/wolf/serialization)
diff --git a/src/solver/CMakeLists.txt b/src/solver/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7263fb5e8ffab31a2b7dce2857fc840f2604b2b7
--- /dev/null
+++ b/src/solver/CMakeLists.txt
@@ -0,0 +1,9 @@
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+# Forward var to parent scope
+
+SET(HDRS_SOLVER ${HDRS_SOLVER}
+                ${CMAKE_CURRENT_SOURCE_DIR}/solver_manager.h PARENT_SCOPE)
+
+SET(SRCS_SOLVER ${SRCS_SOLVER}
+                ${CMAKE_CURRENT_SOURCE_DIR}/solver_manager.cpp PARENT_SCOPE)
diff --git a/src/solver/solver_manager.cpp b/src/solver/solver_manager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f86bb35ed3305820e521e5ad178b0ae6398978a
--- /dev/null
+++ b/src/solver/solver_manager.cpp
@@ -0,0 +1,136 @@
+#include "solver_manager.h"
+#include "../trajectory_base.h"
+#include "../map_base.h"
+#include "../landmark_base.h"
+
+namespace wolf {
+
+SolverManager::SolverManager(const ProblemPtr& _wolf_problem) :
+  wolf_problem_(_wolf_problem)
+{
+  //
+}
+
+inline void SolverManager::update()
+{
+  StateBlockList& states = wolf_problem_->getNotifiedStateBlockList();
+
+  for (StateBlockPtr& state : states)
+  {
+    switch (state->notify())
+    {
+    case StateBlock::Notification::ADD:
+    {
+      state_blocks_[state] = state->getState();
+      addStateBlock(state);
+      state->notify(StateBlock::Notification::ENABLED);
+      break;
+    }
+    case StateBlock::Notification::UPDATE:
+    {
+      state_blocks_[state] = state->getState();
+      state->notify(StateBlock::Notification::ENABLED);
+      break;
+    }
+    case StateBlock::Notification::FIX_UPDATE:
+    {
+      // something to do ?
+      //state_blocks_
+
+      updateStateBlockStatus(state);
+      state->notify(StateBlock::Notification::ENABLED);
+      break;
+    }
+    case StateBlock::Notification::REMOVE:
+    {
+      if (state_blocks_.erase(state) > 0)
+        removeStateBlock(state);
+      break;
+    }
+    case StateBlock::Notification::ENABLED:
+    {
+      // do nothing
+      break;
+    }
+    default:
+      throw std::runtime_error("SolverManager::update: State Block notification "
+                               "must be ADD, UPDATE, FIX_UPDATE, REMOVE or ENABLED.");
+    }
+  }
+
+  states.clear();
+
+  // ADD CONSTRAINTS
+  while (!wolf_problem_->getConstraintNotificationList().empty())
+  {
+    switch (wolf_problem_->getConstraintNotificationList().front().notification_)
+    {
+    case Notification::ADD:
+    {
+      addConstraint(wolf_problem_->getConstraintNotificationList().front().constraint_ptr_);
+
+      break;
+    }
+    default:
+      throw std::runtime_error("SolverManager::update:"
+                               " Constraint notification must be ADD or REMOVE.");
+    }
+
+    wolf_problem_->getConstraintNotificationList().pop_front();
+  }
+
+  assert(wolf_problem_->getConstraintNotificationList().empty() &&
+         "wolf problem's constraints notification list not empty after update");
+  assert(wolf_problem_->getNotifiedStateBlockList().empty() &&
+         "wolf problem's state_blocks notification list not empty after update");
+}
+
+inline wolf::ProblemPtr SolverManager::getProblemPtr()
+{
+  return wolf_problem_;
+}
+
+std::string SolverManager::solve(const ReportVerbosity report_level)
+{
+  // update problem
+  update();
+
+  std::string report = solveImpl(report_level);
+
+  // update StateBlocks with optimized state value.
+  /// @todo whatif someone has changed the state notification during opti ??
+//  std::for_each(state_blocks_.begin(), state_blocks_.end(),
+//                [](std::pair<StateBlockPtr, Eigen::VectorXs>& p)
+//                { if (p.first->notify() == StateBlock::Notification::ENABLED) p.first->setState(p.second); });
+
+  std::map<StateBlockPtr, Eigen::VectorXs>::iterator it = state_blocks_.begin(),
+                                                     it_end = state_blocks_.end();
+
+  for(; it != it_end; ++it)
+    if (it->first->notify() == StateBlock::Notification::ENABLED)
+      it->first->setState(it->second);
+
+  return report;
+}
+
+Eigen::VectorXs& SolverManager::getAssociatedMemBlock(const StateBlockPtr& state_ptr)
+{
+  auto it = state_blocks_.find(state_ptr);
+
+  if (it == state_blocks_.end())
+    throw std::runtime_error("Tried to retrieve the memory block of an unregistered StateBlock !");
+
+  return it->second;
+}
+
+Scalar* SolverManager::getAssociatedMemBlockPtr(const StateBlockPtr& state_ptr)
+{
+  auto it = state_blocks_.find(state_ptr);
+
+  if (it == state_blocks_.end())
+    throw std::runtime_error("Tried to retrieve the memory block of an unregistered StateBlock !");
+
+  return it->second.data();
+}
+
+} // namespace wolf
diff --git a/src/solver/solver_manager.h b/src/solver/solver_manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..45a9b4760dd416b079308dd0b0b962865ec5ef51
--- /dev/null
+++ b/src/solver/solver_manager.h
@@ -0,0 +1,84 @@
+#ifndef _WOLF_SOLVER_MANAGER_H_
+#define _WOLF_SOLVER_MANAGER_H_
+
+//wolf includes
+#include "wolf.h"
+#include "state_block.h"
+#include "constraint_base.h"
+
+namespace wolf {
+
+WOLF_PTR_TYPEDEFS(SolverManager)
+
+/**
+ * \brief Solver manager for WOLF
+ */
+class SolverManager
+{
+public:
+
+  /** \brief Enumeration of covariance blocks to be computed
+   *
+   * Enumeration of covariance blocks to be computed
+   *
+   */
+  enum class CovarianceBlocksToBeComputed : std::size_t
+  {
+    ALL, ///< All blocks and all cross-covariances
+    ALL_MARGINALS, ///< All marginals
+    ROBOT_LANDMARKS ///< marginals of landmarks and current robot pose plus cross covariances of current robot and all landmarks
+  };
+
+  /**
+   * \brief Enumeration for the verbosity of the solver report.
+   */
+  enum class ReportVerbosity : std::size_t
+  {
+    QUIET = 0,
+    BRIEF,
+    FULL
+  };
+
+protected:
+
+  ProblemPtr wolf_problem_;
+
+public:
+
+  SolverManager(const ProblemPtr& wolf_problem);
+
+  virtual ~SolverManager() = default;
+
+  std::string solve(const ReportVerbosity report_level);
+
+  virtual void computeCovariances(const CovarianceBlocksToBeComputed blocks) = 0;
+
+  virtual void computeCovariances(const StateBlockList& st_list) = 0;
+
+  virtual void update();
+
+  ProblemPtr getProblemPtr();
+
+protected:
+
+  std::map<StateBlockPtr, Eigen::VectorXs> state_blocks_;
+
+  virtual Eigen::VectorXs& getAssociatedMemBlock(const StateBlockPtr& state_ptr);
+  virtual Scalar* getAssociatedMemBlockPtr(const StateBlockPtr& state_ptr);
+
+  virtual std::string solveImpl(const ReportVerbosity report_level) = 0;
+
+  virtual void addConstraint(const ConstraintBasePtr& ctr_ptr) = 0;
+
+  virtual void removeConstraint(const ConstraintBasePtr& ctr_ptr) = 0;
+
+  virtual void addStateBlock(const StateBlockPtr& state_ptr) = 0;
+
+  virtual void removeStateBlock(const StateBlockPtr& state_ptr) = 0;
+
+  virtual void updateStateBlockStatus(const StateBlockPtr& state_ptr) = 0;
+};
+
+} // namespace wolf
+
+#endif /* _WOLF_SOLVER_MANAGER_H_ */