diff --git a/hello_plugin/hello_plugin.cpp b/hello_plugin/hello_plugin.cpp
index f15d005abd80bf110809135922228661c0ab2f6c..cc837fa4395dc660a4711817d4b71d4cd23687f7 100644
--- a/hello_plugin/hello_plugin.cpp
+++ b/hello_plugin/hello_plugin.cpp
@@ -26,157 +26,178 @@ using namespace wolf;
 using namespace Eigen;
 
 int main(int argc, char** argv) {
-    string file = "";
-    if(argc > 1) file = argv[1];
-    parserYAML parser = parserYAML(file);
-    parser.parse();
-    paramsServer server = paramsServer(parser.getParams(), parser.sensorsSerialization(), parser.processorsSerialization());
-    cout << "PRINTING SERVER MAP" << endl;
-    server.print();
-    cout << "-----------------------------------" << endl;
-    /**
-       It seems to be a requirement that each file is loaded by its own ClassLoader object, otherwise I get
-       a segmentation fault. Likewise, it seems that these ClassLoaders must be allocated at the heap, because
-       the constructor refuses to build an object if I try to do local (stack) allocation, i.e `ClassLoader(it)` is not allowed but `new ClassLoader(it)` is.
-     **/
-    // vector<ClassLoader*> class_loaders = vector<ClassLoader*>();
-    // for(auto it : parser.getFiles()) {
-    //     auto c = new ClassLoader(it);
-    //     class_loaders.push_back(c);
-    // }
-    auto loaders = vector<Loader*>();
-    for(auto it : parser.getFiles()) {
-        auto l = new LoaderRaw(it);
-        loaders.push_back(l);
-    }
-    ProblemPtr problem = Problem::create("PO", 2);
-    auto sensorMap = map<string, SensorBasePtr>();
-    auto procesorMap = map<string, ProcessorBasePtr>();
-    for(auto s : server.getSensors()){
-        cout << s._name << " " << s._type << endl;
-        sensorMap.insert(pair<string, SensorBasePtr>(s._name,problem->installSensor(s._type, s._name, server)));
-    }
-    for(auto s : server.getProcessors()){
-        cout << s._name << " " << s._type << " " << s._name_assoc_sensor << endl;
-        procesorMap.insert(pair<string, ProcessorBasePtr>(s._name,problem->installProcessor(s._type, s._name, s._name_assoc_sensor, server)));
-    }
-
-    problem->print(4,1,1,1);
-    Vector2s motion_data(1.0, 0.0);                     // Will advance 1m at each keyframe, will not turn.
-    Matrix2s motion_cov = 0.1 * Matrix2s::Identity();
-
-    // landmark observations data
-    VectorXi ids;
-    VectorXs ranges, bearings;
-
-
-    // SET OF EVENTS =======================================================
-    std::cout << std::endl;
-    WOLF_TRACE("======== BUILD PROBLEM =======");
-
-    // ceres::Solver::Options options;
-    // options.max_num_iterations              = 1000; // We depart far from solution, need a lot of iterations
-    // CeresManagerPtr ceres                   = std::make_shared<CeresManager>(problem, options);
-    auto ceres = SolverFactory::get().create("Solver", problem, server);
-    // We'll do 3 steps of motion and landmark observations.
-
-    // STEP 1 --------------------------------------------------------------
-
-    // initialize
-    TimeStamp   t(0.0);                     // t : 0.0
-    Vector3s    x(0,0,0);
-    Matrix3s    P = Matrix3s::Identity() * 0.1;
-    problem->setPrior(x, P, t, 0.5);             // KF1 : (0,0,0)
-    auto sensor_rb = sensorMap.find("rb")->second;
-    // observe lmks
-    ids.resize(1); ranges.resize(1); bearings.resize(1);
-    ids         << 1;                       // will observe Lmk 1
-    ranges      << 1.0;                     // see drawing
-    bearings    << M_PI/2;
-    CaptureRangeBearingPtr cap_rb = std::make_shared<CaptureRangeBearing>(t, sensor_rb, ids, ranges, bearings);
-    sensor_rb   ->process(cap_rb);          // L1 : (1,2)
-
-    // STEP 2 --------------------------------------------------------------
-    t += 1.0;                     // t : 1.0
-
-    // motion
-    auto sensor_odometry = sensorMap.find("odom")->second;
-    CaptureOdom2DPtr cap_motion = std::make_shared<CaptureOdom2D>(t, sensor_odometry, motion_data, motion_cov);
-    sensor_odometry ->process(cap_motion);      // KF2 : (1,0,0)
-
-    // observe lmks
-    ids.resize(2); ranges.resize(2); bearings.resize(2);
-    ids         << 1, 2;                    // will observe Lmks 1 and 2
-    ranges      << sqrt(2.0), 1.0;          // see drawing
-    bearings    << 3*M_PI/4, M_PI/2;
-    cap_rb      = std::make_shared<CaptureRangeBearing>(t, sensor_rb, ids, ranges, bearings);
-    sensor_rb   ->process(cap_rb);          // L1 : (1,2), L2 : (2,2)
-
-    // STEP 3 --------------------------------------------------------------
-    t += 1.0;                     // t : 2.0
-
-    // motion
-    cap_motion  ->setTimeStamp(t);
-    sensor_odometry  ->process(cap_motion);      // KF3 : (2,0,0)
-    // observe lmks
-    ids.resize(2); ranges.resize(2); bearings.resize(2);
-    ids         << 2, 3;                    // will observe Lmks 2 and 3
-    ranges      << sqrt(2.0), 1.0;          // see drawing
-    bearings    << 3*M_PI/4, M_PI/2;
-    cap_rb      = std::make_shared<CaptureRangeBearing>(t, sensor_rb, ids, ranges, bearings);
-    sensor_rb   ->process(cap_rb);          // L1 : (1,2), L2 : (2,2), L3 : (3,2)
-    problem->print(1,0,1,0);
-
-
-    // SOLVE ================================================================
-
-    // SOLVE with exact initial guess
-    WOLF_TRACE("======== SOLVE PROBLEM WITH EXACT PRIORS =======")
-    std::string report = ceres->solve(wolf::SolverManager::ReportVerbosity::FULL);
-    WOLF_TRACE(report);                     // should show a very low iteration number (possibly 1)
-    problem->print(1,0,1,0);
-
-    // PERTURB initial guess
-    WOLF_TRACE("======== PERTURB PROBLEM PRIORS =======")
-    for (auto sen : problem->getHardware()->getSensorList())
-        for (auto sb : sen->getStateBlockVec())
-            if (sb && !sb->isFixed())
-                sb->setState(sb->getState() + VectorXs::Random(sb->getSize()) * 0.5);       // We perturb A LOT !
-    for (auto kf : problem->getTrajectory()->getFrameList())
-        if (kf->isKey())
-            for (auto sb : kf->getStateBlockVec())
-                if (sb && !sb->isFixed())
-                    sb->setState(sb->getState() + VectorXs::Random(sb->getSize()) * 0.5);   // We perturb A LOT !
-    for (auto lmk : problem->getMap()->getLandmarkList())
-        for (auto sb : lmk->getStateBlockVec())
-            if (sb && !sb->isFixed())
-                sb->setState(sb->getState() + VectorXs::Random(sb->getSize()) * 0.5);       // We perturb A LOT !
-    problem->print(1,0,1,0);
-
-    // SOLVE again
-    WOLF_TRACE("======== SOLVE PROBLEM WITH PERTURBED PRIORS =======")
-    report = ceres->solve(wolf::SolverManager::ReportVerbosity::FULL);
-    WOLF_TRACE(report);                     // should show a very high iteration number (more than 10, or than 100!)
-    problem->print(1,0,1,0);
-
-    // GET COVARIANCES of all states
-    WOLF_TRACE("======== COVARIANCES OF SOLVED PROBLEM =======")
-    ceres->computeCovariances(SolverManager::CovarianceBlocksToBeComputed::ALL_MARGINALS);
-    for (auto kf : problem->getTrajectory()->getFrameList()){
-        if (kf->isKey())
-            {
-                Eigen::MatrixXs cov;
-                WOLF_TRACE("KF", kf->id(), "_cov = \n", kf->getCovariance(cov));
-            }
-        for (auto lmk : problem->getMap()->getLandmarkList()) {
-            Eigen::MatrixXs cov;
-            WOLF_TRACE("L", lmk->id(), "_cov = \n", lmk->getCovariance(cov));
-        }
-    }
-    std::cout << std::endl;
-
-    WOLF_TRACE("======== FINAL PRINT FOR INTERPRETATION =======")
-    problem->print(4,1,1,1);
-
-    return 0;
+	string file = "";
+	if (argc > 1)
+		file = argv[1];
+	parserYAML parser = parserYAML(file);
+	parser.parse();
+	paramsServer server = paramsServer(parser.getParams(),
+			parser.sensorsSerialization(), parser.processorsSerialization());
+	cout << "PRINTING SERVER MAP" << endl;
+	server.print();
+	cout << "-----------------------------------" << endl;
+	/**
+	 It seems to be a requirement that each file is loaded by its own ClassLoader object, otherwise I get
+	 a segmentation fault. Likewise, it seems that these ClassLoaders must be allocated at the heap, because
+	 the constructor refuses to build an object if I try to do local (stack) allocation, i.e `ClassLoader(it)` is not allowed but `new ClassLoader(it)` is.
+	 **/
+	// vector<ClassLoader*> class_loaders = vector<ClassLoader*>();
+	// for(auto it : parser.getFiles()) {
+	//     auto c = new ClassLoader(it);
+	//     class_loaders.push_back(c);
+	// }
+	auto loaders = vector<Loader*>();
+	for (auto it : parser.getFiles()) {
+		auto l = new LoaderRaw(it);
+		loaders.push_back(l);
+	}
+	ProblemPtr problem = Problem::create("PO", 2);
+	auto sensorMap = map<string, SensorBasePtr>();
+	auto procesorMap = map<string, ProcessorBasePtr>();
+	for (auto s : server.getSensors()) {
+		cout << s._name << " " << s._type << endl;
+		sensorMap.insert(
+				pair<string, SensorBasePtr>(s._name,
+						problem->installSensor(s._type, s._name, server)));
+	}
+	for (auto s : server.getProcessors()) {
+		cout << s._name << " " << s._type << " " << s._name_assoc_sensor
+				<< endl;
+		procesorMap.insert(
+				pair<string, ProcessorBasePtr>(s._name,
+						problem->installProcessor(s._type, s._name,
+								s._name_assoc_sensor, server)));
+	}
+
+	problem->print(4, 1, 1, 1);
+	Vector2s motion_data(1.0, 0.0); // Will advance 1m at each keyframe, will not turn.
+	Matrix2s motion_cov = 0.1 * Matrix2s::Identity();
+
+	// landmark observations data
+	VectorXi ids;
+	VectorXs ranges, bearings;
+
+	// SET OF EVENTS =======================================================
+	std::cout << std::endl;
+	WOLF_TRACE("======== BUILD PROBLEM =======");
+
+	// ceres::Solver::Options options;
+	// options.max_num_iterations              = 1000; // We depart far from solution, need a lot of iterations
+	// CeresManagerPtr ceres                   = std::make_shared<CeresManager>(problem, options);
+	auto ceres = SolverFactory::get().create("Solver", problem, server);
+	// We'll do 3 steps of motion and landmark observations.
+
+	// STEP 1 --------------------------------------------------------------
+
+	// initialize
+	TimeStamp t(0.0);                     // t : 0.0
+	Vector3s x(0, 0, 0);
+	Matrix3s P = Matrix3s::Identity() * 0.1;
+	problem->setPrior(x, P, t, 0.5);             // KF1 : (0,0,0)
+	auto sensor_rb = sensorMap.find("rb")->second;
+	// observe lmks
+	ids.resize(1);
+	ranges.resize(1);
+	bearings.resize(1);
+	ids << 1;                       // will observe Lmk 1
+	ranges << 1.0;                     // see drawing
+	bearings << M_PI / 2;
+	CaptureRangeBearingPtr cap_rb = std::make_shared < CaptureRangeBearing
+			> (t, sensor_rb, ids, ranges, bearings);
+	sensor_rb->process(cap_rb);          // L1 : (1,2)
+
+	// STEP 2 --------------------------------------------------------------
+	t += 1.0;                     // t : 1.0
+
+	// motion
+	auto sensor_odometry = sensorMap.find("odom")->second;
+	CaptureOdom2DPtr cap_motion = std::make_shared < CaptureOdom2D
+			> (t, sensor_odometry, motion_data, motion_cov);
+	sensor_odometry->process(cap_motion);      // KF2 : (1,0,0)
+
+	// observe lmks
+	ids.resize(2);
+	ranges.resize(2);
+	bearings.resize(2);
+	ids << 1, 2;                    // will observe Lmks 1 and 2
+	ranges << sqrt(2.0), 1.0;          // see drawing
+	bearings << 3 * M_PI / 4, M_PI / 2;
+	cap_rb = std::make_shared < CaptureRangeBearing
+			> (t, sensor_rb, ids, ranges, bearings);
+	sensor_rb->process(cap_rb);          // L1 : (1,2), L2 : (2,2)
+
+	// STEP 3 --------------------------------------------------------------
+	t += 1.0;                     // t : 2.0
+
+	// motion
+	cap_motion->setTimeStamp(t);
+	sensor_odometry->process(cap_motion);      // KF3 : (2,0,0)
+	// observe lmks
+	ids.resize(2);
+	ranges.resize(2);
+	bearings.resize(2);
+	ids << 2, 3;                    // will observe Lmks 2 and 3
+	ranges << sqrt(2.0), 1.0;          // see drawing
+	bearings << 3 * M_PI / 4, M_PI / 2;
+	cap_rb = std::make_shared < CaptureRangeBearing
+			> (t, sensor_rb, ids, ranges, bearings);
+	sensor_rb->process(cap_rb);          // L1 : (1,2), L2 : (2,2), L3 : (3,2)
+	problem->print(1, 0, 1, 0);
+
+	// SOLVE ================================================================
+
+	// SOLVE with exact initial guess
+	WOLF_TRACE("======== SOLVE PROBLEM WITH EXACT PRIORS =======")
+	std::string report = ceres->solve(
+			wolf::SolverManager::ReportVerbosity::FULL);
+	WOLF_TRACE(report);  // should show a very low iteration number (possibly 1)
+	problem->print(1, 0, 1, 0);
+
+	// PERTURB initial guess
+	WOLF_TRACE("======== PERTURB PROBLEM PRIORS =======")
+	for (auto sen : problem->getHardware()->getSensorList())
+		for (auto sb : sen->getStateBlockVec())
+			if (sb && !sb->isFixed())
+				sb->setState(
+						sb->getState() + VectorXs::Random(sb->getSize()) * 0.5); // We perturb A LOT !
+	for (auto kf : problem->getTrajectory()->getFrameList())
+		if (kf->isKey())
+			for (auto sb : kf->getStateBlockVec())
+				if (sb && !sb->isFixed())
+					sb->setState(
+							sb->getState()
+									+ VectorXs::Random(sb->getSize()) * 0.5); // We perturb A LOT !
+	for (auto lmk : problem->getMap()->getLandmarkList())
+		for (auto sb : lmk->getStateBlockVec())
+			if (sb && !sb->isFixed())
+				sb->setState(
+						sb->getState() + VectorXs::Random(sb->getSize()) * 0.5); // We perturb A LOT !
+	problem->print(1, 0, 1, 0);
+
+	// SOLVE again
+	WOLF_TRACE("======== SOLVE PROBLEM WITH PERTURBED PRIORS =======")
+	report = ceres->solve(wolf::SolverManager::ReportVerbosity::FULL);
+	WOLF_TRACE(report); // should show a very high iteration number (more than 10, or than 100!)
+	problem->print(1, 0, 1, 0);
+
+	// GET COVARIANCES of all states
+	WOLF_TRACE("======== COVARIANCES OF SOLVED PROBLEM =======")
+	ceres->computeCovariances(
+			SolverManager::CovarianceBlocksToBeComputed::ALL_MARGINALS);
+	for (auto kf : problem->getTrajectory()->getFrameList()) {
+		if (kf->isKey()) {
+			Eigen::MatrixXs cov;
+			WOLF_TRACE("KF", kf->id(), "_cov = \n", kf->getCovariance(cov));
+		}
+		for (auto lmk : problem->getMap()->getLandmarkList()) {
+			Eigen::MatrixXs cov;
+			WOLF_TRACE("L", lmk->id(), "_cov = \n", lmk->getCovariance(cov));
+		}
+	}
+	std::cout << std::endl;
+
+	WOLF_TRACE("======== FINAL PRINT FOR INTERPRETATION =======")
+	problem->print(4, 1, 1, 1);
+
+	return 0;
 }
