diff --git a/include/core/ceres_wrapper/solver_ceres.h b/include/core/ceres_wrapper/solver_ceres.h
index b81d9f8cfaf90396ffdf904ebf3c12d9bb6249d1..c899b7a054d6e1a9ebab5f45cca35fa0bd86c3d0 100644
--- a/include/core/ceres_wrapper/solver_ceres.h
+++ b/include/core/ceres_wrapper/solver_ceres.h
@@ -169,14 +169,13 @@ inline ceres::Solver::Options& SolverCeres::getSolverOptions()
 
 inline bool SolverCeres::isFactorRegisteredDerived(const FactorBasePtr& fac_ptr) const
 {
-    return fac_2_residual_idx_.find(fac_ptr) != fac_2_residual_idx_.end()
-            && fac_2_costfunction_.find(fac_ptr) != fac_2_costfunction_.end();
+    return fac_2_residual_idx_.find(fac_ptr) != fac_2_residual_idx_.end() and
+           fac_2_costfunction_.find(fac_ptr) != fac_2_costfunction_.end();
 }
 
 inline bool SolverCeres::isStateBlockRegisteredDerived(const StateBlockPtr& state_ptr) const
 {
-    return state_blocks_local_param_.find(state_ptr) != state_blocks_local_param_.end()
-            && ceres_problem_->HasParameterBlock(getAssociatedMemBlockPtr(state_ptr));
+    return ceres_problem_->HasParameterBlock(getAssociatedMemBlockPtr(state_ptr));
 }
 
 inline bool SolverCeres::isStateBlockFixedDerived(const StateBlockPtr& st)
@@ -184,14 +183,6 @@ inline bool SolverCeres::isStateBlockFixedDerived(const StateBlockPtr& st)
     return ceres_problem_->IsParameterBlockConstant(SolverManager::getAssociatedMemBlockPtr(st));
 };
 
-inline bool SolverCeres::hasThisLocalParametrizationDerived(const StateBlockPtr& st,
-                                                            const LocalParametrizationBasePtr& local_param)
-{
-    return state_blocks_local_param_.count(st) == 1 and
-           state_blocks_local_param_.at(st)->getLocalParametrization() == local_param and
-           ceres_problem_->GetParameterization(getAssociatedMemBlockPtr(st)) == state_blocks_local_param_.at(st).get();
-};
-
 inline bool SolverCeres::hasLocalParametrizationDerived(const StateBlockPtr& st) const
 {
     return state_blocks_local_param_.count(st) == 1;
diff --git a/src/ceres_wrapper/solver_ceres.cpp b/src/ceres_wrapper/solver_ceres.cpp
index 033b0f9100b2befc728157cb0fb8d282d9808dd0..1d9cc7dd2e8f43c76820974caa473ad876b0a97c 100644
--- a/src/ceres_wrapper/solver_ceres.cpp
+++ b/src/ceres_wrapper/solver_ceres.cpp
@@ -579,6 +579,14 @@ const Eigen::SparseMatrixd SolverCeres::computeHessian() const
     return H;
 }
 
+bool SolverCeres::hasThisLocalParametrizationDerived(const StateBlockPtr& st,
+                                                     const LocalParametrizationBasePtr& local_param)
+{
+    return state_blocks_local_param_.count(st) == 1
+            && state_blocks_local_param_.at(st)->getLocalParametrization() == local_param
+            && ceres_problem_->GetParameterization(getAssociatedMemBlockPtr(st))
+                    == state_blocks_local_param_.at(st).get();
+}
 
 } // namespace wolf
 #include "core/solver/factory_solver.h"
diff --git a/src/solver/solver_manager.cpp b/src/solver/solver_manager.cpp
index 9649f9e063fab5b8ead117332ca8f070836b8b86..60b06fd1f7b0744f8c8a293ff4f35e0e265c9f60 100644
--- a/src/solver/solver_manager.cpp
+++ b/src/solver/solver_manager.cpp
@@ -368,26 +368,35 @@ bool SolverManager::isFactorRegistered(const FactorBasePtr& fac_ptr) const
 
 bool SolverManager::isStateBlockFixed(const StateBlockPtr& st)
 {
+    if (!isStateBlockRegistered(st))
+        return false;
+
     if (isStateBlockFloating(st))
         return st->isFixed();
-    else
-        return isStateBlockFixedDerived(st);
+
+    return isStateBlockFixedDerived(st);
 }
 
 bool SolverManager::hasThisLocalParametrization(const StateBlockPtr& st, const LocalParametrizationBasePtr& local_param)
 {
+    if (!isStateBlockRegistered(st))
+        return false;
+
     if (isStateBlockFloating(st))
         return st->getLocalParametrization() == local_param;
-    else
-        return hasThisLocalParametrizationDerived(st, local_param);
+
+    return hasThisLocalParametrizationDerived(st, local_param);
 };
 
 bool SolverManager::hasLocalParametrization(const StateBlockPtr& st) const
 {
+    if (!isStateBlockRegistered(st))
+        return false;
+
     if (isStateBlockFloating(st))
         return st->hasLocalParametrization();
-    else
-        return hasLocalParametrizationDerived(st);
+
+    return hasLocalParametrizationDerived(st);
 };
 
 int SolverManager::numFactors() const
@@ -483,7 +492,7 @@ bool SolverManager::check(std::string prefix) const
     for (auto sb : state_blocks_)
         if (!isStateBlockRegisteredDerived(sb.first))
         {
-            WOLF_ERROR("SolverManager::checkAgainstDerived: state block ", sb.first, " is in state_blocks_ but not registered in derived solver - in ", prefix);
+            WOLF_ERROR("SolverManager::check: state block ", sb.first, " is in state_blocks_ but not registered in derived solver - in ", prefix);
             ok = false;
         }
 
@@ -491,19 +500,19 @@ bool SolverManager::check(std::string prefix) const
     for (auto fac : factors_)
         if (!isFactorRegisteredDerived(fac))
         {
-            WOLF_ERROR("SolverManager::checkAgainstDerived: factor ", fac->id(), " is in factors_ but not registered in derived solver - in ", prefix);
+            WOLF_ERROR("SolverManager::check: factor ", fac->id(), " is in factors_ but not registered in derived solver - in ", prefix);
             ok = false;
         }
 
     // numbers
     if (numStateBlocksDerived() != state_blocks_.size())
     {
-        WOLF_ERROR("SolverManager::checkAgainstDerived: numStateBlocksDerived() = ", numStateBlocksDerived(), " DIFFERENT THAN state_blocks_.size() = ", state_blocks_.size(), " - in ", prefix);
+        WOLF_ERROR("SolverManager::check: numStateBlocksDerived() = ", numStateBlocksDerived(), " DIFFERENT THAN state_blocks_.size() = ", state_blocks_.size(), " - in ", prefix);
         ok = false;
     }
     if (numFactorsDerived() != numFactors())
     {
-        WOLF_ERROR("SolverManager::checkAgainstDerived: numFactorsDerived() = ", numFactorsDerived(), " DIFFERENT THAN numFactors() = ", numFactors(), " - in ", prefix);
+        WOLF_ERROR("SolverManager::check: numFactorsDerived() = ", numFactorsDerived(), " DIFFERENT THAN numFactors() = ", numFactors(), " - in ", prefix);
         ok = false;
     }
 
