diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6f9c6e3e2ca856c90b41f8e45e7981f221e0c440..98de6dbd9bfb7521238c7c784b077456b35b5629 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -181,14 +181,14 @@ SET(HDRS_MATH
   include/core/math/covariance.h
   )
 SET(HDRS_UTILS
-  include/core/utils/check_log.hpp
+  include/core/utils/check_log.h
   include/core/utils/converter.h
   include/core/utils/eigen_assert.h
   include/core/utils/eigen_predicates.h
-  include/core/utils/loader.hpp
+  include/core/utils/loader.h
   include/core/utils/logging.h
   include/core/utils/make_unique.h
-  include/core/utils/params_server.hpp
+  include/core/utils/params_server.h
   include/core/utils/singleton.h
   include/core/utils/utils_gtest.h
   include/core/utils/converter_utils.h
@@ -291,7 +291,7 @@ SET(HDRS_TREE_MANAGER
   include/core/tree_manager/tree_manager_sliding_window.h
   )
 SET(HDRS_YAML
-  include/core/yaml/parser_yaml.hpp
+  include/core/yaml/parser_yaml.h
   include/core/yaml/yaml_conversion.h
   )
 #SOURCES
@@ -325,6 +325,9 @@ SET(SRCS_MATH
   )
 SET(SRCS_UTILS
   src/utils/converter_utils.cpp
+  src/utils/params_server.cpp
+  src/utils/loader.cpp
+  src/utils/check_log.cpp
   )
 
 SET(SRCS_CAPTURE
@@ -376,6 +379,7 @@ SET(SRCS_TREE_MANAGER
   src/tree_manager/tree_manager_sliding_window.cpp
   )
 SET(SRCS_YAML
+  src/yaml/parser_yaml.cpp
   src/yaml/processor_odom_3d_yaml.cpp
   src/yaml/sensor_odom_2d_yaml.cpp
   src/yaml/sensor_odom_3d_yaml.cpp
diff --git a/hello_wolf/hello_wolf_autoconf.cpp b/hello_wolf/hello_wolf_autoconf.cpp
index a97d8d2f9c5c7fb8c7f1f37c12330038beb3ba98..a387adfe9656523c37d025bb3a74f0f198281b3d 100644
--- a/hello_wolf/hello_wolf_autoconf.cpp
+++ b/hello_wolf/hello_wolf_autoconf.cpp
@@ -9,7 +9,7 @@
 // wolf core includes
 #include "core/common/wolf.h"
 #include "core/capture/capture_odom_2d.h"
-#include "core/yaml/parser_yaml.hpp"
+#include "core/yaml/parser_yaml.h"
 #include "core/ceres_wrapper/ceres_manager.h"
 
 // hello wolf local includes
diff --git a/hello_wolf/sensor_range_bearing.h b/hello_wolf/sensor_range_bearing.h
index e62bfc1a5cd4ff7115cac06f9738204c71017f2b..491efff4f533edc993051482de7d0e84562a790a 100644
--- a/hello_wolf/sensor_range_bearing.h
+++ b/hello_wolf/sensor_range_bearing.h
@@ -9,7 +9,7 @@
 #define HELLO_WOLF_SENSOR_RANGE_BEARING_H_
 
 #include "core/sensor/sensor_base.h"
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 
 namespace wolf
 {
diff --git a/include/core/capture/capture_base.h b/include/core/capture/capture_base.h
index aaa76c9220c4351f1cca5b6a38bf290ef8e69c58..2491d5a6a5afbdc4d3b52a3e86003c3794b6cd81 100644
--- a/include/core/capture/capture_base.h
+++ b/include/core/capture/capture_base.h
@@ -79,6 +79,8 @@ class CaptureBase : public NodeBase, public HasStateBlocks, public std::enable_s
     public:
         unsigned int getHits() const;
         const FactorBasePtrList& getConstrainedByList() const;
+        bool isConstrainedBy(const FactorBasePtr &_factor) const;
+
 
         // State blocks
         const std::string& getStructure() const;
@@ -101,7 +103,7 @@ class CaptureBase : public NodeBase, public HasStateBlocks, public std::enable_s
         static std::shared_ptr<classType> emplace(FrameBasePtr _frm_ptr, T&&... all);
 
     protected:
-        SizeEigen computeCalibSize() const;
+        virtual SizeEigen computeCalibSize() const;
 
     private:
         FeatureBasePtr addFeature(FeatureBasePtr _ft_ptr);
@@ -183,6 +185,7 @@ inline const FactorBasePtrList& CaptureBase::getConstrainedByList() const
     return constrained_by_list_;
 }
 
+
 inline TimeStamp CaptureBase::getTimeStamp() const
 {
     return time_stamp_;
diff --git a/include/core/ceres_wrapper/ceres_manager.h b/include/core/ceres_wrapper/ceres_manager.h
index f124325950a06f74642cff38b6d0c053958cab8e..802ab7b49dabf93455f8f93fc8c30745415fe33e 100644
--- a/include/core/ceres_wrapper/ceres_manager.h
+++ b/include/core/ceres_wrapper/ceres_manager.h
@@ -8,7 +8,7 @@
 
 //wolf includes
 #include "core/solver/solver_manager.h"
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 #include "core/ceres_wrapper/cost_function_wrapper.h"
 #include "core/ceres_wrapper/local_parametrization_wrapper.h"
 #include "core/ceres_wrapper/create_numeric_diff_cost_function.h"
@@ -84,6 +84,8 @@ class CeresManager : public SolverManager
 
         void check();
 
+        const Eigen::SparseMatrixd computeHessian() const;
+
     protected:
 
         std::string solveImpl(const ReportVerbosity report_level) override;
diff --git a/include/core/common/params_base.h b/include/core/common/params_base.h
index 5295bc0ac17f941503a8f28e462962290a9ee82b..80f6516415e28ddce47ab272415604014ffb0a66 100644
--- a/include/core/common/params_base.h
+++ b/include/core/common/params_base.h
@@ -1,7 +1,7 @@
 #ifndef PARAMS_BASE_H_
 #define PARAMS_BASE_H_
 
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 
 namespace wolf {
   struct ParamsBase
diff --git a/include/core/common/wolf.h b/include/core/common/wolf.h
index 741ad7f155884175aafb1b8183f8c672842abc1e..b11165468e47ef55e7c65ce046571d7e68ebd945 100644
--- a/include/core/common/wolf.h
+++ b/include/core/common/wolf.h
@@ -195,7 +195,11 @@ struct MatrixSizeCheck
         typedef std::list<ClassName##Ptr>             ClassName##PtrList; \
         typedef ClassName##PtrList::iterator          ClassName##Iter; \
         typedef ClassName##PtrList::const_iterator    ClassName##ConstIter; \
-        typedef ClassName##PtrList::reverse_iterator  ClassName##RevIter;
+        typedef ClassName##PtrList::reverse_iterator  ClassName##RevIter; \
+        typedef std::list<ClassName##WPtr>            ClassName##WPtrList; \
+        typedef ClassName##WPtrList::iterator         ClassName##WIter; \
+        typedef ClassName##WPtrList::const_iterator   ClassName##WConstIter; \
+        typedef ClassName##WPtrList::reverse_iterator ClassName##WRevIter;
 
 #define WOLF_STRUCT_PTR_TYPEDEFS(StructName) \
         struct StructName; \
diff --git a/include/core/factor/factor_base.h b/include/core/factor/factor_base.h
index 6f215396071b757b980faac31be8d0250716ea71..cd1439f96e437dc39dde137dd1014f37abee10db 100644
--- a/include/core/factor/factor_base.h
+++ b/include/core/factor/factor_base.h
@@ -40,19 +40,19 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa
 {
   friend FeatureBase;
     private:
-        FeatureBaseWPtr feature_ptr_;                    ///< FeatureBase pointer (upper node)
+        FeatureBaseWPtr feature_ptr_;                       ///< FeatureBase pointer (upper node)
 
         static unsigned int factor_id_count_;
 
     protected:
         unsigned int factor_id_;
-        FactorStatus status_;                           ///< status of factor
-        bool apply_loss_function_;                      ///< flag for applying loss function to this factor
-        FrameBaseWPtr frame_other_ptr_;                 ///< FrameBase pointer
-        CaptureBaseWPtr capture_other_ptr_;             ///< CaptureBase pointer
-        FeatureBaseWPtr feature_other_ptr_;             ///< FeatureBase pointer
-        LandmarkBaseWPtr landmark_other_ptr_;           ///< LandmarkBase pointer
-        ProcessorBaseWPtr processor_ptr_;               ///< ProcessorBase pointer
+        FactorStatus status_;                               ///< status of factor
+        bool apply_loss_function_;                          ///< flag for applying loss function to this factor
+        FrameBaseWPtrList frame_other_list_;                ///< FrameBase pointer list
+        CaptureBaseWPtrList capture_other_list_;            ///< CaptureBase pointer list
+        FeatureBaseWPtrList feature_other_list_;            ///< FeatureBase pointer list
+        LandmarkBaseWPtrList landmark_other_list_;          ///< LandmarkBase pointer list
+        ProcessorBaseWPtr processor_ptr_;                   ///< ProcessorBase pointer list
 
         virtual void setProblem(ProblemPtr) final;
     public:
@@ -72,6 +72,17 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa
                    bool _apply_loss_function,
                    FactorStatus _status = FAC_ACTIVE);
 
+        FactorBase(const std::string&  _tp,
+                   const FrameBasePtrList& _frame_other_list,
+                   const CaptureBasePtrList& _capture_other_list,
+                   const FeatureBasePtrList& _feature_other_list,
+                   const LandmarkBasePtrList& _landmark_other_list,
+                   const ProcessorBasePtr& _processor_ptr,
+                   bool _apply_loss_function,
+                   FactorStatus _status = FAC_ACTIVE);
+
+
+
         virtual ~FactorBase() = default;
 
         virtual void remove(bool viral_remove_empty_parent=false);
@@ -133,6 +144,14 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa
          **/
         CaptureBasePtr getCapture() const;
 
+        /** \brief Returns a pointer to its frame
+         **/
+        FrameBasePtr getFrame() const;
+
+        /** \brief Returns a pointer to its capture's sensor
+         **/
+        SensorBasePtr getSensor() const;
+
         /** \brief Returns the factor residual size
          **/
         virtual unsigned int getSize() const = 0;
@@ -149,21 +168,32 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa
          */
         bool getApplyLossFunction() const;
 
-        /** \brief Returns a pointer to the frame constrained to
+        /** \brief Returns a pointer to the first frame constrained to
          **/
-        FrameBasePtr getFrameOther() const       { return frame_other_ptr_.lock(); }
+        FrameBasePtr getFrameOther() const;
 
-        /** \brief Returns a pointer to the capture constrained to
+        /** \brief Returns a pointer to the first capture constrained to
          **/
-        CaptureBasePtr getCaptureOther() const       { return capture_other_ptr_.lock(); }
+        CaptureBasePtr getCaptureOther() const;
 
-        /** \brief Returns a pointer to the feature constrained to
+        /** \brief Returns a pointer to the first feature constrained to
          **/
-        FeatureBasePtr getFeatureOther() const       { return feature_other_ptr_.lock(); }
+        FeatureBasePtr getFeatureOther() const;
 
-        /** \brief Returns a pointer to the landmark constrained to
+        /** \brief Returns a pointer to the first landmark constrained to
          **/
-        LandmarkBasePtr getLandmarkOther() const     { return landmark_other_ptr_.lock(); }
+        LandmarkBasePtr getLandmarkOther() const;
+
+        // get pointer lists to other nodes
+        FrameBaseWPtrList getFrameOtherList() const         { return frame_other_list_; }
+        CaptureBaseWPtrList getCaptureOtherList() const     { return capture_other_list_; }
+        FeatureBaseWPtrList getFeatureOtherList() const     { return feature_other_list_; }
+        LandmarkBaseWPtrList getLandmarkOtherList() const   { return landmark_other_list_; }
+
+        bool hasFrameOther(const FrameBasePtr& _frm_other) const;
+        bool hasCaptureOther(const CaptureBasePtr& _cap_other) const;
+        bool hasFeatureOther(const FeatureBasePtr& _ftr_other) const;
+        bool hasLandmarkOther(const LandmarkBasePtr& _lmk_other) const;
 
     public:
         /**
@@ -228,6 +258,39 @@ inline bool FactorBase::getApplyLossFunction() const
     return apply_loss_function_;
 }
 
+inline FrameBasePtr FactorBase::getFrameOther() const
+{
+    if (frame_other_list_.empty()) return nullptr;
+    if (frame_other_list_.front().expired()) return nullptr;
+
+    return frame_other_list_.front().lock();
+}
+
+inline CaptureBasePtr FactorBase::getCaptureOther() const
+{
+    if (capture_other_list_.empty()) return nullptr;
+    if (capture_other_list_.front().expired()) return nullptr;
+
+    return capture_other_list_.front().lock();
+}
+
+inline FeatureBasePtr FactorBase::getFeatureOther() const
+{
+    if (feature_other_list_.empty()) return nullptr;
+    if (feature_other_list_.front().expired()) return nullptr;
+
+    return feature_other_list_.front().lock();
+}
+
+inline LandmarkBasePtr FactorBase::getLandmarkOther() const
+{
+    if (landmark_other_list_.empty()) return nullptr;
+    if (landmark_other_list_.front().expired()) return nullptr;
+
+    return landmark_other_list_.front().lock();
+}
+
+
 inline ProcessorBasePtr FactorBase::getProcessor() const
 {
   return processor_ptr_.lock();
diff --git a/include/core/factor/factor_block_absolute.h b/include/core/factor/factor_block_absolute.h
index eb55faae757f7fe1b02d2fe29c75a049e0b04299..0743548b7b4aad0517ecdd2590955c4cdf7c023c 100644
--- a/include/core/factor/factor_block_absolute.h
+++ b/include/core/factor/factor_block_absolute.h
@@ -41,7 +41,7 @@ class FactorBlockAbsolute : public FactorAnalytic
                             ProcessorBasePtr _processor_ptr = nullptr,
                             bool _apply_loss_function = false,
                             FactorStatus _status = FAC_ACTIVE) :
-            FactorAnalytic("BLOCK ABS",
+            FactorAnalytic("FactorBlockAbsolute",
                            nullptr,
                            nullptr,
                            nullptr,
diff --git a/include/core/factor/factor_block_difference.h b/include/core/factor/factor_block_difference.h
index 8f62b63838d79c6a654c80120bff4e4a144f4098..d3558ef21aa6e6577fc54d26015db3f9e3193312 100644
--- a/include/core/factor/factor_block_difference.h
+++ b/include/core/factor/factor_block_difference.h
@@ -37,8 +37,12 @@ class FactorBlockDifference : public FactorAnalytic
          *
          */
         FactorBlockDifference(
-                            StateBlockPtr _sb1_ptr,
-                            StateBlockPtr _sb2_ptr,
+                            const StateBlockPtr& _sb1_ptr,
+                            const StateBlockPtr& _sb2_ptr,
+                            const FrameBasePtr& _frame_other = nullptr,
+                            const CaptureBasePtr& _cap_other = nullptr,
+                            const FeatureBasePtr& _feat_other = nullptr,
+                            const LandmarkBasePtr& _lmk_other = nullptr,
                             unsigned int _start_idx1 = 0,
                             int _size1 = -1,
                             unsigned int _start_idx2 = 0,
@@ -46,11 +50,11 @@ class FactorBlockDifference : public FactorAnalytic
                             ProcessorBasePtr _processor_ptr = nullptr,
                             bool _apply_loss_function = false,
                             FactorStatus _status = FAC_ACTIVE) :
-            FactorAnalytic("BLOCK ABS",
-                           nullptr,
-                           nullptr,
-                           nullptr,
-                           nullptr,
+            FactorAnalytic("FactorBlockDifference",
+                           _frame_other,
+                           _cap_other,
+                           _feat_other,
+                           _lmk_other,
                            _processor_ptr,
                            _apply_loss_function,
                            _status,
@@ -146,10 +150,16 @@ inline void FactorBlockDifference::evaluateJacobians(const std::vector<Eigen::Ma
     assert(_st_vector[1].size() == sb2_size_ && "Wrong StateBlock size");
     assert(_st_vector[0].size() >= getMeasurement().size() && "StateBlock size and measurement size should match");
     assert(_st_vector[1].size() >= getMeasurement().size() && "StateBlock size and measurement size should match");
-
-    // normalized jacobian
-    _jacobians[0] = getMeasurementSquareRootInformationUpper() * J_res_sb1_;
-    _jacobians[1] = getMeasurementSquareRootInformationUpper() * J_res_sb2_;
+    assert(getMeasurementSquareRootInformationUpper().cols() == J_res_sb1_.rows() && "Wrong jacobian sb1 or covariance size");
+    assert(getMeasurementSquareRootInformationUpper().cols() == J_res_sb2_.rows() && "Wrong jacobian sb2 or covariance size");
+
+    // normalized jacobian, computed according to the _compute_jacobian flag
+    if (_compute_jacobian[0]){
+        _jacobians[0] = getMeasurementSquareRootInformationUpper() * J_res_sb1_;
+    }
+    if (_compute_jacobian[1]){
+        _jacobians[1] = getMeasurementSquareRootInformationUpper() * J_res_sb2_;
+    }
 }
 
 inline void FactorBlockDifference::evaluateJacobians(const std::vector<Eigen::Map<const Eigen::VectorXd>>& _st_vector,
@@ -163,10 +173,16 @@ inline void FactorBlockDifference::evaluateJacobians(const std::vector<Eigen::Ma
     assert(_st_vector[1].size() == sb2_size_ && "Wrong StateBlock size");
     assert(_st_vector[0].size() >= getMeasurement().size() && "StateBlock size and measurement size should match");
     assert(_st_vector[1].size() >= getMeasurement().size() && "StateBlock size and measurement size should match");
-
-    // normalized jacobian
-    _jacobians[0] = getMeasurementSquareRootInformationUpper() * J_res_sb1_;
-    _jacobians[1] = getMeasurementSquareRootInformationUpper() * J_res_sb2_;
+    assert(getMeasurementSquareRootInformationUpper().cols() == J_res_sb1_.rows() && "Wrong jacobian sb1 or covariance size");
+    assert(getMeasurementSquareRootInformationUpper().cols() == J_res_sb2_.rows() && "Wrong jacobian sb2 or covariance size");
+
+    // normalized jacobian, computed according to the _compute_jacobian flag
+    if (_compute_jacobian[0]){
+        _jacobians[0] = getMeasurementSquareRootInformationUpper() * J_res_sb1_;
+    }
+    if (_compute_jacobian[1]){
+        _jacobians[1] = getMeasurementSquareRootInformationUpper() * J_res_sb2_;
+    }
 }
 
 inline void FactorBlockDifference::evaluatePureJacobians(std::vector<Eigen::MatrixXd>& _pure_jacobians) const
diff --git a/include/core/factor/factor_diff_drive.h b/include/core/factor/factor_diff_drive.h
index 2338f699de73d38c74ce13509cdc0b70a1a82130..d936a99d6c1d64f29fda2c5aeca1806e0065c4d1 100644
--- a/include/core/factor/factor_diff_drive.h
+++ b/include/core/factor/factor_diff_drive.h
@@ -140,10 +140,12 @@ inline bool FactorDiffDrive::operator ()(const T* const _p1, const T* const _o1,
 inline Eigen::VectorXd FactorDiffDrive::residual()
 {
     VectorXd residual(3);
-    operator ()(getFrameOther()->getP()->getState().data(), getFrameOther()->getO()->getState().data(),
-                getCapture()->getFrame()->getP()->getState().data(),
-                getCapture()->getFrame()->getO()->getState().data(),
-                getCaptureOther()->getSensorIntrinsic()->getState().data(), residual.data());
+    operator ()(getFrameOther()   ->getP()               ->getState() .data(),
+                getFrameOther()   ->getO()               ->getState() .data(),
+                getFrame()        ->getP()               ->getState() .data(),
+                getFrame()        ->getO()               ->getState() .data(),
+                getCaptureOther() ->getSensorIntrinsic() ->getState() .data(),
+                residual.data());
     return residual;
 }
 
diff --git a/include/core/feature/feature_base.h b/include/core/feature/feature_base.h
index 7203425913de8bb5a3ff5a0fb267b4aef98f9fd5..a2ba3bc60f5d0db16d6c486099ac5e3e9b3116ec 100644
--- a/include/core/feature/feature_base.h
+++ b/include/core/feature/feature_base.h
@@ -95,6 +95,9 @@ class FeatureBase : public NodeBase, public std::enable_shared_from_this<Feature
 
         unsigned int getHits() const;
         const FactorBasePtrList& getConstrainedByList() const;
+        bool isConstrainedBy(const FactorBasePtr &_factor) const;
+
+
 
         // all factors
         void getFactorList(FactorBasePtrList & _fac_list) const;
diff --git a/include/core/frame/frame_base.h b/include/core/frame/frame_base.h
index 3745de04806c78f65463c39da49bcf9ba42cf0f8..eea8873b3e804743f4cd224bffd6442d4c17febf 100644
--- a/include/core/frame/frame_base.h
+++ b/include/core/frame/frame_base.h
@@ -126,6 +126,7 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha
         void getFactorList(FactorBasePtrList& _fac_list) const;
         unsigned int getHits() const;
         const FactorBasePtrList& getConstrainedByList() const;
+        bool isConstrainedBy(const FactorBasePtr& _factor) const;
         void link(TrajectoryBasePtr);
         template<typename classType, typename... T>
         static std::shared_ptr<classType> emplace(TrajectoryBasePtr _ptr, T&&... all);
diff --git a/include/core/landmark/landmark_base.h b/include/core/landmark/landmark_base.h
index 2f80a3d6fbe26d171126a82d280e65a3acaf4349..254e03e480f8471029c38c8f59626b230dc962f9 100644
--- a/include/core/landmark/landmark_base.h
+++ b/include/core/landmark/landmark_base.h
@@ -71,6 +71,8 @@ class LandmarkBase : public NodeBase, public HasStateBlocks, public std::enable_
 
         unsigned int getHits() const;
         const FactorBasePtrList& getConstrainedByList() const;
+        bool isConstrainedBy(const FactorBasePtr &_factor) const;
+
 
         MapBasePtr getMap() const;
         void link(MapBasePtr);
diff --git a/include/core/problem/problem.h b/include/core/problem/problem.h
index e0463b12f2d09b370375b9aa2bdb57894a134ca2..edda0b3b59fa839cdb6c5156abf61e1f2c338174 100644
--- a/include/core/problem/problem.h
+++ b/include/core/problem/problem.h
@@ -18,7 +18,7 @@ struct ProcessorParamsBase;
 #include "core/common/wolf.h"
 #include "core/frame/frame_base.h"
 #include "core/state_block/state_block.h"
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 #include "core/sensor/sensor_factory.h"
 #include "core/processor/processor_factory.h"
 #include "core/processor/is_motion.h"
@@ -47,8 +47,7 @@ class Problem : public std::enable_shared_from_this<Problem>
         HardwareBasePtr     hardware_ptr_;
         TrajectoryBasePtr   trajectory_ptr_;
         MapBasePtr          map_ptr_;
-        IsMotionPtr  processor_motion_ptr_;
-//        IsMotionPtr         is_motion_ptr_;
+        std::list<IsMotionPtr>  processor_is_motion_list_;
         std::map<std::pair<StateBlockPtr, StateBlockPtr>, Eigen::MatrixXd> covariances_;
         SizeEigen state_size_, state_cov_size_, dim_;
         std::map<FactorBasePtr, Notification> factor_notification_map_;
@@ -152,15 +151,15 @@ class Problem : public std::enable_shared_from_this<Problem>
     protected:
         /** \brief Set the processor motion
          *
-         * Set the processor motion.
+         * Add a new processor of type is motion to the processor is motion list.
          */
-        void setProcessorMotion(IsMotionPtr _processor_motion_ptr);
-        IsMotionPtr setProcessorMotion(const std::string& _unique_processor_name);
-        void clearProcessorMotion();
+        void addProcessorIsMotion(IsMotionPtr _processor_motion_ptr);
+        void clearProcessorIsMotion(IsMotionPtr proc);
 
     public:
-        IsMotionPtr& getProcessorMotion();
-
+        IsMotionPtr getProcessorIsMotion();
+        std::list<IsMotionPtr> getProcessorIsMotionList();
+        
         // Trajectory branch ----------------------------------
         TrajectoryBasePtr getTrajectory() const;
         virtual FrameBasePtr setPrior(const Eigen::VectorXd& _prior_state, //
@@ -276,10 +275,10 @@ class Problem : public std::enable_shared_from_this<Problem>
         // Zero state provider
         Eigen::VectorXd zeroState ( ) const;
         bool priorIsSet() const;
+        void setPriorIsSet(bool _prior_is_set);
         // Perturb state
         void            perturb(double amplitude = 0.01);
 
-
         // Map branch -----------------------------------------
         MapBasePtr getMap() const;
         void loadMap(const std::string& _filename_dot_yaml);
@@ -377,9 +376,22 @@ inline bool Problem::priorIsSet() const
     return prior_is_set_;
 }
 
-inline IsMotionPtr& Problem::getProcessorMotion()
+inline void Problem::setPriorIsSet(bool _prior_is_set)
+{
+    prior_is_set_ = _prior_is_set;
+}
+
+inline IsMotionPtr Problem::getProcessorIsMotion()
+{
+    if (!processor_is_motion_list_.empty())
+        return processor_is_motion_list_.front();
+    return nullptr;
+}
+
+
+inline std::list<IsMotionPtr> Problem::getProcessorIsMotionList()
 {
-    return processor_motion_ptr_;
+    return processor_is_motion_list_;
 }
 
 inline std::map<StateBlockPtr,Notification> Problem::consumeStateBlockNotificationMap()
diff --git a/include/core/processor/is_motion.h b/include/core/processor/is_motion.h
index f3cf0d781f39c9fda6ffb9e64817ceed0acfa162..8c99fe72e37698a2210e35a3af0c14bf9168f65e 100644
--- a/include/core/processor/is_motion.h
+++ b/include/core/processor/is_motion.h
@@ -43,6 +43,12 @@ class IsMotion
         TimeStamp       getCurrentTimeStamp() const;
         Eigen::VectorXd getState(const TimeStamp& _ts) const;
 
+        std::string getStateStructure(){return state_structure_;};
+        void setStateStructure(std::string _state_structure){state_structure_ = _state_structure;};
+    
+    protected:
+        std::string state_structure_; ///< The structure of the state vector (to retrieve state blocks from frames)
+
 };
 
 }
diff --git a/include/core/processor/processor_base.h b/include/core/processor/processor_base.h
index f3feeb56a3bcc6787d8efeb1355175b989dd3f3e..dc62abcac8375fc238f7c93617a33ccb8662d246 100644
--- a/include/core/processor/processor_base.h
+++ b/include/core/processor/processor_base.h
@@ -117,13 +117,18 @@ public:
     *
     * elements are ordered from most recent to oldest
     */
-    std::map<TimeStamp,T> getContainer();
+    const std::map<TimeStamp,T>& getContainer();
 
     /**\brief Remove all packs in the buffer with a time stamp older than the specified
     *
     */
     void removeUpTo(const TimeStamp& _time_stamp);
 
+    /**\brief Remove all packs in the buffer with a time stamp older than the specified
+    *
+    */
+    void removeUpToLower(const TimeStamp& _time_stamp);
+
     /**\brief Clear the buffer
     *
     */
@@ -503,7 +508,7 @@ void Buffer<T>::add(const TimeStamp& _time_stamp, const T& _element)
 }
 
 template <typename T>
-std::map<TimeStamp,T> Buffer<T>::getContainer()
+const std::map<TimeStamp,T>& Buffer<T>::getContainer()
 {
     return container_;
 }
@@ -533,6 +538,13 @@ inline void Buffer<T>::removeUpTo(const TimeStamp& _time_stamp)
     container_.erase(container_.begin(), post); // erasing by range
 }
 
+template <typename T>
+inline void Buffer<T>::removeUpToLower(const TimeStamp& _time_stamp)
+{
+    Buffer::Iterator post = container_.lower_bound(_time_stamp);
+    container_.erase(container_.begin(), post); // erasing by range
+}
+
 template <typename T>
 inline bool Buffer<T>::doubleCheckTimeTolerance(const TimeStamp& _time_stamp1, const double& _time_tolerance1,
                                 const TimeStamp& _time_stamp2, const double& _time_tolerance2)
diff --git a/include/core/processor/processor_motion.h b/include/core/processor/processor_motion.h
index 2ac6c8d5949ad07c1529fd06739c0ce80211f243..81a9184ad4798ccbaac1ebd61a194f6e287331b4 100644
--- a/include/core/processor/processor_motion.h
+++ b/include/core/processor/processor_motion.h
@@ -13,7 +13,7 @@
 #include "core/processor/processor_base.h"
 #include "core/processor/is_motion.h"
 #include "core/common/time_stamp.h"
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 
 // std
 #include <iomanip>
@@ -148,6 +148,7 @@ class ProcessorMotion : public ProcessorBase, public IsMotion
     // This is the main public interface
     public:
         ProcessorMotion(const std::string& _type,
+                        std::string _state_structure,
                         int _dim,
                         SizeEigen _state_size,
                         SizeEigen _delta_size,
@@ -505,11 +506,12 @@ inline void ProcessorMotion::getCurrentState(Eigen::VectorXd& _x) const
     assert(origin_ptr_ && "Trying to access origin_ptr_ but it is nullptr!");
 
     // ensure proper size of the provided reference
-    _x.resize( getProblem()->getFrameStructureSize() );
+    Eigen::VectorXd curr_x = origin_ptr_->getFrame()->getState(state_structure_);
+    _x.resize( curr_x.size() );
 
     // do get timestamp and state corrected by possible self-calibrations
     double Dt = getCurrentTimeStamp() - origin_ptr_->getTimeStamp();
-    statePlusDelta(origin_ptr_->getFrame()->getState(), last_ptr_->getDeltaCorrected(origin_ptr_->getCalibration()), Dt, _x);
+    statePlusDelta(curr_x, last_ptr_->getDeltaCorrected(origin_ptr_->getCalibration()), Dt, _x);
 }
 
 inline const Eigen::MatrixXd ProcessorMotion::getCurrentDeltaPreintCov() const
diff --git a/include/core/processor/processor_odom_2d.h b/include/core/processor/processor_odom_2d.h
index 6d46ab61a32c1b9573f386c97f1ae671086478c6..b03416837ec1b0a6a86a67ff0cf40fdf820b1370 100644
--- a/include/core/processor/processor_odom_2d.h
+++ b/include/core/processor/processor_odom_2d.h
@@ -12,7 +12,7 @@
 #include "core/capture/capture_odom_2d.h"
 #include "core/factor/factor_odom_2d.h"
 #include "core/math/rotations.h"
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 
 namespace wolf {
 
diff --git a/include/core/sensor/sensor_factory.h b/include/core/sensor/sensor_factory.h
index 3930176443a22cebb8c9591253af7f58b0a40a2c..daf01499ac759d799517cdd73ab830fb6ccaf4d5 100644
--- a/include/core/sensor/sensor_factory.h
+++ b/include/core/sensor/sensor_factory.h
@@ -16,7 +16,7 @@ struct ParamsSensorBase;
 
 // wolf
 #include "core/common/factory.h"
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 
 namespace wolf
 {
diff --git a/include/core/sensor/sensor_odom_2d.h b/include/core/sensor/sensor_odom_2d.h
index d6a431d3102b0a82a218ee71247552066c1ef8eb..45499f5c56fb342ed8a82b8521e6c2e156d06031 100644
--- a/include/core/sensor/sensor_odom_2d.h
+++ b/include/core/sensor/sensor_odom_2d.h
@@ -3,7 +3,7 @@
 
 //wolf includes
 #include "core/sensor/sensor_base.h"
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 
 namespace wolf {
 
diff --git a/include/core/sensor/sensor_odom_3d.h b/include/core/sensor/sensor_odom_3d.h
index 67efe1e9af27f8456401c400766dcbf32f44057b..3d08375b4fc30e43f07f201a5653d5e83a258381 100644
--- a/include/core/sensor/sensor_odom_3d.h
+++ b/include/core/sensor/sensor_odom_3d.h
@@ -10,7 +10,7 @@
 
 //wolf includes
 #include "core/sensor/sensor_base.h"
-#include "core/utils/params_server.hpp"
+#include "core/utils/params_server.h"
 
 namespace wolf {
 
diff --git a/include/core/state_block/has_state_blocks.h b/include/core/state_block/has_state_blocks.h
index ef55d163be4764393c4e1b08ac0003ae67b1d223..07c6d757bc09125c4a4e8a55aefd6d37b480c7d4 100644
--- a/include/core/state_block/has_state_blocks.h
+++ b/include/core/state_block/has_state_blocks.h
@@ -15,6 +15,10 @@
 namespace wolf
 {
 
+/// State of nodes containing several state blocks
+typedef std::unordered_map<std::string, Eigen::VectorXd> State;
+
+
 class HasStateBlocks
 {
     public:
@@ -44,10 +48,13 @@ class HasStateBlocks
         virtual unsigned int    removeStateBlock(const char _sb_type);
         bool            hasStateBlock(const std::string& _sb_type) const { return state_block_map_.count(_sb_type) > 0; }
         bool            hasStateBlock(const char _sb_type) const { return hasStateBlock(std::string(1, _sb_type)); }
+        bool            hasStateBlock(const StateBlockPtr& _sb) const;
         StateBlockPtr   getStateBlock(const std::string& _sb_type) const;
         StateBlockPtr   getStateBlock(const char _sb_type) const { return getStateBlock(std::string(1,_sb_type)); }
         bool            setStateBlock(const std::string _sb_type, const StateBlockPtr& _sb);
         bool            setStateBlock(const char _sb_type, const StateBlockPtr& _sb) { return setStateBlock(std::string(1, _sb_type), _sb); }
+        bool            stateBlockKey(const StateBlockPtr& _sb, std::string& _key) const;
+        std::unordered_map<std::string, StateBlockPtr>::const_iterator find(const StateBlockPtr& _sb) const;
 
         // Emplace derived state blocks (angle, quaternion, etc).
         template<typename SB, typename ... Args>
@@ -62,11 +69,13 @@ class HasStateBlocks
         void removeStateBlocks(ProblemPtr _problem);
 
         // States
-        virtual void    setState(const Eigen::VectorXd& _state, const bool _notify = true);
-        Eigen::VectorXd getState() const;
-        void            getState(Eigen::VectorXd& _state) const;
-        unsigned int    getSize() const;
-        unsigned int    getLocalSize() const;
+        inline void setState(const Eigen::VectorXd& _state, std::string _sub_structure="", const bool _notify = true);
+        void getState(Eigen::VectorXd& _state, std::string structure="") const;
+        Eigen::VectorXd getState(std::string structure="") const;
+        unsigned int getSize(std::string _sub_structure="") const;
+        unsigned int getLocalSize(std::string _sub_structure="") const;
+
+        State getStateComposite();
 
         // Perturb state
         void            perturb(double amplitude = 0.01);
@@ -198,62 +207,145 @@ inline bool HasStateBlocks::isFixed() const
     return fixed;
 }
 
-inline void HasStateBlocks::setState(const Eigen::VectorXd& _state, const bool _notify)
+inline void HasStateBlocks::setState(const Eigen::VectorXd& _state, std::string _sub_structure, const bool _notify)
 {
-    int size = getSize();
-
+    if (_sub_structure == ""){
+        _sub_structure = structure_;
+    }
+    int size = getSize(_sub_structure);
     assert(_state.size() == size && "In FrameBase::setState wrong state size");
 
     unsigned int index = 0;
-    for (const char key : getStructure())
+    for (const char key : _sub_structure)
     {
         const auto& sb = getStateBlock(key);
-
+        if (!sb){
+            WOLF_ERROR("Stateblock key ", key, " not in the structure");
+        }
         sb->setState(_state.segment(index, sb->getSize()), _notify); // do not notify if state block is not estimated by the solver
         index += sb->getSize();
     }
 
 }
 
-inline void HasStateBlocks::getState(Eigen::VectorXd& _state) const
+// _sub_structure can be either stateblock structure of the node or a subset of this structure
+inline void HasStateBlocks::getState(Eigen::VectorXd& _state, std::string _sub_structure) const
 {
-    _state.resize(getSize());
+    if (_sub_structure == ""){
+        _sub_structure = structure_;
+    }
+    _state.resize(getSize(_sub_structure));
 
     unsigned int index = 0;
-    for (const char key : getStructure())
+    for (const char key : _sub_structure)
     {
         const auto& sb = getStateBlock(key);
-
+        if (!sb){
+            WOLF_ERROR("Stateblock key ", key, " not in the structure");
+        }
         _state.segment(index,sb->getSize()) = sb->getState();
         index += sb->getSize();
     }
 
 }
 
-inline Eigen::VectorXd HasStateBlocks::getState() const
+inline Eigen::VectorXd HasStateBlocks::getState(std::string _sub_structure) const
 {
     Eigen::VectorXd state;
 
-    getState(state);
+    getState(state, _sub_structure);
 
     return state;
 }
 
-inline unsigned int HasStateBlocks::getSize() const
+inline State HasStateBlocks::getStateComposite()
 {
+    State state;
+    for (auto& pair_key_kf : state_block_map_)
+    {
+        state.emplace(pair_key_kf.first, pair_key_kf.second->getState());
+    }
+    return state;
+}
+
+inline unsigned int HasStateBlocks::getSize(std::string _sub_structure) const
+{
+    if (_sub_structure == ""){
+        _sub_structure = structure_;
+    }
     unsigned int size = 0;
-    for (const auto& pair_key_sb : getStateBlockMap())
-            size += pair_key_sb.second->getSize();
+    for (const char key : _sub_structure)
+    {
+        const auto& sb = getStateBlock(key);
+        if (!sb){
+            WOLF_ERROR("Stateblock key ", key, " not in the structure");
+        }
+        size += sb->getSize();
+    }
+
     return size;
 }
 
-inline unsigned int HasStateBlocks::getLocalSize() const
+//<<<<<<< HEAD
+inline std::unordered_map<std::string, StateBlockPtr>::const_iterator HasStateBlocks::find(const StateBlockPtr& _sb) const
+{
+    const auto& it = std::find_if(state_block_map_.begin(),
+                                  state_block_map_.end(),
+                                  [_sb](const std::pair<std::string, StateBlockPtr>& pair)
+                                  {
+                                    return pair.second == _sb;
+                                  }
+                                  );
+
+    return it;
+}
+
+inline bool HasStateBlocks::hasStateBlock(const StateBlockPtr &_sb) const
+{
+    const auto& it = this->find(_sb);
+
+    return it != state_block_map_.end();
+}
+
+inline bool HasStateBlocks::stateBlockKey(const StateBlockPtr &_sb, std::string& _key) const
 {
+    const auto& it = this->find(_sb);
+
+    bool found = (it != state_block_map_.end());
+
+    if (found)
+    {
+        _key = it->first;
+        return true;
+    }
+    else
+    {
+        _key = "";
+        return false;
+    }
+}
+
+//inline unsigned int HasStateBlocks::getLocalSize() const
+//=======
+inline unsigned int HasStateBlocks::getLocalSize(std::string _sub_structure) const
+//>>>>>>> devel
+{
+    if (_sub_structure == ""){
+        _sub_structure = structure_;
+    }
     unsigned int size = 0;
-    for (const auto& pair_key_sb : getStateBlockMap())
-            size += pair_key_sb.second->getLocalSize();
+    for (const char key : _sub_structure)
+    {
+        const auto& sb = getStateBlock(key);
+        if (!sb){
+            WOLF_ERROR("Stateblock key ", key, " not in the structure");
+        }
+        size += sb->getLocalSize();
+    }
+
     return size;
 }
 
 } // namespace wolf
+
 #endif /* STATE_BLOCK_HAS_STATE_BLOCKS_H_ */
diff --git a/include/core/state_block/state_block.h b/include/core/state_block/state_block.h
index 33aa6fcb4b221ea1dc23f24b21f4a0fb12cbfc0d..ab3bb7147f3c81f57a3436216412274394acc04a 100644
--- a/include/core/state_block/state_block.h
+++ b/include/core/state_block/state_block.h
@@ -74,6 +74,10 @@ public:
          **/
         Eigen::VectorXd getState() const;
 
+        /** \brief Returns the state vector data array
+         **/
+        double* getStateData();
+
         /** \brief Sets the state vector
          **/
         void setState(const Eigen::VectorXd& _state, const bool _notify = true);
@@ -283,6 +287,11 @@ inline void StateBlock::resetLocalParamUpdated()
     local_param_updated_.store(false);
 }
 
+inline double* StateBlock::getStateData()
+{
+    return state_.data();
+}
+
 }// namespace wolf
 
 #endif
diff --git a/include/core/utils/check_log.h b/include/core/utils/check_log.h
new file mode 100644
index 0000000000000000000000000000000000000000..035bd0aa0e2e9fa4989c95509800d1fee517bd46
--- /dev/null
+++ b/include/core/utils/check_log.h
@@ -0,0 +1,22 @@
+#ifndef CHECK_LOG_H
+#define CHECK_LOG_H
+#include <iostream>
+#include <string>
+#include <sstream>
+
+namespace wolf
+{
+class CheckLog
+{
+  public:
+    bool        is_consistent_;
+    std::string explanation_;
+
+    CheckLog();
+    CheckLog(bool _consistent, std::string _explanation);
+    ~CheckLog(){};
+    void compose(CheckLog l);
+    void assertTrue(bool _condition, std::stringstream& _stream);
+};
+}  // namespace wolf
+#endif
diff --git a/include/core/utils/check_log.hpp b/include/core/utils/check_log.hpp
deleted file mode 100644
index db3ab2dc9dd6e165c3541544bf7770022568f2fe..0000000000000000000000000000000000000000
--- a/include/core/utils/check_log.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef CHECK_LOG_HPP
-#define CHECK_LOG_HPP
-#include <iostream>
-#include <string>
-
-class CheckLog {
-
-public:
-
-  bool is_consistent_;
-  std::string explanation_;
-
-  CheckLog() {
-    is_consistent_ = true;
-    explanation_ = "";
-  }
-  CheckLog(bool consistent, std::string explanation) {
-    is_consistent_ = consistent;
-    if (not consistent)
-      explanation_ = explanation;
-    else
-      explanation_ = "";
-  }
-  ~CheckLog(){};
-  void compose(CheckLog l) {
-
-    CheckLog result_log;
-    is_consistent_ = is_consistent_ and l.is_consistent_;
-    explanation_ = explanation_ + l.explanation_;
-  }
-};
-#endif
diff --git a/include/core/utils/loader.h b/include/core/utils/loader.h
new file mode 100644
index 0000000000000000000000000000000000000000..6f1a4cc68c2d0dcb20a6ef18f53ec259507fc176
--- /dev/null
+++ b/include/core/utils/loader.h
@@ -0,0 +1,32 @@
+#ifndef LOADER_H
+#define LOADER_H
+
+#include <string>
+
+class Loader{
+protected:
+    std::string path_;
+public:
+    Loader(std::string _file);
+    virtual void load() = 0;
+    virtual void close() = 0;
+};
+
+class LoaderRaw: public Loader{
+    void* resource_;
+public:
+    LoaderRaw(std::string _file);
+    ~LoaderRaw();
+    void load();
+    void close();
+};
+// class LoaderPlugin: public Loader{
+//     ClassLoader* resource_;
+//     void load(){
+//         this->resource_ = new ClassLoader(this->path_);
+//     }
+//     void close(){
+//         delete this->resource_;
+//     }
+// };
+#endif
diff --git a/include/core/utils/loader.hpp b/include/core/utils/loader.hpp
deleted file mode 100644
index 3d867d799b36bfd53fb42e93577554caf1b050c1..0000000000000000000000000000000000000000
--- a/include/core/utils/loader.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef LOADER_HPP
-#define LOADER_HPP
-#include <dlfcn.h>
-#include <string>
-#include <stdexcept>
-class Loader{
-protected:
-    std::string path_;
-public:
-    Loader(std::string _file){
-        this->path_ = _file;
-    }
-    virtual void load() = 0;
-    virtual void close() = 0;
-};
-class LoaderRaw: public Loader{
-    void* resource_;
-public:
-    LoaderRaw(std::string _file):
-        Loader(_file)
-    {
-        //
-    }
-    ~LoaderRaw(){
-        this->close();
-    }
-    void load(){
-        this->resource_ = dlopen(this->path_.c_str(), RTLD_LAZY);
-        if(not this->resource_)
-            throw std::runtime_error("Couldn't load resource with path " + this->path_ + "\n" + "Error info: " + dlerror());
-    }
-    void close(){
-        if(this->resource_) dlclose(this->resource_);
-    }
-};
-// class LoaderPlugin: public Loader{
-//     ClassLoader* resource_;
-//     void load(){
-//         this->resource_ = new ClassLoader(this->path_);
-//     }
-//     void close(){
-//         delete this->resource_;
-//     }
-// };
-#endif
\ No newline at end of file
diff --git a/include/core/utils/params_server.h b/include/core/utils/params_server.h
new file mode 100644
index 0000000000000000000000000000000000000000..e8b473ca26703f17ea932cca4d1e913717108026
--- /dev/null
+++ b/include/core/utils/params_server.h
@@ -0,0 +1,55 @@
+#ifndef PARAMS_SERVER_H
+#define PARAMS_SERVER_H
+
+#include "core/utils/converter.h"
+
+#include <map>
+#include <exception>
+
+namespace wolf{
+
+class MissingValueException : public std::runtime_error
+{
+public:
+  MissingValueException(std::string _msg) : std::runtime_error(_msg) {}
+};
+
+class ParamsServer{
+    std::map<std::string, std::string> params_;
+public:
+    ParamsServer();
+    ParamsServer(std::map<std::string, std::string> _params);
+    ~ParamsServer(){
+        //
+    }
+
+    void print();
+
+
+    void addParam(std::string _key, std::string _value);
+
+    void addParams(std::map<std::string, std::string> _params);
+
+   // template<typename T>
+   // T getParam(std::string key, std::string def_value) const {
+   //     if(params_.find(key) != params_.end()){
+   //         return converter<T>::convert(params_.find(key)->second);
+   //     }else{
+   //         return converter<T>::convert(def_value);
+   //     }
+   // }
+
+    template<typename T>
+    T getParam(std::string _key) const {
+        if(params_.find(_key) != params_.end()){
+            return converter<T>::convert(params_.find(_key)->second);
+        }else{
+            throw MissingValueException("The following key: '" + _key + "' has not been found in the parameters server.");
+        }
+    }
+
+};
+
+}
+
+#endif
diff --git a/include/core/utils/params_server.hpp b/include/core/utils/params_server.hpp
deleted file mode 100644
index a750eab79f4ee90b39e4e21d1926129897c29d92..0000000000000000000000000000000000000000
--- a/include/core/utils/params_server.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#ifndef PARAMS_SERVER_HPP
-#define PARAMS_SERVER_HPP
-
-#include "core/utils/converter.h"
-//#include "core/yaml/parser_yaml.hpp"
-
-#include <vector>
-#include <regex>
-#include <map>
-#include <exception>
-
-namespace wolf{
-
-class MissingValueException : public std::runtime_error
-{
-public:
-  MissingValueException(std::string msg) : std::runtime_error(msg) {}
-};
-
-class ParamsServer{
-    std::map<std::string, std::string> _params;
-public:
-    ParamsServer(){
-        _params = std::map<std::string, std::string>();
-    }
-    ParamsServer(std::map<std::string, std::string> params){
-        _params = params;
-    }
-    ~ParamsServer(){
-        //
-    }
-
-    void print(){
-        for(auto it : _params)
-            std::cout << it.first << "~~" << it.second << std::endl;
-    }
-
-
-    void addParam(std::string key, std::string value){
-        _params.insert(std::pair<std::string, std::string>(key, value));
-    }
-
-    void addParams(std::map<std::string, std::string> params)
-    {
-        _params.insert(params.begin(), params.end());
-    }
-
-   // template<typename T>
-   // T getParam(std::string key, std::string def_value) const {
-   //     if(_params.find(key) != _params.end()){
-   //         return converter<T>::convert(_params.find(key)->second);
-   //     }else{
-   //         return converter<T>::convert(def_value);
-   //     }
-   // }
-
-    template<typename T>
-    T getParam(std::string key) const {
-        if(_params.find(key) != _params.end()){
-            return converter<T>::convert(_params.find(key)->second);
-        }else{
-            throw MissingValueException("The following key: '" + key + "' has not been found in the parameters server.");
-        }
-    }
-
-};
-
-}
-
-#endif
diff --git a/include/core/yaml/parser_yaml.h b/include/core/yaml/parser_yaml.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b6f659ebd609dffef4f3c472800cf32714f22e1
--- /dev/null
+++ b/include/core/yaml/parser_yaml.h
@@ -0,0 +1,80 @@
+#ifndef PARSER_YAML_H
+#define PARSER_YAML_H
+
+#include "core/utils/converter.h"
+#include "core/common/wolf.h"
+
+#include "yaml-cpp/yaml.h"
+
+namespace wolf
+{
+class ParserYAML {
+    struct ParamsInitSensor{
+        std::string type_;
+        std::string name_;
+        std::string plugin_;
+        YAML::Node n_;
+    };
+    struct ParamsInitProcessor{
+        std::string type_;
+        std::string name_;
+        std::string name_assoc_sensor_;
+        std::string plugin_;
+        YAML::Node n_;
+    };
+    struct SubscriberManager{
+        std::string package_;
+        std::string subscriber_;
+        std::string topic_;
+        std::string sensor_name_;
+        YAML::Node n_;
+    };
+    struct PublisherManager{
+        std::string subscriber_;
+        std::string topic_;
+        std::string period_;
+        YAML::Node n_;
+    };
+    std::map<std::string, std::string> params_;
+    std::string active_name_;
+    std::vector<ParamsInitSensor> paramsSens_;
+    std::vector<ParamsInitProcessor> paramsProc_;
+    std::stack<std::string> parsing_file_;
+    std::string file_;
+    std::string path_root_;
+    std::vector<SubscriberManager> subscriber_managers_;
+    std::vector<PublisherManager> publisher_managers_;
+    YAML::Node problem;
+    std::string generatePath(std::string);
+    YAML::Node loadYAML(std::string);
+    void insert_register(std::string, std::string);
+public:
+    ParserYAML(std::string _file, std::string _path_root = "",
+               bool _freely_parse = false);
+    ~ParserYAML()
+    {
+        //
+    }
+    void parse_freely();
+    std::map<std::string, std::string> getParams();
+
+  private:
+    void walkTree(std::string _file);
+    void walkTree(std::string _file, std::vector<std::string>& _tags);
+    void walkTree(std::string _file, std::vector<std::string>& _tags, std::string _hdr);
+/** @Brief Recursively walks the YAML tree while filling a map with the values parsed from the file
+ * @param YAML node to be parsed
+ * @param tags represents the path from the root of the YAML tree to the current node
+ * @param hdr is the name of the current YAML node
+ */
+    void walkTreeR(YAML::Node _n, std::vector<std::string>& _tags, std::string _hdr);
+    void updateActiveName(std::string _tag);
+/** @Brief Parse the sensors, processors, callbacks and files elements of the YAML file. We assume that these elements
+    are defined at the top level of the YAML file.
+ * @param file is the path to the YAML file */
+    void parseFirstLevel(std::string _file);
+    std::string tagsToString(std::vector<std::string>& _tags);
+    void parse();
+};
+}
+#endif
diff --git a/include/core/yaml/parser_yaml.hpp b/include/core/yaml/parser_yaml.hpp
deleted file mode 100644
index 22f584d76bab2aa2c3a6bd6ca30edbeb4873a4ea..0000000000000000000000000000000000000000
--- a/include/core/yaml/parser_yaml.hpp
+++ /dev/null
@@ -1,532 +0,0 @@
-#ifndef PARSER_YAML_HPP
-#define PARSER_YAML_HPP
-
-#include "core/utils/converter.h"
-#include "core/common/wolf.h"
-
-#include "yaml-cpp/yaml.h"
-
-#include <string>
-#include <vector>
-#include <list>
-#include <stack>
-#include <regex>
-#include <map>
-#include <iostream>
-#include <algorithm>
-#include <numeric>
-
-namespace {
-  //====== START OF FORWARD DECLARATION ========
-  std::string parseAtomicNode(YAML::Node);
-  std::string fetchMapEntry(YAML::Node);
-  std::string mapToString(std::map<std::string,std::string>);
-  //====== END OF FORWARD DECLARATION ========
-
-/** @Brief Interprets a map as being atomic and thus parses it as a single entity. We assume that the map has as values only scalars and sequences.
- *  @param n the node representing a map
- *  @return std::map<std::string, std::string> populated with the key,value pairs in n
- */
-std::map<std::string, std::string> fetchAsMap(YAML::Node n){
-    assert(n.Type() == YAML::NodeType::Map && "trying to fetch as Map a non-Map node");
-    auto m = std::map<std::string, std::string>();
-    for(const auto& kv : n){
-        std::string key = kv.first.as<std::string>();
-        switch (kv.second.Type()) {
-        case YAML::NodeType::Scalar : {
-            std::string value = kv.second.Scalar();
-            m.insert(std::pair<std::string,std::string>(key, value));
-            break;
-        }
-        case YAML::NodeType::Sequence : {
-            std::string aux = parseAtomicNode(kv.second);
-            m.insert(std::pair<std::string,std::string>(key, aux));
-            break;
-        }
-        case YAML::NodeType::Map : {
-          std::string value = fetchMapEntry(kv.second);
-          std::regex r("^\\$.*");
-          if (std::regex_match(key, r)) key = key.substr(1,key.size()-1);
-          m.insert(std::pair<std::string,std::string>(key, value));
-          break;
-        }
-        default:
-            assert(1 == 0 && "Unsupported node Type at fetchAsMap");
-            break;
-        }
-    }
-    return m;
-}
-  std::string fetchMapEntry(YAML::Node n){
-    switch (n.Type()) {
-    case YAML::NodeType::Scalar: {
-      return n.Scalar();
-      break;
-    }
-    case YAML::NodeType::Sequence: {
-      return parseAtomicNode(n);
-      break;
-    }
-    case YAML::NodeType::Map: {
-      return mapToString(fetchAsMap(n));
-      break;
-    }
-    default: {
-      assert(1 == 0 && "Unsupported node Type at fetchMapEntry");
-      return "";
-      break;
-    }
-    }
-  }
-    /** @Brief Transforms a std::map<std::string,std::string> to its std::string representation [{k1:v1},{k2:v2},{k3:v3},...]
-    * @param _map just a std::map<std::string,std::string>
-    * @return <b>{std::string}</b> [{k1:v1},{k2:v2},{k3:v3},...]
-    */
-    std::string mapToString(std::map<std::string,std::string> _map){
-        std::string result = "";
-        auto v = std::vector<std::string>();
-        std::transform(_map.begin(), _map.end(), back_inserter(v), [](const std::pair<std::string,std::string> p){return "{" + p.first + ":" + p.second + "}";});
-        auto concat = [](std::string ac, std::string str)-> std::string {
-                          return ac + str + ",";
-                      };
-        std::string aux = "";
-        std::string accumulated = std::accumulate(v.begin(), v.end(), aux, concat);
-        if(accumulated.size() > 1) accumulated = accumulated.substr(0,accumulated.size() - 1);
-        else accumulated = "";
-        return "[" + accumulated + "]";
-    }
-    /** @Brief Generates a std::string representing a YAML sequence. The sequence is assumed to be scalar or at most be a sequence of sequences of scalars.
-    * @param n a vector of YAML::Node that represents a YAML::Sequence
-    * @return <b>{std::string}</b> representing the YAML sequence
-    */
-    std::string parseAtomicNode(YAML::Node n){
-      std::string aux = "";
-      bool first = true;
-      std::string separator = "";
-      switch(n.Type()){
-      case YAML::NodeType::Scalar:
-        return n.Scalar();
-        break;
-      case YAML::NodeType::Sequence:
-        for(auto it : n){
-          aux += separator + parseAtomicNode(it);
-          if(first){
-            separator = ",";
-            first = false;
-          }
-        }
-        return "[" + aux + "]";
-        break;
-      case YAML::NodeType::Map:
-        return mapToString(fetchAsMap(n));
-        break;
-      default:
-        return "";
-        break;
-      }
-    }
-
-    /** @Brief checks if a node of the YAML tree is atomic. Only works if the nodes are of type
-     * Scalar, Sequence or Map.
-     * @param key is the key associated to the node n if n.Type() == YAML::NodeType::Map
-     * @param n node to be test for atomicity
-    */
-    bool isAtomic(std::string key, YAML::Node n){
-      assert(n.Type() != YAML::NodeType::Undefined && n.Type() != YAML::NodeType::Null && "Cannot determine atomicity of Undefined/Null node");
-      std::regex r("^\\$.*");
-      bool is_atomic = true;
-      switch(n.Type()){
-      case YAML::NodeType::Scalar:
-        return true;
-        break;
-      case YAML::NodeType::Sequence:
-        for(auto it : n) {
-          switch(it.Type()){
-          case YAML::NodeType::Map:
-            for(const auto& kv : it){
-              is_atomic = is_atomic and isAtomic(kv.first.as<std::string>(), it);
-            }
-            break;
-          default:
-            is_atomic = is_atomic and isAtomic("", it);
-            break;
-          }
-        }
-        return is_atomic;
-        break;
-      case YAML::NodeType::Map:
-        is_atomic = std::regex_match(key, r);
-        return is_atomic;
-        break;
-      default:
-        throw std::runtime_error("Cannot determine atomicity of node type " + std::to_string(n.Type()));
-        return false;
-        break;
-      }
-      return false;
-    }
-}
-class ParserYAML {
-    struct ParamsInitSensor{
-        std::string _type;
-        std::string _name;
-        std::string _plugin;
-        YAML::Node n;
-    };
-    struct ParamsInitProcessor{
-        std::string _type;
-        std::string _name;
-        std::string _name_assoc_sensor;
-        std::string _plugin;
-        YAML::Node n;
-    };
-    struct SubscriberManager{
-        std::string _package;
-        std::string _subscriber;
-        std::string _topic;
-        std::string _sensor_name;
-        YAML::Node n;
-    };
-    struct PublisherManager{
-        std::string _subscriber;
-        std::string _topic;
-        std::string _period;
-        YAML::Node n;
-    };
-    std::map<std::string, std::string> _params;
-    std::string _active_name;
-    std::vector<ParamsInitSensor> _paramsSens;
-    std::vector<ParamsInitProcessor> _paramsProc;
-    std::stack<std::string> _parsing_file;
-    std::string _file;
-    std::string _path_root;
-    std::vector<SubscriberManager> _subscriber_managers;
-    std::vector<PublisherManager> _publisher_managers;
-    YAML::Node problem;
-    std::string generatePath(std::string);
-    YAML::Node loadYAML(std::string);
-    void insert_register(std::string, std::string);
-public:
-    ParserYAML(std::string file, std::string path_root = "",
-               bool freely_parse = false) {
-      _params = std::map<std::string, std::string>();
-      _active_name = "";
-      _paramsSens = std::vector<ParamsInitSensor>();
-      _paramsProc = std::vector<ParamsInitProcessor>();
-      _subscriber_managers = std::vector<SubscriberManager>();
-      _publisher_managers = std::vector<PublisherManager>();
-      _parsing_file = std::stack<std::string>();
-      _file = file;
-      if (path_root != "") {
-        std::regex r(".*/ *$");
-        if (not std::regex_match(path_root, r))
-          _path_root = path_root + "/";
-        else
-          _path_root = path_root;
-      }
-      if(not freely_parse) this->parse();
-      else this->parse_freely();
-    }
-    ~ParserYAML()
-    {
-        //
-    }
-    void parse_freely();
-    std::map<std::string, std::string> getParams();
-
-  private:
-    void walkTree(std::string file);
-    void walkTree(std::string file, std::vector<std::string>& tags);
-    void walkTree(std::string file, std::vector<std::string>& tags, std::string hdr);
-    void walkTreeR(YAML::Node n, std::vector<std::string>& tags, std::string hdr);
-    void updateActiveName(std::string tag);
-    void parseFirstLevel(std::string file);
-    std::string tagsToString(std::vector<std::string>& tags);
-    void parse();
-};
-std::string ParserYAML::generatePath(std::string file){
-    std::regex r("^/.*");
-    if(std::regex_match(file, r)){
-        return file;
-    }else{
-        return _path_root + file;
-    }
-}
-YAML::Node ParserYAML::loadYAML(std::string file){
-  try{
-    // std::cout << "Parsing " << generatePath(file) << std::endl;
-    WOLF_INFO("Parsing file: ", generatePath(file));
-    return YAML::LoadFile(generatePath(file));
-  }catch (YAML::BadFile& e){
-    throw std::runtime_error("Couldn't load file " + generatePath(file) + ". Tried to open it from " + this->_parsing_file.top());
-  }
-}
-std::string ParserYAML::tagsToString(std::vector<std::string> &tags){
-    std::string hdr = "";
-    for(auto it : tags){
-        hdr = hdr + "/" + it;
-    }
-    return hdr;
-}
-void ParserYAML::walkTree(std::string file){
-    YAML::Node n;
-    n = loadYAML(generatePath(file));
-    this->_parsing_file.push(generatePath(file));
-    std::vector<std::string> hdrs = std::vector<std::string>();
-    walkTreeR(n, hdrs, "");
-    this->_parsing_file.pop();
-}
-void ParserYAML::walkTree(std::string file, std::vector<std::string>& tags){
-    YAML::Node n;
-    n = loadYAML(generatePath(file));
-    this->_parsing_file.push(generatePath(file));
-    walkTreeR(n, tags, "");
-    this->_parsing_file.pop();
-}
-void ParserYAML::walkTree(std::string file, std::vector<std::string>& tags, std::string hdr){
-    YAML::Node n;
-    n = loadYAML(generatePath(file));
-    this->_parsing_file.push(generatePath(file));
-    walkTreeR(n, tags, hdr);
-    this->_parsing_file.pop();
-}
-/** @Brief Recursively walks the YAML tree while filling a map with the values parsed from the file
-* @param YAML node to be parsed
-* @param tags represents the path from the root of the YAML tree to the current node
-* @param hdr is the name of the current YAML node
-*/
-void ParserYAML::walkTreeR(YAML::Node n, std::vector<std::string>& tags, std::string hdr){
-    switch (n.Type()) {
-    case YAML::NodeType::Scalar : {
-        std::regex r("^@.*");
-        if(std::regex_match(n.Scalar(), r)){
-            std::string str = n.Scalar();
-            walkTree(str.substr(1,str.size() - 1), tags, hdr);
-        }else{
-          insert_register(hdr, n.Scalar());
-        }
-        break;
-    }
-    case YAML::NodeType::Sequence : {
-      if(isAtomic("", n)){
-        insert_register(hdr, parseAtomicNode(n));
-        }else{
-          for(const auto& kv : n){
-            walkTreeR(kv, tags, hdr);
-          }
-        }
-        break;
-    }
-    case YAML::NodeType::Map : {
-      for(const auto& kv : n){
-        if(isAtomic(kv.first.as<std::string>(), n)){
-          std::string key = kv.first.as<std::string>();
-          //WOLF_DEBUG("KEY IN MAP ATOMIC ", hdr + "/" + key);
-          key = key.substr(1,key.size() - 1);
-          insert_register(hdr + "/" + key, parseAtomicNode(kv.second));
-      }else{
-            /*
-              If key=="follow" then the parser will assume that the value is a path and will parse
-              the (expected) yaml file at the specified path. Note that this does not increase the header depth.
-              The following example shows how the header remains unafected:
-              @my_main_config                |  @some_path
-              - cov_det: 1                   |  - my_value : 23
-              - follow: "@some_path"         |
-              - var: 1.2                     |
-              Resulting map:
-              cov_det -> 1
-              my_value-> 23
-              var: 1.2
-              Instead of:
-              cov_det -> 1
-              follow/my_value-> 23
-              var: 1.2
-              Which would result from the following yaml files
-              @my_main_config                |  @some_path
-              - cov_det: 1                   |  - my_value : 23
-              - $follow: "@some_path"        |
-              - var: 1.2                     |
-            */
-          std::string key = kv.first.as<std::string>();
-          //WOLF_DEBUG("KEY IN MAP NON ATOMIC ", key);
-          std::regex rr("follow");
-          if(not std::regex_match(kv.first.as<std::string>(), rr)) {
-            tags.push_back(kv.first.as<std::string>());
-            if(tags.size() == 2) this->updateActiveName(kv.first.as<std::string>());
-            walkTreeR(kv.second, tags, hdr +"/"+ kv.first.as<std::string>());
-            tags.pop_back();
-            if(tags.size() == 1) this->updateActiveName("");
-          }else{
-            walkTree(kv.second.as<std::string>(), tags, hdr);
-          }
-      }
-      }
-        break;
-    }
-      case YAML::NodeType::Null :
-        break;
-    default:
-        assert(1 == 0 && "Unsupported node Type at walkTreeR.");
-        break;
-    }
-}
-void ParserYAML::updateActiveName(std::string tag){
-    this->_active_name = tag;
-}
-/** @Brief Parse the sensors, processors, callbacks and files elements of the YAML file. We assume that these elements
-    are defined at the top level of the YAML file.
- * @param file is the path to the YAML file */
-void ParserYAML::parseFirstLevel(std::string file){
-    YAML::Node n;
-    n = loadYAML(generatePath(file));
-
-    YAML::Node n_config = n["config"];
-    // assert(n_config.Type() == YAML::NodeType::Map && "trying to parse config node but found a non-Map node");
-    if(n_config.Type() != YAML::NodeType::Map) throw std::runtime_error("Could not find config node. Please make sure that your YAML file " + generatePath(file) + " starts with 'config:'");
-    if(n_config["problem"].Type() != YAML::NodeType::Map) throw std::runtime_error("Could not find problem node. Please make sure that the 'config' node in YAML file " + generatePath(file) + " has a 'problem' entry");
-    this->problem = n_config["problem"];
-    std::vector<std::map<std::string, std::string>> map_container;
-    try{
-      for(const auto& kv : n_config["sensors"]){
-          ParamsInitSensor pSensor = {kv["type"].Scalar(), kv["name"].Scalar(), kv["plugin"].Scalar(), kv};
-          _paramsSens.push_back(pSensor);
-          map_container.push_back(std::map<std::string, std::string>({
-                                                                      {"type", kv["type"].Scalar()},
-                                                                      {"name", kv["name"].Scalar()},
-                                                                      {"plugin", kv["plugin"].Scalar()}
-                  }));
-      }
-      insert_register("sensors", wolf::converter<std::string>::convert(map_container));
-      map_container.clear();
-    } catch(YAML::InvalidNode& e){
-      throw std::runtime_error("Error parsing sensors @" + generatePath(file) + ". Please make sure that each sensor entry has 'type', 'name' and 'plugin' entries.");
-    }
-
-    try{
-      for(const auto& kv : n_config["processors"]){
-          ParamsInitProcessor pProc = {kv["type"].Scalar(), kv["name"].Scalar(), kv["sensor_name"].Scalar(), kv["plugin"].Scalar(), kv};
-          _paramsProc.push_back(pProc);
-          map_container.push_back(std::map<std::string, std::string>({
-                                                                      {"type", kv["type"].Scalar()},
-                                                                      {"name", kv["name"].Scalar()},
-                                                                      {"plugin", kv["plugin"].Scalar()},
-                                                                      {"sensor_name", kv["sensor_name"].Scalar()}}));
-      }
-      insert_register("processors",
-                      wolf::converter<std::string>::convert(map_container));
-      map_container.clear();
-    } catch(YAML::InvalidNode& e){
-      throw std::runtime_error("Error parsing processors @" + generatePath(file) + ". Please make sure that each processor has 'type', 'name', 'plugin' and 'sensor_name' entries.");
-    }
-    try {
-      for (const auto &kv : n_config["ROS subscriber"]) {
-          SubscriberManager pSubscriberManager = {kv["package"].Scalar(), kv["type"].Scalar(), kv["topic"].Scalar(), kv["sensor_name"].Scalar(), kv};
-          _subscriber_managers.push_back(pSubscriberManager);
-          map_container.push_back(std::map<std::string, std::string>({
-                                                                      {"package", kv["package"].Scalar()},
-                                                                      {"type", kv["type"].Scalar()},
-                                                                      {"topic", kv["topic"].Scalar()},
-                                                                      {"sensor_name", kv["sensor_name"].Scalar()}}));
-      }
-      insert_register("ROS subscriber", wolf::converter<std::string>::convert(map_container));
-      map_container.clear();
-    } catch (YAML::InvalidNode &e) {
-        throw std::runtime_error("Error parsing subscriber @" + generatePath(file) + ". Please make sure that each manager has 'package', 'type', 'topic' and 'sensor_name' entries.");
-    }
-
-    try {
-      for (const auto &kv : n_config["ROS publisher"]) {
-        WOLF_DEBUG("WHAT");
-          PublisherManager pPublisherManager = {kv["type"].Scalar(), kv["topic"].Scalar(), kv["period"].Scalar(), kv};
-          _publisher_managers.push_back(pPublisherManager);
-          map_container.push_back(std::map<std::string, std::string>({
-                                                                      {"type", kv["type"].Scalar()},
-                                                                      {"topic", kv["topic"].Scalar()},
-                                                                      {"period", kv["period"].Scalar()}}));
-      }
-      insert_register("ROS publisher", wolf::converter<std::string>::convert(map_container));
-      map_container.clear();
-    } catch (YAML::InvalidNode &e) {
-        throw std::runtime_error("Error parsing publisher @" + generatePath(file) + ". Please make sure that each manager has 'type', 'topic' and 'period' entries.");
-    }
-}
-std::map<std::string,std::string> ParserYAML::getParams(){
-    std::map<std::string,std::string> rtn = _params;
-    return rtn;
-}
-void ParserYAML::parse(){
-    this->_parsing_file.push(generatePath(this->_file));
-    this->parseFirstLevel(this->_file);
-
-    if(this->problem.Type() != YAML::NodeType::Undefined){
-      std::vector<std::string> tags = std::vector<std::string>();
-      this->walkTreeR(this->problem, tags , "problem");
-    }
-    for(auto it : _paramsSens){
-      std::vector<std::string> tags = std::vector<std::string>();
-      tags.push_back("sensor");
-      this->walkTreeR(it.n , tags , "sensor/" + it._name);
-    }
-    for(auto it : _paramsProc){
-      std::vector<std::string> tags = std::vector<std::string>();
-      tags.push_back("processor");
-      this->walkTreeR(it.n , tags , "processor/" + it._name);
-    }
-    std::list<std::string> plugins, packages;
-    for (const auto& it : this->_paramsSens)
-        plugins.push_back(it._plugin);
-    for (const auto& it : this->_paramsProc)
-        plugins.push_back(it._plugin);
-    for (const auto& it : this->_subscriber_managers)
-        packages.push_back(it._package);
-    plugins.sort();
-    plugins.unique();
-    packages.sort();
-    packages.unique();
-    insert_register("plugins", wolf::converter<std::string>::convert(plugins));
-    insert_register("packages", wolf::converter<std::string>::convert(packages));
-
-    YAML::Node n;
-    n = loadYAML(generatePath(this->_file));
-
-    if (n.Type() == YAML::NodeType::Map)
-        {
-            for (auto it : n)
-                {
-                    auto node = it.second;
-                    // WOLF_INFO("WUT ", it.first);
-                    std::vector<std::string> tags = std::vector<std::string>();
-                    if(it.first.as<std::string>() != "config")
-                        this->walkTreeR(node, tags, it.first.as<std::string>());
-                    else
-                        {
-                            for (auto itt : node)
-                                {
-                                    std::string node_key = itt.first.as<std::string>();
-                                    if (node_key != "problem" and node_key != "sensors" and node_key != "processors" and
-                                        node_key != "ROS subscriber" and node_key != "ROS publisher")
-                                        {
-                                            this->walkTreeR(itt.second, tags, node_key);
-                                        }
-                                }
-                        }
-                }
-        }else
-        {
-            std::vector<std::string> tags = std::vector<std::string>();
-            this->walkTreeR(n, tags, "");
-        }
-    this->_parsing_file.pop();
-    }
-void ParserYAML::parse_freely(){
-    this->_parsing_file.push(generatePath(this->_file));
-    std::vector<std::string> tags = std::vector<std::string>();
-    this->walkTreeR(loadYAML(this->_file), tags, "");
-    this->_parsing_file.pop();
-}
-void ParserYAML::insert_register(std::string key, std::string value){
-    if(key.substr(0,1) == "/") key = key.substr(1,key.size()-1);
-  auto inserted_it = _params.insert(std::pair<std::string, std::string>(key, value));
-  if(not inserted_it.second) WOLF_WARN("Skipping key '", key, "' with value '", value, "'. There already exists the register: (", inserted_it.first->first, ",", inserted_it.first->second, ")");
-}
-#endif
diff --git a/src/capture/capture_base.cpp b/src/capture/capture_base.cpp
index 54e5d2a3cdedb301a7580e691cad9543df3c24c2..d07b9b055d8197593dbdde99d05f6a4eddd46bfe 100644
--- a/src/capture/capture_base.cpp
+++ b/src/capture/capture_base.cpp
@@ -130,6 +130,22 @@ void CaptureBase::removeConstrainedBy(FactorBasePtr _fac_ptr)
     constrained_by_list_.remove(_fac_ptr);
 }
 
+bool CaptureBase::isConstrainedBy(const FactorBasePtr &_factor) const
+{
+    FactorBaseConstIter cby_it = std::find_if(constrained_by_list_.begin(),
+                                              constrained_by_list_.end(),
+                                              [_factor](const FactorBasePtr & cby)
+                                              {
+                                                 return cby == _factor;
+                                              }
+                                              );
+    if (cby_it != constrained_by_list_.end())
+        return true;
+    else
+        return false;
+}
+
+
 const std::string& CaptureBase::getStructure() const
 {
     if (getSensor())
diff --git a/src/ceres_wrapper/ceres_manager.cpp b/src/ceres_wrapper/ceres_manager.cpp
index ecf57e7d7e29b4b8ccfecf09f8c39d8eacdafdbb..0d8cba6f97cb7e2c2cdf067e7ebcb65d8ac79c10 100644
--- a/src/ceres_wrapper/ceres_manager.cpp
+++ b/src/ceres_wrapper/ceres_manager.cpp
@@ -443,6 +443,77 @@ void CeresManager::check()
     }
 }
 
+void insertSparseBlock(const Eigen::MatrixXd& ins, Eigen::SparseMatrixd& original, const unsigned int& row, const unsigned int& col)
+{
+    for (auto ins_row = 0; ins_row < ins.rows(); ins_row++)
+        for (auto ins_col = 0; ins_col < ins.cols(); ins_col++)
+            original.insert(row+ins_row, col+ins_col) = ins(ins_row,ins_col);
+
+    original.makeCompressed();
+}
+
+const Eigen::SparseMatrixd CeresManager::computeHessian() const
+{
+    Eigen::SparseMatrixd H;
+    Eigen::SparseMatrixd A;
+    // fac_2_residual_idx_
+    // fac_2_costfunction_
+    // state_blocks_local_param_
+    int ix_row = 0;  // index of the factor/measurement in the 
+    for (auto fac_res_pair: fac_2_residual_idx_){
+        FactorBasePtr fac_ptr = fac_res_pair.first;
+        ix_row += fac_ptr->getSize();
+
+        // retrieve all stateblocks data related to this factor
+        std::vector<const double*> fac_states_ptr;
+        for (auto sb : fac_res_pair.first->getStateBlockPtrVector()){
+            fac_states_ptr.push_back(sb->getStateData());
+        }
+        
+        // retrieve residual value, not used afterwards in this case since we just care about jacobians
+        Eigen::VectorXd residual(fac_ptr->getSize());
+        // retrieve jacobian in group size, not local size
+        std::vector<Eigen::MatrixXd> jacobians;
+        fac_ptr->evaluate(fac_states_ptr, residual, jacobians);
+
+        // Retrieve the block row sparse matrix of this factor
+        Eigen::SparseMatrixd A_block_row(fac_ptr->getSize(), A.cols());
+        for (auto i = 0; i < jacobians.size(); i++)
+        {
+            StateBlockPtr sb = fac_ptr->getStateBlockPtrVector()[i];
+            if (!sb->isFixed())
+            {
+                assert((state_blocks_local_param_.find(sb) != state_blocks_local_param_.end()) && "factor involving a state block not added");
+                assert((A.cols() >= sb->getLocalSize() + jacobians[i].cols()) - 1 && "bad A number of cols");
+
+                // insert since A_block_row has just been created so it's empty for sure
+                if (sb->hasLocalParametrization()){
+                    // if the state block has a local parameterization, we need to right multiply by the manifold element / tangent element jacobian
+                    Eigen::MatrixXd J_manif_tang(sb->getSize(), sb->getLocalSize());
+                    Eigen::Map<Eigen::MatrixRowXd> J_manif_tang_map(J_manif_tang.data(), sb->getSize(), sb->getLocalSize());
+                    Eigen::Map<const Eigen::VectorXd> sb_state_map(sb->getStateData(), sb->getSize());
+
+                    sb->getLocalParametrization()->computeJacobian(sb_state_map, J_manif_tang_map);
+                    insertSparseBlock(jacobians[i] * J_manif_tang, A_block_row, 0, sb->getLocalSize());  // (to_insert, matrix_to_fill, row, col)
+                }
+                else {
+                    insertSparseBlock(jacobians[i], A_block_row, 0, sb->getLocalSize());
+                }
+            }
+        }
+        
+        // fill the weighted jacobian matrix block row
+        A.block(ix_row, 0, fac_ptr->getSize(), A.cols());
+
+    }
+
+    // compute the hessian matrix from the weighted jacobian 
+    H = A.transpose() * A;
+
+    return H;
+}
+
+
 } // namespace wolf
 #include "core/solver/solver_factory.h"
 namespace wolf {
diff --git a/src/factor/factor_base.cpp b/src/factor/factor_base.cpp
index 46b244d9e83f9c01f4fca0bf84af35d81d36d53f..72b36c519a0d8d0ce2cb7ac4748e0dfc110026d0 100644
--- a/src/factor/factor_base.cpp
+++ b/src/factor/factor_base.cpp
@@ -19,15 +19,52 @@ FactorBase::FactorBase(const std::string&  _tp,
     factor_id_(++factor_id_count_),
     status_(_status),
     apply_loss_function_(_apply_loss_function),
-    frame_other_ptr_(_frame_other_ptr),
-    capture_other_ptr_(_capture_other_ptr),
-    feature_other_ptr_(_feature_other_ptr),
-    landmark_other_ptr_(_landmark_other_ptr),
+    frame_other_list_(),
+    capture_other_list_(),
+    feature_other_list_(),
+    landmark_other_list_(),
     processor_ptr_(_processor_ptr)
 {
-//    std::cout << "constructed        +c" << id() << std::endl;
+    if (_frame_other_ptr)
+        frame_other_list_.push_back(_frame_other_ptr);
+    if (_capture_other_ptr)
+        capture_other_list_.push_back(_capture_other_ptr);
+    if (_feature_other_ptr)
+        feature_other_list_.push_back(_feature_other_ptr);
+    if (_landmark_other_ptr)
+        landmark_other_list_.push_back(_landmark_other_ptr);
 }
 
+FactorBase::FactorBase(const std::string&  _tp,
+                       const FrameBasePtrList& _frame_other_list,
+                       const CaptureBasePtrList& _capture_other_list,
+                       const FeatureBasePtrList& _feature_other_list,
+                       const LandmarkBasePtrList& _landmark_other_list,
+                       const ProcessorBasePtr& _processor_ptr,
+                       bool _apply_loss_function,
+                       FactorStatus _status) :
+            NodeBase("FACTOR", _tp),
+            feature_ptr_(),
+            factor_id_(++factor_id_count_),
+            status_(_status),
+            apply_loss_function_(_apply_loss_function),
+            frame_other_list_(),
+            capture_other_list_(),
+            feature_other_list_(),
+            landmark_other_list_(),
+            processor_ptr_(_processor_ptr)
+{
+    for (auto& Fo : _frame_other_list)
+        frame_other_list_.push_back(Fo);
+    for (auto& Co : _capture_other_list)
+        capture_other_list_.push_back(Co);
+    for (auto& fo : _feature_other_list)
+        feature_other_list_.push_back(fo);
+    for (auto& Lo : landmark_other_list_)
+        landmark_other_list_.push_back(Lo);
+}
+
+
 void FactorBase::remove(bool viral_remove_empty_parent)
 {
     if (!is_removing_)
@@ -46,36 +83,48 @@ void FactorBase::remove(bool viral_remove_empty_parent)
             getProblem()->notifyFactor(this_fac,REMOVE);
 
         // remove other: {Frame, Capture, Feature, Landmark}
-        FrameBasePtr frm_o = frame_other_ptr_.lock();
-        if (frm_o)
+        for (auto& frm_ow : frame_other_list_)
         {
-            frm_o->removeConstrainedBy(this_fac);
-            if (frm_o->getConstrainedByList().empty() && frm_o->getCaptureList().empty())
-                frm_o->remove(viral_remove_empty_parent);
+            auto frm_o = frm_ow.lock();
+            if (frm_o)
+            {
+                frm_o->removeConstrainedBy(this_fac);
+                if (frm_o->getConstrainedByList().empty() && frm_o->getCaptureList().empty())
+                    frm_o->remove(viral_remove_empty_parent);
+            }
         }
 
-        CaptureBasePtr cap_o = capture_other_ptr_.lock();
-        if (cap_o)
+        for (auto& cap_ow : capture_other_list_)
         {
-            cap_o->removeConstrainedBy(this_fac);
-            if (cap_o->getConstrainedByList().empty() && cap_o->getFeatureList().empty())
-                cap_o->remove(viral_remove_empty_parent);
+            auto cap_o = cap_ow.lock();
+            if (cap_o)
+            {
+                cap_o->removeConstrainedBy(this_fac);
+                if (cap_o->getConstrainedByList().empty() && cap_o->getFeatureList().empty())
+                    cap_o->remove(viral_remove_empty_parent);
+            }
         }
 
-        FeatureBasePtr ftr_o = feature_other_ptr_.lock();
-        if (ftr_o)
+        for (auto& ftr_ow : feature_other_list_)
         {
-            ftr_o->removeConstrainedBy(this_fac);
-            if (ftr_o->getConstrainedByList().empty() && ftr_o->getFactorList().empty())
-                ftr_o->remove(viral_remove_empty_parent);
+            auto ftr_o = ftr_ow.lock();
+            if (ftr_o)
+            {
+                ftr_o->removeConstrainedBy(this_fac);
+                if (ftr_o->getConstrainedByList().empty() && ftr_o->getFactorList().empty())
+                    ftr_o->remove(viral_remove_empty_parent);
+            }
         }
 
-        LandmarkBasePtr lmk_o = landmark_other_ptr_.lock();
-        if (lmk_o)
+        for (auto& lmk_ow : landmark_other_list_)
         {
-            lmk_o->removeConstrainedBy(this_fac);
-            if (lmk_o->getConstrainedByList().empty())
-                lmk_o->remove(viral_remove_empty_parent);
+            auto lmk_o = lmk_ow.lock();
+            if (lmk_o)
+            {
+                lmk_o->removeConstrainedBy(this_fac);
+                if (lmk_o->getConstrainedByList().empty())
+                    lmk_o->remove(viral_remove_empty_parent);
+            }
         }
 
         //        std::cout << "Removed             c" << id() << std::endl;
@@ -106,6 +155,18 @@ CaptureBasePtr FactorBase::getCapture() const
     return getFeature()->getCapture();
 }
 
+FrameBasePtr FactorBase::getFrame() const
+{
+    assert(getCapture() != nullptr && "calling getFrame before linking with a capture");
+    return getCapture()->getFrame();
+}
+
+SensorBasePtr FactorBase::getSensor() const
+{
+    assert(getCapture() != nullptr && "calling getSensor before linking with a capture");
+    return getCapture()->getSensor();
+}
+
 void FactorBase::setStatus(FactorStatus _status)
 {
     if (getProblem() == nullptr)
@@ -120,6 +181,66 @@ void FactorBase::setStatus(FactorStatus _status)
     status_ = _status;
 }
 
+bool FactorBase::hasFrameOther(const FrameBasePtr &_frm_other) const
+{
+    FrameBaseWConstIter frm_it = find_if(frame_other_list_.begin(),
+                                         frame_other_list_.end(),
+                                         [_frm_other](const FrameBaseWPtr &frm_ow)
+                                         {
+                                             return frm_ow.lock() == _frm_other;
+                                         }
+    );
+    if (frm_it != frame_other_list_.end())
+        return true;
+
+    return false;
+}
+
+bool FactorBase::hasCaptureOther(const CaptureBasePtr &_cap_other) const
+{
+    CaptureBaseWConstIter cap_it = find_if(capture_other_list_.begin(),
+                                           capture_other_list_.end(),
+                                           [_cap_other](const CaptureBaseWPtr &cap_ow)
+                                           {
+                                               return cap_ow.lock() == _cap_other;
+                                           }
+    );
+    if (cap_it != capture_other_list_.end())
+        return true;
+
+    return false;
+}
+
+bool FactorBase::hasFeatureOther(const FeatureBasePtr &_ftr_other) const
+{
+    FeatureBaseWConstIter ftr_it = find_if(feature_other_list_.begin(),
+                                           feature_other_list_.end(),
+                                           [_ftr_other](const FeatureBaseWPtr &ftr_ow)
+                                           {
+                                               return ftr_ow.lock() == _ftr_other;
+                                           }
+    );
+    if (ftr_it != feature_other_list_.end())
+        return true;
+
+    return false;
+}
+
+bool FactorBase::hasLandmarkOther(const LandmarkBasePtr &_lmk_other) const
+{
+    LandmarkBaseWConstIter lmk_it = find_if(landmark_other_list_.begin(),
+                                            landmark_other_list_.end(),
+                                            [_lmk_other](const LandmarkBaseWPtr &lmk_ow)
+                                            {
+                                                return lmk_ow.lock() == _lmk_other;
+                                            }
+                                            );
+    if (lmk_it != landmark_other_list_.end())
+        return true;
+
+    return false;
+}
+
 //void FactorBase::setApplyLossFunction(const bool _apply)
 //{
 //    apply_loss_function_ = _apply;
@@ -146,14 +267,26 @@ void FactorBase::link(FeatureBasePtr _ftr_ptr)
     this->setProblem(_ftr_ptr->getProblem());
 
     // constrained by
-    auto frame_other = this->frame_other_ptr_.lock();
-    if(frame_other != nullptr) frame_other->addConstrainedBy(shared_from_this());
-    auto capture_other = this->capture_other_ptr_.lock();
-    if(capture_other != nullptr) capture_other->addConstrainedBy(shared_from_this());
-    auto feature_other = this->feature_other_ptr_.lock();
-    if(feature_other != nullptr) feature_other->addConstrainedBy(shared_from_this());
-    auto landmark_other = this->landmark_other_ptr_.lock();
-    if(landmark_other != nullptr) landmark_other->addConstrainedBy(shared_from_this());
+    for (auto& frm_ow : frame_other_list_)
+    {
+        auto frame_other = frm_ow.lock();
+        if(frame_other != nullptr) frame_other->addConstrainedBy(shared_from_this());
+    }
+    for (auto& cap_ow : capture_other_list_)
+    {
+        auto capture_other = cap_ow.lock();
+        if(capture_other != nullptr) capture_other->addConstrainedBy(shared_from_this());
+    }
+    for (auto& ftr_ow : feature_other_list_)
+    {
+        auto feature_other = ftr_ow.lock();
+        if(feature_other != nullptr) feature_other->addConstrainedBy(shared_from_this());
+    }
+    for (auto& lmk_ow : landmark_other_list_)
+    {
+        auto landmark_other = lmk_ow.lock();
+        if(landmark_other != nullptr) landmark_other->addConstrainedBy(shared_from_this());
+    }
 }
 
 void FactorBase::setProblem(ProblemPtr _problem)
diff --git a/src/feature/feature_base.cpp b/src/feature/feature_base.cpp
index df5d1f1e7aa0f214adab2e0f74dc496623e7cf48..8dc3801efa5f93e5bd0df593442e4860cb75135e 100644
--- a/src/feature/feature_base.cpp
+++ b/src/feature/feature_base.cpp
@@ -92,6 +92,21 @@ void FeatureBase::removeConstrainedBy(FactorBasePtr _fac_ptr)
     constrained_by_list_.remove(_fac_ptr);
 }
 
+bool FeatureBase::isConstrainedBy(const FactorBasePtr &_factor) const
+{
+    FactorBaseConstIter cby_it = std::find_if(constrained_by_list_.begin(),
+                                              constrained_by_list_.end(),
+                                              [_factor](const FactorBasePtr & cby)
+                                              {
+                                                 return cby == _factor;
+                                              }
+                                              );
+    if (cby_it != constrained_by_list_.end())
+        return true;
+    else
+        return false;
+}
+
 const FactorBasePtrList& FeatureBase::getFactorList() const
 {
     return factor_list_;
diff --git a/src/frame/frame_base.cpp b/src/frame/frame_base.cpp
index 85f94bd2a97af8a68e4b1551d3352daa8e8906d8..c0f4d310e1062c9a68ea94a0ee0b70f912cd9d15 100644
--- a/src/frame/frame_base.cpp
+++ b/src/frame/frame_base.cpp
@@ -64,14 +64,14 @@ FrameBase::FrameBase(const std::string _frame_structure, const SizeEigen _dim, c
            time_stamp_(_ts)
 {
     if(_frame_structure.compare("PO") == 0 and _dim == 2){
-        assert(_x.size() == 3 && "Wrong state vector size. Should be 3 for 2d!");
+        assert(_x.size() == 3 && "Wrong state vector size. Should be 3 for PO 2D!");
         StateBlockPtr p_ptr ( std::make_shared<StateBlock>    (_x.head    <2> ( ) ) );
         StateBlockPtr o_ptr ( std::make_shared<StateAngle>    ((double) _x(2) ) );
         addStateBlock("P", p_ptr);
         addStateBlock("O", o_ptr);
         this->setType("PO 2d");
     }else if(_frame_structure.compare("PO") == 0 and _dim == 3){
-        assert(_x.size() == 7 && "Wrong state vector size. Should be 7 for 3d!");
+        assert(_x.size() == 7 && "Wrong state vector size. Should be 7 for PO 3D!");
         StateBlockPtr p_ptr ( std::make_shared<StateBlock>      (_x.head    <3> ( ) ) );
         StateBlockPtr o_ptr ( std::make_shared<StateQuaternion> (_x.tail    <4> ( ) ) );
         addStateBlock("P", p_ptr);
@@ -79,7 +79,7 @@ FrameBase::FrameBase(const std::string _frame_structure, const SizeEigen _dim, c
         this->setType("PO 3d");
     }else if(_frame_structure.compare("POV") == 0 and _dim == 3){
         // auto _x = Eigen::VectorXd::Zero(10);
-        assert(_x.size() == 10 && "Wrong state vector size. Should be 10 for 3d!");
+        assert(_x.size() == 10 && "Wrong state vector size. Should be 10 for POV 3D!");
         StateBlockPtr p_ptr ( std::make_shared<StateBlock>      (_x.head    <3> ( ) ) );
         StateBlockPtr o_ptr ( std::make_shared<StateQuaternion> (_x.segment <4> (3) ) );
         StateBlockPtr v_ptr ( std::make_shared<StateBlock>      (_x.tail    <3> ( ) ) );
@@ -87,6 +87,22 @@ FrameBase::FrameBase(const std::string _frame_structure, const SizeEigen _dim, c
         addStateBlock("O", o_ptr);
         addStateBlock("V", v_ptr);
         this->setType("POV 3d");
+    }else if(_frame_structure.compare("POVCDL") == 0 and _dim == 3){
+        // auto _x = Eigen::VectorXd::Zero(10);
+        assert(_x.size() == 19 && "Wrong state vector size. Should be 19 for POVCDL 3D!");
+        StateBlockPtr p_ptr ( std::make_shared<StateBlock>      (_x.head    <3> (  ) ) );
+        StateBlockPtr o_ptr ( std::make_shared<StateQuaternion> (_x.segment <4> (3 ) ) );
+        StateBlockPtr v_ptr ( std::make_shared<StateBlock>      (_x.segment <3> (7 ) ) );
+        StateBlockPtr c_ptr ( std::make_shared<StateBlock>      (_x.segment <3> (10) ) );
+        StateBlockPtr cd_ptr ( std::make_shared<StateBlock>      (_x.segment <3> (13) ) );
+        StateBlockPtr Lc_ptr ( std::make_shared<StateBlock>      (_x.segment <3> (16) ) );
+        addStateBlock("P", p_ptr);
+        addStateBlock("O", o_ptr);
+        addStateBlock("V", v_ptr);
+        addStateBlock("C", c_ptr);
+        addStateBlock("D", cd_ptr);
+        addStateBlock("L", Lc_ptr);
+        this->setType("POVCDL 3d");
     }else{
         std::cout << _frame_structure << " ^^ " << _dim << std::endl;
         throw std::runtime_error("Unknown frame structure");
@@ -298,6 +314,21 @@ void FrameBase::removeConstrainedBy(FactorBasePtr _fac_ptr)
     constrained_by_list_.remove(_fac_ptr);
 }
 
+bool FrameBase::isConstrainedBy(const FactorBasePtr &_factor) const
+{
+    FactorBaseConstIter cby_it = std::find_if(constrained_by_list_.begin(),
+                                              constrained_by_list_.end(),
+                                              [_factor](const FactorBasePtr & cby)
+                                              {
+                                                 return cby == _factor;
+                                              }
+    );
+    if (cby_it != constrained_by_list_.end())
+        return true;
+    else
+        return false;
+}
+
 void FrameBase::link(TrajectoryBasePtr _trj_ptr)
 {
     assert(!is_removing_ && "linking a removed frame");
diff --git a/src/landmark/landmark_base.cpp b/src/landmark/landmark_base.cpp
index 7c9b8b664573bd296902ad420c1e5a161605e635..bc57f27294e6a0b05d67cbcf44725dd2b819f63b 100644
--- a/src/landmark/landmark_base.cpp
+++ b/src/landmark/landmark_base.cpp
@@ -138,6 +138,21 @@ void LandmarkBase::removeConstrainedBy(FactorBasePtr _fac_ptr)
     constrained_by_list_.remove(_fac_ptr);
 }
 
+bool LandmarkBase::isConstrainedBy(const FactorBasePtr &_factor) const
+{
+    FactorBaseConstIter cby_it = std::find_if(constrained_by_list_.begin(),
+                                              constrained_by_list_.end(),
+                                              [_factor](const FactorBasePtr & cby)
+                                              {
+                                                 return cby == _factor;
+                                              }
+                                              );
+    if (cby_it != constrained_by_list_.end())
+        return true;
+    else
+        return false;
+}
+
 LandmarkBasePtr LandmarkBase::create(const YAML::Node& _node)
 {
     unsigned int    id          = _node["id"]               .as< unsigned int     >();
diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp
index 550118c396c94561ce398d4cc1b9f3b2f8b31ed4..747737dc1ff0ea4b742a97017065d229889ea7d6 100644
--- a/src/problem/problem.cpp
+++ b/src/problem/problem.cpp
@@ -12,10 +12,15 @@
 #include "core/processor/processor_factory.h"
 #include "core/state_block/state_block.h"
 #include "core/tree_manager/factory_tree_manager.h"
+#include "core/tree_manager/tree_manager_base.h"
 #include "core/utils/logging.h"
-#include "core/utils/params_server.hpp"
-#include "core/utils/loader.hpp"
-#include "core/utils/check_log.hpp"
+#include "core/utils/params_server.h"
+#include "core/utils/loader.h"
+#include "core/utils/check_log.h"
+
+// IRI libs includes
+
+// C++ includes
 #include <algorithm>
 #include <map>
 #include <sstream>
@@ -24,7 +29,6 @@
 #include <vector>
 #include <unordered_set>
 
-#include "../../include/core/tree_manager/tree_manager_base.h"
 
 namespace wolf
 {
@@ -34,25 +38,27 @@ Problem::Problem(const std::string& _frame_structure, SizeEigen _dim) :
         hardware_ptr_(std::make_shared<HardwareBase>()),
         trajectory_ptr_(std::make_shared<TrajectoryBase>(_frame_structure)),
         map_ptr_(std::make_shared<MapBase>()),
-        processor_motion_ptr_(),
+        processor_is_motion_list_(std::list<IsMotionPtr>()),
         prior_is_set_(false),
         frame_structure_(_frame_structure)
 {
+    dim_ = _dim;
     if (_frame_structure == "PO" and _dim == 2)
     {
         state_size_ = 3;
         state_cov_size_ = 3;
-        dim_ = 2;
     }else if (_frame_structure == "PO" and _dim == 3)
     {
         state_size_ = 7;
         state_cov_size_ = 6;
-        dim_ = 3;
-    } else if (_frame_structure == "POV" and _dim == 3)
+    }else if (_frame_structure == "POV" and _dim == 3)
     {
         state_size_ = 10;
         state_cov_size_ = 9;
-        dim_ = 3;
+    }else if (_frame_structure == "POVCDL" and _dim == 3)
+    {
+        state_size_ = 19;
+        state_cov_size_ = 18;
     }
     else std::runtime_error(
             "Problem::Problem(): Unknown frame structure. Add appropriate frame structure to the switch statement.");
@@ -231,7 +237,7 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, //
     //Dimension check
     int prc_dim = prc_ptr->getDim();
     auto prb = this;
-    assert((prc_dim == 0 or prc_dim == prb->getDim()) && "Processor and Problem do not agree on dimension");
+    assert(((prc_dim == 0) or (prc_dim == prb->getDim())) && "Processor and Problem do not agree on dimension");
 
     prc_ptr->configure(_corresponding_sensor_ptr);
     prc_ptr->link(_corresponding_sensor_ptr);
@@ -240,10 +246,6 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, //
     if (prc_ptr->isMotion() && prior_is_set_)
         (std::static_pointer_cast<ProcessorMotion>(prc_ptr))->setOrigin(getLastKeyFrame());
 
-    // setting the main processor motion
-    if (prc_ptr->isMotion() && processor_motion_ptr_ == nullptr)
-        processor_motion_ptr_ = std::dynamic_pointer_cast<IsMotion>(prc_ptr);
-
     return prc_ptr;
 }
 
@@ -279,7 +281,7 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, //
     //Dimension check
     int prc_dim = prc_ptr->getDim();
     auto prb = this;
-    assert((prc_dim == 0 or prc_dim == prb->getDim()) && "Processor and Problem do not agree on dimension");
+    assert(((prc_dim == 0) or (prc_dim == prb->getDim())) && "Processor and Problem do not agree on dimension");
 
     prc_ptr->configure(sen_ptr);
     prc_ptr->link(sen_ptr);
@@ -289,10 +291,6 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, //
     if (prc_ptr->isMotion() && prior_is_set_)
         (std::static_pointer_cast<ProcessorMotion>(prc_ptr))->setOrigin(getLastKeyFrame());
 
-    // setting the main processor motion
-    if (prc_ptr->isMotion() && processor_motion_ptr_ == nullptr)
-        processor_motion_ptr_ = std::static_pointer_cast<ProcessorMotion>(prc_ptr);
-
     return prc_ptr;
 }
 
@@ -311,47 +309,6 @@ SensorBasePtr Problem::getSensor(const std::string& _sensor_name) const
     return (*sen_it);
 }
 
-IsMotionPtr Problem::setProcessorMotion(const std::string& _processor_name)
-{
-    for (auto sen : getHardware()->getSensorList()) // loop all sensors
-    {
-        auto prc_it = std::find_if(sen->getProcessorList().begin(), // find processor by its name
-                                   sen->getProcessorList().end(),
-                                   [&](ProcessorBasePtr prc)
-                                   {
-                                       return prc->getName() == _processor_name;
-                                   }); // lambda function for the find_if
-
-        if (prc_it != sen->getProcessorList().end())  // found something!
-        {
-            if ((*prc_it)->isMotion()) // found, and it's motion!
-            {
-                std::cout << "Found processor '" << _processor_name << "', of type Motion, and set as the main motion processor." << std::endl;
-                processor_motion_ptr_ = std::dynamic_pointer_cast<IsMotion>(*prc_it);
-                return processor_motion_ptr_;
-            }
-            else // found, but it's not motion!
-            {
-                std::cout << "Found processor '" << _processor_name << "', but not of type Motion!" << std::endl;
-                return nullptr;
-            }
-        }
-    }
-    // nothing found!
-    std::cout << "Processor '" << _processor_name << "' not found!" << std::endl;
-    return nullptr;
-}
-
-void Problem::setProcessorMotion(IsMotionPtr _processor_motion_ptr)
-{
-    processor_motion_ptr_ = _processor_motion_ptr;
-}
-
-void Problem::clearProcessorMotion()
-{
-    processor_motion_ptr_.reset();
-}
-
 FrameBasePtr Problem::emplaceFrame(const std::string& _frame_structure, //
                                    const SizeEigen _dim, //
                                    FrameType _frame_key_type, //
@@ -392,41 +349,108 @@ Eigen::VectorXd Problem::getCurrentState() const
 
 void Problem::getCurrentState(Eigen::VectorXd& _state) const
 {
-    if (processor_motion_ptr_ != nullptr)
-        processor_motion_ptr_->getCurrentState(_state);
-    else if (trajectory_ptr_->getLastKeyOrAuxFrame() != nullptr)
-        trajectory_ptr_->getLastKeyOrAuxFrame()->getState(_state);
-    else
-        _state = zeroState();
+    TimeStamp ts;  // throwaway timestamp
+    getCurrentStateAndStamp(_state, ts);
 }
 
-void Problem::getCurrentStateAndStamp(Eigen::VectorXd& _state, TimeStamp& ts) const
-{
-    if (processor_motion_ptr_ != nullptr)
+void Problem::getCurrentStateAndStamp(Eigen::VectorXd& _state, TimeStamp& _ts) const
+{   
+    if (!processor_is_motion_list_.empty())
     {
-        processor_motion_ptr_->getCurrentState(_state);
-        processor_motion_ptr_->getCurrentTimeStamp(ts);
+        // retrieve the minimum of the most recent ts in all processor is motion then call getSate(ts, state)
+        std::list<TimeStamp> proc_is_motion_current_ts;
+        for (auto proc: processor_is_motion_list_){
+            proc_is_motion_current_ts.push_back(proc->getCurrentTimeStamp());
+        }
+        auto min_it = std::min_element(proc_is_motion_current_ts.begin(), proc_is_motion_current_ts.end());
+        getState(*min_it, _state);
+        _ts = *min_it;
     }
     else if (trajectory_ptr_->getLastKeyOrAuxFrame() != nullptr)
     {
-        trajectory_ptr_->getLastKeyOrAuxFrame()->getTimeStamp(ts);
+        // kind of redundant with getState(_ts, _state)
+        trajectory_ptr_->getLastKeyOrAuxFrame()->getTimeStamp(_ts);
         trajectory_ptr_->getLastKeyOrAuxFrame()->getState(_state);
     }
     else
         _state = zeroState();
 }
 
+
+// Problem of this implmentation: if more state
 void Problem::getState(const TimeStamp& _ts, Eigen::VectorXd& _state) const
 {
-    // try to get the state from processor_motion if any, otherwise...
-    if (processor_motion_ptr_ == nullptr || !processor_motion_ptr_->getState(_ts, _state))
-    {
-        FrameBasePtr closest_frame = trajectory_ptr_->closestKeyOrAuxFrameToTimeStamp(_ts);
+    // if _ts is too recent, for some of the processor is motion, they return the state corresponding to their last frame timestamp
+    FrameBasePtr closest_frame = trajectory_ptr_->closestKeyOrAuxFrameToTimeStamp(_ts);
+    if (processor_is_motion_list_.empty()){
         if (closest_frame != nullptr)
-            closest_frame->getState(_state);
+            _state = closest_frame->getState();
         else
             _state = zeroState();
     }
+
+    // RETRIEVE FROM PROCESSOR MOTION
+    // TODO: current implementation messy, would be much easier with a state being an std::unordered_map
+    else {
+        // Iterate over the problem state structure and get the corresponding state
+        // in the first processor is motion that provides it
+        // finally check if the state to concatenate list has the same total size as the problem state_size 
+        
+        // an map is necessary as a temporary structure because we do not know in which order we will find the state blocks in processors 
+        std::unordered_map<char, Eigen::VectorXd> states_to_concat_map;  // not necessary to be ordered
+        for (auto proc: processor_is_motion_list_){
+            Eigen::VectorXd proc_state = proc->getState(_ts);
+
+            int idx = 0;
+            for (char sb_name: proc->getStateStructure()){
+                // not already there
+                if (states_to_concat_map.find(sb_name) == states_to_concat_map.end()){
+                    if (sb_name == 'O'){
+                        int size_sb = dim_ == 3 ? 4 : 1;  // really bad: should be more transparent
+                        states_to_concat_map[sb_name] = proc_state.segment(idx, size_sb);
+                        idx += size_sb;
+                    }
+                    else{
+                        int size_sb = dim_ == 3 ? 3 : 2;
+                        states_to_concat_map[sb_name] = proc_state.segment(idx, size_sb);
+                        idx += size_sb;
+                    } 
+                }
+            }
+        }
+
+        int concat_size = 0;
+        for (auto state_map_it: states_to_concat_map){
+            concat_size += state_map_it.second.size();
+        }
+        // assert(concat_size == state_size_  && "Problem with the concatenated size: " );
+
+        // fill the state value from the state concatenation in the order dictated by frame_structure_
+        int idx = 0;
+        _state.resize(state_size_);
+        for (char sb_name: frame_structure_){
+            Eigen::VectorXd sb_state;
+            int size_sb;  // really bad...
+            if (sb_name == 'O'){
+                size_sb = dim_ == 3 ? 4 : 1;
+            }
+            else {
+                size_sb = dim_ == 3 ? 3 : 2;
+            }
+            if (states_to_concat_map.find(sb_name) != states_to_concat_map.end()){
+                sb_state = states_to_concat_map[sb_name];
+            }
+            else {
+                // Should be taken from the last state but too messy already
+                sb_state.resize(size_sb); 
+                sb_state.setZero();
+            }
+
+            _state.segment(idx, size_sb) = sb_state;
+            idx += size_sb;
+
+        }
+    }
 }
 
 Eigen::VectorXd Problem::getState(const TimeStamp& _ts) const
@@ -462,6 +486,20 @@ void Problem::setTreeManager(TreeManagerBasePtr _gm)
         tree_manager_->setProblem(nullptr);
     tree_manager_ = _gm;
     tree_manager_->setProblem(shared_from_this());
+
+}
+
+void Problem::addProcessorIsMotion(IsMotionPtr _processor_motion_ptr)
+{
+    processor_is_motion_list_.push_back(_processor_motion_ptr);
+}
+
+void Problem::clearProcessorIsMotion(IsMotionPtr proc)
+{
+    auto it = std::find(processor_is_motion_list_.begin(), processor_is_motion_list_.end(), proc);
+    if (it != processor_is_motion_list_.end()){
+        processor_is_motion_list_.erase(it);
+    }
 }
 
 Eigen::VectorXd Problem::zeroState() const
@@ -863,10 +901,16 @@ FrameBasePtr Problem::setPrior(const Eigen::VectorXd& _prior_state, const Eigen:
         // create origin capture with the given state as data
         // Capture fix only takes 3d position and Quaternion orientation
         CapturePosePtr init_capture;
-        if (this->getFrameStructure() == "POV" and this->getDim() == 3)
+        // if (this->getFrameStructure() == "POV" and this->getDim() == 3)
+        //     init_capture = CaptureBase::emplace<CapturePose>(origin_keyframe, _ts, nullptr, _prior_state.head(7), _prior_cov.topLeftCorner(6,6));
+        // else
+        //     init_capture = CaptureBase::emplace<CapturePose>(origin_keyframe, _ts, nullptr, _prior_state, _prior_cov);
+
+        if (this->getDim() == 3)
             init_capture = CaptureBase::emplace<CapturePose>(origin_keyframe, _ts, nullptr, _prior_state.head(7), _prior_cov.topLeftCorner(6,6));
         else
-            init_capture = CaptureBase::emplace<CapturePose>(origin_keyframe, _ts, nullptr, _prior_state, _prior_cov);
+            init_capture = CaptureBase::emplace<CapturePose>(origin_keyframe, _ts, nullptr, _prior_state.head(3), _prior_cov.topLeftCorner(3,3));
+
 
         // emplace feature and factor
         init_capture->emplaceFeatureAndFactor();
@@ -908,218 +952,226 @@ void Problem::saveMap(const std::string& _filename_dot_yaml, const std::string&
     getMap()->save(_filename_dot_yaml, _map_name);
 }
 
-void Problem::print(int depth, std::ostream& stream, bool constr_by, bool metric, bool state_blocks) const
+void Problem::print(int _depth, std::ostream& _stream, bool _constr_by, bool _metric, bool _state_blocks) const
 {
 
-    stream << std::endl;
-    stream << "P: wolf tree status ---------------------" << std::endl;
-    stream << "Hardware" << ((depth < 1) ? ("   -- " + std::to_string(getHardware()->getSensorList().size()) + "S") : "")  << std::endl;
-    if (depth >= 1)
+    _stream << std::endl;
+    _stream << "P: wolf tree status ---------------------" << std::endl;
+    _stream << "Hardware" << ((_depth < 1) ? ("   -- " + std::to_string(getHardware()->getSensorList().size()) + "S") : "")  << std::endl;
+    if (_depth >= 1)
     {
         // Sensors =======================================================================================
         for (auto S : getHardware()->getSensorList())
         {
-            stream << "  Sen" << S->id() << " " << S->getType() << " \"" << S->getName() << "\"";
-            if (depth < 2)
-                stream << " -- " << S->getProcessorList().size() << "p";
-            stream << std::endl;
-            if (metric && state_blocks)
+            _stream << "  Sen" << S->id() << " " << S->getType() << " \"" << S->getName() << "\"";
+            if (_depth < 2)
+                _stream << " -- " << S->getProcessorList().size() << "p";
+            _stream << std::endl;
+            if (_metric && _state_blocks)
             {
-                stream << "    sb: ";
+                _stream << "    sb: ";
                 for (auto& _key : S->getStructure())
                 {
                     auto key = std::string(1,_key);
                     auto sb = S->getStateBlock(key);
-                    stream << key << "[" << (S->isStateBlockDynamic(key) ? "Dyn" : "Sta") << "," << (sb->isFixed() ? "Fix" : "Est") << "] = ( " << sb->getState().transpose() << " ); ";
+                    _stream << key << "[" << (S->isStateBlockDynamic(key) ? "Dyn" : "Sta") << "," << (sb->isFixed() ? "Fix" : "Est") << "] = ( " << sb->getState().transpose() << " ); ";
                 }
-                stream << std::endl;
+                _stream << std::endl;
             }
-            else if (metric)
+            else if (_metric)
             {
-                stream << "    ( ";
+                _stream << "    ( ";
                 for (auto& _key : S->getStructure())
                 {
                     auto key = std::string(1,_key);
                     auto sb = S->getStateBlock(key);
-                    stream << sb->getState().transpose() << " ";
+                    _stream << sb->getState().transpose() << " ";
                 }
-                stream << ")" << std::endl;
+                _stream << ")" << std::endl;
             }
-            else if (state_blocks)
+            else if (_state_blocks)
             {
-                stream << "    sb: ";
+                _stream << "    sb: ";
                 for (auto& _key : S->getStructure())
                 {
                     auto key = std::string(1,_key);
                     auto sb = S->getStateBlock(key);
-                    stream << key << "[" << (S->isStateBlockDynamic(key) ? "Dyn" : "Sta") << "," << (sb->isFixed() ? "Fix" : "Est") << "]; ";
+                    _stream << key << "[" << (S->isStateBlockDynamic(key) ? "Dyn" : "Sta") << "," << (sb->isFixed() ? "Fix" : "Est") << "]; ";
                 }
-                stream << std::endl;
+                _stream << std::endl;
             }
-            if (depth >= 2)
+            if (_depth >= 2)
             {
                 // Processors =======================================================================================
                 for (auto p : S->getProcessorList())
                 {
                     if (p->isMotion())
                     {
-                        stream << "    PrcM" << p->id() << " " << p->getType() << " \"" << p->getName() << "\"" << std::endl;
+                        _stream << "    PrcM" << p->id() << " " << p->getType() << " \"" << p->getName() << "\"" << std::endl;
                         ProcessorMotionPtr pm = std::static_pointer_cast<ProcessorMotion>(p);
                         if (pm->getOrigin())
-                            stream << "      o: C" << pm->getOrigin()->id() << " - " << (pm->getOrigin()->getFrame()->isKeyOrAux() ? (pm->getOrigin()->getFrame()->isKey() ? "  KFrm" : "  AFrm" ) : "  Frm")
+                            _stream << "      o: Cap" << pm->getOrigin()->id() << " - " << (pm->getOrigin()->getFrame()->isKeyOrAux() ? (pm->getOrigin()->getFrame()->isKey() ? "  KFrm" : "  AFrm" ) : "  Frm")
                             << pm->getOrigin()->getFrame()->id() << std::endl;
                         if (pm->getLast())
-                            stream << "      l: C" << pm->getLast()->id() << " - " << (pm->getLast()->getFrame()->isKeyOrAux() ? (pm->getLast()->getFrame()->isKey() ? "  KFrm" : " AFrm") : "  Frm")
+                            _stream << "      l: Cap" << pm->getLast()->id() << " - " << (pm->getLast()->getFrame()->isKeyOrAux() ? (pm->getLast()->getFrame()->isKey() ? "  KFrm" : " AFrm") : "  Frm")
                             << pm->getLast()->getFrame()->id() << std::endl;
                         if (pm->getIncoming())
-                            stream << "      i: C" << pm->getIncoming()->id() << std::endl;
+                            _stream << "      i: Cap" << pm->getIncoming()->id() << std::endl;
                     }
                     else
                     {
-                        stream << "    PrcT" << p->id() << " " << p->getType() << " \"" << p->getName() << "\"" << std::endl;
+                        _stream << "    PrcT" << p->id() << " " << p->getType() << " \"" << p->getName() << "\"" << std::endl;
                         ProcessorTrackerPtr pt = std::dynamic_pointer_cast<ProcessorTracker>(p);
                         if (pt)
                         {
                             if (pt->getOrigin())
-                                stream << "      o: C" << pt->getOrigin()->id() << " - " << (pt->getOrigin()->getFrame()->isKeyOrAux() ? (pt->getOrigin()->getFrame()->isKey() ? "  KFrm" : " AFrm") : "  Frm")
+                                _stream << "      o: Cap" << pt->getOrigin()->id() << " - " << (pt->getOrigin()->getFrame()->isKeyOrAux() ? (pt->getOrigin()->getFrame()->isKey() ? "  KFrm" : " AFrm") : "  Frm")
                                 << pt->getOrigin()->getFrame()->id() << std::endl;
                             if (pt->getLast())
-                                stream << "      l: C" << pt->getLast()->id() << " - " << (pt->getLast()->getFrame()->isKeyOrAux() ? (pt->getLast()->getFrame()->isKey() ? "  KFrm" : " AFrm") : "  Frm")
+                                _stream << "      l: Cap" << pt->getLast()->id() << " - " << (pt->getLast()->getFrame()->isKeyOrAux() ? (pt->getLast()->getFrame()->isKey() ? "  KFrm" : " AFrm") : "  Frm")
                                 << pt->getLast()->getFrame()->id() << std::endl;
                             if (pt->getIncoming())
-                                stream << "      i: C" << pt->getIncoming()->id() << std::endl;
+                                _stream << "      i: Cap" << pt->getIncoming()->id() << std::endl;
                         }
                     }
                 } // for p
             }
         } // for S
     }
-    stream << "Trajectory" << ((depth < 1) ? (" -- " + std::to_string(getTrajectory()->getFrameList().size()) + "F") : "")  << std::endl;
-    if (depth >= 1)
+    _stream << "Trajectory" << ((_depth < 1) ? (" -- " + std::to_string(getTrajectory()->getFrameList().size()) + "F") : "")  << std::endl;
+    if (_depth >= 1)
     {
         // Frames =======================================================================================
         for (auto F : getTrajectory()->getFrameList())
         {
-            stream << (F->isKeyOrAux() ? (F->isKey() ? "  KFrm" : " AFrm") : "  Frm") << F->id() << ((depth < 2) ? " -- " + std::to_string(F->getCaptureList().size()) + "C  " : "");
-            if (constr_by)
+            _stream << (F->isKeyOrAux() ? (F->isKey() ? "  KFrm" : " AFrm") : "  Frm") << F->id() << ((_depth < 2) ? " -- " + std::to_string(F->getCaptureList().size()) + "C  " : "");
+            if (_constr_by)
             {
-                stream << "  <-- ";
+                _stream << "  <-- ";
                 for (auto cby : F->getConstrainedByList())
-                    stream << "Fac" << cby->id() << " \t";
+                    _stream << "Fac" << cby->id() << " \t";
             }
-            stream << std::endl;
-            if (metric)
+            _stream << std::endl;
+            if (_metric)
             {
-                stream << (F->isFixed() ? "    Fix" : "    Est") << ", ts=" << std::setprecision(5)
+                _stream << (F->isFixed() ? "    Fix" : "    Est") << ", ts=" << std::setprecision(5)
                         << F->getTimeStamp();
-                stream << ",\t x = ( " << std::setprecision(2) << F->getState().transpose() << " )";
-                stream << std::endl;
+                _stream << ",\t x = ( " << std::setprecision(2) << F->getState().transpose() << " )";
+                _stream << std::endl;
             }
-            if (state_blocks)
+            if (_state_blocks)
             {
-                stream << "    sb:";
+                _stream << "    sb:";
                 for (const auto& sb : F->getStateBlockVec())
                 {
-                    stream << " " << (sb->isFixed() ? "Fix" : "Est");
+                    _stream << " " << (sb->isFixed() ? "Fix" : "Est");
                 }
-                stream << std::endl;
+                _stream << std::endl;
             }
-            if (depth >= 2)
+            if (_depth >= 2)
             {
                 // Captures =======================================================================================
                 for (auto C : F->getCaptureList())
                 {
-                    stream << "    Cap" << (C->isMotion() ? "M" : "") << C->id() << " " << C->getType();
+                    _stream << "    Cap" << (C->isMotion() ? "M" : "") << C->id() << " " << C->getType();
 
                     if(C->getSensor() != nullptr)
                     {
-                        stream << " -> Sen" << C->getSensor()->id();
+                        _stream << " -> Sen" << C->getSensor()->id();
                     }
                     else
-                        stream << " -> S-";
+                        _stream << " -> Sen-";
                     if (C->isMotion())
                     {
                         auto CM = std::static_pointer_cast<CaptureMotion>(C);
                         if (auto OC = CM->getOriginCapture())
                         {
-                            stream << " -> OCap" << OC->id();
+                            _stream << " -> OCap" << OC->id();
                             if (auto OF = OC->getFrame())
-                                stream << " ; OFrm" << OF->id();
+                                _stream << " ; OFrm" << OF->id();
                         }
                     }
 
-                    stream << ((depth < 3) ? " -- " + std::to_string(C->getFeatureList().size()) + "f" : "");
-                    if (constr_by)
+                    _stream << ((_depth < 3) ? " -- " + std::to_string(C->getFeatureList().size()) + "f" : "");
+                    if (_constr_by)
                     {
-                        stream << "  <-- ";
+                        _stream << "  <-- ";
                         for (auto cby : C->getConstrainedByList())
-                            stream << "Fac" << cby->id() << " \t";
+                            _stream << "Fac" << cby->id() << " \t";
                     }
-                    stream << std::endl;
+                    _stream << std::endl;
 
-                    if (state_blocks)
+                    if (_state_blocks)
                         for (const auto& sb : C->getStateBlockVec())
                         {
                             if(sb != nullptr)
                             {
-                                stream << "      sb: ";
-                                stream << (sb->isFixed() ? "Fix" : "Est");
-                                if (metric)
-                                    stream << std::setprecision(2) << " (" << sb->getState().transpose() << " )";
-                                stream << std::endl;
+                                _stream << "      sb: ";
+                                _stream << (sb->isFixed() ? "Fix" : "Est");
+                                if (_metric)
+                                    _stream << std::setprecision(2) << " (" << sb->getState().transpose() << " )";
+                                _stream << std::endl;
                             }
                         }
 
                     if (C->isMotion() )
                     {
                         CaptureMotionPtr CM = std::dynamic_pointer_cast<CaptureMotion>(C);
-                        stream << "      buffer size  :  " << CM->getBuffer().get().size() << std::endl;
-                        if ( metric && ! CM->getBuffer().get().empty())
+                        _stream << "      buffer size  :  " << CM->getBuffer().get().size() << std::endl;
+                        if ( _metric && ! CM->getBuffer().get().empty())
                         {
-                            stream << "      delta preint : (" << CM->getDeltaPreint().transpose() << ")" << std::endl;
+                            _stream << "      delta preint : (" << CM->getDeltaPreint().transpose() << ")" << std::endl;
                             if (CM->hasCalibration())
                             {
-                                stream << "      calib preint : (" << CM->getCalibrationPreint().transpose() << ")" << std::endl;
-                                stream << "      jacob preint : (" << CM->getJacobianCalib().row(0) << ")" << std::endl;
-                                stream << "      calib current: (" << CM->getCalibration().transpose() << ")" << std::endl;
-                                stream << "      delta correct: (" << CM->getDeltaCorrected(CM->getCalibration()).transpose() << ")" << std::endl;
+                                _stream << "      calib preint : (" << CM->getCalibrationPreint().transpose() << ")" << std::endl;
+                                _stream << "      jacob preint : (" << CM->getJacobianCalib().row(0) << ")" << std::endl;
+                                _stream << "      calib current: (" << CM->getCalibration().transpose() << ")" << std::endl;
+                                _stream << "      delta correct: (" << CM->getDeltaCorrected(CM->getCalibration()).transpose() << ")" << std::endl;
                             }
                         }
                     }
 
-                    if (depth >= 3)
+                    if (_depth >= 3)
                     {
                         // Features =======================================================================================
                         for (auto f : C->getFeatureList())
                         {
-                            stream << "      Ftr" << f->id() << " trk" << f->trackId() << " " << f->getType() << ((depth < 4) ? " -- " + std::to_string(f->getFactorList().size()) + "c  " : "");
-                            if (constr_by)
+                            _stream << "      Ftr" << f->id() << " trk" << f->trackId() << " " << f->getType() << ((_depth < 4) ? " -- " + std::to_string(f->getFactorList().size()) + "c  " : "");
+                            if (_constr_by)
                             {
-                                stream << "  <--\t";
+                                _stream << "  <--\t";
                                 for (auto cby : f->getConstrainedByList())
-                                    stream << "Fac" << cby->id() << " \t";
+                                    _stream << "Fac" << cby->id() << " \t";
                             }
-                            stream << std::endl;
-                            if (metric)
-                                stream << "        m = ( " << std::setprecision(2) << f->getMeasurement().transpose()
+                            _stream << std::endl;
+                            if (_metric)
+                                _stream << "        m = ( " << std::setprecision(2) << f->getMeasurement().transpose()
                                         << " )" << std::endl;
-                            if (depth >= 4)
+                            if (_depth >= 4)
                             {
                                 // Factors =======================================================================================
                                 for (auto c : f->getFactorList())
                                 {
-                                    stream << "        Fac" << c->id() << " " << c->getType() << " -->";
-                                    if (c->getFrameOther() == nullptr && c->getCaptureOther() == nullptr && c->getFeatureOther() == nullptr && c->getLandmarkOther() == nullptr)
-                                        stream << " Abs";
-                                    if (c->getFrameOther() != nullptr)
-                                        stream << " Frm" << c->getFrameOther()->id();
-                                    if (c->getCaptureOther() != nullptr)
-                                        stream << " Cap" << c->getCaptureOther()->id();
-                                    if (c->getFeatureOther() != nullptr)
-                                        stream << " Fac" << c->getFeatureOther()->id();
-                                    if (c->getLandmarkOther() != nullptr)
-                                        stream << " Lmk" << c->getLandmarkOther()->id();
-                                    stream << std::endl;
+                                    _stream << "        Fac" << c->id() << " " << c->getType() << " -->";
+                                    if (       c->getFrameOtherList()   .empty()
+                                            && c->getCaptureOtherList() .empty()
+                                            && c->getFeatureOtherList() .empty()
+                                            && c->getLandmarkOtherList().empty())
+                                        _stream << " Abs";
+
+                                    for (const auto& Fow : c->getFrameOtherList())
+                                        if (!Fow.expired())
+                                            _stream << " Frm" << Fow.lock()->id();
+                                    for (const auto& Cow : c->getCaptureOtherList())
+                                        if (!Cow.expired())
+                                            _stream << " Cap" << Cow.lock()->id();
+                                    for (const auto& fow : c->getFeatureOtherList())
+                                        if (!fow.expired())
+                                            _stream << " Ftr" << fow.lock()->id();
+                                    for (const auto& Low : c->getLandmarkOtherList())
+                                        if (!Low.expired())
+                                            _stream << " Lmk" << Low.lock()->id();
+                                    _stream << std::endl;
                                 } // for c
                             }
                         } // for f
@@ -1128,236 +1180,208 @@ void Problem::print(int depth, std::ostream& stream, bool constr_by, bool metric
             }
         } // for F
     }
-    stream << "Map" << ((depth < 1) ? ("        -- " + std::to_string(getMap()->getLandmarkList().size()) + "L") : "") << std::endl;
-    if (depth >= 1)
+    _stream << "Map" << ((_depth < 1) ? ("        -- " + std::to_string(getMap()->getLandmarkList().size()) + "L") : "") << std::endl;
+    if (_depth >= 1)
     {
         // Landmarks =======================================================================================
         for (auto L : getMap()->getLandmarkList())
         {
-            stream << "  Lmk" << L->id() << " " << L->getType();
-            if (constr_by)
+            _stream << "  Lmk" << L->id() << " " << L->getType();
+            if (_constr_by)
             {
-                stream << "\t<-- ";
+                _stream << "\t<-- ";
                 for (auto cby : L->getConstrainedByList())
-                    stream << "Fac" << cby->id() << " \t";
+                    _stream << "Fac" << cby->id() << " \t";
             }
-            stream << std::endl;
-            if (metric)
+            _stream << std::endl;
+            if (_metric)
             {
-                stream << (L->isFixed() ? "    Fix" : "    Est");
-                stream << ",\t x = ( " << std::setprecision(2) << L->getState().transpose() << " )";
-                stream << std::endl;
+                _stream << (L->isFixed() ? "    Fix" : "    Est");
+                _stream << ",\t x = ( " << std::setprecision(2) << L->getState().transpose() << " )";
+                _stream << std::endl;
             }
-            if (state_blocks)
+            if (_state_blocks)
             {
-                stream << "    sb:";
+                _stream << "    sb:";
                 for (const auto& sb : L->getStateBlockVec())
                 {
                     if (sb != nullptr)
-                        stream << (sb->isFixed() ? " Fix" : " Est");
+                        _stream << (sb->isFixed() ? " Fix" : " Est");
                 }
-                stream << std::endl;
+                _stream << std::endl;
             }
         } // for L
     }
-    stream << "-----------------------------------------" << std::endl;
-    stream << std::endl;
+    _stream << "-----------------------------------------" << std::endl;
+    _stream << std::endl;
 }
 
-bool Problem::check(bool verbose, std::ostream& stream) const
+bool Problem::check(bool _verbose, std::ostream& _stream) const
 {
 
     CheckLog log(true, "");
     log.explanation_ = "## WOLF::problem inconsistencies list \n   ---------------------------------- \n";
 
-    if (verbose) stream << std::endl;
-    if (verbose) stream << "Wolf tree integrity ---------------------" << std::endl;
-    auto P_raw = this;
-    if (verbose)
+    if (_verbose) _stream << std::endl;
+    if (_verbose) _stream << "Wolf tree integrity ---------------------" << std::endl;
+    auto P = shared_from_this();
+    if (_verbose)
     {
-        stream << "Prb @ " << P_raw << std::endl;
+        _stream << "Prb @ " << P.get() << std::endl;
     }
     // ------------------------
     //     HARDWARE branch
     // ------------------------
     auto H = hardware_ptr_;
-    if (verbose)
+    if (_verbose)
     {
-        stream << "Hrw @ " << H.get() << std::endl;
+        _stream << "Hrw @ " << H.get() << std::endl;
     }
-    // check pointer to Problem
-    // is_consistent = is_consistent && (H->getProblem().get() == P_raw);
 
+    // check pointer to Problem
     std::stringstream inconsistency_explanation;
     inconsistency_explanation << "Hardware problem pointer is " << H->getProblem().get()
-        << " but problem pointer is " << P_raw << "\n";
-    log.compose(CheckLog((H->getProblem().get() == P_raw), inconsistency_explanation.str()));
-    //Clear inconsistency_explanation
-    std::stringstream().swap(inconsistency_explanation);
+        << " but problem pointer is " << P.get() << "\n";
+    log.assertTrue((H->getProblem() == P), inconsistency_explanation);
+
 
     // Sensors =======================================================================================
     for (auto S : H->getSensorList())
     {
-        if (verbose)
+        if (_verbose)
         {
-            stream << "  Sen" << S->id() << " @ " << S.get() << std::endl;
-            stream << "    -> Prb @ " << S->getProblem().get() << std::endl;
-            stream << "    -> Hrw @ " << S->getHardware().get() << std::endl;
+            _stream << "  Sen" << S->id() << " @ " << S.get() << std::endl;
+            _stream << "    -> Prb @ " << S->getProblem().get() << std::endl;
+            _stream << "    -> Hrw @ " << S->getHardware().get() << std::endl;
             for (auto pair: S->getStateBlockMap())
             {
                 auto sb = pair.second;
-                stream <<  "    " << pair.first << " sb @ " << sb.get();
+                _stream <<  "    " << pair.first << " sb @ " << sb.get();
                 if (sb)
                 {
                     auto lp = sb->getLocalParametrization();
                     if (lp)
-                        stream <<  " (lp @ " << lp.get() << ")";
+                        _stream <<  " (lp @ " << lp.get() << ")";
                 }
-                stream << std::endl;
+                _stream << std::endl;
             }
         }
+
         // check problem and hardware pointers
-        // is_consistent = is_consistent && (S->getProblem().get() == P_raw);
         inconsistency_explanation << "Sensor problem pointer is " << S->getProblem().get()
-            << " but problem pointer is " << P_raw << "\n";
-        log.compose(CheckLog((S->getProblem().get() == P_raw), inconsistency_explanation.str()));
-        //Clear inconsistency_explanation
-        std::stringstream().swap(inconsistency_explanation);
+            << " but problem pointer is " << P.get() << "\n";
+        log.assertTrue((S->getProblem() == P), inconsistency_explanation);
+
 
-        //  is_consistent = is_consistent && (S->getHardware() == H);
         inconsistency_explanation << "Sensor hardware pointer is " << S->getHardware()
             << " but hardware pointer is " << H << "\n";
-        log.compose(CheckLog((S->getHardware() == H), inconsistency_explanation.str()));
-        //Clear inconsistency_explanation
-        std::stringstream().swap(inconsistency_explanation);
+        log.assertTrue((S->getHardware() == H), inconsistency_explanation);
+
 
         //  Processors =======================================================================================
         for (auto p : S->getProcessorList())
         {
-            if (verbose)
+            if (_verbose)
             {
-                stream << "    Prc" << p->id() << " @ " << p.get() << " -> Sen" << p->getSensor()->id() << std::endl;
-                stream << "      -> Prb  @ " << p->getProblem().get() << std::endl;
-                stream << "      -> Sen" << p->getSensor()->id() << " @ " << p->getSensor().get() << std::endl;
+                _stream << "    Prc" << p->id() << " @ " << p.get() << " -> Sen" << p->getSensor()->id() << std::endl;
+                _stream << "      -> Prb  @ " << p->getProblem().get() << std::endl;
+                _stream << "      -> Sen" << p->getSensor()->id() << " @ " << p->getSensor().get() << std::endl;
             }
-            // check problem and sensor pointers
-
-            //  is_consistent = is_consistent && (p->getProblem().get() == P_raw);
 
+            // check problem and sensor pointers
             inconsistency_explanation << "Processor problem pointer is " << p->getProblem().get()
-                << " but problem pointer is " << P_raw << "\n";
-            log.compose(CheckLog((p->getProblem().get() == P_raw), inconsistency_explanation.str()));
-            //Clear inconsistency_explanation
-            std::stringstream().swap(inconsistency_explanation);
+                << " but problem pointer is " << P.get() << "\n";
+            log.assertTrue((p->getProblem() == P), inconsistency_explanation);
 
-            // is_consistent = is_consistent && (p->getSensor() == S);
 
             inconsistency_explanation << "Processor sensor pointer is " << p->getSensor()
-                << " but sensor pointer is " << P_raw << "\n";
-            log.compose(CheckLog((p->getProblem().get() == P_raw), inconsistency_explanation.str()));
-            //Clear inconsistency_explanation
-            std::stringstream().swap(inconsistency_explanation);
+                << " but sensor pointer is " << P.get() << "\n";
+            log.assertTrue((p->getProblem() == P), inconsistency_explanation);
+
         }
     }
     // ------------------------
     //    TRAJECTORY branch
     // ------------------------
     auto T = trajectory_ptr_;
-    if (verbose)
+    if (_verbose)
     {
-        stream << "Trj @ " << T.get() << std::endl;
+        _stream << "Trj @ " << T.get() << std::endl;
     }
-    // check pointer to Problem
-    // is_consistent = is_consistent && (T->getProblem().get() == P_raw);
-
 
+    // check pointer to Problem
     inconsistency_explanation << "Trajectory problem pointer is " << T->getProblem().get()
-       << " but problem pointer is" << P_raw << "\n";
-    log.compose(CheckLog((T->getProblem().get() == P_raw), inconsistency_explanation.str()));
-    //Clear inconsistency_explanation
-    std::stringstream().swap(inconsistency_explanation);
+       << " but problem pointer is" << P.get() << "\n";
+    log.assertTrue((T->getProblem() == P), inconsistency_explanation);
+
 
     // Frames =======================================================================================
     for (auto F : T->getFrameList())
     {
-      if (verbose) {
-        stream << (F->isKeyOrAux() ? (F->isKey() ? "  KFrm" : " EFrm") : "  Frm")
+      if (_verbose) {
+        _stream << (F->isKeyOrAux() ? (F->isKey() ? "  KFrm" : " EFrm") : "  Frm")
              << F->id() << " @ " << F.get() << std::endl;
-        stream << "    -> Prb @ " << F->getProblem().get() << std::endl;
-        stream << "    -> Trj @ " << F->getTrajectory().get() << std::endl;
+        _stream << "    -> Prb @ " << F->getProblem().get() << std::endl;
+        _stream << "    -> Trj @ " << F->getTrajectory().get() << std::endl;
       }
       for (const auto &pair: F->getStateBlockMap()) {
+
           auto sb = pair.second;
-          inconsistency_explanation << "Frame's " << F.get()
+
+          // check for valid state block
+          inconsistency_explanation << "Frame " << F->id() << " @ "<< F.get()
                                   << " has State block pointer " << sb.get()
-                                  << " null! \n";
-          log.compose(
-              CheckLog((sb.get() != 0), inconsistency_explanation.str()));
-          // Clear inconsistency_explanation
-          std::stringstream().swap(inconsistency_explanation);
-          if (verbose) {
-            stream << "    "<< pair.first << " sb @ " << sb.get();
+                                  << " = 0 \n";
+          log.assertTrue((sb.get() != 0), inconsistency_explanation);
+
+          if (_verbose) {
+            _stream << "    "<< pair.first << " sb @ " << sb.get();
             if (sb) {
               auto lp = sb->getLocalParametrization();
               if (lp)
-                stream << " (lp @ " << lp.get() << ")";
+                _stream << " (lp @ " << lp.get() << ")";
             }
-            stream << std::endl;
+            _stream << std::endl;
           }
       }
 
-        // check problem and trajectory pointers
-        // is_consistent = is_consistent && (F->getProblem().get() == P_raw);
-
+        // check problem pointer
         inconsistency_explanation << "Frame problem pointer is " << F->getProblem().get()
-        << " but problem pointer is" << P_raw << "\n";
-        log.compose(CheckLog((F->getProblem().get() == P_raw), inconsistency_explanation.str()));
-        //Clear inconsistency_explanation
-        std::stringstream().swap(inconsistency_explanation);
-
-        // is_consistent = is_consistent && (F->getTrajectory() == T);
+                        << " but problem pointer is" << P.get() << "\n";
+        log.assertTrue((F->getProblem() == P), inconsistency_explanation);
 
+        // check trajectory pointer
         inconsistency_explanation << "Frame trajectory pointer is " << F->getTrajectory()
-        << " but trajectory pointer is" << T << "\n";
-        log.compose(CheckLog((F->getTrajectory() == T), inconsistency_explanation.str()));
-        //Clear inconsistency_explanation
-        std::stringstream().swap(inconsistency_explanation);
+                        << " but trajectory pointer is" << T << "\n";
+        log.assertTrue((F->getTrajectory() == T), inconsistency_explanation);
 
+
+        // check constrained_by
         for (auto cby : F->getConstrainedByList())
         {
-          for (auto sb : cby->getStateBlockPtrVector()) {
-            inconsistency_explanation
-                << "Factor " << cby.get() << " constraining " << F.get()
-                << " has State block pointer " << sb.get() << " null! \n";
-            log.compose(
-                CheckLog((sb.get() != 0), inconsistency_explanation.str()));
-            // Clear inconsistency_explanation
-            std::stringstream().swap(inconsistency_explanation);
-          }
-          if (verbose) {
-            stream << "    <- c" << cby->id() << " -> Frm"
-                 << cby->getFrameOther()->id() << std::endl;
-          }
-            // check constrained_by pointer to this frame
-            // is_consistent = is_consistent && (cby->getFrameOther() == F);
+            if (_verbose)
+            {
+                _stream << "    <- c" << cby->id() << " -> ";
+                for (const auto& Fow : cby->getFrameOtherList())
+                    _stream << " F" << Fow.lock()->id() << std::endl;
+            }
 
-            inconsistency_explanation << "constrained-by frame pointer is " << cby->getFrameOther()
-            << " but frame pointer is" << F << "\n";
-            log.compose(CheckLog((cby->getFrameOther() == F), inconsistency_explanation.str()));
-            //Clear inconsistency_explanation
-            std::stringstream().swap(inconsistency_explanation);
+            // check constrained_by pointer to this frame
+            inconsistency_explanation << "constrained-by frame " << F->id() << " @ " << F
+                                << " not found among constrained-by factors\n";
+            log.assertTrue((cby->hasFrameOther(F)), inconsistency_explanation);
 
             for (auto sb : cby->getStateBlockPtrVector())
             {
 
-              if (verbose) {
-                stream << "      sb @ " << sb.get();
+              if (_verbose) {
+                _stream << "      sb @ " << sb.get();
                 if (sb) {
                   auto lp = sb->getLocalParametrization();
                   if (lp)
-                    stream << " (lp @ " << lp.get() << ")";
+                    _stream << " (lp @ " << lp.get() << ")";
                 }
-                stream << std::endl;
+                _stream << std::endl;
               }
             }
         }
@@ -1365,361 +1389,383 @@ bool Problem::check(bool verbose, std::ostream& stream) const
         // Captures =======================================================================================
         for (auto C : F->getCaptureList())
         {
-            if (verbose)
+            if (_verbose)
             {
-                stream << "    Cap" << C->id() << " @ " << C.get() << " -> Sen";
-                if (C->getSensor()) stream << C->getSensor()->id();
-                else stream << "-";
-                stream << std::endl;
-                stream << "      -> Prb  @ " << C->getProblem().get() << std::endl;
-                stream << "      -> Frm" << C->getFrame()->id() << " @ " << C->getFrame().get() << std::endl;
+                _stream << "    Cap" << C->id() << " @ " << C.get() << " -> Sen";
+                if (C->getSensor()) _stream << C->getSensor()->id();
+                else _stream << "-";
+                _stream << std::endl;
+                _stream << "      -> Prb  @ " << C->getProblem().get() << std::endl;
+                _stream << "      -> Frm" << C->getFrame()->id() << " @ " << C->getFrame().get() << std::endl;
             }
-                for (auto pair: C->getStateBlockMap())
+            for (auto pair: C->getStateBlockMap())
+            {
+                auto sb = pair.second;
+
+                // check for valid state block
+                inconsistency_explanation << "Capture " << C->id() << " @ " << C.get() << " has State block pointer "
+                                          << sb.get() << " = 0 \n";
+                log.assertTrue((sb.get() != 0), inconsistency_explanation);
+
+                if (_verbose)
                 {
-                    auto sb = pair.second;
-                    if (verbose)
-                    {
-                    stream <<  "      " << pair.first << " sb @ " << sb.get();
+                    _stream <<  "      " << pair.first << " sb @ " << sb.get();
                     if (sb) {
-                      auto lp = sb->getLocalParametrization();
-                      if (lp)
-                        stream << " (lp @ " << lp.get() << ")";
-                    }
-                    stream << std::endl;
+                        auto lp = sb->getLocalParametrization();
+                        if (lp)
+                            _stream << " (lp @ " << lp.get() << ")";
                     }
+                    _stream << std::endl;
                 }
+            }
 
             // check problem and frame pointers
-            // is_consistent = is_consistent && (C->getProblem().get() == P_raw);
-
             inconsistency_explanation << "Capture problem pointer is " << C->getProblem().get()
-            << " but problem pointer is" << P_raw << "\n";
-            log.compose(CheckLog((C->getProblem().get() == P_raw), inconsistency_explanation.str()));
-            //Clear inconsistency_explanation
-            std::stringstream().swap(inconsistency_explanation);
+            << " but problem pointer is" << P.get() << "\n";
+            log.assertTrue((C->getProblem() == P), inconsistency_explanation);
 
-            // is_consistent = is_consistent && (C->getFrame() == F);
 
             inconsistency_explanation << "Capture frame pointer is " << C->getFrame()
             << " but frame pointer is" << F << "\n";
-            log.compose(CheckLog((C->getFrame() == F), inconsistency_explanation.str()));
-            //Clear inconsistency_explanation
-            std::stringstream().swap(inconsistency_explanation);
+            log.assertTrue((C->getFrame() == F), inconsistency_explanation);
+
+
+            // check contrained_by
+            for (const auto& cby : C->getConstrainedByList())
+            {
+                if (_verbose)
+                {
+                    _stream << "      <- c" << cby->id() << " -> ";
+                    for (const auto& Cow : cby->getCaptureOtherList())
+                        _stream << " C" << Cow.lock()->id();
+                    _stream << std::endl;
+                }
+
+                // check constrained_by pointer to this capture
+                inconsistency_explanation << "constrained by capture " << C->id() << " @ " << C
+                                          << " not found among constrained-by factors\n";
+                log.assertTrue((cby->hasCaptureOther(C)), inconsistency_explanation);
+
+                for (auto sb : cby->getStateBlockPtrVector())
+                {
+                    if (_verbose)
+                    {
+                        _stream << "      sb @ " << sb.get();
+                        if (sb)
+                        {
+                            auto lp = sb->getLocalParametrization();
+                            if (lp)
+                                _stream <<  " (lp @ " << lp.get() << ")";
+                        }
+                        _stream << std::endl;
+                    }
+                }
+
+            }
 
             // Features =======================================================================================
             for (auto f : C->getFeatureList())
             {
-                if (verbose)
+                if (_verbose)
                 {
-                    stream << "      Ftr" << f->id() << " @ " << f.get() << std::endl;
-                    stream << "        -> Prb  @ " << f->getProblem().get() << std::endl;
-                    stream << "        -> Cap" << f->getCapture()->id() << " @ " << f->getCapture().get()
+                    _stream << "      Ftr" << f->id() << " @ " << f.get() << std::endl;
+                    _stream << "        -> Prb  @ " << f->getProblem().get() << std::endl;
+                    _stream << "        -> Cap" << f->getCapture()->id() << " @ " << f->getCapture().get()
                             << std::endl;
                 }
-                // check problem and capture pointers
-                // is_consistent = is_consistent && (f->getProblem().get() == P_raw);
 
+                // check problem and capture pointers
                 inconsistency_explanation << "Feature frame pointer is " << f->getProblem().get()
-                << " but problem pointer is" << P_raw << "\n";
-                log.compose(CheckLog((f->getProblem().get() == P_raw), inconsistency_explanation.str()));
-                //Clear inconsistency_explanation
-                std::stringstream().swap(inconsistency_explanation);
+                << " but problem pointer is" << P.get() << "\n";
+                log.assertTrue((f->getProblem() == P), inconsistency_explanation);
 
-                // is_consistent = is_consistent && (f->getCapture() == C);
 
                 inconsistency_explanation << "Feature capture pointer is " << f->getCapture()
                 << " but capture pointer is" << C << "\n";
-                log.compose(CheckLog((f->getCapture() == C), inconsistency_explanation.str()));
-                //Clear inconsistency_explanation
-                std::stringstream().swap(inconsistency_explanation);
+                log.assertTrue((f->getCapture() == C), inconsistency_explanation);
 
+
+                // check contrained_by
                 for (auto cby : f->getConstrainedByList())
                 {
-                    if (verbose)
+                    if (_verbose)
                     {
-                        stream << "     <- c" << cby->id() << " -> Ftr" << cby->getFeatureOther()->id() << std::endl;
+                        _stream << "        <- c" << cby->id() << " -> ";
+                        for (const auto& fow : cby->getFeatureOtherList())
+                            _stream << " f" << fow.lock()->id();
+                        _stream << std::endl;
                     }
+
                     // check constrained_by pointer to this feature
-                    // is_consistent = is_consistent && (cby->getFeatureOther() == f);
+                    inconsistency_explanation << "constrained by Feature " << f->id() << " @ " << f
+                                                << " not found among constrained-by factors\n";
+                    log.assertTrue((cby->hasFeatureOther(f)), inconsistency_explanation);
 
-                    inconsistency_explanation << "constrained by Feature pointer is " << cby->getFeatureOther()
-                    << " but feature pointer is" << f << "\n";
-                    log.compose(CheckLog((cby->getFeatureOther() == f), inconsistency_explanation.str()));
-                    //Clear inconsistency_explanation
-                    std::stringstream().swap(inconsistency_explanation);
                 }
 
                 // Factors =======================================================================================
                 for (auto c : f->getFactorList())
                 {
-                    if (verbose)
-                        stream << "        Fac" << c->id() << " @ " << c.get();
-
-                    auto Fo = c->getFrameOther();
-                    auto Co = c->getCaptureOther();
-                    auto fo = c->getFeatureOther();
-                    auto Lo = c->getLandmarkOther();
+                    if (_verbose)
+                        _stream << "        Fac" << c->id() << " @ " << c.get();
 
-                    if ( !Fo && !Co && !fo && !Lo )    // case ABSOLUTE:
+                    if (       c->getFrameOtherList()   .empty()
+                            && c->getCaptureOtherList() .empty()
+                            && c->getFeatureOtherList() .empty()
+                            && c->getLandmarkOtherList().empty() )    // case ABSOLUTE:
                     {
-                        if (verbose)
-                            stream << " --> Abs." << std::endl;
+                        if (_verbose)
+                            _stream << " --> Abs.";
                     }
 
                     // find constrained_by pointer in constrained frame
-                    if ( Fo )  // case FRAME:
+                    for (const auto& Fow : c->getFrameOtherList())
                     {
-                        if (verbose)
-                            stream << " ( --> Frm" << Fo->id() << " <- ";
-                        bool found = false;
-                        for (auto cby : Fo->getConstrainedByList())
+                        if (!Fow.expired())
                         {
-                            if (verbose)
-                                stream << " Fac" << cby->id();
-                            found = found || (c == cby);
-                        }
-                        if (verbose)
-                            stream << ")";
-                        // check constrained_by pointer in constrained frame
-                        // is_consistent = is_consistent && found;
+                            const auto& Fo = Fow.lock();
+                            if (_verbose)
+                            {
+                                _stream << " ( --> F" << Fo->id() << " <- ";
+                                for (auto cby : Fo->getConstrainedByList())
+                                    _stream << " c" << cby->id();
+                            }
 
-                        inconsistency_explanation << "The constrained Feature " << Fo
-                            << " does not close the constrained-by loop start =  " << c << "\n";
-                        log.compose(CheckLog((found), inconsistency_explanation.str()));
-                        //Clear inconsistency_explanation
-                        std::stringstream().swap(inconsistency_explanation);
+                            // check constrained_by pointer in constrained frame
+                            bool found = Fo->isConstrainedBy(c);
+                            inconsistency_explanation << "The constrained Feature " << Fo->id() << " @ " << Fo
+                                    << " not found among constrained-by factors\n";
+                            log.assertTrue((found), inconsistency_explanation);
 
+                        }
                     }
+                    if (_verbose && !c->getFrameOtherList().empty())
+                        _stream << ")";
 
                     // find constrained_by pointer in constrained capture
-                    if ( Co )  // case CAPTURE:
+                    for (const auto& Cow : c->getCaptureOtherList())
                     {
-                        if (verbose)
-                            stream << " ( --> Cap" << Co->id() << " <- ";
-                        bool found = false;
-                        for (auto cby : Co->getConstrainedByList())
+                        if (!Cow.expired())
                         {
-                            if (verbose)
-                                stream << " Fac" << cby->id();
-                            found = found || (c == cby);
-                        }
-                        if (verbose)
-                            stream << ")";
-                        // check constrained_by pointer in constrained frame
-                        // is_consistent = is_consistent && found;
+                            const auto& Co = Cow.lock();
 
-                        inconsistency_explanation << "The constrained capture " << Co
-                            << " does not close the constrained-by loop start =  " << c << "\n";
-                        log.compose(CheckLog((found), inconsistency_explanation.str()));
-                        //Clear inconsistency_explanation
-                        std::stringstream().swap(inconsistency_explanation);
+                            if (_verbose)
+                            {
+                                _stream << " ( --> C" << Co->id() << " <- ";
+                                for (auto cby : Co->getConstrainedByList())
+                                    _stream << " c" << cby->id();
+                            }
+
+                            // check constrained_by pointer in constrained frame
+                            bool found = Co->isConstrainedBy(c);
+                            inconsistency_explanation << "The constrained capture " << Co->id() << " @ " << Co
+                                    << " not found among constrained-by factors\n";
+                            log.assertTrue((found), inconsistency_explanation);
 
+                        }
                     }
+                    if (_verbose && !c->getCaptureOtherList().empty())
+                        _stream << ")";
 
                     // find constrained_by pointer in constrained feature
-                    if ( fo )   // case FEATURE:
+                    for (const auto& fow : c->getFeatureOtherList())
                     {
-                        if (verbose)
-                            stream << " ( --> Ftr" << fo->id() << " <- ";
-                        bool found = false;
-                        for (auto cby : fo->getConstrainedByList())
+                        if (!fow.expired())
                         {
-                            if (verbose)
-                                stream << " Fac" << cby->id();
-                            found = found || (c == cby);
+                            const auto& fo = fow.lock();
+                            if (_verbose)
+                            {
+                                _stream << " ( --> f" << fo->id() << " <- ";
+                                for (auto cby : fo->getConstrainedByList())
+                                    _stream << " c" << cby->id();
+                            }
+
+                            // check constrained_by pointer in constrained feature
+                            bool found = fo->isConstrainedBy(c);
+                            inconsistency_explanation << "The constrained feature " << fo->id() << " @ " << fo
+                                                      << " not found among constrained-by factors\n";
+                            log.assertTrue((found), inconsistency_explanation);
                         }
-                        if (verbose)
-                            stream << ")";
-                        // check constrained_by pointer in constrained feature
-                        // is_consistent = is_consistent && found;
-
-                        inconsistency_explanation << "The constrained feature" << fo
-                            << " does not close the constrained-by loop start =  " << c << "\n";
-                        log.compose(CheckLog((found), inconsistency_explanation.str()));
-                        //Clear inconsistency_explanation
-                        std::stringstream().swap(inconsistency_explanation);
                     }
+                    if (_verbose && !c->getFeatureOtherList().empty())
+                        _stream << ")";
 
                     // find constrained_by pointer in constrained landmark
-                    if ( Lo )      // case LANDMARK:
+                    for (const auto& Low : c->getLandmarkOtherList())
                     {
-                        if (verbose)
-                            stream << " ( --> Lmk" << Lo->id() << " <- ";
-                        bool found = false;
-                        for (auto cby : Lo->getConstrainedByList())
+                        if (Low.expired())
                         {
-                            if (verbose)
-                                stream << " Fac" << cby->id();
-                            found = found || (c == cby);
+                            const auto& Lo = Low.lock();
+
+                            if (_verbose)
+                            {
+                                _stream << " ( --> L" << Lo->id() << " <- ";
+                                for (auto cby : Lo->getConstrainedByList())
+                                    _stream << " c" << cby->id();
+                            }
+
+                            // check constrained_by pointer in constrained landmark
+                            bool found = Lo->isConstrainedBy(c);
+                            inconsistency_explanation << "The constrained landmark " << Lo->id() << " @ " << Lo
+                                    << " not found among constrained-by factors\n";
+                            log.assertTrue((found), inconsistency_explanation);
+
                         }
-                        if (verbose)
-                            stream << ")";
-                        // check constrained_by pointer in constrained landmark
-                        // is_consistent = is_consistent && found;
-
-                        inconsistency_explanation << "The constrained landmark " << Lo
-                            << " does not close the constrained-by loop start =  " << c << "\n";
-                        log.compose(CheckLog((found), inconsistency_explanation.str()));
-                        //Clear inconsistency_explanation
-                        std::stringstream().swap(inconsistency_explanation);
                     }
-                    if (verbose)
-                        stream << std::endl;
+                    if (_verbose && !c->getLandmarkOtherList().empty())
+                        _stream << ")";
 
-                    if (verbose)
+                    if (_verbose)
+                        _stream << std::endl;
+
+                    if (_verbose)
                     {
-                        stream << "          -> Prb  @ " << c->getProblem().get() << std::endl;
-                        stream << "          -> Ftr" << c->getFeature()->id() << " @ " << c->getFeature().get() << std::endl;
+                        _stream << "          -> Prb  @ " << c->getProblem().get() << std::endl;
+                        _stream << "          -> Ftr" << c->getFeature()->id() << " @ " << c->getFeature().get() << std::endl;
                     }
-                    // check problem and feature pointers
-                    // is_consistent = is_consistent && (c->getProblem().get() == P_raw);
 
-                    inconsistency_explanation << "The factor " << c << " has problem ptr " << c->getProblem().get()
-                        << " but problem ptr is " << P_raw << "\n";
-                    log.compose(CheckLog((c->getProblem().get() == P_raw), inconsistency_explanation.str()));
-                    //Clear inconsistency_explanation
-                    std::stringstream().swap(inconsistency_explanation);
+                    // check problem and feature pointers
+                    inconsistency_explanation << "The factor " << c->id() << " @ " << c << " has problem ptr " << c->getProblem().get()
+                        << " but problem ptr is " << P.get() << "\n";
+                    log.assertTrue((c->getProblem() == P), inconsistency_explanation);
 
-                    // is_consistent = is_consistent && (c->getFeature() == f);
 
-                    inconsistency_explanation << "The factor " << c << " has feature ptr " << c->getFeature()
+                    inconsistency_explanation << "The factor " << c->id() << " @ " << c << " has feature ptr " << c->getFeature()
                         << " but it should have " << f << "\n";
-                    log.compose(CheckLog((c->getProblem().get() == P_raw), inconsistency_explanation.str()));
-                    //Clear inconsistency_explanation
-                    std::stringstream().swap(inconsistency_explanation);
+                    log.assertTrue((c->getProblem() == P), inconsistency_explanation);
+
 
                     // find state block pointers in all constrained nodes
                     SensorBasePtr S = c->getFeature()->getCapture()->getSensor(); // get own sensor to check sb
                     for (auto sb : c->getStateBlockPtrVector())
                     {
                         bool found = false;
-                        if (verbose)
+                        if (_verbose)
                         {
-                            stream <<  "          sb @ " << sb.get();
+                            _stream <<  "          sb @ " << sb.get();
                             if (sb)
                             {
                                 auto lp = sb->getLocalParametrization();
                                 if (lp)
-                                    stream <<  " (lp @ " << lp.get() << ")";
+                                    _stream <<  " (lp @ " << lp.get() << ")";
                             }
                         }
                         bool found_here;
-                        std::vector<StateBlockPtr> sb_vec;
 
                         // find in own Frame
-                        sb_vec          = F->getStateBlockVec();
-                        found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                        if (found_here) stream << " F" << F->id();
+                        found_here  = F->hasStateBlock(sb);
+                        if (found_here && _verbose) _stream << " F" << F->id();
                         found       = found || found_here;
 
                         // find in own Capture
-                        sb_vec          = C->getStateBlockVec();
-                        found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                        if (found_here) stream << " C" << C->id();
+                        found_here  = C->hasStateBlock(sb);
+                        if (found_here && _verbose) _stream << " C" << C->id();
                         found       = found || found_here;
 
                         // Find in other Captures of the own Frame
                         if (!found_here)
                             for (auto FC : F->getCaptureList())
                             {
-                                sb_vec          = FC->getStateBlockVec();
-                                found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                                if (found_here) stream << " F" << F->id() << ".C" << FC->id();
+                                found_here  = FC->hasStateBlock(sb);
+                                if (found_here && _verbose) _stream << " F" << F->id() << ".C" << FC->id();
                                 found       = found || found_here;
                             }
 
                         // find in own Sensor
                         if (S)
                         {
-                            sb_vec          = S->getStateBlockVec();
-                            found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                            if (found_here) stream << " S" << S->id();
+                            found_here  = S->hasStateBlock(sb);
+                            if (found_here && _verbose) _stream << " S" << S->id();
                             found       = found || found_here;
                         }
 
+
                         // find in constrained Frame
-                        if (Fo){
-                            sb_vec          = Fo->getStateBlockVec();
-                            found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                            if (found_here) stream << " Fo" << Fo->id();
-                            found       = found || found_here;
+                        for (const auto& Fow : c->getFrameOtherList())
+                        {
+                            if (!Fow.expired())
+                            {
+                                const auto& Fo = Fow.lock();
+                                found_here  = Fo->hasStateBlock(sb);
+                                if (found_here && _verbose) _stream << " Fo" << Fo->id();
+                                found       = found || found_here;
+
+                                // find in feature other's captures
+                                for (auto FoC : Fo->getCaptureList())
+                                {
+                                    found_here  = FoC->hasStateBlock(sb);
+                                    if (found_here && _verbose) _stream << " Fo" << Fo->id() << ".C" << FoC->id();
+                                    found       = found || found_here;
+                                }
 
+                            }
                         }
 
                         // find in constrained Capture
-                        if (Co)
+                        for (const auto& Cow : c->getCaptureOtherList())
                         {
-                            sb_vec          = Co->getStateBlockVec();
-                            found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                            if (found_here) stream << " Co" << Co->id();
-                            found       = found || found_here;
-                        }
-
-                        // Find in other Captures of the constrained Frame
-                        if (!found_here && Fo)
-                            for (auto FoC : Fo->getCaptureList())
+                            if (!Cow.expired())
                             {
-                                sb_vec          = FoC->getStateBlockVec();
-                                found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                                if (found_here) stream << " Fo" << Fo->id() << ".C" << FoC->id();
+                                const auto& Co = Cow.lock();
+                                found_here  = Co->hasStateBlock(sb);
+                                if (found_here && _verbose) _stream << " Co" << Co->id();
                                 found       = found || found_here;
                             }
+                        }
 
                         // find in constrained Feature
-                        if (fo)
+                        for (const auto& fow : c->getFeatureOtherList())
                         {
-                            // find in constrained feature's Frame
-                            auto foF    = fo->getFrame();
-                            sb_vec          = foF->getStateBlockVec();
-                            found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                            if (found_here) stream << " foF" << foF->id();
-                            found       = found || found_here;
+                            if (!fow.expired())
+                            {
+                                const auto& fo = fow.lock();
+                                // find in constrained feature's Frame
+                                auto foF    = fo->getFrame();
+                                found_here  = foF->hasStateBlock(sb);
+                                if (found_here && _verbose) _stream << " foF" << foF->id();
+                                found       = found || found_here;
 
-                            // find in constrained feature's Capture
-                            auto foC    = fo->getCapture();
-                            sb_vec          = foC->getStateBlockVec();
-                            found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                            if (found_here) stream << " foC" << foC->id();
-                            found       = found || found_here;
+                                // find in constrained feature's Capture
+                                auto foC    = fo->getCapture();
+                                found_here  = foC->hasStateBlock(sb);
+                                if (found_here && _verbose) _stream << " foC" << foC->id();
+                                found       = found || found_here;
 
-                            // find in constrained feature's Sensor
-                            auto foS    = fo->getCapture()->getSensor();
-                            sb_vec          = foS->getStateBlockVec();
-                            found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                            if (found_here) stream << " foS" << foS->id();
-                            found       = found || found_here;
+                                // find in constrained feature's Sensor
+                                auto foS    = fo->getCapture()->getSensor();
+                                found_here  = foS->hasStateBlock(sb);
+                                if (found_here && _verbose) _stream << " foS" << foS->id();
+                                found       = found || found_here;
+                            }
                         }
 
                         // find in constrained landmark
-                        if (Lo)
+                        for (const auto& Low : c->getLandmarkOtherList())
                         {
-                            sb_vec          = Lo->getStateBlockVec();
-                            found_here      = (std::find(sb_vec.begin(), sb_vec.end(), sb) != sb_vec.end());
-                            if (found_here) stream << " Lo" << Lo->id();
-                            found       = found || found_here;
+                            if (!Low.expired())
+                            {
+                                const auto& Lo = Low.lock();
+                                found_here  = Lo->hasStateBlock(sb);
+                                if (found_here && _verbose) _stream << " Lo" << Lo->id();
+                                found       = found || found_here;
+                            }
                         }
 
-                        if (verbose)
+                        if (_verbose)
                         {
                             if (found)
-                                stream << " found";
+                                _stream << " found";
                             else
-                                stream << " NOT FOUND !";
-                            stream << std::endl;
+                                _stream << " NOT FOUND !";
+                            _stream << std::endl;
                         }
 
+                        // check that the state block has been found somewhere
                         inconsistency_explanation << "The stateblock " << sb << " has not been found (is floating!)";
-                        log.compose(CheckLog((found), inconsistency_explanation.str()));
-                        //Clear inconsistency_explanation
-                        std::stringstream().swap(inconsistency_explanation);
-
-                        inconsistency_explanation << "The stateblock " << sb << " of factor " << c << " is null\n";
-                        log.compose(CheckLog((sb.get() != nullptr), inconsistency_explanation.str()));
-                        //Clear inconsistency_explanation
-                        std::stringstream().swap(inconsistency_explanation);
+                        log.assertTrue((found), inconsistency_explanation);
 
-                        // check that all state block pointers were found
-                        // is_consistent = is_consistent && found;
+                        inconsistency_explanation << "The stateblock " << sb << " of factor " << c->id() << " @ " << c << " is null\n";
+                        log.assertTrue((sb.get() != nullptr), inconsistency_explanation);
                     }
                 }
             }
@@ -1729,98 +1775,93 @@ bool Problem::check(bool verbose, std::ostream& stream) const
     //       MAP branch
     // ------------------------
     auto M = map_ptr_;
-    if (verbose)
-        stream << "Map @ " << M.get() << std::endl;
-    // check pointer to Problem
-    // is_consistent = is_consistent && (M->getProblem().get() == P_raw);
+    if (_verbose)
+        _stream << "Map @ " << M.get() << std::endl;
 
-    inconsistency_explanation << "The map problem ptr is " << M->getProblem().get() << " but problem is " << P_raw << "\n";
-    log.compose(CheckLog((M->getProblem().get() == P_raw), inconsistency_explanation.str()));
-    //Clear inconsistency_explanation
-    std::stringstream().swap(inconsistency_explanation);
+    // check pointer to Problem
+    inconsistency_explanation << "The map problem ptr is " << M->getProblem().get() << " but problem is " << P.get() << "\n";
+    log.assertTrue((M->getProblem() == P), inconsistency_explanation);
 
     // Landmarks =======================================================================================
     for (auto L : M->getLandmarkList())
     {
-        if (verbose)
+        if (_verbose)
         {
-            stream << "  Lmk" << L->id() << " @ " << L.get() << std::endl;
-            stream << "  -> Prb @ " << L->getProblem().get() << std::endl;
-            stream << "  -> Map @ " << L->getMap().get() << std::endl;
+            _stream << "  Lmk" << L->id() << " @ " << L.get() << std::endl;
+            _stream << "  -> Prb @ " << L->getProblem().get() << std::endl;
+            _stream << "  -> Map @ " << L->getMap().get() << std::endl;
             for (const auto& pair : L->getStateBlockMap())
             {
                 auto sb = pair.second;
-                stream <<  "  " << pair.first << " sb @ " << sb.get();
+                _stream <<  "  " << pair.first << " sb @ " << sb.get();
                 if (sb)
                 {
                     auto lp = sb->getLocalParametrization();
                     if (lp)
-                        stream <<  " (lp @ " << lp.get() << ")";
+                        _stream <<  " (lp @ " << lp.get() << ")";
                 }
-                stream << std::endl;
+                _stream << std::endl;
             }
         }
-        // check problem and map pointers
-        // is_consistent = is_consistent && (L->getProblem().get() == P_raw);
 
-        inconsistency_explanation << "The landmarks problem ptr is "
+        // check problem and map pointers
+        inconsistency_explanation << "Landmarks' problem ptr is "
                                   << L->getProblem().get() << " but problem is "
-                                  << P_raw << "\n";
-
-        log.compose(CheckLog((L->getProblem().get() == P_raw), inconsistency_explanation.str()));
-        // Clear inconsistency_explanation
-        std::stringstream().swap(inconsistency_explanation);
+                                  << P.get() << "\n";
 
-        // is_consistent = is_consistent && (L->getMap() == M);
+        log.assertTrue((L->getProblem() == P), inconsistency_explanation);
 
-        inconsistency_explanation << "The landmarks map ptr is "
+        inconsistency_explanation << "The Landmarks' map ptr is "
                                   << L->getMap() << " but map is "
                                   << M << "\n";
-        log.compose(CheckLog((M->getProblem().get() == P_raw), inconsistency_explanation.str()));
-        // Clear inconsistency_explanation
-        std::stringstream().swap(inconsistency_explanation);
-
-        for (auto cby : L->getConstrainedByList()) {
-          if (verbose)
-            stream << "      <- Fac" << cby->id() << " -> Lmk"
-                 << cby->getLandmarkOther()->id() << std::endl;
-          // check constrained_by pointer to this landmark
-          // is_consistent =
-              // is_consistent && (cby->getLandmarkOther() &&
-              //                   L->id() == cby->getLandmarkOther()->id());
-
-          inconsistency_explanation << "The landmark constrained-by loop started at "
-                                    << cby
-                                    << " is not closed\n";
-          log.compose(CheckLog((cby->getLandmarkOther() &&
-                                L->id() == cby->getLandmarkOther()->id()), inconsistency_explanation.str()));
-          // Clear inconsistency_explanation
-          std::stringstream().swap(inconsistency_explanation);
+        log.assertTrue((M->getProblem() == P), inconsistency_explanation);
+
+        for (auto cby : L->getConstrainedByList())
+        {
+          if (_verbose)
+          {
+              _stream << "      <- Fac" << cby->id() << " ->";
+
+              for (const auto& Low : cby->getLandmarkOtherList())
+              {
+                  if (!Low.expired())
+                  {
+                      const auto& Lo = Low.lock();
+                      _stream << " Lmk" << Lo->id();
+                  }
+              }
+              _stream << std::endl;
+          }
+
+          // check constrained-by factors
+          inconsistency_explanation << "constrained-by landmark " << L->id() << " @ " << L
+                                    << " not found among constrained-by factors\n";
+          log.assertTrue((cby->hasLandmarkOther(L)), inconsistency_explanation);
 
           for (auto sb : cby->getStateBlockPtrVector()) {
-            if (verbose) {
-              stream << "      sb @ " << sb.get();
+            if (_verbose) {
+              _stream << "      sb @ " << sb.get();
               if (sb) {
                 auto lp = sb->getLocalParametrization();
                 if (lp)
-                  stream << " (lp @ " << lp.get() << ")";
+                  _stream << " (lp @ " << lp.get() << ")";
               }
-              stream << std::endl;
+              _stream << std::endl;
             }
           }
         }
     }
 
-    if (verbose) stream << "--------------------------- Wolf tree " << (log.is_consistent_ ? " OK" : "Not OK !!") << std::endl;
-    if (verbose) stream << std::endl;
-    if (verbose and not log.is_consistent_) stream << log.explanation_ << std::endl;
+    if (_verbose) _stream << "--------------------------- Wolf tree " << (log.is_consistent_ ? " OK" : "Not OK !!") << std::endl;
+    if (_verbose) _stream << std::endl;
+    if (_verbose and not log.is_consistent_) _stream << log.explanation_ << std::endl;
 
     return log.is_consistent_;
 }
 
-bool Problem::check(int verbose_level) const
+bool Problem::check(int _verbose_level) const
 {
-    return check((verbose_level > 0), std::cout);
+    return check((_verbose_level > 0), std::cout);
 }
 void Problem::print(int depth, bool constr_by, bool metric, bool state_blocks) const
 {
diff --git a/src/processor/processor_base.cpp b/src/processor/processor_base.cpp
index a35097f2c70d3b047117ae6d0c9bf81a5fe2f5da..f61f861b021e51a08dd92db301aa1bd8de159272 100644
--- a/src/processor/processor_base.cpp
+++ b/src/processor/processor_base.cpp
@@ -53,12 +53,13 @@ void ProcessorBase::captureCallback(CaptureBasePtr _capture_ptr)
     assert(_capture_ptr != nullptr && "captureCallback with a nullptr capture");
     WOLF_DEBUG("P", isMotion() ? "M " : "T ", getName(), ": Capture ", _capture_ptr->id(), " callback received with ts = ", _capture_ptr->getTimeStamp());
 
-    // if trigger, process directly without buffering
-    if (triggerInCapture(_capture_ptr))
-        processCapture(_capture_ptr);
     // asking if capture should be stored
     if (storeCapture(_capture_ptr))
         buffer_capture_.add(_capture_ptr->getTimeStamp(), _capture_ptr);
+
+    // if trigger, process directly without buffering
+    if (triggerInCapture(_capture_ptr))
+        processCapture(_capture_ptr);
 }
 
 void ProcessorBase::remove()
@@ -68,12 +69,12 @@ void ProcessorBase::remove()
         is_removing_ = true;
         ProcessorBasePtr this_p = shared_from_this();
 
-        // clear Problem::processor_motion_ptr_
         if (isMotion())
         {
             ProblemPtr P = getProblem();
-            if(P && (P->getProcessorMotion() == std::dynamic_pointer_cast<IsMotion>( shared_from_this() ) ) )
-                P->clearProcessorMotion();
+            auto this_proc_cast_attempt = std::dynamic_pointer_cast<IsMotion>( shared_from_this() );
+            if(P && this_proc_cast_attempt )
+                P->clearProcessorIsMotion(this_proc_cast_attempt);
         }
 
         // remove from upstream
diff --git a/src/processor/processor_motion.cpp b/src/processor/processor_motion.cpp
index 634d1f6d1284997573ef763bd329dcdf37cc94d3..aded1532cc17fc6a0f2e0d48edbbca857a1ab28b 100644
--- a/src/processor/processor_motion.cpp
+++ b/src/processor/processor_motion.cpp
@@ -7,6 +7,7 @@ namespace wolf
 {
 
 ProcessorMotion::ProcessorMotion(const std::string& _type,
+                                 std::string _state_structure,
                                  int _dim,
                                  SizeEigen _state_size,
                                  SizeEigen _delta_size,
@@ -25,7 +26,8 @@ ProcessorMotion::ProcessorMotion(const std::string& _type,
         origin_ptr_(),
         last_ptr_(),
         incoming_ptr_(),
-        dt_(0.0), x_(_state_size),
+        dt_(0.0), 
+        x_(_state_size),
         delta_(_delta_size),
         delta_cov_(_delta_cov_size, _delta_cov_size),
         delta_integrated_(_delta_size),
@@ -34,7 +36,8 @@ ProcessorMotion::ProcessorMotion(const std::string& _type,
         jacobian_delta_preint_(delta_cov_size_, delta_cov_size_),
         jacobian_delta_(delta_cov_size_, delta_cov_size_),
         jacobian_calib_(delta_cov_size_, calib_size_)
-{
+{   
+    setStateStructure(_state_structure);
     //
 }
 
@@ -267,7 +270,7 @@ void ProcessorMotion::processCapture(CaptureBasePtr _incoming_ptr)
     // Update state and time stamps
     last_ptr_->setTimeStamp(getCurrentTimeStamp());
     last_ptr_->getFrame()->setTimeStamp(getCurrentTimeStamp());
-    last_ptr_->getFrame()->setState(getCurrentState());
+    last_ptr_->getFrame()->setState(getProblem()->getState(getCurrentTimeStamp()));
 
     if (permittedKeyFrame() && voteForKeyFrame())
     {
@@ -315,7 +318,7 @@ void ProcessorMotion::processCapture(CaptureBasePtr _incoming_ptr)
 
         // create a new frame
         auto frame_new      = getProblem()->emplaceFrame(NON_ESTIMATED,
-                                                        getCurrentState(),
+                                                        getProblem()->getCurrentState(),
                                                         getCurrentTimeStamp());
         // create a new capture
         auto capture_new    = emplaceCapture(frame_new,
@@ -346,6 +349,7 @@ void ProcessorMotion::processCapture(CaptureBasePtr _incoming_ptr)
     postProcess();
 }
 
+// _x needs to have the size of the processor state
 bool ProcessorMotion::getState(const TimeStamp& _ts, Eigen::VectorXd& _x) const
 {
     CaptureMotionPtr capture_motion;
@@ -360,7 +364,7 @@ bool ProcessorMotion::getState(const TimeStamp& _ts, Eigen::VectorXd& _x) const
     {
         // Get origin state and calibration
         CaptureBasePtr cap_orig   = capture_motion->getOriginCapture();
-        VectorXd state_0          = cap_orig->getFrame()->getState();
+        VectorXd state_0          = cap_orig->getFrame()->getState(state_structure_);
         VectorXd calib            = cap_orig->getCalibration();
 
         // Get delta and correct it with new calibration params
@@ -371,7 +375,7 @@ bool ProcessorMotion::getState(const TimeStamp& _ts, Eigen::VectorXd& _x) const
         VectorXd delta            = capture_motion->correctDelta( motion.delta_integr_, delta_step);
 
         // ensure proper size of the provided reference
-        _x.resize( getProblem()->getFrameStructureSize() );
+        _x.resize( state_0.size() );
 
         // Compose on top of origin state using the buffered time stamp, not the query time stamp
         double dt = motion.ts_ - capture_motion->getBuffer().get().front().ts_;
@@ -380,7 +384,7 @@ bool ProcessorMotion::getState(const TimeStamp& _ts, Eigen::VectorXd& _x) const
     else
     {
         // We could not find any CaptureMotion for the time stamp requested
-        WOLF_ERROR("Could not find any Capture for the time stamp requested. ");
+        WOLF_ERROR("Could not find any Capture for the time stamp requested. ", _ts);
         WOLF_TRACE("Did you forget to call Problem::setPrior() in your application?")
         return false;
     }
@@ -415,9 +419,11 @@ void ProcessorMotion::setOrigin(FrameBasePtr _origin_frame)
 
     // ---------- LAST ----------
     // Make non-key-frame for last Capture
+    TimeStamp origin_ts = _origin_frame->getTimeStamp();
     auto new_frame_ptr  = getProblem()->emplaceFrame(NON_ESTIMATED,
-                                                     _origin_frame->getState(),
-                                                     _origin_frame->getTimeStamp());
+                                                      _origin_frame->getState(),
+                                                     origin_ts);
+                                        
     // emplace (emtpy) last Capture
     last_ptr_ = emplaceCapture(new_frame_ptr,
                                getSensor(),
@@ -562,7 +568,8 @@ CaptureMotionPtr ProcessorMotion::findCaptureContainingTimeStamp(const TimeStamp
             ++frame_rev_iter)
     {
         frame   = *frame_rev_iter;
-        capture = frame->getCaptureOf(getSensor());
+        auto sensor = getSensor();
+        capture = frame->getCaptureOf(sensor);
         if (capture != nullptr)
         {
             // Rule 1 satisfied! We found a Capture belonging to this processor's Sensor ==> it is a CaptureMotion
@@ -621,6 +628,9 @@ PackKeyFramePtr ProcessorMotion::computeProcessingStep()
 
 void ProcessorMotion::setProblem(ProblemPtr _problem)
 {
+    std::string str = "Processor works with " + std::to_string(dim_) + "D but problem is " + std::to_string(_problem->getDim()) + "D";
+    assert((dim_ == 0 or dim_ == _problem->getDim()) && str.c_str());
+
     if (_problem == nullptr or _problem == this->getProblem())
         return;
 
@@ -629,11 +639,10 @@ void ProcessorMotion::setProblem(ProblemPtr _problem)
     // set the origin
     if (origin_ptr_ == nullptr && this->getProblem()->getLastKeyFrame() != nullptr)
         this->setOrigin(this->getProblem()->getLastKeyFrame());
-
-    // set the main processor motion
-    if (this->getProblem()->getProcessorMotion() == nullptr)
-        this->getProblem()->setProcessorMotion(std::static_pointer_cast<ProcessorMotion>(shared_from_this()));
-};
+    
+    // adding processor is motion to the processor is motion vector
+    getProblem()->addProcessorIsMotion(std::dynamic_pointer_cast<IsMotion>(shared_from_this()));
+}
 
 bool ProcessorMotion::storeKeyFrame(FrameBasePtr _frame_ptr)
 {
diff --git a/src/processor/processor_odom_2d.cpp b/src/processor/processor_odom_2d.cpp
index c986ebf7cf9cd7fb83df1417ea19c42beed66c74..929c1ed7ceb825fdaa265a1af592fa8125832789 100644
--- a/src/processor/processor_odom_2d.cpp
+++ b/src/processor/processor_odom_2d.cpp
@@ -6,7 +6,7 @@ namespace wolf
 {
 
 ProcessorOdom2d::ProcessorOdom2d(ProcessorParamsOdom2dPtr _params) :
-                ProcessorMotion("ProcessorOdom2d", 2, 3, 3, 3, 2, 0, _params),
+                ProcessorMotion("ProcessorOdom2d", "PO", 2, 3, 3, 3, 2, 0, _params),
                 params_odom_2d_(_params)
 {
     unmeasured_perturbation_cov_ = _params->unmeasured_perturbation_std * _params->unmeasured_perturbation_std * Matrix3d::Identity();
diff --git a/src/processor/processor_odom_3d.cpp b/src/processor/processor_odom_3d.cpp
index 967031e9ccd1a68fcee41567be0f7dbf7523ef2c..3e1268eb1d705b3a335d9c8d9389e0c9449ebba1 100644
--- a/src/processor/processor_odom_3d.cpp
+++ b/src/processor/processor_odom_3d.cpp
@@ -3,7 +3,7 @@ namespace wolf
 {
 
 ProcessorOdom3d::ProcessorOdom3d(ProcessorParamsOdom3dPtr _params) :
-                        ProcessorMotion("ProcessorOdom3d", 3, 7, 7, 6, 6, 0, _params),
+                        ProcessorMotion("ProcessorOdom3d", "PO", 3, 7, 7, 6, 6, 0, _params),
                         params_odom_3d_ (_params),
                         k_disp_to_disp_ (0),
                         k_disp_to_rot_  (0),
diff --git a/src/utils/check_log.cpp b/src/utils/check_log.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..06e58733aa3d99b9cffa312a9a88bdb223d15eb5
--- /dev/null
+++ b/src/utils/check_log.cpp
@@ -0,0 +1,29 @@
+#include "core/utils/check_log.h"
+
+using namespace wolf;
+
+CheckLog::CheckLog()
+{
+    is_consistent_ = true;
+    explanation_   = "";
+}
+CheckLog::CheckLog(bool _consistent, std::string _explanation)
+{
+    is_consistent_ = _consistent;
+    if (not _consistent)
+        explanation_ = _explanation;
+    else
+        explanation_ = "";
+}
+void CheckLog::compose(CheckLog l)
+{
+    is_consistent_ = is_consistent_ and l.is_consistent_;
+    explanation_   = explanation_ + l.explanation_;
+}
+void CheckLog::assertTrue(bool _condition, std::stringstream& _stream)
+{
+    auto cl = CheckLog(_condition, _stream.str());
+    this->compose(cl);
+    // Clear inconsistency_explanation
+    std::stringstream().swap(_stream);
+}
diff --git a/src/utils/loader.cpp b/src/utils/loader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9fdf6984b6a3de57fa8a8ae062232a685897209f
--- /dev/null
+++ b/src/utils/loader.cpp
@@ -0,0 +1,37 @@
+#include "core/utils/loader.h"
+
+#include <dlfcn.h>
+#include <stdexcept>
+
+Loader::Loader(std::string _file)
+{
+    path_ = _file;
+}
+LoaderRaw::LoaderRaw(std::string _file) : Loader(_file)
+{
+    //
+}
+LoaderRaw::~LoaderRaw()
+{
+    close();
+}
+void LoaderRaw::load()
+{
+    resource_ = dlopen(path_.c_str(), RTLD_LAZY);
+    if (not resource_)
+        throw std::runtime_error("Couldn't load resource with path " + path_ + "\n" + "Error info: " + dlerror());
+}
+void LoaderRaw::close()
+{
+    if (resource_)
+        dlclose(resource_);
+}
+// class LoaderPlugin: public Loader{
+//     ClassLoader* resource_;
+//     void load(){
+//         resource_ = new ClassLoader(path_);
+//     }
+//     void close(){
+//         delete resource_;
+//     }
+// };
diff --git a/src/utils/params_server.cpp b/src/utils/params_server.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6344466792706c9e499695721f95e781089ec07e
--- /dev/null
+++ b/src/utils/params_server.cpp
@@ -0,0 +1,28 @@
+#include "core/utils/params_server.h"
+
+using namespace wolf;
+
+ParamsServer::ParamsServer()
+{
+    params_ = std::map<std::string, std::string>();
+}
+ParamsServer::ParamsServer(std::map<std::string, std::string> _params)
+{
+    params_ = _params;
+}
+
+void ParamsServer::print()
+{
+    for (auto it : params_)
+        std::cout << it.first << "~~" << it.second << std::endl;
+}
+
+void ParamsServer::addParam(std::string _key, std::string _value)
+{
+    params_.insert(std::pair<std::string, std::string>(_key, _value));
+}
+
+void ParamsServer::addParams(std::map<std::string, std::string> _params)
+{
+    params_.insert(_params.begin(), _params.end());
+}
diff --git a/src/yaml/parser_yaml.cpp b/src/yaml/parser_yaml.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..267d0c9da2024abd59ed5b529d13de7680d14472
--- /dev/null
+++ b/src/yaml/parser_yaml.cpp
@@ -0,0 +1,547 @@
+#include "core/yaml/parser_yaml.h"
+
+#include <string>
+#include <vector>
+#include <list>
+#include <stack>
+#include <regex>
+#include <map>
+#include <iostream>
+#include <algorithm>
+#include <numeric>
+
+using namespace wolf;
+namespace {
+  //====== START OF FORWARD DECLARATION ========
+  std::string parseAtomicNode(YAML::Node);
+  std::string fetchMapEntry(YAML::Node);
+  std::string mapToString(std::map<std::string,std::string>);
+  //====== END OF FORWARD DECLARATION ========
+
+/** @Brief Interprets a map as being atomic and thus parses it as a single entity. We assume that the map has as values only scalars and sequences.
+ *  @param n the node representing a map
+ *  @return std::map<std::string, std::string> populated with the key,value pairs in n
+ */
+std::map<std::string, std::string> fetchAsMap(YAML::Node _n){
+    assert(_n.Type() == YAML::NodeType::Map && "trying to fetch as Map a non-Map node");
+    auto m = std::map<std::string, std::string>();
+    for(const auto& kv : _n){
+        std::string key = kv.first.as<std::string>();
+        switch (kv.second.Type()) {
+        case YAML::NodeType::Scalar : {
+            std::string value = kv.second.Scalar();
+            m.insert(std::pair<std::string,std::string>(key, value));
+            break;
+        }
+        case YAML::NodeType::Sequence : {
+            std::string aux = parseAtomicNode(kv.second);
+            m.insert(std::pair<std::string,std::string>(key, aux));
+            break;
+        }
+        case YAML::NodeType::Map : {
+          std::string value = fetchMapEntry(kv.second);
+          std::regex r("^\\$.*");
+          if (std::regex_match(key, r)) key = key.substr(1,key.size()-1);
+          m.insert(std::pair<std::string,std::string>(key, value));
+          break;
+        }
+        default:
+            assert(1 == 0 && "Unsupported node Type at fetchAsMap");
+            break;
+        }
+    }
+    return m;
+}
+  std::string fetchMapEntry(YAML::Node _n){
+    switch (_n.Type()) {
+    case YAML::NodeType::Scalar: {
+      return _n.Scalar();
+      break;
+    }
+    case YAML::NodeType::Sequence: {
+      return parseAtomicNode(_n);
+      break;
+    }
+    case YAML::NodeType::Map: {
+      return mapToString(fetchAsMap(_n));
+      break;
+    }
+    default: {
+      assert(1 == 0 && "Unsupported node Type at fetchMapEntry");
+      return "";
+      break;
+    }
+    }
+  }
+    /** @Brief Transforms a std::map<std::string,std::string> to its std::string representation [{k1:v1},{k2:v2},{k3:v3},...]
+    * @param map_ just a std::map<std::string,std::string>
+    * @return <b>{std::string}</b> [{k1:v1},{k2:v2},{k3:v3},...]
+    */
+    std::string mapToString(std::map<std::string,std::string> _map){
+        std::string result = "";
+        auto v = std::vector<std::string>();
+        std::transform(_map.begin(), _map.end(), back_inserter(v), [](const std::pair<std::string,std::string> p){return "{" + p.first + ":" + p.second + "}";});
+        auto concat = [](std::string ac, std::string str)-> std::string {
+                          return ac + str + ",";
+                      };
+        std::string aux = "";
+        std::string accumulated = std::accumulate(v.begin(), v.end(), aux, concat);
+        if(accumulated.size() > 1) accumulated = accumulated.substr(0,accumulated.size() - 1);
+        else accumulated = "";
+        return "[" + accumulated + "]";
+    }
+    /** @Brief Generates a std::string representing a YAML sequence. The sequence is assumed to be scalar or at most be a sequence of sequences of scalars.
+    * @param n a vector of YAML::Node that represents a YAML::Sequence
+    * @return <b>{std::string}</b> representing the YAML sequence
+    */
+    std::string parseAtomicNode(YAML::Node _n){
+      std::string aux = "";
+      bool first = true;
+      std::string separator = "";
+      switch(_n.Type()){
+      case YAML::NodeType::Scalar:
+        return _n.Scalar();
+        break;
+      case YAML::NodeType::Sequence:
+        for(auto it : _n){
+          aux += separator + parseAtomicNode(it);
+          if(first){
+            separator = ",";
+            first = false;
+          }
+        }
+        return "[" + aux + "]";
+        break;
+      case YAML::NodeType::Map:
+        return mapToString(fetchAsMap(_n));
+        break;
+      default:
+        return "";
+        break;
+      }
+    }
+
+    /** @Brief checks if a node of the YAML tree is atomic. Only works if the nodes are of type
+     * Scalar, Sequence or Map.
+     * @param key is the key associated to the node n if n.Type() == YAML::NodeType::Map
+     * @param n node to be test for atomicity
+    */
+    bool isAtomic(std::string _key, YAML::Node _n){
+      assert(_n.Type() != YAML::NodeType::Undefined && _n.Type() != YAML::NodeType::Null && "Cannot determine atomicity of Undefined/Null node");
+      std::regex r("^\\$.*");
+      bool is_atomic = true;
+      switch(_n.Type()){
+      case YAML::NodeType::Scalar:
+        return true;
+        break;
+      case YAML::NodeType::Sequence:
+        for(auto it : _n) {
+          switch(it.Type()){
+          case YAML::NodeType::Map:
+            for(const auto& kv : it){
+              is_atomic = is_atomic and isAtomic(kv.first.as<std::string>(), it);
+            }
+            break;
+          default:
+            is_atomic = is_atomic and isAtomic("", it);
+            break;
+          }
+        }
+        return is_atomic;
+        break;
+      case YAML::NodeType::Map:
+        is_atomic = std::regex_match(_key, r);
+        return is_atomic;
+        break;
+      default:
+        throw std::runtime_error("Cannot determine atomicity of node type " + std::to_string(_n.Type()));
+        return false;
+        break;
+      }
+      return false;
+    }
+}
+ParserYAML::ParserYAML(std::string _file, std::string path_root, bool freely_parse)
+{
+    params_              = std::map<std::string, std::string>();
+    active_name_         = "";
+    paramsSens_          = std::vector<ParamsInitSensor>();
+    paramsProc_          = std::vector<ParamsInitProcessor>();
+    subscriber_managers_ = std::vector<SubscriberManager>();
+    publisher_managers_  = std::vector<PublisherManager>();
+    parsing_file_        = std::stack<std::string>();
+    file_                = _file;
+    if (path_root != "")
+    {
+        std::regex r(".*/ *$");
+        if (not std::regex_match(path_root, r))
+            path_root_ = path_root + "/";
+        else
+            path_root_ = path_root;
+    }
+    if (not freely_parse)
+        parse();
+    else
+        parse_freely();
+}
+
+std::string ParserYAML::generatePath(std::string _file)
+{
+    std::regex r("^/.*");
+    if (std::regex_match(_file, r))
+    {
+        return _file;
+    }
+    else
+    {
+        return path_root_ + _file;
+    }
+}
+YAML::Node ParserYAML::loadYAML(std::string _file)
+{
+    try
+    {
+        // std::cout << "Parsing " << generatePath(_file) << std::endl;
+        WOLF_INFO("Parsing file: ", generatePath(_file));
+        return YAML::LoadFile(generatePath(_file));
+    }
+    catch (YAML::BadFile& e)
+    {
+        throw std::runtime_error("Couldn't load file " + generatePath(_file) + ". Tried to open it from " +
+                                 parsing_file_.top());
+    }
+}
+std::string ParserYAML::tagsToString(std::vector<std::string>& _tags)
+{
+    std::string hdr = "";
+    for (auto it : _tags)
+    {
+        hdr = hdr + "/" + it;
+    }
+    return hdr;
+}
+void ParserYAML::walkTree(std::string _file)
+{
+    YAML::Node n;
+    n = loadYAML(generatePath(_file));
+    parsing_file_.push(generatePath(_file));
+    std::vector<std::string> hdrs = std::vector<std::string>();
+    walkTreeR(n, hdrs, "");
+    parsing_file_.pop();
+}
+void ParserYAML::walkTree(std::string _file, std::vector<std::string>& _tags)
+{
+    YAML::Node n;
+    n = loadYAML(generatePath(_file));
+    parsing_file_.push(generatePath(_file));
+    walkTreeR(n, _tags, "");
+    parsing_file_.pop();
+}
+void ParserYAML::walkTree(std::string _file, std::vector<std::string>& _tags, std::string hdr)
+{
+    YAML::Node n;
+    n = loadYAML(generatePath(_file));
+    parsing_file_.push(generatePath(_file));
+    walkTreeR(n, _tags, hdr);
+    parsing_file_.pop();
+}
+void ParserYAML::walkTreeR(YAML::Node _n, std::vector<std::string>& _tags, std::string hdr)
+{
+    switch (_n.Type())
+    {
+        case YAML::NodeType::Scalar:
+        {
+            std::regex r("^@.*");
+            if (std::regex_match(_n.Scalar(), r))
+            {
+                std::string str = _n.Scalar();
+                walkTree(str.substr(1, str.size() - 1), _tags, hdr);
+            }
+            else
+            {
+                insert_register(hdr, _n.Scalar());
+            }
+            break;
+        }
+        case YAML::NodeType::Sequence:
+        {
+            if (isAtomic("", _n))
+            {
+                insert_register(hdr, parseAtomicNode(_n));
+            }
+            else
+            {
+                for (const auto& kv : _n)
+                {
+                    walkTreeR(kv, _tags, hdr);
+                }
+            }
+            break;
+        }
+        case YAML::NodeType::Map:
+        {
+            for (const auto& kv : _n)
+            {
+                if (isAtomic(kv.first.as<std::string>(), _n))
+                {
+                    std::string key = kv.first.as<std::string>();
+                    // WOLF_DEBUG("KEY IN MAP ATOMIC ", hdr + "/" + key);
+                    key = key.substr(1, key.size() - 1);
+                    insert_register(hdr + "/" + key, parseAtomicNode(kv.second));
+                }
+                else
+                {
+                    /*
+                      If key=="follow" then the parser will assume that the value is a path and will parse
+                      the (expected) yaml file at the specified path. Note that this does not increase the header depth.
+                      The following example shows how the header remains unafected:
+                      @my_main_config                |  @some_path
+                      - cov_det: 1                   |  - my_value : 23
+                      - follow: "@some_path"         |
+                      - var: 1.2                     |
+                      Resulting map:
+                      cov_det -> 1
+                      my_value-> 23
+                      var: 1.2
+                      Instead of:
+                      cov_det -> 1
+                      follow/my_value-> 23
+                      var: 1.2
+                      Which would result from the following yaml files
+                      @my_main_config                |  @some_path
+                      - cov_det: 1                   |  - my_value : 23
+                      - $follow: "@some_path"        |
+                      - var: 1.2                     |
+                    */
+                    std::string key = kv.first.as<std::string>();
+                    // WOLF_DEBUG("KEY IN MAP NON ATOMIC ", key);
+                    std::regex rr("follow");
+                    if (not std::regex_match(kv.first.as<std::string>(), rr))
+                    {
+                        _tags.push_back(kv.first.as<std::string>());
+                        if (_tags.size() == 2)
+                            updateActiveName(kv.first.as<std::string>());
+                        walkTreeR(kv.second, _tags, hdr + "/" + kv.first.as<std::string>());
+                        _tags.pop_back();
+                        if (_tags.size() == 1)
+                            updateActiveName("");
+                    }
+                    else
+                    {
+                        walkTree(kv.second.as<std::string>(), _tags, hdr);
+                    }
+                }
+            }
+            break;
+        }
+        case YAML::NodeType::Null:
+            break;
+        default:
+            assert(1 == 0 && "Unsupported node Type at walkTreeR.");
+            break;
+    }
+}
+void ParserYAML::updateActiveName(std::string _tag)
+{
+    active_name_ = _tag;
+}
+void ParserYAML::parseFirstLevel(std::string _file)
+{
+    YAML::Node n;
+    n = loadYAML(generatePath(_file));
+
+    YAML::Node n_config = n["config"];
+    // assert(n_config.Type() == YAML::NodeType::Map && "trying to parse config node but found a non-Map node");
+    if (n_config.Type() != YAML::NodeType::Map)
+        throw std::runtime_error("Could not find config node. Please make sure that your YAML file " +
+                                 generatePath(_file) + " starts with 'config:'");
+    if (n_config["problem"].Type() != YAML::NodeType::Map)
+        throw std::runtime_error("Could not find problem node. Please make sure that the 'config' node in YAML file " +
+                                 generatePath(_file) + " has a 'problem' entry");
+    problem = n_config["problem"];
+    std::vector<std::map<std::string, std::string>> map_container;
+    try
+    {
+        for (const auto& kv : n_config["sensors"])
+        {
+            ParamsInitSensor pSensor = { kv["type"].Scalar(), kv["name"].Scalar(), kv["plugin"].Scalar(), kv };
+            paramsSens_.push_back(pSensor);
+            map_container.push_back(std::map<std::string, std::string>({ { "type", kv["type"].Scalar() },
+                                                                         { "name", kv["name"].Scalar() },
+                                                                         { "plugin", kv["plugin"].Scalar() } }));
+        }
+        insert_register("sensors", wolf::converter<std::string>::convert(map_container));
+        map_container.clear();
+    }
+    catch (YAML::InvalidNode& e)
+    {
+        throw std::runtime_error("Error parsing sensors @" + generatePath(_file) +
+                                 ". Please make sure that each sensor entry has 'type', 'name' and 'plugin' entries.");
+    }
+
+    try
+    {
+        for (const auto& kv : n_config["processors"])
+        {
+            ParamsInitProcessor pProc = {
+                kv["type"].Scalar(), kv["name"].Scalar(), kv["sensor_name"].Scalar(), kv["plugin"].Scalar(), kv
+            };
+            paramsProc_.push_back(pProc);
+            map_container.push_back(
+                std::map<std::string, std::string>({ { "type", kv["type"].Scalar() },
+                                                     { "name", kv["name"].Scalar() },
+                                                     { "plugin", kv["plugin"].Scalar() },
+                                                     { "sensor_name", kv["sensor_name"].Scalar() } }));
+        }
+        insert_register("processors", wolf::converter<std::string>::convert(map_container));
+        map_container.clear();
+    }
+    catch (YAML::InvalidNode& e)
+    {
+        throw std::runtime_error("Error parsing processors @" + generatePath(_file) +
+                                 ". Please make sure that each processor has 'type', 'name', 'plugin' and "
+                                 "'sensor_name' entries.");
+    }
+    try
+    {
+        for (const auto& kv : n_config["ROS subscriber"])
+        {
+            SubscriberManager pSubscriberManager = {
+                kv["package"].Scalar(), kv["type"].Scalar(), kv["topic"].Scalar(), kv["sensor_name"].Scalar(), kv
+            };
+            subscriber_managers_.push_back(pSubscriberManager);
+            map_container.push_back(
+                std::map<std::string, std::string>({ { "package", kv["package"].Scalar() },
+                                                     { "type", kv["type"].Scalar() },
+                                                     { "topic", kv["topic"].Scalar() },
+                                                     { "sensor_name", kv["sensor_name"].Scalar() } }));
+        }
+        insert_register("ROS subscriber", wolf::converter<std::string>::convert(map_container));
+        map_container.clear();
+    }
+    catch (YAML::InvalidNode& e)
+    {
+        throw std::runtime_error("Error parsing subscriber @" + generatePath(_file) +
+                                 ". Please make sure that each manager has 'package', 'type', 'topic' and "
+                                 "'sensor_name' entries.");
+    }
+
+    try
+    {
+        for (const auto& kv : n_config["ROS publisher"])
+        {
+            WOLF_DEBUG("WHAT");
+            PublisherManager pPublisherManager = {
+                kv["type"].Scalar(), kv["topic"].Scalar(), kv["period"].Scalar(), kv
+            };
+            publisher_managers_.push_back(pPublisherManager);
+            map_container.push_back(std::map<std::string, std::string>({ { "type", kv["type"].Scalar() },
+                                                                         { "topic", kv["topic"].Scalar() },
+                                                                         { "period", kv["period"].Scalar() } }));
+        }
+        insert_register("ROS publisher", wolf::converter<std::string>::convert(map_container));
+        map_container.clear();
+    }
+    catch (YAML::InvalidNode& e)
+    {
+        throw std::runtime_error("Error parsing publisher @" + generatePath(_file) +
+                                 ". Please make sure that each manager has 'type', 'topic' and 'period' entries.");
+    }
+}
+std::map<std::string, std::string> ParserYAML::getParams()
+{
+    std::map<std::string, std::string> rtn = params_;
+    return rtn;
+}
+void ParserYAML::parse()
+{
+    parsing_file_.push(generatePath(file_));
+    parseFirstLevel(file_);
+
+    if (problem.Type() != YAML::NodeType::Undefined)
+    {
+        std::vector<std::string> tags = std::vector<std::string>();
+        walkTreeR(problem, tags, "problem");
+    }
+    for (auto it : paramsSens_)
+    {
+        std::vector<std::string> tags = std::vector<std::string>();
+        tags.push_back("sensor");
+        walkTreeR(it.n_, tags, "sensor/" + it.name_);
+    }
+    for (auto it : paramsProc_)
+    {
+        std::vector<std::string> tags = std::vector<std::string>();
+        tags.push_back("processor");
+        walkTreeR(it.n_, tags, "processor/" + it.name_);
+    }
+    std::list<std::string> plugins, packages;
+    for (const auto& it : paramsSens_)
+        plugins.push_back(it.plugin_);
+    for (const auto& it : paramsProc_)
+        plugins.push_back(it.plugin_);
+    for (const auto& it : subscriber_managers_)
+        packages.push_back(it.package_);
+    plugins.sort();
+    plugins.unique();
+    packages.sort();
+    packages.unique();
+    insert_register("plugins", wolf::converter<std::string>::convert(plugins));
+    insert_register("packages", wolf::converter<std::string>::convert(packages));
+
+    YAML::Node n;
+    n = loadYAML(generatePath(file_));
+
+    if (n.Type() == YAML::NodeType::Map)
+    {
+        for (auto it : n)
+        {
+            auto node = it.second;
+            // WOLF_INFO("WUT ", it.first);
+            std::vector<std::string> tags = std::vector<std::string>();
+            if (it.first.as<std::string>() != "config")
+                walkTreeR(node, tags, it.first.as<std::string>());
+            else
+            {
+                for (auto itt : node)
+                {
+                    std::string node_key = itt.first.as<std::string>();
+                    if (node_key != "problem" and node_key != "sensors" and node_key != "processors" and
+                        node_key != "ROS subscriber" and node_key != "ROS publisher")
+                    {
+                        walkTreeR(itt.second, tags, node_key);
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        std::vector<std::string> tags = std::vector<std::string>();
+        walkTreeR(n, tags, "");
+    }
+    parsing_file_.pop();
+}
+void ParserYAML::parse_freely()
+{
+    parsing_file_.push(generatePath(file_));
+    std::vector<std::string> tags = std::vector<std::string>();
+    walkTreeR(loadYAML(file_), tags, "");
+    parsing_file_.pop();
+}
+void ParserYAML::insert_register(std::string _key, std::string _value)
+{
+    if (_key.substr(0, 1) == "/")
+        _key = _key.substr(1, _key.size() - 1);
+    auto inserted_it = params_.insert(std::pair<std::string, std::string>(_key, _value));
+    if (not inserted_it.second)
+        WOLF_WARN("Skipping key '",
+                  _key,
+                  "' with value '",
+                  _value,
+                  "'. There already exists the register: (",
+                  inserted_it.first->first,
+                  ",",
+                  inserted_it.first->second,
+                  ")");
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 83e0aa1df36f4018463fc2bb16ac57f96e329def..501965cdff67102f807e482f87ca7eafb7109e54 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -47,13 +47,9 @@ add_library(dummy ${SRC_DUMMY})
 wolf_add_gtest(gtest_capture_base gtest_capture_base.cpp)
 target_link_libraries(gtest_capture_base ${PROJECT_NAME})
 
-# CaptureBase class test
-#wolf_add_gtest(gtest_factor_sparse gtest_factor_sparse.cpp)
-#target_link_libraries(gtest_factor_sparse ${PROJECT_NAME})
-
-# FactorBlockDifference class test
-wolf_add_gtest(gtest_factor_block_difference gtest_factor_block_difference.cpp)
-target_link_libraries(gtest_factor_block_difference ${PROJECT_NAME})
+# FactorBase class test
+wolf_add_gtest(gtest_factor_base gtest_factor_base.cpp)
+target_link_libraries(gtest_factor_base ${PROJECT_NAME})
 
 # FactorAutodiff class test
 wolf_add_gtest(gtest_factor_autodiff gtest_factor_autodiff.cpp)
@@ -173,6 +169,10 @@ target_link_libraries(gtest_factor_absolute ${PROJECT_NAME})
 wolf_add_gtest(gtest_factor_autodiff_distance_3d gtest_factor_autodiff_distance_3d.cpp)
 target_link_libraries(gtest_factor_autodiff_distance_3d ${PROJECT_NAME})
 
+# FactorBlockDifference class test
+wolf_add_gtest(gtest_factor_block_difference gtest_factor_block_difference.cpp)
+target_link_libraries(gtest_factor_block_difference ${PROJECT_NAME})
+
 # FactorOdom3d class test
 wolf_add_gtest(gtest_factor_diff_drive gtest_factor_diff_drive.cpp)
 target_link_libraries(gtest_factor_diff_drive ${PROJECT_NAME})
diff --git a/test/gtest_factor_base.cpp b/test/gtest_factor_base.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9e4f2ef10e8bf2fc1fb9a47d48468e254e46d0af
--- /dev/null
+++ b/test/gtest_factor_base.cpp
@@ -0,0 +1,120 @@
+/*
+ * gtest_factor_base.cpp
+ *
+ *  Created on: Apr 2, 2020
+ *      Author: jsola
+ */
+
+
+#include "core/utils/utils_gtest.h"
+#include "core/utils/logging.h"
+
+#include "core/factor/factor_base.h"
+
+using namespace wolf;
+using namespace Eigen;
+
+class FactorBaseTest : public testing::Test
+{
+    public:
+        FrameBasePtr F0,F1;
+        CaptureBasePtr C0,C1;
+        FeatureBasePtr f0,f1;
+        LandmarkBasePtr L0,L1;
+
+        virtual void SetUp()
+        {
+            F0 = std::make_shared<FrameBase>(0.0, nullptr);
+            F1 = std::make_shared<FrameBase>(1.0, nullptr);
+            C0 = std::make_shared<CaptureBase>("Capture", 0.0, nullptr);
+            C1 = std::make_shared<CaptureBase>("Capture", 1.0, nullptr);
+            f0 = std::make_shared<FeatureBase>("Feature", Vector2d(1,2), Matrix2d::Identity(), FeatureBase::UncertaintyType::UNCERTAINTY_IS_COVARIANCE);
+            f1 = std::make_shared<FeatureBase>("Feature", Vector2d(1,2), Matrix2d::Identity(), FeatureBase::UncertaintyType::UNCERTAINTY_IS_COVARIANCE);
+            L0 = std::make_shared<LandmarkBase>("Lmk", nullptr);
+            L1 = std::make_shared<LandmarkBase>("Lmk", nullptr);
+        }
+//        virtual void TearDown(){}
+};
+
+class FactorDummy : public FactorBase
+{
+    public:
+        FactorDummy(const FrameBasePtr& _frame_other,
+                    const CaptureBasePtr& _capture_other,
+                    const FeatureBasePtr& _feature_other,
+                    const LandmarkBasePtr& _landmark_other) :
+                        FactorBase("Dummy",
+                                   _frame_other,
+                                   _capture_other,
+                                   _feature_other,
+                                   _landmark_other,
+                                   nullptr,
+                                   false)
+        {
+            //
+        }
+        FactorDummy(const FrameBasePtrList& _frame_other_list,
+                    const CaptureBasePtrList& _capture_other_list,
+                    const FeatureBasePtrList& _feature_other_list,
+                    const LandmarkBasePtrList& _landmark_other_list) :
+                        FactorBase("Dummy",
+                                   _frame_other_list,
+                                   _capture_other_list,
+                                   _feature_other_list,
+                                   _landmark_other_list,
+                                   nullptr,
+                                   false)
+        {
+            //
+        }
+        virtual ~FactorDummy() = default;
+
+        virtual std::string getTopology() const override {return "DUMMY";}
+        virtual bool evaluate(double const* const* _parameters, double* _residuals, double** _jacobians) const override {return true;}
+        virtual void evaluate(const std::vector<const double*>& _states_ptr, Eigen::VectorXd& _residual, std::vector<Eigen::MatrixXd>& _jacobians) const override {}
+        virtual JacobianMethod getJacobianMethod() const override {return JacobianMethod::JAC_ANALYTIC;}
+        virtual std::vector<StateBlockPtr> getStateBlockPtrVector() const override {std::vector<StateBlockPtr> v; return v;}
+        virtual std::vector<unsigned int> getStateSizes() const override {std::vector<unsigned int> v; return v;}
+        virtual unsigned int getSize() const override {return 0;}
+
+};
+
+TEST_F(FactorBaseTest, constructor_from_pointers)
+{
+    FactorDummy fac(nullptr,C0,f0,nullptr);
+
+    ASSERT_TRUE(fac.getFrameOtherList().empty());
+
+    ASSERT_EQ(fac.getCaptureOtherList().size(), 1);
+
+    ASSERT_EQ(fac.getFeatureOtherList().size(), 1);
+
+    ASSERT_TRUE(fac.getLandmarkOtherList().empty());
+}
+
+TEST_F(FactorBaseTest, constructor_from_lists)
+{
+    FactorDummy fac({},{C0},{f0,f1},{});
+
+    ASSERT_TRUE(fac.getFrameOtherList().empty());
+
+    ASSERT_EQ(fac.getCaptureOtherList().size(), 1);
+
+    ASSERT_EQ(fac.getFeatureOtherList().size(), 2);
+
+    ASSERT_TRUE(fac.getLandmarkOtherList().empty());
+}
+
+
+int main(int argc, char **argv)
+{
+    testing::InitGoogleTest(&argc, argv);
+
+    // restrict to a group of tests only
+    //::testing::GTEST_FLAG(filter) = "TestInit.*";
+
+    // restrict to this test only
+    //::testing::GTEST_FLAG(filter) = "TestInit.testName";
+
+    return RUN_ALL_TESTS();
+}
diff --git a/test/gtest_factor_block_difference.cpp b/test/gtest_factor_block_difference.cpp
index 20bbe2c42ed27688820569a3da345596da3903f1..1e06c7a80377b99197a721e85473319f9bf34862 100644
--- a/test/gtest_factor_block_difference.cpp
+++ b/test/gtest_factor_block_difference.cpp
@@ -50,18 +50,17 @@ class FixtureFactorBlockDifference : public testing::Test
 
             Vector10d x_origin = problem_->zeroState();
             Eigen::Matrix9d cov_prior = 1e-3 * Eigen::Matrix9d::Identity(); 
-            KF0_ =problem_->setPrior(x_origin, cov_prior, t0, 0.1);
+            KF0_ = problem_->setPrior(x_origin, cov_prior, t0, 0.1);
             
             CaptureBasePtr capV0 = CaptureBase::emplace<CaptureBase>(KF0_, "Vel0", t0);
             FeatureBasePtr featV0 = FeatureBase::emplace<FeatureBase>(capV0, "Vel0", x_origin.tail(3), cov_prior.bottomRightCorner<3,3>());
             FactorBasePtr facV0 = FactorBase::emplace<FactorBlockAbsolute>(featV0, KF0_->getV());
 
-            // KF0_ = problem_->emplaceFrame(KEY, problem_->zeroState(), t0);
             KF1_ = problem_->emplaceFrame(KEY, problem_->zeroState(), t1);
 
-            Cap_ = CaptureBase::emplace<CaptureBase>(KF1_, "DIFF", t1);
+            Cap_ = CaptureBase::emplace<CaptureBase>(KF1_, "BlockDifference", t1);
             Eigen::Matrix3d cov = 0.2 * Eigen::Matrix3d::Identity();
-            Feat_ = FeatureBase::emplace<FeatureBase>(Cap_, "DIFF", zero3, cov);
+            Feat_ = FeatureBase::emplace<FeatureBase>(Cap_, "BlockDifference", zero3, cov);
         }
 
         virtual void TearDown() override {}
@@ -150,6 +149,7 @@ TEST_F(FixtureFactorBlockDifference, DiffPx)
     Feat_->setMeasurementCovariance(cov_diff);
     FactorBlockDifferencePtr Fac = FactorBase::emplace<FactorBlockDifference>(
         Feat_, KF0_->getP(), KF1_->getP(),
+        nullptr, nullptr, nullptr, nullptr,
         0, 1, 0, 1
     );
 
@@ -174,6 +174,7 @@ TEST_F(FixtureFactorBlockDifference, DiffPxy)
     Feat_->setMeasurementCovariance(cov_diff);
     FactorBlockDifferencePtr Fac = FactorBase::emplace<FactorBlockDifference>(
         Feat_, KF0_->getP(), KF1_->getP(),
+        nullptr, nullptr, nullptr, nullptr,
         0, 2, 0, 2
     );
 
@@ -195,6 +196,7 @@ TEST_F(FixtureFactorBlockDifference, DiffPyz)
     Feat_->setMeasurementCovariance(cov_diff);
     FactorBlockDifferencePtr Fac = FactorBase::emplace<FactorBlockDifference>(
         Feat_, KF0_->getP(), KF1_->getP(),
+        nullptr, nullptr, nullptr, nullptr,
         1, 2, 1, 2
     );
 
diff --git a/test/gtest_has_state_blocks.cpp b/test/gtest_has_state_blocks.cpp
index d8b46e9b721fa4f9947138eee2655ed3ad25bff0..df90859ba57d46382d97e7fa29fa66b23b137580 100644
--- a/test/gtest_has_state_blocks.cpp
+++ b/test/gtest_has_state_blocks.cpp
@@ -162,6 +162,23 @@ TEST_F(HasStateBlocksTest, Add_solve_notify_solve_add)
 
 }
 
+TEST_F(HasStateBlocksTest, hasStateBlock)
+{
+    ASSERT_TRUE(F0->hasStateBlock(sbp0));
+    ASSERT_FALSE(F0->hasStateBlock(sbv1));
+}
+
+TEST_F(HasStateBlocksTest, stateBlockKey)
+{
+    std::string key;
+    ASSERT_TRUE(F0->stateBlockKey(sbp0, key));
+    ASSERT_TRUE(key == "P");
+
+    ASSERT_FALSE(F0->stateBlockKey(sbp1, key));
+    ASSERT_TRUE(key == "");
+}
+
+
 int main(int argc, char **argv)
 {
   testing::InitGoogleTest(&argc, argv);
diff --git a/test/gtest_param_server.cpp b/test/gtest_param_server.cpp
index 18f6b1eded0955faf7c6b823e25bbde62894203d..1f1f468360e1aa5073606f8ea32e7d82cafbc438 100644
--- a/test/gtest_param_server.cpp
+++ b/test/gtest_param_server.cpp
@@ -1,8 +1,8 @@
 #include "core/utils/utils_gtest.h"
 #include "core/utils/converter.h"
 #include "core/common/wolf.h"
-#include "core/yaml/parser_yaml.hpp"
-#include "core/utils/params_server.hpp"
+#include "core/yaml/parser_yaml.h"
+#include "core/utils/params_server.h"
 
 using namespace std;
 using namespace wolf;
diff --git a/test/gtest_parser_yaml.cpp b/test/gtest_parser_yaml.cpp
index c8702619bc5150eb688bcb7dccfa11f71ab909e5..de5164ec6a9db61ad8a0344e8e6ee6d6e52dec16 100644
--- a/test/gtest_parser_yaml.cpp
+++ b/test/gtest_parser_yaml.cpp
@@ -1,7 +1,7 @@
 #include "core/utils/utils_gtest.h"
 #include "core/utils/converter.h"
 #include "core/common/wolf.h"
-#include "core/yaml/parser_yaml.hpp"
+#include "core/yaml/parser_yaml.h"
 
 using namespace std;
 using namespace wolf;
diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp
index e0ba9a42a17936b62ec329c1fb022052d5ae6c30..6d262ba06b81438499b29ab3d45fd4bb101c89db 100644
--- a/test/gtest_problem.cpp
+++ b/test/gtest_problem.cpp
@@ -19,8 +19,12 @@
 #include "core/sensor/sensor_diff_drive.h"
 #include "core/processor/processor_diff_drive.h"
 #include "core/capture/capture_diff_drive.h"
+//#include "core/feature/feature_diff_drive.h"
+#include "core/factor/factor_diff_drive.h"
+
 #include "core/state_block/state_quaternion.h"
 
+
 #include <iostream>
 
 using namespace wolf;
@@ -94,7 +98,7 @@ TEST(Problem, Processor)
     ProblemPtr P = Problem::create("PO", 3);
 
     // check motion processor is null
-    ASSERT_FALSE(P->getProcessorMotion());
+    ASSERT_FALSE(P->getProcessorIsMotion());
 
     // add a motion sensor and processor
     auto Sm = SensorBase::emplace<SensorOdom3d>(P->getHardware(), (Eigen::Vector7d()<<0,0,0, 0,0,0,1).finished(), ParamsSensorOdom3d());
@@ -103,7 +107,7 @@ TEST(Problem, Processor)
     auto Pm = ProcessorBase::emplace<ProcessorOdom3d>(Sm, std::make_shared<ProcessorParamsOdom3d>());
 
     // check motion processor IS NOT by emplace
-    ASSERT_EQ(P->getProcessorMotion(), Pm);
+    ASSERT_EQ(P->getProcessorIsMotion(), Pm);
 }
 
 TEST(Problem, Installers)
@@ -118,16 +122,16 @@ TEST(Problem, Installers)
     auto pt = P->installProcessor("ProcessorTrackerFeatureDummy", "dummy", "odometer");
 
     // check motion processor IS NOT set
-    ASSERT_FALSE(P->getProcessorMotion());
+    ASSERT_FALSE(P->getProcessorIsMotion());
 
     // install processor motion
     ProcessorBasePtr pm = P->installProcessor("ProcessorOdom3d", "odom integrator", "odometer", wolf_root + "/test/yaml/processor_odom_3d.yaml");
 
     // check motion processor is set
-    ASSERT_TRUE(P->getProcessorMotion());
+    ASSERT_TRUE(P->getProcessorIsMotion() != nullptr);
 
     // check motion processor is correct
-    ASSERT_EQ(std::dynamic_pointer_cast<ProcessorMotion>(P->getProcessorMotion()), pm);
+    ASSERT_EQ(std::dynamic_pointer_cast<ProcessorMotion>(P->getProcessorIsMotion()), pm);
 }
 
 TEST(Problem, SetOrigin_PO_2d)
@@ -413,6 +417,70 @@ TEST(Problem, perturb)
     }
 }
 
+TEST(Problem, check)
+{
+    auto problem = Problem::create("PO", 2);
+
+    // make a sensor first
+    auto intr = std::make_shared<ParamsSensorDiffDrive>();
+    intr->radius_left                   = 1.0;
+    intr->radius_right                  = 1.0;
+    intr->wheel_separation              = 1.0;
+    intr->ticks_per_wheel_revolution    = 100;
+    Vector3d extr(0,0,0);
+    auto sensor = std::static_pointer_cast<SensorDiffDrive>(problem->installSensor("SensorDiffDrive", "sensor diff drive", extr, intr));
+    sensor->setStateBlockDynamic("I", true);
+
+    Vector3d pose; pose << 0,0,0;
+
+    int i = 0;
+    for (TimeStamp t = 0.0; t < 2.0; t += 1.0)
+    {
+        auto F = problem->emplaceFrame(KEY, pose, t);
+        if (i==0) F->fix();
+
+        for (int j = 0; j< 2 ; j++)
+        {
+            auto sb     = std::make_shared<StateBlock>(Vector3d(1,1,1));
+            auto cap    = CaptureBase::emplace<CaptureDiffDrive>(F, t, sensor, Vector2d(1,2), Matrix2d::Identity(), nullptr, nullptr, nullptr, sb);
+
+            for (int k = 0; k<2; k++)
+            {
+                Vector3d d(1,2,3), c(1,1,1);
+                Matrix3d D = Matrix3d::Identity(), J=Matrix3d::Zero();
+                auto fea = FeatureBase::emplace<FeatureMotion>(cap, "FeatureDiffDrive", d, D, c, J);
+                auto fac = FactorBase::emplace<FactorDiffDrive>(fea, fea, cap, nullptr, false);
+            }
+        }
+        i++;
+    }
+
+    for (int l = 0; l < 2; l++)
+    {
+        auto sb1    = std::make_shared<StateBlock>(Vector2d(1,2));
+        auto sb2    = std::make_shared<StateBlock>(Vector1d(3));
+        auto L      = LandmarkBase::emplace<LandmarkBase>(problem->getMap(), "LandmarkBase", sb1, sb2);
+        if (l==0) L->fix();
+    }
+
+    ASSERT_TRUE(problem->check(true, std::cout));
+
+    // remove stuff from problem, and re-check
+
+    auto F = problem->getLastKeyFrame();
+
+    auto cby = F->getConstrainedByList().front();
+
+    cby->remove(true);
+
+    ASSERT_TRUE(problem->check(true, std::cout));
+
+    F->remove();
+
+    ASSERT_TRUE(problem->check(true, std::cout));
+}
+
+
 int main(int argc, char **argv)
 {
   testing::InitGoogleTest(&argc, argv);
diff --git a/test/gtest_processor_base.cpp b/test/gtest_processor_base.cpp
index 1933da8599234e61c534e9f05008710ac4396661..c4a1c4b0470c92bf09df1a950a1c19e57d35642d 100644
--- a/test/gtest_processor_base.cpp
+++ b/test/gtest_processor_base.cpp
@@ -125,7 +125,7 @@ TEST(ProcessorBase, KeyFrameCallback)
         capt_trk = make_shared<CaptureVoid>(t, sens_trk);
         proc_trk->captureCallback(capt_trk);
 
-//        problem->print(4,1,1,0);
+       problem->print(4,1,1,0);
 
         // Only odom creating KFs
         ASSERT_TRUE( problem->getLastKeyFrame()->getType().compare("PO 2d")==0 );
diff --git a/test/gtest_tree_manager.cpp b/test/gtest_tree_manager.cpp
index 52f86aced4329f61c433942cc25fd06d3cbe6034..5799117ffa523a9cbf5132ed504fa1525001c0ae 100644
--- a/test/gtest_tree_manager.cpp
+++ b/test/gtest_tree_manager.cpp
@@ -3,7 +3,7 @@
 
 #include "core/problem/problem.h"
 #include "dummy/tree_manager_dummy.h"
-#include "core/yaml/parser_yaml.hpp"
+#include "core/yaml/parser_yaml.h"
 
 using namespace wolf;
 using namespace Eigen;
diff --git a/test/gtest_tree_manager_sliding_window.cpp b/test/gtest_tree_manager_sliding_window.cpp
index 14b05976faa99160657c303e028c1f651872f7ac..ed3a8052bfb4a73b4395cc885904d8f752af91d2 100644
--- a/test/gtest_tree_manager_sliding_window.cpp
+++ b/test/gtest_tree_manager_sliding_window.cpp
@@ -3,7 +3,7 @@
 
 #include "core/problem/problem.h"
 #include "core/tree_manager/tree_manager_sliding_window.h"
-#include "core/yaml/parser_yaml.hpp"
+#include "core/yaml/parser_yaml.h"
 #include "core/capture/capture_void.h"
 #include "core/feature/feature_base.h"
 #include "core/factor/factor_odom_3d.h"