diff --git a/include/core/ceres_wrapper/solver_manager.h b/include/core/ceres_wrapper/solver_manager.h
deleted file mode 100644
index f7bad6f57e5d11173ed5a583b67d492d2d107439..0000000000000000000000000000000000000000
--- a/include/core/ceres_wrapper/solver_manager.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef SOLVER_MANAGER_H_
-#define SOLVER_MANAGER_H_
-
-//wolf includes
-#include "core/common/wolf.h"
-#include "core/state_block/state_block.h"
-#include "core/factor/factor_base.h"
-
-namespace wolf {
-
-/** \brief Enumeration of covariance blocks to be computed
- *
- * Enumeration of covariance blocks to be computed
- *
- */
-typedef enum
-{
-    ALL, ///< All blocks and all cross-covariances
-    ALL_MARGINALS, ///< All marginals
-    ROBOT_LANDMARKS ///< marginals of landmarks and current robot pose plus cross covariances of current robot and all landmarks
-} CovarianceBlocksToBeComputed;
-
-WOLF_PTR_TYPEDEFS(SolverManager);
-
-/** \brief Solver manager for WOLF
- *
- */
-
-class SolverManager
-{
-	protected:
-		ProblemPtr wolf_problem_;
-
-	public:
-        SolverManager(ProblemPtr _wolf_problem);
-
-		virtual ~SolverManager();
-
-		virtual std::string solve(const unsigned int& _report_level) = 0;
-
-		virtual void computeCovariances(CovarianceBlocksToBeComputed _blocks = ROBOT_LANDMARKS) = 0;
-
-		virtual void computeCovariances(const StateBlockPtrList& st_list) = 0;
-
-		virtual void update();
-
-        virtual ProblemPtr getProblem();
-
-	private:
-
-		virtual void addFactor(FactorBasePtr _fac_ptr) = 0;
-
-		virtual void removeFactor(FactorBasePtr _fac_ptr) = 0;
-
-		virtual void addStateBlock(StateBlockPtr _st_ptr) = 0;
-
-		virtual void removeStateBlock(StateBlockPtr _st_ptr) = 0;
-
-		virtual void updateStateBlockStatus(StateBlockPtr _st_ptr) = 0;
-};
-
-} // namespace wolf
-
-#endif
diff --git a/src/ceres_wrapper/solver_manager.cpp b/src/ceres_wrapper/solver_manager.cpp
deleted file mode 100644
index 586d76034d7001008ecfd0426f308c92b4f4c819..0000000000000000000000000000000000000000
--- a/src/ceres_wrapper/solver_manager.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "core/solver/solver_manager.h"
-#include "core/trajectory/trajectory_base.h"
-#include "core/map/map_base.h"
-#include "core/landmark/landmark_base.h"
-
-namespace wolf {
-
-SolverManager::SolverManager(ProblemPtr _wolf_problem) :
-    wolf_problem_(_wolf_problem)
-{
-}
-
-SolverManager::~SolverManager()
-{
-}
-
-void SolverManager::update()
-{
-    //std::cout << "SolverManager: updating... " << std::endl;
-    //std::cout << wolf_problem_->getStateBlockNotificationList().size() << " state block notifications" << std::endl;
-    //std::cout << wolf_problem_->getFactorNotificationList().size() << " factor notifications" << std::endl;
-
-	// REMOVE CONSTRAINTS
-	auto fac_notification_it = wolf_problem_->getFactorNotificationList().begin();
-	while ( fac_notification_it != wolf_problem_->getFactorNotificationList().end() )
-		if (fac_notification_it->notification_ == REMOVE)
-		{
-			removeFactor(fac_notification_it->factor_ptr_);
-			fac_notification_it = wolf_problem_->getFactorNotificationList().erase(fac_notification_it);
-		}
-		else
-			fac_notification_it++;
-
-	// REMOVE STATE BLOCKS
-	auto state_notification_it = wolf_problem_->getStateBlockNotificationList().begin();
-	while ( state_notification_it != wolf_problem_->getStateBlockNotificationList().end() )
-		if (state_notification_it->notification_ == REMOVE)
-		{
-			removeStateBlock(state_notification_it->state_block_ptr_);
-			state_notification_it = wolf_problem_->getStateBlockNotificationList().erase(state_notification_it);
-		}
-		else
-			state_notification_it++;
-
-    // ADD/UPDATE STATE BLOCKS
-    while (!wolf_problem_->getStateBlockNotificationList().empty())
-    {
-        switch (wolf_problem_->getStateBlockNotificationList().front().notification_)
-        {
-            case ADD:
-            {
-                addStateBlock(wolf_problem_->getStateBlockNotificationList().front().state_block_ptr_);
-                if (wolf_problem_->getStateBlockNotificationList().front().state_block_ptr_->isFixed())
-                    updateStateBlockStatus(wolf_problem_->getStateBlockNotificationList().front().state_block_ptr_);
-                break;
-            }
-            case UPDATE:
-            {
-                updateStateBlockStatus(wolf_problem_->getStateBlockNotificationList().front().state_block_ptr_);
-                break;
-            }
-            default:
-                throw std::runtime_error("SolverManager::update: State Block notification must be ADD, UPATE or REMOVE.");
-        }
-        wolf_problem_->getStateBlockNotificationList().pop_front();
-    }
-    // ADD CONSTRAINTS
-    while (!wolf_problem_->getFactorNotificationList().empty())
-    {
-        switch (wolf_problem_->getFactorNotificationList().front().notification_)
-        {
-            case ADD:
-            {
-                addFactor(wolf_problem_->getFactorNotificationList().front().factor_ptr_);
-                break;
-            }
-            default:
-                throw std::runtime_error("SolverManager::update: Factor notification must be ADD or REMOVE.");
-        }
-        wolf_problem_->getFactorNotificationList().pop_front();
-    }
-
-    assert(wolf_problem_->getFactorNotificationList().empty() && "wolf problem's factors notification list not empty after update");
-    assert(wolf_problem_->getStateBlockNotificationList().empty() && "wolf problem's state_blocks notification list not empty after update");
-}
-
-ProblemPtr SolverManager::getProblem()
-{
-    return wolf_problem_;
-}
-
-} // namespace wolf
-
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9a9d1d36147dc655deda32e39b7dcb4eb9286cba..2f224b98496619e2c1d947d0b9dbce33b648d8db 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -62,8 +62,8 @@ target_link_libraries(gtest_eigen_predicates ${PROJECT_NAME})
 
 # Node Emplace test
 # TODO: TO BE FIXED