diff --git a/test/dummy/solver_manager_dummy.h b/test/dummy/solver_manager_dummy.h
index 89febb761317bc9bf81d10642e5ee6a981ab356b..5faef11f35874747a5f0b98f8d99b42911d116e1 100644
--- a/test/dummy/solver_manager_dummy.h
+++ b/test/dummy/solver_manager_dummy.h
@@ -33,12 +33,12 @@ class SolverManagerDummy : public SolverManager
 
         bool hasThisLocalParametrizationDerived(const StateBlockPtr& st, const LocalParametrizationBasePtr& local_param) override
         {
-            return state_block_local_param_.count(st) == 1 and  state_block_local_param_.at(st) == local_param;
+            return state_block_local_param_.at(st) == local_param;
         };
 
         bool hasLocalParametrizationDerived(const StateBlockPtr& st) const override
         {
-            return state_block_local_param_.count(st) == 1;
+            return state_block_local_param_.at(st) != nullptr;
         };
 
         virtual int numStateBlocksDerived() const override
@@ -61,8 +61,6 @@ class SolverManagerDummy : public SolverManager
         double  initialCost() override   { return double(1); }
         double  finalCost() override     { return double(0); }
 
-
-
     protected:
 
         bool checkDerived(std::string prefix="") const override {return true;}
@@ -91,10 +89,7 @@ class SolverManagerDummy : public SolverManager
         };
         void updateStateBlockLocalParametrizationDerived(const StateBlockPtr& state_ptr) override
         {
-            if (state_ptr->getLocalParametrization() == nullptr)
-                state_block_local_param_.erase(state_ptr);
-            else
-                state_block_local_param_[state_ptr] = state_ptr->getLocalParametrization();
+            state_block_local_param_[state_ptr] = state_ptr->getLocalParametrization();
         };
         bool isStateBlockRegisteredDerived(const StateBlockPtr& state_ptr) const override
         {
diff --git a/test/gtest_solver_ceres.cpp b/test/gtest_solver_ceres.cpp
index 3dd5a30b546edc5755b130ea204c60c5592a4c23..9fe0e4306704919bcd7ab234716a3acf107e0227 100644
--- a/test/gtest_solver_ceres.cpp
+++ b/test/gtest_solver_ceres.cpp
@@ -1,5 +1,5 @@
 /*
- * gtest_solver_ceres.cpp
+ * gtest_solver_ptr.cpp
  *
  *  Created on: Jun, 2018
  *      Author: jvallve
@@ -13,6 +13,7 @@
 #include "core/capture/capture_void.h"
 #include "core/factor/factor_pose_2d.h"
 #include "core/factor/factor_quaternion_absolute.h"
+#include "core/factor/factor_block_absolute.h"
 #include "core/state_block/local_parametrization_angle.h"
 #include "core/state_block/local_parametrization_quaternion.h"
 
@@ -27,568 +28,1533 @@
 using namespace wolf;
 using namespace Eigen;
 
-WOLF_PTR_TYPEDEFS(SolverCeresWrapper);
-class SolverCeresWrapper : public SolverCeres
-{
-    public:
-        SolverCeresWrapper(const ProblemPtr& wolf_problem) :
-            SolverCeres(wolf_problem)
-        {
-        };
-
-        int numStateBlocks()
-        {
-            return ceres_problem_->NumParameterBlocks();
-        };
+/*
+ * Following tests are the same as in gtest_solver_manager.cpp
+ * (modifications should be applied to both tests)
+ */
 
-        int numFactors()
-        {
-            return ceres_problem_->NumResidualBlocks();
-        };
+StateBlockPtr createStateBlock()
+{
+    Vector4d state; state << 1, 0, 0, 0;
+    return std::make_shared<StateBlock>(state);
+}
 
-};
+FactorBasePtr createFactor(StateBlockPtr sb_ptr)
+{
+    return std::make_shared<FactorBlockAbsolute>(std::make_shared<FeatureBase>("Dummy",
+                                                                               VectorXd::Zero(sb_ptr->getSize()),
+                                                                               MatrixXd::Identity(sb_ptr->getSize(),sb_ptr->getSize())),
+                                                 sb_ptr,
+                                                 nullptr,
+                                                 false);
+}
 
 TEST(SolverCeres, Create)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
-    // check double ointers to branches
-    ASSERT_EQ(P, solver_ceres->getProblem());
+    // check pointers
+    EXPECT_EQ(P, solver_ptr->getProblem());
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // run solver check
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, AddStateBlock)
+////////////////////////////////////////////////////////
+// FLOATING STATE BLOCKS
+TEST(SolverCeres, FloatingStateBlock_Add)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector2d state; state << 1, 2;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // check stateblock
-    ASSERT_TRUE(solver_ceres->isStateBlockRegistered(sb_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check stateblock
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, DoubleAddStateBlock)
+TEST(SolverCeres, FloatingStateBlock_DoubleAdd)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector2d state; state << 1, 2;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // add stateblock again
+    // notify stateblock again
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // check stateblock
-    ASSERT_TRUE(solver_ceres->isStateBlockRegistered(sb_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check stateblock
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, UpdateStateBlock)
+TEST(SolverCeres, FloatingStateBlock_AddFix)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector2d state; state << 1, 2;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock unfixed
-    ASSERT_FALSE(solver_ceres->isStateBlockFixed(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 
     // Fix frame
     sb_ptr->fix();
 
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
     // update solver manager
-    solver_ceres->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock fixed
-    ASSERT_TRUE(solver_ceres->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverCeres, FloatingStateBlock_AddFixed)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // Fix state block
+    sb_ptr->fix();
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // update solver manager
+    solver_ptr->update();
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // check stateblock fixed
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, AddUpdateStateBlock)
+TEST(SolverCeres, FloatingStateBlock_AddUpdateLocalParam)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector2d state; state << 1, 2;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // Local param
+    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationQuaternionLocal>();
+    sb_ptr->setLocalParametrization(local_ptr);
+
     // Fix state block
     sb_ptr->fix();
 
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+    EXPECT_TRUE(sb_ptr->localParamUpdated());
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver manager
-    solver_ceres->update();
+    solver_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock fixed
-    ASSERT_TRUE(solver_ceres->isStateBlockRegistered(sb_ptr));
-    ASSERT_TRUE(solver_ceres->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverCeres, FloatingStateBlock_AddLocalParamRemoveLocalParam)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Local param
+    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationQuaternionLocal>();
+    sb_ptr->setLocalParametrization(local_ptr);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_TRUE(sb_ptr->localParamUpdated());
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // update solver manager
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check stateblock localparam
+    EXPECT_TRUE(solver_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // Remove local param
+    sb_ptr->removeLocalParametrization();
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_TRUE(sb_ptr->localParamUpdated());
+
+    // update solver manager
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check stateblock localparam
+    EXPECT_FALSE(solver_ptr->hasLocalParametrization(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, RemoveStateBlock)
+TEST(SolverCeres, FloatingStateBlock_Remove)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector2d state; state << 1, 2;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    ASSERT_TRUE(solver_ceres->isStateBlockRegistered(sb_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE);
 
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // check stateblock
-    ASSERT_FALSE(solver_ceres->isStateBlockRegistered(sb_ptr));
-    ASSERT_EQ(solver_ceres->numStateBlocks(), 0);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check stateblock
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, AddRemoveStateBlock)
+TEST(SolverCeres, FloatingStateBlock_AddRemove)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector2d state; state << 1, 2;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // remove state_block
-    P->notifyStateBlock(sb_ptr,REMOVE);
+    P->notifyStateBlock(sb_ptr,REMOVE); // should cancell out the ADD
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // check no stateblocks
-    ASSERT_FALSE(solver_ceres->isStateBlockRegistered(sb_ptr));
-    ASSERT_EQ(solver_ceres->numStateBlocks(), 0);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check state block
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, RemoveUpdateStateBlock)
+TEST(SolverCeres, FloatingStateBlock_AddRemoveAdd)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector2d state; state << 1, 2;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
-    // update solver
-    solver_ceres->update();
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // remove state_block
-    P->notifyStateBlock(sb_ptr,REMOVE);
+    P->notifyStateBlock(sb_ptr,REMOVE); // should cancell out the ADD
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD); // again ADD in notification list
+
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check state block
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, DoubleRemoveStateBlock)
+TEST(SolverCeres, FloatingStateBlock_DoubleRemove)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector2d state; state << 1, 2;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // update solver
+    solver_ptr->update();
+
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver manager
-    solver_ceres->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // checks
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, AddFactor)
+TEST(SolverCeres, FloatingStateBlock_AddUpdated)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Fix
+    sb_ptr->fix();
+
+    // Set State
+    sb_ptr->setState(2*sb_ptr->getState());
+
+    // Check flags have been set true
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+    EXPECT_TRUE(sb_ptr->stateUpdated());
+
+    // == When an ADD is notified: a ADD notification should be stored ==
+
+    // notify state block
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // check notifications
+    // check notifications
+    Notification notif;
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),1);
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(notif, ADD);
+
+    // == Insert OTHER notifications ==
 
-    // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceKeyFrame( 0, P->stateZero() );
-    auto C = CaptureBase::emplace<CaptureVoid>(F, 0, nullptr);
-    auto f = FeatureBase::emplace<FeatureBase>(C, "FeatureOdom2d", Vector3d::Zero(), Matrix3d::Identity());
-    FactorPose2dPtr c = FactorBase::emplace<FactorPose2d>(f,f,nullptr,false);
+    // Set State --> FLAG
+    sb_ptr->setState(2*sb_ptr->getState());
+
+    // Fix --> FLAG
+    sb_ptr->unfix();
+    // Check flag has been set true
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),1); // No new notifications (fix and set state are flags in sb)
+
+    // == consume empties the notification map ==
+    solver_ptr->update(); // it calls P->consumeStateBlockNotificationMap();
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    // Check flags have been reset
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+
+    // == When an REMOVE is notified: a REMOVE notification should be stored ==
+
+    // remove state_block
+    P->notifyStateBlock(sb_ptr,REMOVE);
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),1);
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(notif, REMOVE);
+
+    // == REMOVE + ADD: notification map should be empty ==
+    P->notifyStateBlock(sb_ptr,ADD);
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+
+    // == UPDATES should clear the list of notifications ==
+    // notify state block
+    P->notifyStateBlock(sb_ptr,ADD);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // check factor
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c));
-    ASSERT_EQ(solver_ceres->numFactors(), 1);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0); // After solver_manager->update, notifications should be empty
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // == ADD + REMOVE: notification map should be empty ==
+    P->notifyStateBlock(sb_ptr,ADD);
+    P->notifyStateBlock(sb_ptr,REMOVE);
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
 }
 
-TEST(SolverCeres, DoubleAddFactor)
+////////////////////////////////////////////////////////
+// STATE BLOCKS AND FACTOR
+TEST(SolverCeres, StateBlockAndFactor_Add)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock (floating for the moment)
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // update solver
+    solver_ptr->update();
+
+    // checks
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
 
-    // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceKeyFrame(0, P->stateZero() );
-    auto C = CaptureBase::emplace<CaptureVoid>(F, 0, nullptr);
-    auto f = FeatureBase::emplace<FeatureBase>(C, "FeatureOdom2d", Vector3d::Zero(), Matrix3d::Identity());
-    FactorPose2dPtr c = FactorBase::emplace<FactorPose2d>(f,f,nullptr,false);
+    // notify factor (state block now not floating)
+    P->notifyFactor(fac_ptr,ADD);
 
-    // add factor again
-    P->notifyFactor(c,ADD);
+    // check notifications
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // check factor
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c));
-    ASSERT_EQ(solver_ceres->numFactors(), 1);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // checks
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, RemoveFactor)
+TEST(SolverCeres, StateBlockAndFactor_DoubleAdd)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
 
-    // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceKeyFrame(0, P->stateZero() );
-    auto C = CaptureBase::emplace<CaptureVoid>(F, 0, nullptr);
-    auto f = FeatureBase::emplace<FeatureBase>(C, "FeatureOdom2d", Vector3d::Zero(), Matrix3d::Identity());
-    FactorPose2dPtr c = FactorBase::emplace<FactorPose2d>(f,f,nullptr,false);
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // notify stateblock again
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
 
-    // remove factor
-    P->notifyFactor(c,REMOVE);
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // check factor
-    ASSERT_FALSE(solver_ceres->isFactorRegistered(c));
-    ASSERT_EQ(solver_ceres->numFactors(), 0);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check stateblock
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, AddRemoveFactor)
+TEST(SolverCeres, StateBlockAndFactor_Fix)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
 
-    // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceKeyFrame(0, P->stateZero() );
-    auto C = CaptureBase::emplace<CaptureVoid>(F, 0, nullptr);
-    auto f = FeatureBase::emplace<FeatureBase>(C, "FeatureOdom2d", Vector3d::Zero(), Matrix3d::Identity());
-    FactorPose2dPtr c = FactorBase::emplace<FactorPose2d>(f,f,nullptr,false);
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
 