-# wolf_add_gtest(gtest_emplace gtest_emplace.cpp)
-# target_link_libraries(gtest_emplace ${PROJECT_NAME})
+wolf_add_gtest(gtest_emplace gtest_emplace.cpp)
+target_link_libraries(gtest_emplace ${PROJECT_NAME})
 
 # FeatureBase classes test
 wolf_add_gtest(gtest_feature_base gtest_feature_base.cpp)
diff --git a/test/gtest_emplace.cpp b/test/gtest_emplace.cpp
index ee32a9b429a0aac16a8a211338ce56fde9b96708..8a2f6ed2ce0d5d89bb54d1d169c1f94920c335f6 100644
--- a/test/gtest_emplace.cpp
+++ b/test/gtest_emplace.cpp
@@ -9,14 +9,12 @@
 #include "core/utils/logging.h"
 
 #include "core/problem/problem.h"
-#include "core/capture/capture_IMU.h"
 #include "core/sensor/sensor_base.h"
+#include "core/sensor/sensor_odom_2D.h"
 #include "core/sensor/sensor_odom_3D.h"
-#include "core/sensor/sensor_IMU.h"
 #include "core/processor/processor_odom_3D.h"
 #include "core/processor/processor_odom_2D.h"
 #include "core/feature/feature_odom_2D.h"
-#include "core/feature/feature_IMU.h"
 #include "core/processor/processor_tracker_feature_dummy.h"
 
 #include <iostream>
@@ -122,20 +120,18 @@ TEST(Emplace, EmplaceDerived)
 
     auto frm = FrameBase::emplace<FrameBase>(P->getTrajectory(),  KEY, TimeStamp(0), std::make_shared<StateBlock>(2,true), std::make_shared<StateBlock>(2,true));
     // LandmarkBase::emplace<LandmarkBase>(MapBaseWPtr(P->getMap()),"Dummy", nullptr, nullptr);
-    auto sen = SensorBase::emplace<SensorIMU>(P->getHardware(), Eigen::VectorXs(7), IntrinsicsIMU());
+    auto sen = SensorBase::emplace<SensorOdom2D>(P->getHardware(), Eigen::VectorXs(3), IntrinsicsOdom2D());
     auto cov = Eigen::MatrixXs(2,2);
     cov(0,0) = 1;
     cov(1,1) = 1;
-    auto cpt = CaptureBase::emplace<CaptureIMU>(frm, TimeStamp(0), sen, Eigen::Vector6s(), cov,
-                                                Eigen::Vector6s(), frm);
-    auto cpt2 = std::static_pointer_cast<CaptureIMU>(cpt);
+    auto cpt = CaptureBase::emplace<CaptureOdom2D>(frm, TimeStamp(0), sen, Eigen::Vector6s(), cov, frm);
+    auto cpt2 = std::static_pointer_cast<CaptureOdom2D>(cpt);
     auto m = Eigen::Matrix<Scalar,9,6>();
     for(int i = 0; i < 9; i++)
         for(int j = 0; j < 6; j++)
             m(i,j) = 1;
 