-    // remove factor
-    P->notifyFactor(c,REMOVE);
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
-    ASSERT_TRUE(P->getFactorNotificationMapSize() == 0); // add+remove = empty
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // check stateblock unfixed
+    EXPECT_FALSE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+
+    // Fix frame
+    sb_ptr->fix();
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // update solver manager
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // check factor
-    ASSERT_FALSE(solver_ceres->isFactorRegistered(c));
-    ASSERT_EQ(solver_ceres->numFactors(), 0);
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check stateblock fixed
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, DoubleRemoveFactor)
+TEST(SolverCeres, StateBlockAndFactor_AddFixed)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // Fix state block
+    sb_ptr->fix();
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // update solver manager
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceKeyFrame(0, P->stateZero() );
-    auto C = CaptureBase::emplace<CaptureVoid>(F, 0, nullptr);
-    auto f = FeatureBase::emplace<FeatureBase>(C, "FeatureOdom2d", Vector3d::Zero(), Matrix3d::Identity());
-    FactorPose2dPtr c = FactorBase::emplace<FactorPose2d>(f,f,nullptr,false);
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // check stateblock fixed
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverCeres, StateBlockAndFactor_UpdateLocalParam)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // Local param
+    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationQuaternionLocal>();
+    sb_ptr->setLocalParametrization(local_ptr);
+
+    // Fix state block
+    sb_ptr->fix();
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+    EXPECT_TRUE(sb_ptr->localParamUpdated());
+
+    // update solver manager
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // check stateblock fixed
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverCeres, StateBlockAndFactor_AddLocalParamRemoveLocalParam)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // Local param
+    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationQuaternionLocal>();
+    sb_ptr->setLocalParametrization(local_ptr);
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_TRUE(sb_ptr->localParamUpdated());
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // update solver manager
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check solver
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->hasLocalParametrization(sb_ptr));
+    EXPECT_TRUE(solver_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->localParamUpdated());
+
+    // Remove local param
+    sb_ptr->removeLocalParametrization();
+
+    // check flags
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_TRUE(sb_ptr->localParamUpdated());
+
+    // update solver manager
+    solver_ptr->update();
+
+    // check solver
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->hasLocalParametrization(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverCeres, StateBlockAndFactor_RemoveStateBlock)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // remove state_block
+    P->notifyStateBlock(sb_ptr,REMOVE);
+
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // update solver
+    solver_ptr->update(); // there is a factor involved, removal posponed (REMOVE in notification list)
+
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // checks
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverCeres, StateBlockAndFactor_RemoveFactor)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
 
-    // remove factor
-    P->notifyFactor(c,REMOVE);
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // remove factor
-    P->notifyFactor(c,REMOVE);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // remove state_block
+    P->notifyFactor(fac_ptr,REMOVE); // state block should be automatically stored as floating
+
+    // check notifications
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update();
 
-    // check factor
-    ASSERT_FALSE(solver_ceres->isFactorRegistered(c));
-    ASSERT_EQ(solver_ceres->numFactors(), 0);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // checks
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, AddStateBlockLocalParam)
+TEST(SolverCeres, StateBlockAndFactor_AddRemoveStateBlock)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector1d state; state << 1;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // Local param
-    LocalParametrizationBasePtr local_param_ptr = std::make_shared<LocalParametrizationAngle>();
-    sb_ptr->setLocalParametrization(local_param_ptr);
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // remove state_block
+    P->notifyStateBlock(sb_ptr,REMOVE); // cancells out ADD notification
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update(); // factor ADD notification is not executed since state block involved is missing (ADD notification added)
 
-    // check stateblock
-    ASSERT_TRUE(solver_ceres->hasLocalParametrization(sb_ptr));
-    ASSERT_TRUE(solver_ceres->hasThisLocalParametrization(sb_ptr,local_param_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check state block
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, RemoveLocalParam)
+TEST(SolverCeres, StateBlockAndFactor_AddRemoveFactor)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector1d state; state << 1;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // Local param
-    LocalParametrizationBasePtr local_param_ptr = std::make_shared<LocalParametrizationAngle>();
-    sb_ptr->setLocalParametrization(local_param_ptr);
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
 
-    // add stateblock
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // remove state_block
+    P->notifyFactor(fac_ptr,REMOVE); // cancells out ADD notification
+
+    // check notifications
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update(); // state block should be automatically stored as floating
 
-    // Remove local param
-    sb_ptr->removeLocalParametrization();
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // checks
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverCeres, StateBlockAndFactor_DoubleRemoveStateBlock)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // remove state_block
+    P->notifyStateBlock(sb_ptr,REMOVE); // cancells out the ADD
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update(); // factor ADD is posponed
 
-    // check stateblock
-    ASSERT_FALSE(solver_ceres->hasLocalParametrization(sb_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // remove state_block
+    P->notifyStateBlock(sb_ptr,REMOVE);
+
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // update solver manager
+    solver_ptr->update(); // repeated REMOVE should be ignored
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // check state block
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, AddLocalParam)
+TEST(SolverCeres, StateBlockAndFactor_DoubleRemoveFactor)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
     // Create State block
-    Vector1d state; state << 1;
-    StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
+    auto sb_ptr = createStateBlock();
 
-    // add stateblock
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // remove state_block
+    P->notifyFactor(fac_ptr,REMOVE); // cancells out ADD
+
+    // check notifications
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_ceres->update();
+    solver_ptr->update(); // state block should be automatically stored as floating
 
-    // check stateblock
-    ASSERT_FALSE(solver_ceres->hasLocalParametrization(sb_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
 
-    // Local param
-    LocalParametrizationBasePtr local_param_ptr = std::make_shared<LocalParametrizationAngle>();
-    sb_ptr->setLocalParametrization(local_param_ptr);
+    // remove state_block
+    P->notifyFactor(fac_ptr,REMOVE);
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update(); // repeated REMOVE should be ignored
 
-    // check stateblock
-    ASSERT_TRUE(solver_ceres->hasLocalParametrization(sb_ptr));
-    ASSERT_TRUE(solver_ceres->hasThisLocalParametrization(sb_ptr,local_param_ptr));
+    // checks
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverCeres, StateBlockAndFactor_AddUpdatedStateBlock)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // Fix
+    sb_ptr->fix();
+
+    // Change State
+    sb_ptr->setState(2*sb_ptr->getState());
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // Check flags have been set true
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+    EXPECT_TRUE(sb_ptr->stateUpdated());
+
+    // == When an ADD is notified: a ADD notification should be stored ==
+
+    // notify state block
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // notify factor
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
+    // == Insert OTHER notifications ==
+
+    // Set State --> FLAG
+    sb_ptr->setState(2*sb_ptr->getState());
+
+    // Fix --> FLAG
+    sb_ptr->unfix();
+    // Check flag has been set true
+    EXPECT_TRUE(sb_ptr->fixUpdated());
+
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),1); // No new notifications (fix and set state are flags in sb)
+
+    // == consume empties the notification map ==
+    solver_ptr->update(); // it calls P->consumeStateBlockNotificationMap();
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    // Check flags have been reset
+    EXPECT_FALSE(sb_ptr->fixUpdated());
+    EXPECT_FALSE(sb_ptr->stateUpdated());
+
+    // == When an REMOVE is notified: a REMOVE notification should be stored ==
+
+    // remove state_block
+    P->notifyStateBlock(sb_ptr,REMOVE);
+
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),1);
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(notif, REMOVE);
+
+    // == REMOVE + ADD: notification map should be empty ==
+    P->notifyStateBlock(sb_ptr,ADD);
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+
+    // == UPDATES should clear the list of notifications ==
+    // notify state block
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // update solver
+    solver_ptr->update();
+
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0); // After solver_manager->update, notifications should be empty
+
+    // == ADD + REMOVE: notification map should be empty ==
+    P->notifyStateBlock(sb_ptr,ADD);
+    P->notifyStateBlock(sb_ptr,REMOVE);
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
 }
 
-TEST(SolverCeres, FactorsRemoveLocalParam)
+////////////////////////////////////////////////////////
+// ONLY FACTOR
+TEST(SolverCeres, OnlyFactor_Add)
 {
     ProblemPtr P = Problem::create("PO", 3);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
-    // Create (and add) 2 factors quaternion
-    FrameBasePtr                    F = P->emplaceKeyFrame(0, P->stateZero() );
-    auto C = CaptureBase::emplace<CaptureVoid>(F, 0, nullptr);
-    auto f = FeatureBase::emplace<FeatureBase>(C, "FeatureOdom2d", Vector3d::Zero(), Matrix3d::Identity());
-    FactorQuaternionAbsolutePtr c1 = FactorBase::emplace<FactorQuaternionAbsolute>(f, f, F->getO(),nullptr,false);
-    FactorQuaternionAbsolutePtr c2 = FactorBase::emplace<FactorQuaternionAbsolute>(f, f, F->getO(),nullptr,false);
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify factor (state block has not been notified)
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update(); // factor ADD should be posponed (in the notification list again)
 
-    // check local param
-    ASSERT_TRUE(solver_ceres->hasLocalParametrization(F->getO()));
-    ASSERT_TRUE(solver_ceres->hasThisLocalParametrization(F->getO(),F->getO()->getLocalParametrization()));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
-    // check factor
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c1));
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c2));
-    ASSERT_EQ(solver_ceres->numFactors(), 2);
+    // checks
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
 
-    // remove local param
-    F->getO()->removeLocalParametrization();
+TEST(SolverCeres, OnlyFactor_Remove)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify factor (state block has not been notified)
+    P->notifyFactor(fac_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update(); // ADD factor should be posponed (in the notification list again)
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
-    // check local param
-    ASSERT_FALSE(solver_ceres->hasLocalParametrization(F->getO()));
+    // notify factor
+    P->notifyFactor(fac_ptr,REMOVE);
 
-    // check factor
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c1));
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c2));
-    ASSERT_EQ(solver_ceres->numFactors(), 2);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // update solver
+    solver_ptr->update(); // nothing to update
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
+
+    // checks
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverCeres, FactorsUpdateLocalParam)
+TEST(SolverCeres, OnlyFactor_AddRemove)
 {
     ProblemPtr P = Problem::create("PO", 3);
-    SolverCeresWrapperPtr solver_ceres = std::make_shared<SolverCeresWrapper>(P);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
-    // Create (and add) 2 factors quaternion
-    FrameBasePtr                    F = P->emplaceKeyFrame(0, P->stateZero() );
-    auto C = CaptureBase::emplace<CaptureVoid>(F, 0, nullptr);
-    auto f = FeatureBase::emplace<FeatureBase>(C, "FeatureOdom2d", Vector3d::Zero(), Matrix3d::Identity());
-    FactorQuaternionAbsolutePtr c1 = FactorBase::emplace<FactorQuaternionAbsolute>(f, f, F->getO(),nullptr,false);
-    FactorQuaternionAbsolutePtr c2 = FactorBase::emplace<FactorQuaternionAbsolute>(f, f, F->getO(),nullptr,false);
+    // Create State block
+    auto sb_ptr = createStateBlock();
 
-    // update solver
-    solver_ceres->update();
+    // Create Factor
+    auto fac_ptr = createFactor(sb_ptr);
+
+    // notify factor (state block has not been notified)
+    P->notifyFactor(fac_ptr,ADD);
 
-    // check local param
-    ASSERT_TRUE(solver_ceres->hasLocalParametrization(F->getO()));
-    ASSERT_TRUE(solver_ceres->hasThisLocalParametrization(F->getO(),F->getO()->getLocalParametrization()));
+    // check notifications
+    Notification notif;
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
-    // check factor
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c1));
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c2));
-    ASSERT_EQ(solver_ceres->numFactors(), 2);
+    // notify factor
+    P->notifyFactor(fac_ptr,REMOVE);
 
-    // remove local param
-    LocalParametrizationBasePtr local_param_ptr = std::make_shared<LocalParametrizationQuaternionGlobal>();
-    F->getO()->setLocalParametrization(local_param_ptr);
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
 
     // update solver
-    solver_ceres->update();
+    solver_ptr->update(); // nothing to update
 
-    // check local param
-    ASSERT_TRUE(solver_ceres->hasLocalParametrization(F->getO()));
-    ASSERT_TRUE(solver_ceres->hasThisLocalParametrization(F->getO(),local_param_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
 
-    // check factor
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c1));
-    ASSERT_TRUE(solver_ceres->isFactorRegistered(c2));
-    ASSERT_EQ(solver_ceres->numFactors(), 2);
+    // checks
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+////////////////////////////////////////////////////////
+// MULTITHREADING
+
+TEST(SolverCeres, MultiThreadingTruncatedNotifications)
+{
+    double Dt = 5.0;
+    ProblemPtr P = Problem::create("PO", 2);
+    auto solver_ptr = std::make_shared<SolverCeres>(P);
 
-    // run ceres manager check
-    ASSERT_TRUE(solver_ceres->check());
+    // loop updating (without sleep)
+    std::thread t([&](){
+        auto start_t = std::chrono::high_resolution_clock::now();
+        while (true)
+        {
+            solver_ptr->update();
+            ASSERT_TRUE(solver_ptr->check());
+            if (std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - start_t).count() > Dt)
+                break;
+        }});
+
+    // loop emplacing and removing frames (window of 10 KF)
+    auto start = std::chrono::high_resolution_clock::now();
+    TimeStamp ts(0);
+    while (true)
+    {
+        // Emplace Frame, Capture, feature and factor pose 2d
+        FrameBasePtr        F = P->emplaceKeyFrame(ts, P->stateZero());
+        auto C = CaptureBase::emplace<CaptureVoid>(F, ts, nullptr);
+        auto f = FeatureBase::emplace<FeatureBase>(C, "FeaturePose2d", Vector3d::Zero(), Matrix3d::Identity());
+        auto c = FactorBase::emplace<FactorPose2d>(f, f, nullptr, false);
+
+        ts += 1.0;
+
+        if (P->getTrajectory()->getFrameMap().size() > 10)
+            (*P->getTrajectory()->begin())->remove();
+
+        if (std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - start).count() > Dt)
+            break;
+    }
+
+    t.join();
 }
 
 int main(int argc, char **argv)
diff --git a/test/gtest_solver_manager.cpp b/test/gtest_solver_manager.cpp
index de2586dfa38d431719c8441863d099058a1d4e65..5226e125d79e059b29fbbfc3a432ce72452ef43c 100644
--- a/test/gtest_solver_manager.cpp
+++ b/test/gtest_solver_manager.cpp
@@ -14,8 +14,7 @@
 #include "core/capture/capture_void.h"
 #include "core/factor/factor_pose_2d.h"
 #include "core/factor/factor_block_absolute.h"