-    auto ftr = FeatureBase::emplace<FeatureIMU>(cpt, Eigen::VectorXs(5), cov,
-                                                Eigen::Vector6s(), m, cpt2);
+    auto ftr = FeatureBase::emplace<FeatureOdom2D>(cpt, Eigen::VectorXs(5), cov);
     ASSERT_EQ(sen, P->getHardware()->getSensorList().front());
     ASSERT_EQ(P, P->getTrajectory()->getFrameList().front()->getCaptureList().front()->getFeatureList().front()->getProblem());
 }
diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp
index 477dcb3d44e44755c2bee6564233217daefe3a02..5f44b20579a001f85075842e5bbc81fbec8ba9ae 100644
--- a/test/gtest_problem.cpp
+++ b/test/gtest_problem.cpp
@@ -24,7 +24,7 @@ using namespace Eigen;
 
 WOLF_PTR_TYPEDEFS(DummySolverManager);
 
-struct DummySolverManager : public SolverManager
+class DummySolverManager : public SolverManager
 {
   DummySolverManager(const ProblemPtr& _problem)
     : SolverManager(_problem)
@@ -239,11 +239,11 @@ TEST(Problem, StateBlocks)
 
     // 2 state blocks, fixed
     SensorBasePtr    Sm = P->installSensor   ("ODOM 3D", "odometer",xs3d, wolf_root + "/src/examples/sensor_odom_3D.yaml");
-    ASSERT_EQ(P->consumeStateBlockNotificationMap().size(), (unsigned int) 2);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 2);
 
     // 2 state blocks, fixed
     SensorBasePtr    St = P->installSensor   ("ODOM 2D", "other odometer", xs2d, "");
-    ASSERT_EQ(P->consumeStateBlockNotificationMap().size(), (unsigned int) (2/* + 3*/)); // consume empties the notification map, so only should contain notification since last call
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) (2/* + 3*/)); // consume empties the notification map, so only should contain notification since last call
 
     ProcessorParamsTrackerFeaturePtr params = std::make_shared<ProcessorParamsTrackerFeature>();
     params->time_tolerance            = 0.1;
@@ -255,16 +255,23 @@ TEST(Problem, StateBlocks)
     ProcessorBasePtr pm = P->installProcessor("ODOM 3D",            "odom integrator",      "odometer", wolf_root + "/src/examples/processor_odom_3D.yaml");
 
     // 2 state blocks, estimated
-    P->emplaceFrame("PO 3D", KEY, xs3d, 0);
-    ASSERT_EQ(P->consumeStateBlockNotificationMap().size(), (unsigned int)(/*2 + 3*/ + 2)); // consume empties the notification map, so only should contain notification since last call
-
+    auto KF = P->emplaceFrame("PO", 3, KEY, xs3d, 0);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd)(/*2 + 3*/ + 2)); // consume empties the notification map, so only should contain notification since last call
+
+    // Notifications
+    Notification notif;
+    ASSERT_TRUE(P->getStateBlockNotification(KF->getP(), notif));
+    ASSERT_EQ(notif, ADD);
+    ASSERT_TRUE(P->getStateBlockNotification(KF->getO(), notif));
+    ASSERT_EQ(notif, ADD);
     //    P->print(4,1,1,1);
 
     // change some SB properties
     St->unfixExtrinsics();
-    ASSERT_TRUE(P->consumeStateBlockNotificationMap().empty()); // changes in state_blocks status (fix/state/localparam) does not raise a notification in problem, only ADD/REMOVE
-    // ASSERT_EQ(P->getStateBlockPtrList().size(), (unsigned int)(2 + 2 + 2));
-    // ASSERT_EQ(P->getStateBlockNotificationMap().size(),(unsigned int)(2 + 2 + 2 /*+ 2*/)); // XXX: 2 more notifications on the same SB!
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd)(0)); // consume empties the notification map, so only should contain notification since last call
+    // ASSERT_TRUE(P->consumeStateBlockNotificationMap().empty()); // changes in state_blocks status (fix/state/localparam) does not raise a notification in problem, only ADD/REMOVE
+    // ASSERT_EQ(P->getStateBlockPtrList().size(), (SizeStd)(2 + 2 + 2));
+    // ASSERT_EQ(P->getStateBlockNotificationMap().size(),(SizeStd)(2 + 2 + 2 /*+ 2*/)); // XXX: 2 more notifications on the same SB!
 
     //    P->print(4,1,1,1);