-#include "core/state_block/local_parametrization_base.h"
-#include "core/state_block/local_parametrization_angle.h"
+#include "core/state_block/local_parametrization_quaternion.h"
 #include "dummy/solver_manager_dummy.h"
 
 #include <iostream>
@@ -24,9 +23,14 @@
 using namespace wolf;
 using namespace Eigen;
 
+/*
+ * Following tests are the same as in gtest_solver_ceres.cpp
+ * (modifications should be applied to both tests)
+ */
+
 StateBlockPtr createStateBlock()
 {
-    Vector2d state; state << 1, 2;
+    Vector4d state; state << 1, 0, 0, 0;
     return std::make_shared<StateBlock>(state);
 }
 
@@ -42,20 +46,22 @@ FactorBasePtr createFactor(StateBlockPtr sb_ptr)
 
 TEST(SolverManager, Create)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
+
+    // check pointers
+    EXPECT_EQ(P, solver_ptr->getProblem());
 
-    // check double pointers to branches
-    EXPECT_EQ(P, solver_manager_ptr->getProblem());
-    EXPECT_TRUE(solver_manager_ptr->check());
+    // run solver check
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 ////////////////////////////////////////////////////////
 // FLOATING STATE BLOCKS
 TEST(SolverManager, FloatingStateBlock_Add)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -63,19 +69,29 @@ TEST(SolverManager, FloatingStateBlock_Add)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check stateblock
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, FloatingStateBlock_DoubleAdd)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -83,25 +99,44 @@ TEST(SolverManager, FloatingStateBlock_DoubleAdd)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // notify stateblock again
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check stateblock
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
-TEST(SolverManager, FloatingStateBlock_AddUpdate)
+TEST(SolverManager, FloatingStateBlock_AddFix)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -109,13 +144,23 @@ TEST(SolverManager, FloatingStateBlock_AddUpdate)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
     EXPECT_FALSE(sb_ptr->fixUpdated());
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -123,20 +168,28 @@ TEST(SolverManager, FloatingStateBlock_AddUpdate)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock unfixed
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockFixed(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_FALSE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 
     // Fix frame
     sb_ptr->fix();
 
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
     EXPECT_TRUE(sb_ptr->fixUpdated());
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -144,15 +197,15 @@ TEST(SolverManager, FloatingStateBlock_AddUpdate)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock fixed
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFixed(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, FloatingStateBlock_AddFixed)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -160,6 +213,12 @@ TEST(SolverManager, FloatingStateBlock_AddFixed)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
     EXPECT_FALSE(sb_ptr->fixUpdated());
@@ -174,7 +233,11 @@ TEST(SolverManager, FloatingStateBlock_AddFixed)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -182,16 +245,16 @@ TEST(SolverManager, FloatingStateBlock_AddFixed)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock fixed
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFixed(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, FloatingStateBlock_AddUpdateLocalParam)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -199,13 +262,19 @@ TEST(SolverManager, FloatingStateBlock_AddUpdateLocalParam)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
     EXPECT_FALSE(sb_ptr->fixUpdated());
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // Local param
-    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationAngle>();
+    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationQuaternionLocal>();
     sb_ptr->setLocalParametrization(local_ptr);
 
     // Fix state block
@@ -215,9 +284,19 @@ TEST(SolverManager, FloatingStateBlock_AddUpdateLocalParam)
     EXPECT_FALSE(sb_ptr->stateUpdated());
     EXPECT_TRUE(sb_ptr->fixUpdated());
     EXPECT_TRUE(sb_ptr->localParamUpdated());
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -225,23 +304,23 @@ TEST(SolverManager, FloatingStateBlock_AddUpdateLocalParam)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock fixed
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFixed(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, FloatingStateBlock_AddLocalParamRemoveLocalParam)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
 
     // Local param
-    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationAngle>();
+    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationQuaternionLocal>();
     sb_ptr->setLocalParametrization(local_ptr);
 
     // check flags
@@ -252,11 +331,21 @@ TEST(SolverManager, FloatingStateBlock_AddLocalParamRemoveLocalParam)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check stateblock localparam
-    EXPECT_TRUE(solver_manager_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+    EXPECT_TRUE(solver_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -272,19 +361,23 @@ TEST(SolverManager, FloatingStateBlock_AddLocalParamRemoveLocalParam)
     EXPECT_TRUE(sb_ptr->localParamUpdated());
 
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check stateblock localparam
-    EXPECT_FALSE(solver_manager_ptr->hasLocalParametrization(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_FALSE(solver_ptr->hasLocalParametrization(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, FloatingStateBlock_Remove)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -292,24 +385,43 @@ TEST(SolverManager, FloatingStateBlock_Remove)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE);
 
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check stateblock
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, FloatingStateBlock_AddRemove)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -317,21 +429,79 @@ TEST(SolverManager, FloatingStateBlock_AddRemove)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // remove state_block
-    P->notifyStateBlock(sb_ptr,REMOVE);
+    P->notifyStateBlock(sb_ptr,REMOVE); // should cancel out the ADD
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check state block
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
+}
+
+TEST(SolverManager, FloatingStateBlock_AddRemoveAdd)
+{
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
+
+    // Create State block
+    auto sb_ptr = createStateBlock();
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD);
+
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // remove state_block
+    P->notifyStateBlock(sb_ptr,REMOVE); // should cancell out the ADD
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // notify stateblock
+    P->notifyStateBlock(sb_ptr,ADD); // again ADD in notification list
+
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // update solver
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check state block
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, FloatingStateBlock_DoubleRemove)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -339,26 +509,39 @@ TEST(SolverManager, FloatingStateBlock_DoubleRemove)
     // notify stateblock
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // update solver
+    solver_ptr->update();
+
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE);
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
 
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // checks
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, FloatingStateBlock_AddUpdated)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -378,6 +561,8 @@ TEST(SolverManager, FloatingStateBlock_AddUpdated)
     // notify state block
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    // check notifications
     Notification notif;
     EXPECT_EQ(P->getStateBlockNotificationMapSize(),1);
     EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
@@ -396,7 +581,7 @@ TEST(SolverManager, FloatingStateBlock_AddUpdated)
     EXPECT_EQ(P->getStateBlockNotificationMapSize(),1); // No new notifications (fix and set state are flags in sb)
 
     // == consume empties the notification map ==
-    solver_manager_ptr->update(); // it calls P->consumeStateBlockNotificationMap();
+    solver_ptr->update(); // it calls P->consumeStateBlockNotificationMap();
     EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
     // Check flags have been reset
     EXPECT_FALSE(sb_ptr->fixUpdated());
@@ -407,6 +592,7 @@ TEST(SolverManager, FloatingStateBlock_AddUpdated)
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE);
 
+    // check notifications
     EXPECT_EQ(P->getStateBlockNotificationMapSize(),1);
     EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
     EXPECT_EQ(notif, REMOVE);
@@ -420,9 +606,11 @@ TEST(SolverManager, FloatingStateBlock_AddUpdated)
     P->notifyStateBlock(sb_ptr,ADD);
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
 
+    // check notifications
     EXPECT_EQ(P->getStateBlockNotificationMapSize(),0); // After solver_manager->update, notifications should be empty
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // == ADD + REMOVE: notification map should be empty ==
     P->notifyStateBlock(sb_ptr,ADD);
@@ -434,8 +622,8 @@ TEST(SolverManager, FloatingStateBlock_AddUpdated)
 // STATE BLOCKS AND FACTOR
 TEST(SolverManager, StateBlockAndFactor_Add)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -446,30 +634,45 @@ TEST(SolverManager, StateBlockAndFactor_Add)
     // notify stateblock (floating for the moment)
     P->notifyStateBlock(sb_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
 
     // checks
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
 
     // notify factor (state block now not floating)
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // checks
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isFactorRegistered(fac_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_DoubleAdd)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -483,8 +686,20 @@ TEST(SolverManager, StateBlockAndFactor_DoubleAdd)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // notify stateblock again
     P->notifyStateBlock(sb_ptr,ADD);
@@ -492,20 +707,30 @@ TEST(SolverManager, StateBlockAndFactor_DoubleAdd)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check stateblock
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isFactorRegistered(fac_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_Fix)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -519,13 +744,24 @@ TEST(SolverManager, StateBlockAndFactor_Fix)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
     EXPECT_FALSE(sb_ptr->fixUpdated());
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -533,8 +769,8 @@ TEST(SolverManager, StateBlockAndFactor_Fix)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock unfixed
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockFixed(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_FALSE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 
     // Fix frame
     sb_ptr->fix();
@@ -544,8 +780,16 @@ TEST(SolverManager, StateBlockAndFactor_Fix)
     EXPECT_TRUE(sb_ptr->fixUpdated());
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -553,14 +797,14 @@ TEST(SolverManager, StateBlockAndFactor_Fix)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock fixed
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFixed(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_AddFixed)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -574,6 +818,13 @@ TEST(SolverManager, StateBlockAndFactor_AddFixed)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
     EXPECT_FALSE(sb_ptr->fixUpdated());
@@ -588,7 +839,11 @@ TEST(SolverManager, StateBlockAndFactor_AddFixed)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -596,15 +851,15 @@ TEST(SolverManager, StateBlockAndFactor_AddFixed)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock fixed
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFixed(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_UpdateLocalParam)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -618,13 +873,20 @@ TEST(SolverManager, StateBlockAndFactor_UpdateLocalParam)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
     EXPECT_FALSE(sb_ptr->fixUpdated());
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // Local param
-    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationAngle>();
+    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationQuaternionLocal>();
     sb_ptr->setLocalParametrization(local_ptr);
 
     // Fix state block
@@ -636,7 +898,11 @@ TEST(SolverManager, StateBlockAndFactor_UpdateLocalParam)
     EXPECT_TRUE(sb_ptr->localParamUpdated());
 
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -644,16 +910,16 @@ TEST(SolverManager, StateBlockAndFactor_UpdateLocalParam)
     EXPECT_FALSE(sb_ptr->localParamUpdated());
 
     // check stateblock fixed
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFixed(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFixed(sb_ptr));
+    EXPECT_TRUE(solver_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_AddLocalParamRemoveLocalParam)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -662,7 +928,7 @@ TEST(SolverManager, StateBlockAndFactor_AddLocalParamRemoveLocalParam)
     auto fac_ptr = createFactor(sb_ptr);
 
     // Local param
-    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationAngle>();
+    LocalParametrizationBasePtr local_ptr = std::make_shared<LocalParametrizationQuaternionLocal>();
     sb_ptr->setLocalParametrization(local_ptr);
 
     // check flags
@@ -676,11 +942,25 @@ TEST(SolverManager, StateBlockAndFactor_AddLocalParamRemoveLocalParam)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
 
-    // check stateblock localparam
-    EXPECT_TRUE(solver_manager_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // check solver
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->hasLocalParametrization(sb_ptr));
+    EXPECT_TRUE(solver_ptr->hasThisLocalParametrization(sb_ptr,local_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 
     // check flags
     EXPECT_FALSE(sb_ptr->stateUpdated());
@@ -696,17 +976,18 @@ TEST(SolverManager, StateBlockAndFactor_AddLocalParamRemoveLocalParam)
     EXPECT_TRUE(sb_ptr->localParamUpdated());
 
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update();
 
-    // check stateblock localparam
-    EXPECT_FALSE(solver_manager_ptr->hasLocalParametrization(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    // check solver
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->hasLocalParametrization(sb_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_RemoveStateBlock)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -720,28 +1001,46 @@ TEST(SolverManager, StateBlockAndFactor_RemoveStateBlock)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // remove state_block
-    P->notifyStateBlock(sb_ptr,REMOVE); // there is afactor involved, removal posponed (REMOVE in notification list)
+    P->notifyStateBlock(sb_ptr,REMOVE);
+
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update(); // there is a factor involved, removal posponed (REMOVE in notification list)
 
-    // checks
-    Notification notif;
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isFactorRegistered(fac_ptr));
+    // check notifications
     EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
-    EXPECT_EQ(notif, REMOVE);
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
+
+    // checks
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_RemoveFactor)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -755,26 +1054,46 @@ TEST(SolverManager, StateBlockAndFactor_RemoveFactor)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // remove state_block
     P->notifyFactor(fac_ptr,REMOVE); // state block should be automatically stored as floating
 
+    // check notifications
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(), 0);
+
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // checks
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isFactorRegistered(fac_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_AddRemoveStateBlock)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -788,25 +1107,39 @@ TEST(SolverManager, StateBlockAndFactor_AddRemoveStateBlock)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE); // cancells out ADD notification
 
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update(); // factor ADD notification is not executed since state block involved is missing (ADD notification added)
+    solver_ptr->update(); // factor ADD notification is not executed since state block involved is missing (ADD notification added)
 
-    // check state block
-    Notification notif;
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isFactorRegistered(fac_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
     EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
-    EXPECT_EQ(notif, ADD);
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_EQ(ADD, notif);
+
+    // check state block
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_AddRemoveFactor)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -820,23 +1153,39 @@ TEST(SolverManager, StateBlockAndFactor_AddRemoveFactor)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // remove state_block
-    P->notifyFactor(fac_ptr,REMOVE); // state block should be automatically stored as floating
+    P->notifyFactor(fac_ptr,REMOVE); // cancells out ADD notification
+
+    // check notifications
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update(); // state block should be automatically stored as floating
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(), 0);
 
     // checks
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isFactorRegistered(fac_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_DoubleRemoveStateBlock)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -850,31 +1199,56 @@ TEST(SolverManager, StateBlockAndFactor_DoubleRemoveStateBlock)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // remove state_block
     P->notifyStateBlock(sb_ptr,REMOVE); // cancells out the ADD
 
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update(); // factor ADD is posponed
+    solver_ptr->update(); // factor ADD is posponed
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // remove state_block
-    P->notifyStateBlock(sb_ptr,REMOVE); // should be ignored
+    P->notifyStateBlock(sb_ptr,REMOVE);
+
+    // check notifications
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // update solver manager
-    solver_manager_ptr->update();
+    solver_ptr->update(); // repeated REMOVE should be ignored
 
-    // check state block
-    Notification notif;
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isFactorRegistered(fac_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
     EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
-    EXPECT_EQ(notif, ADD);
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_EQ(ADD, notif);
+
+    // check state block
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_DoubleRemoveFactor)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -888,29 +1262,50 @@ TEST(SolverManager, StateBlockAndFactor_DoubleRemoveFactor)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // remove state_block
     P->notifyFactor(fac_ptr,REMOVE); // cancells out ADD
 
+    // check notifications
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
+    EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update(); // state block should be automatically stored as floating
+    solver_ptr->update(); // state block should be automatically stored as floating
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
 
     // remove state_block
-    P->notifyFactor(fac_ptr,REMOVE); // should be ignored
+    P->notifyFactor(fac_ptr,REMOVE);
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(REMOVE, notif);
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update(); // repeated REMOVE should be ignored
 
     // checks
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_TRUE(solver_manager_ptr->isStateBlockFloating(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isFactorRegistered(fac_ptr));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_TRUE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_TRUE(solver_ptr->isStateBlockFloating(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, StateBlockAndFactor_AddUpdatedStateBlock)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -936,10 +1331,12 @@ TEST(SolverManager, StateBlockAndFactor_AddUpdatedStateBlock)
     // notify factor
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
     Notification notif;
-    EXPECT_EQ(P->getStateBlockNotificationMapSize(),1);
     EXPECT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
-    EXPECT_EQ(notif, ADD);
+    EXPECT_EQ(ADD, notif);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // == Insert OTHER notifications ==
 
@@ -954,7 +1351,7 @@ TEST(SolverManager, StateBlockAndFactor_AddUpdatedStateBlock)
     EXPECT_EQ(P->getStateBlockNotificationMapSize(),1); // No new notifications (fix and set state are flags in sb)
 
     // == consume empties the notification map ==
-    solver_manager_ptr->update(); // it calls P->consumeStateBlockNotificationMap();
+    solver_ptr->update(); // it calls P->consumeStateBlockNotificationMap();
     EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
     // Check flags have been reset
     EXPECT_FALSE(sb_ptr->fixUpdated());
@@ -978,7 +1375,7 @@ TEST(SolverManager, StateBlockAndFactor_AddUpdatedStateBlock)
     P->notifyStateBlock(sb_ptr,ADD);
 
     // update solver
-    solver_manager_ptr->update();
+    solver_ptr->update();
 
     EXPECT_EQ(P->getStateBlockNotificationMapSize(),0); // After solver_manager->update, notifications should be empty
 
@@ -992,8 +1389,8 @@ TEST(SolverManager, StateBlockAndFactor_AddUpdatedStateBlock)
 // ONLY FACTOR
 TEST(SolverManager, OnlyFactor_Add)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -1004,22 +1401,30 @@ TEST(SolverManager, OnlyFactor_Add)
     // notify factor (state block has not been notified)
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update(); // factor should be put in the notification list again
+    solver_ptr->update(); // factor ADD should be posponed (in the notification list again)
 
-    // checks
-    Notification notif;
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isFactorRegistered(fac_ptr));
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
     EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
-    EXPECT_EQ(notif, ADD);
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_EQ(ADD, notif);
+
+    // checks
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, OnlyFactor_Remove)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -1030,27 +1435,44 @@ TEST(SolverManager, OnlyFactor_Remove)
     // notify factor (state block has not been notified)
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // update solver
-    solver_manager_ptr->update(); // factor should be put in the notification list again
+    solver_ptr->update(); // ADD factor should be posponed (in the notification list again)
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
 
     // notify factor
     P->notifyFactor(fac_ptr,REMOVE);
 
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
+
     // update solver
-    solver_manager_ptr->update(); // factor ADD notification should be cancelled
+    solver_ptr->update(); // nothing to update
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
 
     // checks
-    Notification notif;
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isFactorRegistered(fac_ptr));
-    EXPECT_FALSE(P->getFactorNotification(fac_ptr, notif));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 TEST(SolverManager, OnlyFactor_AddRemove)
 {
-    ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    ProblemPtr P = Problem::create("PO", 3);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // Create State block
     auto sb_ptr = createStateBlock();
@@ -1061,35 +1483,48 @@ TEST(SolverManager, OnlyFactor_AddRemove)
     // notify factor (state block has not been notified)
     P->notifyFactor(fac_ptr,ADD);
 
+    // check notifications
+    Notification notif;
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_TRUE(P->getFactorNotification(fac_ptr, notif));
+    EXPECT_EQ(ADD, notif);
+
     // notify factor
     P->notifyFactor(fac_ptr,REMOVE);
 
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
+
     // update solver
-    solver_manager_ptr->update(); // factor ADD notification should be cancelled
+    solver_ptr->update(); // nothing to update
+
+    // check notifications
+    EXPECT_EQ(P->getStateBlockNotificationMapSize(),0);
+    EXPECT_EQ(P->getFactorNotificationMapSize(),0);
 
     // checks
-    Notification notif;
-    EXPECT_FALSE(solver_manager_ptr->isStateBlockRegistered(sb_ptr));
-    EXPECT_FALSE(solver_manager_ptr->isFactorRegistered(fac_ptr));
-    EXPECT_FALSE(P->getFactorNotification(fac_ptr, notif));
-    EXPECT_TRUE(solver_manager_ptr->check());
+    EXPECT_FALSE(solver_ptr->isStateBlockRegistered(sb_ptr));
+    EXPECT_FALSE(solver_ptr->isFactorRegistered(fac_ptr));
+    EXPECT_TRUE(solver_ptr->check());
 }
 
 ////////////////////////////////////////////////////////
 // MULTITHREADING
 
-/*TEST(SolverManager, MultiThreadingTruncatedNotifications)
+TEST(SolverManager, MultiThreadingTruncatedNotifications)
 {
     double Dt = 5.0;
     ProblemPtr P = Problem::create("PO", 2);
-    SolverManagerDummyPtr solver_manager_ptr = std::make_shared<SolverManagerDummy>(P);
+    auto solver_ptr = std::make_shared<SolverManagerDummy>(P);
 
     // loop updating (without sleep)
     std::thread t([&](){
         auto start_t = std::chrono::high_resolution_clock::now();
         while (true)
         {
-            solver_manager_ptr->update();
+            solver_ptr->update();
+            ASSERT_TRUE(solver_ptr->check());
             if (std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now() - start_t).count() > Dt)
                 break;
         }});
@@ -1115,7 +1550,7 @@ TEST(SolverManager, OnlyFactor_AddRemove)
     }
 
     t.join();
-}*/
+}
 
 int main(int argc, char **argv)
 {