diff --git a/CMakeLists.txt b/CMakeLists.txt
index cd0c6487988fb0435b6593e8e96a3c9c034320cc..f3eb18d8063ef9182c7e614f4ab22ca33159459c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,12 +45,15 @@ message(STATUS "Configured to compile in ${CMAKE_BUILD_TYPE} mode.")
 SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -D_REENTRANT")
 SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -D_REENTRANT")
 
+<<<<<<< HEAD
 if(UNIX)
   # GCC is not strict enough by default, so enable most of the warnings.
   set(CMAKE_CXX_FLAGS
     "${CMAKE_CXX_FLAGS} -Werror=all -Werror=extra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-but-set-variable")
 endif(UNIX)
 
+=======
+>>>>>>> devel
 #Set compiler according C++11 support
 include(CheckCXXCompilerFlag)
 CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
@@ -65,6 +68,12 @@ else()
   message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
 endif()
 
+if(UNIX)
+  # GCC is not strict enough by default, so enable most of the warnings.
+  set(CMAKE_CXX_FLAGS
+    "${CMAKE_CXX_FLAGS} -Werror=all -Werror=extra -Wno-unknown-pragmas -Wno-sign-compare -Wno-unused-parameter -Wno-missing-field-initializers")
+endif(UNIX)
+
 
 #OPTION(BUILD_DOC "Build Documentation" OFF)
 OPTION(BUILD_TESTS "Build Unit tests" ON)
diff --git a/hello_wolf/hello_wolf.cpp b/hello_wolf/hello_wolf.cpp
index 3708f51d3aa1141756dc54c27f76039671bfa42e..c73e295083b71c0237d2569ff90ff0b9191b1192 100644
--- a/hello_wolf/hello_wolf.cpp
+++ b/hello_wolf/hello_wolf.cpp
@@ -225,7 +225,7 @@ int main()
             if (sb && !sb->isFixed())
                 sb->setState(sb->getState() + VectorXs::Random(sb->getSize()) * 0.5);       // We perturb A LOT !
     for (auto kf : problem->getTrajectory()->getFrameList())
-        if (kf->isKey())
+        if (kf->isKeyOrAux())
             for (auto sb : kf->getStateBlockVec())
                 if (sb && !sb->isFixed())
                     sb->setState(sb->getState() + VectorXs::Random(sb->getSize()) * 0.5);   // We perturb A LOT !
@@ -245,7 +245,7 @@ int main()
     WOLF_TRACE("======== COVARIANCES OF SOLVED PROBLEM =======")
     ceres->computeCovariances(SolverManager::CovarianceBlocksToBeComputed::ALL_MARGINALS);
     for (auto kf : problem->getTrajectory()->getFrameList())
-        if (kf->isKey())
+        if (kf->isKeyOrAux())
         {
             Eigen::MatrixXs cov;
             kf->getCovariance(cov);
diff --git a/include/base/ceres_wrapper/solver_manager.h b/include/base/ceres_wrapper/solver_manager.h
deleted file mode 100644
index 49f3669bf4dbc0c0c1b145eb92687ea6c3506f09..0000000000000000000000000000000000000000
--- a/include/base/ceres_wrapper/solver_manager.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef SOLVER_MANAGER_H_
-#define SOLVER_MANAGER_H_
-
-//wolf includes
-#include "base/common/wolf.h"
-#include "base/state_block/state_block.h"
-#include "base/factor/factor_base.h"
-
-namespace wolf {
-
-/** \brief Enumeration of covariance blocks to be computed
- *
- * Enumeration of covariance blocks to be computed
- *
- */
-typedef enum
-{
-    ALL, ///< All blocks and all cross-covariances
-    ALL_MARGINALS, ///< All marginals
-    ROBOT_LANDMARKS ///< marginals of landmarks and current robot pose plus cross covariances of current robot and all landmarks
-} CovarianceBlocksToBeComputed;
-
-WOLF_PTR_TYPEDEFS(SolverManager);
-
-/** \brief Solver manager for WOLF
- *
- */
-
-class SolverManager
-{
-	protected:
-		ProblemPtr wolf_problem_;
-
-	public:
-        SolverManager(ProblemPtr _wolf_problem);
-
-		virtual ~SolverManager();
-
-		virtual std::string solve(const unsigned int& _report_level) = 0;
-
-		virtual void computeCovariances(CovarianceBlocksToBeComputed _blocks = ROBOT_LANDMARKS) = 0;
-
-		virtual void computeCovariances(const std::vector<StateBlockPtr>& st_list) = 0;
-
-		virtual void update();
-
-        virtual ProblemPtr getProblem();
-
-	private:
-
-		virtual void addFactor(FactorBasePtr _fac_ptr) = 0;
-
-		virtual void removeFactor(FactorBasePtr _fac_ptr) = 0;
-
-		virtual void addStateBlock(StateBlockPtr _st_ptr) = 0;
-
-		virtual void removeStateBlock(StateBlockPtr _st_ptr) = 0;
-
-		virtual void updateStateBlockStatus(StateBlockPtr _st_ptr) = 0;
-};
-
-} // namespace wolf
-
-#endif
diff --git a/include/base/frame/frame_base.h b/include/base/frame/frame_base.h
index ffa84d74d0c7521ce226a5445e58591bfc43be66..f4befb4d11cbc5f54a093e7a6ebcfa221c72b275 100644
--- a/include/base/frame/frame_base.h
+++ b/include/base/frame/frame_base.h
@@ -18,12 +18,13 @@ class StateBlock;
 
 namespace wolf {
 
-/** \brief Enumeration of frame types: key-frame or non-key-frame
+/** \brief Enumeration of frame types
  */
 typedef enum
 {
-    NON_KEY_FRAME = 0,  ///< Regular frame. It does not play at optimization.
-    KEY_FRAME = 1       ///< key frame. It plays at optimizations.
+    KEY = 2,          ///< key frame. It plays at optimizations (estimated).
+    AUXILIARY = 1,    ///< auxiliary frame. It plays at optimizations (estimated).
+    NON_ESTIMATED = 0 ///< regular frame. It does not play at optimization.
 } FrameType;
 
 //class FrameBase
@@ -71,9 +72,14 @@ class FrameBase : public NodeBase, public std::enable_shared_from_this<FrameBase
     public:
         unsigned int id();
 
-        // KeyFrame / NonKeyFrame
+        // get type
         bool isKey() const;
+        bool isAux() const;
+        bool isKeyOrAux() const;
+
+        // set type
         void setKey();
+        void setAux();
 
         // Frame values ------------------------------------------------
     public:
@@ -169,7 +175,17 @@ inline unsigned int FrameBase::id()
 
 inline bool FrameBase::isKey() const
 {
-    return (type_ == KEY_FRAME);
+    return (type_ == KEY);
+}
+
+inline bool FrameBase::isAux() const
+{
+    return (type_ == AUXILIARY);
+}
+
+inline bool FrameBase::isKeyOrAux() const
+{
+    return (type_ == KEY || type_ == AUXILIARY);
 }
 
 inline void FrameBase::getTimeStamp(TimeStamp& _ts) const
diff --git a/include/base/problem/problem.h b/include/base/problem/problem.h
index 938074f78020ebff96905714d70d7f1259a168e1..9c1d768e0d1be2fbac9cf2c9d926e69d8769564e 100644
--- a/include/base/problem/problem.h
+++ b/include/base/problem/problem.h
@@ -3,6 +3,7 @@
 
 // Fwd refs
 namespace wolf{
+class SolverManager;
 class HardwareBase;
 class TrajectoryBase;
 class MapBase;
@@ -33,6 +34,7 @@ enum Notification
  */
 class Problem : public std::enable_shared_from_this<Problem>
 {
+    friend SolverManager; // Enable SolverManager to acces protected functions (consumeXXXNotificationMap())
 
     protected:
         HardwareBasePtr     hardware_ptr_;
@@ -138,7 +140,7 @@ class Problem : public std::enable_shared_from_this<Problem>
 
         /** \brief Emplace frame from string frame_structure
          * \param _frame_structure String indicating the frame structure.
-         * \param _frame_key_type Either KEY_FRAME or NON_KEY_FRAME
+         * \param _frame_key_type Either KEY, AUXILIARY or NON_ESTIMATED
          * \param _frame_state State vector; must match the size and format of the chosen frame structure
          * \param _time_stamp Time stamp of the frame
          *
@@ -154,7 +156,7 @@ class Problem : public std::enable_shared_from_this<Problem>
 
         /** \brief Emplace frame from string frame_structure without state
          * \param _frame_structure String indicating the frame structure.
-         * \param _frame_key_type Either KEY_FRAME or NON_KEY_FRAME
+         * \param _frame_key_type Either KEY, AUXILIARY or NON_ESTIMATED
          * \param _time_stamp Time stamp of the frame
          *
          * This acts as a Frame factory, but also takes care to update related lists in WolfProblem:
@@ -167,7 +169,7 @@ class Problem : public std::enable_shared_from_this<Problem>
                                   const TimeStamp& _time_stamp);
 
         /** \brief Emplace frame from string frame_structure without structure
-         * \param _frame_key_type Either KEY_FRAME or NON_KEY_FRAME
+         * \param _frame_key_type Either KEY, AUXILIARY or NON_ESTIMATED
          * \param _frame_state State vector; must match the size and format of the chosen frame structure
          * \param _time_stamp Time stamp of the frame
          *
@@ -181,7 +183,7 @@ class Problem : public std::enable_shared_from_this<Problem>
                                   const TimeStamp& _time_stamp);
 
         /** \brief Emplace frame from string frame_structure without structure nor state
-         * \param _frame_key_type Either KEY_FRAME or NON_KEY_FRAME
+         * \param _frame_key_type Either KEY, AUXILIARY or NON_ESTIMATED
          * \param _time_stamp Time stamp of the frame
          *
          * This acts as a Frame factory, but also takes care to update related lists in WolfProblem:
@@ -193,26 +195,44 @@ class Problem : public std::enable_shared_from_this<Problem>
                                   const TimeStamp& _time_stamp);
 
         // Frame getters
-        FrameBasePtr    getLastFrame         ( );
-        FrameBasePtr    getLastKeyFrame      ( );
-        FrameBasePtr    closestKeyFrameToTimeStamp(const TimeStamp& _ts);
+        FrameBasePtr getLastFrame( ) const;
+        FrameBasePtr getLastKeyFrame( ) const;
+        FrameBasePtr getLastKeyOrAuxFrame( ) const;
+        FrameBasePtr closestKeyFrameToTimeStamp(const TimeStamp& _ts) const;
+        FrameBasePtr closestKeyOrAuxFrameToTimeStamp(const TimeStamp& _ts) const;
 
-        /** \brief Give the permission to a processor to create a new keyFrame
+        /** \brief Give the permission to a processor to create a new key Frame
          *
-         * This should implement a black list of processors that have forbidden keyframe creation.
+         * This should implement a black list of processors that have forbidden key frame creation.
          *   - This decision is made at problem level, not at processor configuration level.
-         *   - Therefore, if you want to permanently configure a processor for not creating keyframes, see Processor::voting_active_ and its accessors.
+         *   - Therefore, if you want to permanently configure a processor for not creating key frames, see Processor::voting_active_ and its accessors.
          */
         bool permitKeyFrame(ProcessorBasePtr _processor_ptr);
 
         /** \brief New key frame callback
          *
-         * New key frame callback: It should be called by any processor that creates a new keyframe. It calls the keyFrameCallback of the rest of processors.
+         * New key frame callback: It should be called by any processor that creates a new key frame. It calls the keyFrameCallback of the rest of processors.
          */
         void keyFrameCallback(FrameBasePtr _keyframe_ptr, //
                               ProcessorBasePtr _processor_ptr, //
                               const Scalar& _time_tolerance);
 
+        /** \brief Give the permission to a processor to create a new auxiliary Frame
+         *
+         * This should implement a black list of processors that have forbidden auxiliary frame creation.
+         *   - This decision is made at problem level, not at processor configuration level.
+         *   - Therefore, if you want to permanently configure a processor for not creating estimated frames, see Processor::voting_active_ and its accessors.
+         */
+        bool permitAuxFrame(ProcessorBasePtr _processor_ptr);
+
+        /** \brief New auxiliary frame callback
+         *
+         * New auxiliary frame callback: It should be called by any processor that creates a new auxiliary frame. It calls the auxiliaryFrameCallback of the processor motion.
+         */
+        void auxFrameCallback(FrameBasePtr _frame_ptr, //
+                              ProcessorBasePtr _processor_ptr, //
+                              const Scalar& _time_tolerance);
+
         // State getters
         Eigen::VectorXs getCurrentState         ( );
         void            getCurrentState         (Eigen::VectorXs& state);
@@ -240,6 +260,7 @@ class Problem : public std::enable_shared_from_this<Problem>
         bool getCovarianceBlock(StateBlockPtr _state, Eigen::MatrixXs& _cov, const int _row_and_col = 0);
         bool getFrameCovariance(FrameBaseConstPtr _frame_ptr, Eigen::MatrixXs& _covariance);
         bool getLastKeyFrameCovariance(Eigen::MatrixXs& _covariance);
+        bool getLastKeyOrAuxFrameCovariance(Eigen::MatrixXs& _covariance);
         bool getLandmarkCovariance(LandmarkBaseConstPtr _landmark_ptr, Eigen::MatrixXs& _covariance);
 
         // Solver management ----------------------------------------
@@ -252,9 +273,13 @@ class Problem : public std::enable_shared_from_this<Problem>
          */
         void removeStateBlock(StateBlockPtr _state_ptr);
 
-        /** \brief Returns the map of factor notification to be handled by the solver (the map stored in this is emptied)
+        /** \brief Returns the size of the map of state block notification
          */
-        std::map<StateBlockPtr,Notification> consumeStateBlockNotificationMap();
+        SizeStd getStateBlockNotificationMapSize() const;
+
+        /** \brief Returns if the state block has been notified, and the notification via parameter
+         */
+        bool getStateBlockNotification(const StateBlockPtr& sb_ptr, Notification& notif) const;
 
         /** \brief Notifies a new factor to be added to the solver manager
          */
@@ -264,10 +289,24 @@ class Problem : public std::enable_shared_from_this<Problem>
          */
         void removeFactor(FactorBasePtr _factor_ptr);
 
+        /** \brief Returns the size of the map of factor notification
+         */
+        SizeStd getFactorNotificationMapSize() const;
+
+        /** \brief Returns if the factor has been notified, and the notification via parameter
+         */
+        bool getFactorNotification(const FactorBasePtr& fac_ptr, Notification& notif) const;
+
+    protected:
+        /** \brief Returns the map of state block notification to be handled by the solver (the map stored in this is emptied)
+         */
+        std::map<StateBlockPtr,Notification> consumeStateBlockNotificationMap();
+
         /** \brief Returns the map of factor notification to be handled by the solver (the map stored in this is emptied)
          */
         std::map<FactorBasePtr, Notification> consumeFactorNotificationMap();
 
+    public:
         // Print and check ---------------------------------------
         /**
          * \brief print wolf tree
@@ -311,12 +350,25 @@ inline std::map<StateBlockPtr,Notification> Problem::consumeStateBlockNotificati
     return std::move(state_block_notification_map_);
 }
 
+inline SizeStd Problem::getStateBlockNotificationMapSize() const
+{
+    std::lock_guard<std::mutex> lock(mut_state_block_notifications_);
+    return state_block_notification_map_.size();
+}
+
 inline std::map<FactorBasePtr,Notification> Problem::consumeFactorNotificationMap()
 {
     std::lock_guard<std::mutex> lock(mut_factor_notifications_);
     return std::move(factor_notification_map_);
 }
 
+inline wolf::SizeStd Problem::getFactorNotificationMapSize() const
+{
+    std::lock_guard<std::mutex> lock(mut_factor_notifications_);
+    return factor_notification_map_.size();
+}
+
+
 } // namespace wolf
 
 #endif // PROBLEM_H
diff --git a/include/base/processor/processor_base.h b/include/base/processor/processor_base.h
index 5d68c43c7b921532dc1d1d0d32ddabe89d75de93..9e149abcbdfca7c94942b92a1669c9c8ee5f6e70 100644
--- a/include/base/processor/processor_base.h
+++ b/include/base/processor/processor_base.h
@@ -110,16 +110,19 @@ struct ProcessorParamsBase
     ProcessorParamsBase() = default;
 
     ProcessorParamsBase(bool _voting_active,
-                        Scalar _time_tolerance)
-      : voting_active(_voting_active)
-      , time_tolerance(_time_tolerance)
+                        Scalar _time_tolerance,
+                        bool _voting_aux_active = false) :
+        voting_active(_voting_active),
+        voting_aux_active(_voting_aux_active),
+        time_tolerance(_time_tolerance)
     {
       //
     }
 
     virtual ~ProcessorParamsBase() = default;
 
-    bool voting_active = false;
+    bool voting_active = false;     ///< Whether this processor is allowed to vote for a Key Frame or not
+    bool voting_aux_active = false; ///< Whether this processor is allowed to vote for an Auxiliary Frame or not
 
     ///< maximum time difference between a Keyframe time stamp and
     /// a particular Capture of this processor to allow assigning
@@ -159,8 +162,19 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce
          */
         virtual bool voteForKeyFrame() = 0;
 
+        /** \brief Vote for Auxiliary Frame generation
+         *
+         * If a Auxiliary Frame criterion is validated, this function returns true,
+         * meaning that it wants to create a Auxiliary Frame at the \b last Capture.
+         *
+         * WARNING! This function only votes! It does not create Auxiliary Frames!
+         */
+        virtual bool voteForAuxFrame(){return false;};
+
         virtual bool permittedKeyFrame() final;
 
+        virtual bool permittedAuxFrame() final;
+
         /**\brief make a Frame with the provided Capture
          *
          * Provide the following functionality:
@@ -192,7 +206,11 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce
 
         bool isVotingActive() const;
 
+        bool isVotingAuxActive() const;
+
         void setVotingActive(bool _voting_active = true);
+
+        void setVotingAuxActive(bool _voting_active = true);
 };
 
 inline bool ProcessorBase::isVotingActive() const
@@ -200,11 +218,21 @@ inline bool ProcessorBase::isVotingActive() const
     return params_->voting_active;
 }
 
+inline bool ProcessorBase::isVotingAuxActive() const
+{
+    return params_->voting_aux_active;
+}
+
 inline void ProcessorBase::setVotingActive(bool _voting_active)
 {
     params_->voting_active = _voting_active;
 }
 
+inline void ProcessorBase::setVotingAuxActive(bool _voting_active)
+{
+    params_->voting_aux_active = _voting_active;
+}
+
 }
 
 #include "base/sensor/sensor_base.h"
diff --git a/include/base/trajectory/trajectory_base.h b/include/base/trajectory/trajectory_base.h
index 37f9762c7c9955381eaba9bc52aef253441d36e1..aff013ea00d0b40af358ad4d3cb980d8298ccc4e 100644
--- a/include/base/trajectory/trajectory_base.h
+++ b/include/base/trajectory/trajectory_base.h
@@ -26,6 +26,7 @@ class TrajectoryBase : public NodeBase, public std::enable_shared_from_this<Traj
     protected:
         std::string frame_structure_;  // Defines the structure of the Frames in the Trajectory.
         FrameBasePtr last_key_frame_ptr_; // keeps pointer to the last key frame
+        FrameBasePtr last_key_or_aux_frame_ptr_; // keeps pointer to the last estimated frame
         
     public:
         TrajectoryBase(const std::string& _frame_sturcture);
@@ -37,18 +38,21 @@ class TrajectoryBase : public NodeBase, public std::enable_shared_from_this<Traj
         // Frames
         FrameBasePtr addFrame(FrameBasePtr _frame_ptr);
         FrameBasePtrList& getFrameList();
-        FrameBasePtr getLastFrame();
-        FrameBasePtr getLastKeyFrame();
-        FrameBasePtr findLastKeyFrame();
-        FrameBasePtr closestKeyFrameToTimeStamp(const TimeStamp& _ts);
-        void setLastKeyFrame(FrameBasePtr _key_frame_ptr);
+        const FrameBasePtrList& getFrameList() const;
+        FrameBasePtr getLastFrame() const;
+        FrameBasePtr getLastKeyFrame() const;
+        FrameBasePtr getLastKeyOrAuxFrame() const;
+        FrameBasePtr closestKeyFrameToTimeStamp(const TimeStamp& _ts) const;
+        FrameBasePtr closestKeyOrAuxFrameToTimeStamp(const TimeStamp& _ts) const;
         void sortFrame(FrameBasePtr _frm_ptr);
-        void moveFrame(FrameBasePtr _frm_ptr, FrameBaseIter _place);
-        FrameBaseIter computeFrameOrder(FrameBasePtr _frame_ptr);
+        void updateLastFrames();
 
         // factors
         void getFactorList(FactorBasePtrList & _fac_list);
 
+    protected:
+        FrameBaseIter computeFrameOrder(FrameBasePtr _frame_ptr);
+        void moveFrame(FrameBasePtr _frm_ptr, FrameBaseIter _place);
 };
 
 inline FrameBasePtrList& TrajectoryBase::getFrameList()
@@ -56,19 +60,24 @@ inline FrameBasePtrList& TrajectoryBase::getFrameList()
     return frame_list_;
 }
 
-inline FrameBasePtr TrajectoryBase::getLastFrame()
+inline const FrameBasePtrList& TrajectoryBase::getFrameList() const
+{
+    return frame_list_;
+}
+
+inline FrameBasePtr TrajectoryBase::getLastFrame() const
 {
     return frame_list_.back();
 }
 
-inline FrameBasePtr TrajectoryBase::getLastKeyFrame()
+inline FrameBasePtr TrajectoryBase::getLastKeyFrame() const
 {
     return last_key_frame_ptr_;
 }
 
-inline void TrajectoryBase::setLastKeyFrame(FrameBasePtr _key_frame_ptr)
+inline FrameBasePtr TrajectoryBase::getLastKeyOrAuxFrame() const
 {
-    last_key_frame_ptr_ = _key_frame_ptr;
+    return last_key_or_aux_frame_ptr_;
 }
 
 inline std::string TrajectoryBase::getFrameStructure() const
diff --git a/src/ceres_wrapper/ceres_manager.cpp b/src/ceres_wrapper/ceres_manager.cpp
index 0e071669bf7b2320e0ca58001aa4609becc4ab84..a938e36ee5b313d0c696d52b16ee589c0548413d 100644
--- a/src/ceres_wrapper/ceres_manager.cpp
+++ b/src/ceres_wrapper/ceres_manager.cpp
@@ -81,7 +81,7 @@ void CeresManager::computeCovariances(const CovarianceBlocksToBeComputed _blocks
             std::vector<StateBlockPtr> all_state_blocks, landmark_state_blocks;
             //frame state blocks
             for(auto fr_ptr : wolf_problem_->getTrajectory()->getFrameList())
-                if (fr_ptr->isKey())
+                if (fr_ptr->isKeyOrAux())
                     for (auto sb : fr_ptr->getStateBlockVec())
                         if (sb)
                             all_state_blocks.push_back(sb);
@@ -106,7 +106,7 @@ void CeresManager::computeCovariances(const CovarianceBlocksToBeComputed _blocks
         {
             // first create a vector containing all state blocks
             for(auto fr_ptr : wolf_problem_->getTrajectory()->getFrameList())
-                if (fr_ptr->isKey())
+                if (fr_ptr->isKeyOrAux())
                     for (auto sb : fr_ptr->getStateBlockVec())
                         if (sb)
                             for(auto sb2 : fr_ptr->getStateBlockVec())
diff --git a/src/examples/test_ceres_2_lasers.cpp b/src/examples/test_ceres_2_lasers.cpp
index d12f491de7ce0895ca301498454e7f3d451bbd4e..456367a2c67b1c98ca91e9631c3f3da47751882a 100644
--- a/src/examples/test_ceres_2_lasers.cpp
+++ b/src/examples/test_ceres_2_lasers.cpp
@@ -247,7 +247,7 @@ int main(int argc, char** argv)
     odom_trajectory.head(3) = ground_truth_pose;
 
     // Origin Key Frame
-    FrameBasePtr origin_frame = problem.createFrame(KEY_FRAME, ground_truth_pose, ts);
+    FrameBasePtr origin_frame = problem.createFrame(KEY, ground_truth_pose, ts);
 
     // Prior covariance
     CapturePose* initial_covariance = new CapturePose(ts, gps_sensor, ground_truth_pose, Eigen::Matrix3s::Identity() * 0.1);
diff --git a/src/examples/test_ceres_2_lasers_polylines.cpp b/src/examples/test_ceres_2_lasers_polylines.cpp
index 136ba285e0d9fb2c62b4801dc75e597dcdd257ff..62ad277f98576b1bf17e17c7515d8dfb428c93be 100644
--- a/src/examples/test_ceres_2_lasers_polylines.cpp
+++ b/src/examples/test_ceres_2_lasers_polylines.cpp
@@ -254,7 +254,7 @@ int main(int argc, char** argv)
     odom_trajectory.head(3) = ground_truth_pose;
 
     // Origin Key Frame
-    FrameBasePtr origin_frame = problem.createFrame(KEY_FRAME, ground_truth_pose, ts);
+    FrameBasePtr origin_frame = problem.createFrame(KEY, ground_truth_pose, ts);
 
     // Prior covariance
     CapturePose* initial_covariance = new CapturePose(ts, gps_sensor, ground_truth_pose, Eigen::Matrix3s::Identity() * 0.1);
diff --git a/src/examples/test_factor_imu.cpp b/src/examples/test_factor_imu.cpp
index 3d0483e9647f9e3203ab3bb89036de55e0f9adc9..4040194b382e9db0698b2a5d8acf0f852af1286b 100644
--- a/src/examples/test_factor_imu.cpp
+++ b/src/examples/test_factor_imu.cpp
@@ -80,7 +80,7 @@ int main(int argc, char** argv)
     //create FrameIMU
     ts = wolf_problem_ptr_->getProcessorMotion()->getBuffer().get().back().ts_;
     state_vec = wolf_problem_ptr_->getProcessorMotion()->getCurrentState();
-    FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY_FRAME, ts, state_vec);
+    FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY, ts, state_vec);
     wolf_problem_ptr_->getTrajectory()->addFrame(last_frame);
 
         //create a feature
@@ -141,7 +141,7 @@ int main(int argc, char** argv)
     //create FrameIMU
     ts = wolf_problem_ptr_->getProcessorMotion()->getBuffer().get().back().ts_;
     state_vec = wolf_problem_ptr_->getProcessorMotion()->getCurrentState();
-    FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY_FRAME, ts, state_vec);
+    FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY, ts, state_vec);
     wolf_problem_ptr_->getTrajectory()->addFrame(last_frame);
 
         //create a feature
@@ -199,7 +199,7 @@ int main(int argc, char** argv)
         //create FrameIMU
     ts = wolf_problem_ptr_->getProcessorMotion()->getBuffer().get().back().ts_;
     state_vec = wolf_problem_ptr_->getProcessorMotion()->getCurrentState();
-    FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY_FRAME, ts, state_vec);
+    FrameIMUPtr last_frame = std::make_shared<FrameIMU>(KEY, ts, state_vec);
     wolf_problem_ptr_->getTrajectory()->addFrame(last_frame);
 
         //create a feature
diff --git a/src/examples/test_processor_tracker_landmark_image.cpp b/src/examples/test_processor_tracker_landmark_image.cpp
index be7df536e971273559252aeff8dc51bd808bb14b..8baee2c1e75af6ab5a8841e85b082d8f7cdd20c9 100644
--- a/src/examples/test_processor_tracker_landmark_image.cpp
+++ b/src/examples/test_processor_tracker_landmark_image.cpp
@@ -98,7 +98,7 @@ int main(int argc, char** argv)
     //=====================================================
     // Origin Key Frame is fixed
     TimeStamp t = 0;
-    FrameBasePtr origin_frame = problem->emplaceFrame(KEY_FRAME, (Vector7s()<<1,0,0,0,0,0,1).finished(), t);
+    FrameBasePtr origin_frame = problem->emplaceFrame(KEY, (Vector7s()<<1,0,0,0,0,0,1).finished(), t);
     problem->getProcessorMotion()->setOrigin(origin_frame);
     origin_frame->fix();
 
diff --git a/src/examples/test_simple_AHP.cpp b/src/examples/test_simple_AHP.cpp
index 6bd1805dc78a0c65bd27ca022fbb46bd272cf6d4..f07a2c1ce3da6eb7168571d3ec1377ffa8b0c388 100644
--- a/src/examples/test_simple_AHP.cpp
+++ b/src/examples/test_simple_AHP.cpp
@@ -97,11 +97,11 @@ int main(int argc, char** argv)
     /* 1 */
     ProblemPtr problem = Problem::create("PO 3D");
     // One anchor frame to define the lmk, and a copy to make a factor
-    FrameBasePtr kf_1 = problem->emplaceFrame(KEY_FRAME,(Vector7s()<<0,0,0,0,0,0,1).finished(), TimeStamp(0));
-    FrameBasePtr kf_2 = problem->emplaceFrame(KEY_FRAME,(Vector7s()<<0,0,0,0,0,0,1).finished(), TimeStamp(0));
+    FrameBasePtr kf_1 = problem->emplaceFrame(KEY,(Vector7s()<<0,0,0,0,0,0,1).finished(), TimeStamp(0));
+    FrameBasePtr kf_2 = problem->emplaceFrame(KEY,(Vector7s()<<0,0,0,0,0,0,1).finished(), TimeStamp(0));
     // and two other frames to observe the lmk
-    FrameBasePtr kf_3 = problem->emplaceFrame(KEY_FRAME,(Vector7s()<<0,-1,0,0,0,0,1).finished(), TimeStamp(0));
-    FrameBasePtr kf_4 = problem->emplaceFrame(KEY_FRAME,(Vector7s()<<0,+1,0,0,0,0,1).finished(), TimeStamp(0));
+    FrameBasePtr kf_3 = problem->emplaceFrame(KEY,(Vector7s()<<0,-1,0,0,0,0,1).finished(), TimeStamp(0));
+    FrameBasePtr kf_4 = problem->emplaceFrame(KEY,(Vector7s()<<0,+1,0,0,0,0,1).finished(), TimeStamp(0));
 
     kf_1->fix();
     kf_2->fix();
diff --git a/src/examples/test_sort_keyframes.cpp b/src/examples/test_sort_keyframes.cpp
index 56982c9dc7c6fda44b594a04f92a33f911b8ca49..036ed1250c8dea7c1aadf10e0c437eda243e5ecf 100644
--- a/src/examples/test_sort_keyframes.cpp
+++ b/src/examples/test_sort_keyframes.cpp
@@ -31,22 +31,22 @@ int main()
 {
     ProblemPtr problem_ptr = Problem::create(FRM_PO_2D);
 
-    problem_ptr->emplaceFrame(NON_KEY_FRAME, Eigen::VectorXs::Zero(3), TimeStamp(0.1));
-    FrameBasePtr frm2 = problem_ptr->emplaceFrame(NON_KEY_FRAME, Eigen::VectorXs::Zero(3), TimeStamp(0.2));
-    FrameBasePtr frm3 = problem_ptr->emplaceFrame(NON_KEY_FRAME, Eigen::VectorXs::Zero(3), TimeStamp(0.3));
-    problem_ptr->emplaceFrame(NON_KEY_FRAME, Eigen::VectorXs::Zero(3), TimeStamp(0.4));
-    FrameBasePtr frm5 = problem_ptr->emplaceFrame(NON_KEY_FRAME, Eigen::VectorXs::Zero(3), TimeStamp(0.5));
-    FrameBasePtr frm6 = problem_ptr->emplaceFrame(NON_KEY_FRAME, Eigen::VectorXs::Zero(3), TimeStamp(0.6));
+    problem_ptr->emplaceFrame(NON_ESTIMATED, Eigen::VectorXs::Zero(3), TimeStamp(0.1));
+    FrameBasePtr frm2 = problem_ptr->emplaceFrame(NON_ESTIMATED, Eigen::VectorXs::Zero(3), TimeStamp(0.2));
+    FrameBasePtr frm3 = problem_ptr->emplaceFrame(NON_ESTIMATED, Eigen::VectorXs::Zero(3), TimeStamp(0.3));
+    problem_ptr->emplaceFrame(NON_ESTIMATED, Eigen::VectorXs::Zero(3), TimeStamp(0.4));
+    FrameBasePtr frm5 = problem_ptr->emplaceFrame(NON_ESTIMATED, Eigen::VectorXs::Zero(3), TimeStamp(0.5));
+    FrameBasePtr frm6 = problem_ptr->emplaceFrame(NON_ESTIMATED, Eigen::VectorXs::Zero(3), TimeStamp(0.6));
 
     printFrames(problem_ptr);
 
     std::cout << std::endl << "Frame " << frm5->id() << " set KEY" << std::endl;
-    frm5->setKey();
+    frm5->setEstimated();
 
     printFrames(problem_ptr);
 
     std::cout << std::endl << "Frame " << frm2->id() << " set KEY" << std::endl;
-    frm2->setKey();
+    frm2->setEstimated();
 
     printFrames(problem_ptr);
 
@@ -56,21 +56,21 @@ int main()
     printFrames(problem_ptr);
 
     std::cout << std::endl << "Frame " << frm3->id() << " set KEY" << std::endl;
-    frm3->setKey();
+    frm3->setEstimated();
 
     printFrames(problem_ptr);
 
     std::cout << std::endl << "Frame " << frm6->id() << " set KEY" << std::endl;
-    frm6->setKey();
+    frm6->setEstimated();
 
     printFrames(problem_ptr);
 
-    FrameBasePtr frm7 = problem_ptr->emplaceFrame(KEY_FRAME, Eigen::VectorXs::Zero(3), TimeStamp(0.7));
+    FrameBasePtr frm7 = problem_ptr->emplaceFrame(KEY, Eigen::VectorXs::Zero(3), TimeStamp(0.7));
     std::cout << std::endl << "created Key Frame " << frm7->id() << " TS: " << 0.7 << std::endl;
 
     printFrames(problem_ptr);
 
-    FrameBasePtr frm8 = problem_ptr->emplaceFrame(KEY_FRAME, Eigen::VectorXs::Zero(3), TimeStamp(0.35));
+    FrameBasePtr frm8 = problem_ptr->emplaceFrame(KEY, Eigen::VectorXs::Zero(3), TimeStamp(0.35));
     std::cout << std::endl << "created Key Frame " << frm8->id() << " TS: " << 0.35 << std::endl;
 
     printFrames(problem_ptr);
diff --git a/src/examples/test_sparsification.cpp b/src/examples/test_sparsification.cpp
index 7b9e85c085a04dc401097db87be3dcc8ea25e17d..03d214a3d09c8a624129243f181aed1dd722b5a9 100644
--- a/src/examples/test_sparsification.cpp
+++ b/src/examples/test_sparsification.cpp
@@ -216,7 +216,7 @@ int main(int argc, char** argv)
 
 	// ------------------------ START EXPERIMENT ------------------------
 	// First frame FIXED
-	last_frame_ptr = bl_problem_ptr->emplaceFrame(KEY_FRAME, Eigen::Vector3s::Zero(),TimeStamp(0));
+	last_frame_ptr = bl_problem_ptr->emplaceFrame(KEY, Eigen::Vector3s::Zero(),TimeStamp(0));
 	last_frame_ptr->fix();
 	bl_problem_ptr->print(4, true, false, true);
 
@@ -238,7 +238,7 @@ int main(int argc, char** argv)
 				Eigen::Vector3s from_pose = frame_from_ptr->getState();
 				R.topLeftCorner(2,2) = Eigen::Rotation2Ds(from_pose(2)).matrix();
 				Eigen::Vector3s new_frame_pose = from_pose + R*meas;
-				last_frame_ptr = bl_problem_ptr->emplaceFrame(KEY_FRAME, new_frame_pose, TimeStamp(double(edge_to)));
+				last_frame_ptr = bl_problem_ptr->emplaceFrame(KEY, new_frame_pose, TimeStamp(double(edge_to)));
 
 				frame_to_ptr = last_frame_ptr;
 
diff --git a/src/examples/test_wolf_imported_graph.cpp b/src/examples/test_wolf_imported_graph.cpp
index 1113af8b7f7e9bd40033ed60e182cc2f485eee99..40171695f14ac3ef2aeee7091ca53e8de50a2a90 100644
--- a/src/examples/test_wolf_imported_graph.cpp
+++ b/src/examples/test_wolf_imported_graph.cpp
@@ -130,8 +130,8 @@ int main(int argc, char** argv)
                     bNum.clear();
 
                     // add frame to problem
-                    FrameBasePtr vertex_frame_ptr_full = new FrameBase(KEY_FRAME, TimeStamp(0), std::make_shared<StateBlock>(vertex_pose.head(2)), std::make_shared<StateBlock>(vertex_pose.tail(1)));
-                    FrameBasePtr vertex_frame_ptr_prun = new FrameBase(KEY_FRAME, TimeStamp(0), std::make_shared<StateBlock>(vertex_pose.head(2)), std::make_shared<StateBlock>(vertex_pose.tail(1)));
+                    FrameBasePtr vertex_frame_ptr_full = new FrameBase(KEY, TimeStamp(0), std::make_shared<StateBlock>(vertex_pose.head(2)), std::make_shared<StateBlock>(vertex_pose.tail(1)));
+                    FrameBasePtr vertex_frame_ptr_prun = new FrameBase(KEY, TimeStamp(0), std::make_shared<StateBlock>(vertex_pose.head(2)), std::make_shared<StateBlock>(vertex_pose.tail(1)));
                     wolf_problem_full->getTrajectory()->addFrame(vertex_frame_ptr_full);
                     wolf_problem_prun->getTrajectory()->addFrame(vertex_frame_ptr_prun);
                     // store
diff --git a/src/examples/test_wolf_prunning.cpp b/src/examples/test_wolf_prunning.cpp
index f3ed29007190ada48bba1758a1ac4e57843ff423..b4d9ac23316dc5450b269d99ce45cbb0f7c0e2f0 100644
--- a/src/examples/test_wolf_prunning.cpp
+++ b/src/examples/test_wolf_prunning.cpp
@@ -148,8 +148,8 @@ int main(int argc, char** argv)
                     bNum.clear();
 
                     // add frame to problem
-                    FrameBasePtr vertex_frame_ptr_full = new FrameBase(KEY_FRAME, TimeStamp(0), std::make_shared<StateBlock>(vertex_pose.head(2)), std::make_shared<StateBlock>(vertex_pose.tail(1)));
-                    FrameBasePtr vertex_frame_ptr_prun = new FrameBase(KEY_FRAME, TimeStamp(0), std::make_shared<StateBlock>(vertex_pose.head(2)), std::make_shared<StateBlock>(vertex_pose.tail(1)));
+                    FrameBasePtr vertex_frame_ptr_full = new FrameBase(KEY, TimeStamp(0), std::make_shared<StateBlock>(vertex_pose.head(2)), std::make_shared<StateBlock>(vertex_pose.tail(1)));
+                    FrameBasePtr vertex_frame_ptr_prun = new FrameBase(KEY, TimeStamp(0), std::make_shared<StateBlock>(vertex_pose.head(2)), std::make_shared<StateBlock>(vertex_pose.tail(1)));
                     wolf_problem_full->getTrajectory()->addFrame(vertex_frame_ptr_full);
                     wolf_problem_prun->getTrajectory()->addFrame(vertex_frame_ptr_prun);
                     // store
diff --git a/src/frame/frame_base.cpp b/src/frame/frame_base.cpp
index cb7f089c1f21adad761f5fd7c13f0eee786b6741..10c75405b377474905b1040251794067d7df115c 100644
--- a/src/frame/frame_base.cpp
+++ b/src/frame/frame_base.cpp
@@ -16,7 +16,7 @@ FrameBase::FrameBase(const TimeStamp& _ts, StateBlockPtr _p_ptr, StateBlockPtr _
             trajectory_ptr_(),
             state_block_vec_(3), // allow for 3 state blocks by default. Resize in derived constructors if needed.
             frame_id_(++frame_id_count_),
-            type_(NON_KEY_FRAME),
+            type_(NON_ESTIMATED),
             time_stamp_(_ts)
 {
     state_block_vec_[0] = _p_ptr;
@@ -39,8 +39,6 @@ FrameBase::FrameBase(const FrameType & _tp, const TimeStamp& _ts, StateBlockPtr
                 
 FrameBase::~FrameBase()
 {
-    if ( isKey() )
-        removeStateBlocks();
 }
 
 void FrameBase::remove()
@@ -68,11 +66,12 @@ void FrameBase::remove()
         }
 
         // Remove Frame State Blocks
-        if ( isKey() )
+        if ( isKeyOrAux() )
             removeStateBlocks();
 
-        if (getTrajectory()->getLastKeyFrame()->id() == this_F->id())
-            getTrajectory()->setLastKeyFrame(getTrajectory()->findLastKeyFrame());
+
+        if (getTrajectory()->getLastKeyFrame()->id() == this_F->id() || getTrajectory()->getLastKeyOrAuxFrame()->id() == this_F->id())
+            getTrajectory()->updateLastFrames();
 
 //        std::cout << "Removed       F" << id() << std::endl;
     }
@@ -81,7 +80,7 @@ void FrameBase::remove()
 void FrameBase::setTimeStamp(const TimeStamp& _ts)
 {
     time_stamp_ = _ts;
-    if (isKey() && getTrajectory() != nullptr)
+    if (isKeyOrAux() && getTrajectory() != nullptr)
         getTrajectory()->sortFrame(shared_from_this());
 }
 
@@ -113,18 +112,25 @@ void FrameBase::removeStateBlocks()
 
 void FrameBase::setKey()
 {
-    if (type_ != KEY_FRAME)
-    {
-        type_ = KEY_FRAME;
+    // register if previously not estimated
+    if (!isKeyOrAux())
         registerNewStateBlocks();
 
-        if (getTrajectory()->getLastKeyFrame() == nullptr || getTrajectory()->getLastKeyFrame()->getTimeStamp() < time_stamp_)
-            getTrajectory()->setLastKeyFrame(shared_from_this());
+    // WOLF_DEBUG("Set Key", this->id());
+    type_ = KEY;
+    getTrajectory()->sortFrame(shared_from_this());
+    getTrajectory()->updateLastFrames();
+}
 
-        getTrajectory()->sortFrame(shared_from_this());
+void FrameBase::setAux()
+{
+    if (!isKeyOrAux())
+        registerNewStateBlocks();
 
-//        WOLF_DEBUG("Set KF", this->id());
-    }
+    // WOLF_DEBUG("Set Auxiliary", this->id());
+    type_ = AUXILIARY;
+    getTrajectory()->sortFrame(shared_from_this());
+    getTrajectory()->updateLastFrames();
 }
 
 void FrameBase::fix()
@@ -170,7 +176,7 @@ void FrameBase::setState(const Eigen::VectorXs& _state)
     for (StateBlockPtr sb : state_block_vec_)
         if (sb && (index < _st_size))
         {
-            sb->setState(_state.segment(index, sb->getSize()), isKey());
+            sb->setState(_state.segment(index, sb->getSize()), isKeyOrAux()); // do not notify if state block is not estimated by the solver
             index += sb->getSize();
         }
 }
diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp
index 3b476f4fd9e13390160adf993d19f900f8233f3c..321ec061fdba45b4e71f3da8bc3941790f02c21e 100644
--- a/src/problem/problem.cpp
+++ b/src/problem/problem.cpp
@@ -251,8 +251,8 @@ void Problem::getCurrentState(Eigen::VectorXs& state)
 {
     if (processor_motion_ptr_ != nullptr)
         processor_motion_ptr_->getCurrentState(state);
-    else if (trajectory_ptr_->getLastKeyFrame() != nullptr)
-        trajectory_ptr_->getLastKeyFrame()->getState(state);
+    else if (trajectory_ptr_->getLastKeyOrAuxFrame() != nullptr)
+        trajectory_ptr_->getLastKeyOrAuxFrame()->getState(state);
     else
         state = zeroState();
 }
@@ -264,10 +264,10 @@ void Problem::getCurrentStateAndStamp(Eigen::VectorXs& state, TimeStamp& ts)
         processor_motion_ptr_->getCurrentState(state);
         processor_motion_ptr_->getCurrentTimeStamp(ts);
     }
-    else if (trajectory_ptr_->getLastKeyFrame() != nullptr)
+    else if (trajectory_ptr_->getLastKeyOrAuxFrame() != nullptr)
     {
-        trajectory_ptr_->getLastKeyFrame()->getTimeStamp(ts);
-        trajectory_ptr_->getLastKeyFrame()->getState(state);
+        trajectory_ptr_->getLastKeyOrAuxFrame()->getTimeStamp(ts);
+        trajectory_ptr_->getLastKeyOrAuxFrame()->getState(state);
     }
     else
         state = zeroState();
@@ -278,7 +278,7 @@ void Problem::getState(const TimeStamp& _ts, Eigen::VectorXs& state)
     // try to get the state from processor_motion if any, otherwise...
     if (processor_motion_ptr_ == nullptr || !processor_motion_ptr_->getState(_ts, state))
     {
-        FrameBasePtr closest_frame = trajectory_ptr_->closestKeyFrameToTimeStamp(_ts);
+        FrameBasePtr closest_frame = trajectory_ptr_->closestKeyOrAuxFrameToTimeStamp(_ts);
         if (closest_frame != nullptr)
             closest_frame->getState(state);
         else
@@ -348,6 +348,30 @@ void Problem::keyFrameCallback(FrameBasePtr _keyframe_ptr, ProcessorBasePtr _pro
                 processor->keyFrameCallback(_keyframe_ptr, _time_tolerance);
 }
 
+bool Problem::permitAuxFrame(ProcessorBasePtr _processor_ptr)
+{
+    // This should implement a black list of processors that have forbidden auxiliary frame creation
+    // This decision is made at problem level, not at processor configuration level.
+    // If you want to configure a processor for not creating auxiliary frames, see Processor::voting_active_ and its accessors.
+
+    // Currently allowing all processors to vote:
+    return true;
+}
+
+void Problem::auxFrameCallback(FrameBasePtr _frame_ptr, ProcessorBasePtr _processor_ptr, const Scalar& _time_tolerance)
+{
+    if (_processor_ptr)
+    {
+        WOLF_DEBUG((_processor_ptr->isMotion() ? "PM " : "PT "), _processor_ptr->getName(), ": AuxF", _frame_ptr->id(), " Callback emitted with ts = ", _frame_ptr->getTimeStamp());
+    }
+    else
+    {
+        WOLF_DEBUG("External callback: AuxF", _frame_ptr->id(), " Callback emitted with ts = ", _frame_ptr->getTimeStamp());
+    }
+
+    processor_motion_ptr_->keyFrameCallback(_frame_ptr, _time_tolerance);
+}
+
 LandmarkBasePtr Problem::addLandmark(LandmarkBasePtr _lmk_ptr)
 {
     getMap()->addLandmark(_lmk_ptr);
@@ -401,6 +425,16 @@ void Problem::removeStateBlock(StateBlockPtr _state_ptr)
         state_block_notification_map_[_state_ptr] = REMOVE;
 }
 
+bool Problem::getStateBlockNotification(const StateBlockPtr& sb_ptr, Notification& notif) const
+{
+    std::lock_guard<std::mutex> lock(mut_state_block_notifications_);
+    if (state_block_notification_map_.find(sb_ptr) == state_block_notification_map_.end())
+        return false;
+
+    notif = state_block_notification_map_.at(sb_ptr);
+    return true;
+}
+
 FactorBasePtr Problem::addFactor(FactorBasePtr _factor_ptr)
 {
     std::lock_guard<std::mutex> lock(mut_factor_notifications_);
@@ -442,6 +476,16 @@ void Problem::removeFactor(FactorBasePtr _factor_ptr)
         factor_notification_map_[_factor_ptr] = REMOVE;
 }
 
+bool Problem::getFactorNotification(const FactorBasePtr& fac_ptr, Notification& notif) const
+{
+    std::lock_guard<std::mutex> lock(mut_factor_notifications_);
+    if (factor_notification_map_.find(fac_ptr) == factor_notification_map_.end())
+        return false;
+
+    notif = factor_notification_map_.at(fac_ptr);
+    return true;
+}
+
 void Problem::clearCovariance()
 {
     std::lock_guard<std::mutex> lock(mut_covariances_);
@@ -587,6 +631,12 @@ bool Problem::getLastKeyFrameCovariance(Eigen::MatrixXs& cov)
     return getFrameCovariance(frm, cov);
 }
 
+bool Problem::getLastKeyOrAuxFrameCovariance(Eigen::MatrixXs& cov)
+{
+    FrameBasePtr frm = getLastKeyOrAuxFrame();
+    return getFrameCovariance(frm, cov);
+}
+
 bool Problem::getLandmarkCovariance(LandmarkBaseConstPtr _landmark_ptr, Eigen::MatrixXs& _covariance)
 {
     bool success(true);
@@ -639,22 +689,37 @@ HardwareBasePtr Problem::getHardware()
     return hardware_ptr_;
 }
 
-FrameBasePtr Problem::getLastFrame()
+FrameBasePtr Problem::getLastFrame() const
 {
     return trajectory_ptr_->getLastFrame();
 }
 
-FrameBasePtr Problem::getLastKeyFrame()
+FrameBasePtr Problem::getLastKeyFrame() const
 {
     return trajectory_ptr_->getLastKeyFrame();
 }
 
+FrameBasePtr Problem::getLastKeyOrAuxFrame() const
+{
+    return trajectory_ptr_->getLastKeyOrAuxFrame();
+}
+
+FrameBasePtr Problem::closestKeyFrameToTimeStamp(const TimeStamp& _ts) const
+{
+    return trajectory_ptr_->closestKeyFrameToTimeStamp(_ts);
+}
+
+FrameBasePtr Problem::closestKeyOrAuxFrameToTimeStamp(const TimeStamp& _ts) const
+{
+    return trajectory_ptr_->closestKeyOrAuxFrameToTimeStamp(_ts);
+}
+
 FrameBasePtr Problem::setPrior(const Eigen::VectorXs& _prior_state, const Eigen::MatrixXs& _prior_cov, const TimeStamp& _ts, const Scalar _time_tolerance)
 {
     if ( ! prior_is_set_ )
     {
         // Create origin frame
-        FrameBasePtr origin_keyframe = emplaceFrame(KEY_FRAME, _prior_state, _ts);
+        FrameBasePtr origin_keyframe = emplaceFrame(KEY, _prior_state, _ts);
 
         // create origin capture with the given state as data
         // Capture fix only takes 3D position and Quaternion orientation
@@ -765,10 +830,10 @@ void Problem::print(int depth, bool constr_by, bool metric, bool state_blocks)
                         std::cout << "    pm" << p->id() << " " << p->getType() << endl;
                         ProcessorMotionPtr pm = std::static_pointer_cast<ProcessorMotion>(p);
                         if (pm->getOrigin())
-                            cout << "      o: C" << pm->getOrigin()->id() << " - " << (pm->getOrigin()->getFrame()->isKey() ? "  KF" : "  F")
+                            cout << "      o: C" << pm->getOrigin()->id() << " - " << (pm->getOrigin()->getFrame()->isKeyOrAux() ? (pm->getOrigin()->getFrame()->isKey() ? "  KF" : "  AuxF" ) : "  F")
                             << pm->getOrigin()->getFrame()->id() << endl;
                         if (pm->getLast())
-                            cout << "      l: C" << pm->getLast()->id() << " - " << (pm->getLast()->getFrame()->isKey() ? "  KF" : "  F")
+                            cout << "      l: C" << pm->getLast()->id() << " - " << (pm->getLast()->getFrame()->isKeyOrAux() ? (pm->getLast()->getFrame()->isKey() ? "  KF" : " AuxF") : "  F")
                             << pm->getLast()->getFrame()->id() << endl;
                         if (pm->getIncoming())
                             cout << "      i: C" << pm->getIncoming()->id() << endl;
@@ -783,14 +848,14 @@ void Problem::print(int depth, bool constr_by, bool metric, bool state_blocks)
 //                            if (ptt)
 //                            {
 //                                if (ptt->getPrevOrigin())
-//                                    cout << "      p: C" << ptt->getPrevOrigin()->id() << " - " << (ptt->getPrevOrigin()->getFrame()->isKey() ? "  KF" : "  F")
+//                                    cout << "      p: C" << ptt->getPrevOrigin()->id() << " - " << (ptt->getPrevOrigin()->getFrame()->isEstimated() ? (ptt->getPrevOrigin()->getFrame()->isKey() ? "  KF" : " AuxF") : "  F")
 //                                    << ptt->getPrevOrigin()->getFrame()->id() << endl;
 //                            }
                             if (pt->getOrigin())
-                                cout << "      o: C" << pt->getOrigin()->id() << " - " << (pt->getOrigin()->getFrame()->isKey() ? "  KF" : "  F")
+                                cout << "      o: C" << pt->getOrigin()->id() << " - " << (pt->getOrigin()->getFrame()->isKeyOrAux() ? (pt->getOrigin()->getFrame()->isKey() ? "  KF" : " AuxF") : "  F")
                                 << pt->getOrigin()->getFrame()->id() << endl;
                             if (pt->getLast())
-                                cout << "      l: C" << pt->getLast()->id() << " - " << (pt->getLast()->getFrame()->isKey() ? "  KF" : "  F")
+                                cout << "      l: C" << pt->getLast()->id() << " - " << (pt->getLast()->getFrame()->isKeyOrAux() ? (pt->getLast()->getFrame()->isKey() ? "  KF" : " AuxF") : "  F")
                                 << pt->getLast()->getFrame()->id() << endl;
                             if (pt->getIncoming())
                                 cout << "      i: C" << pt->getIncoming()->id() << endl;
@@ -806,7 +871,7 @@ void Problem::print(int depth, bool constr_by, bool metric, bool state_blocks)
         // Frames =======================================================================================
         for (auto F : getTrajectory()->getFrameList())
         {
-            cout << (F->isKey() ? "  KF" : "  F") << F->id() << ((depth < 2) ? " -- " + std::to_string(F->getCaptureList().size()) + "C  " : "");
+            cout << (F->isKeyOrAux() ? (F->isKey() ? "  KF" : " AuxF") : "  F") << F->id() << ((depth < 2) ? " -- " + std::to_string(F->getCaptureList().size()) + "C  " : "");
             if (constr_by)
             {
                 cout << "  <-- ";
@@ -963,11 +1028,6 @@ void Problem::print(int depth, bool constr_by, bool metric, bool state_blocks)
     cout << endl;
 }
 
-FrameBasePtr Problem::closestKeyFrameToTimeStamp(const TimeStamp& _ts)
-{
-    return trajectory_ptr_->closestKeyFrameToTimeStamp(_ts);
-}
-
 bool Problem::check(int verbose_level)
 {
     using std::cout;
@@ -1047,7 +1107,7 @@ bool Problem::check(int verbose_level)
     {
         if (verbose_level > 0)
         {
-            cout << (F->isKey() ? "  KF" : "  F") << F->id() << " @ " << F.get() << endl;
+            cout << (F->isKeyOrAux() ? (F->isKey() ? "  KF" : " EF") : "  F") << F->id() << " @ " << F.get() << endl;
             cout << "    -> P @ " << F->getProblem().get() << endl;
             cout << "    -> T @ " << F->getTrajectory().get() << endl;
             for (auto sb : F->getStateBlockVec())
diff --git a/src/processor/processor_IMU.cpp b/src/processor/processor_IMU.cpp
index 761b7729d058233bfc0750ed69fe70c8ed219144..41dfe959093847801a1fd8ad487923e97c981ffe 100644
--- a/src/processor/processor_IMU.cpp
+++ b/src/processor/processor_IMU.cpp
@@ -36,8 +36,6 @@ ProcessorBasePtr ProcessorIMU::create(const std::string& _unique_name, const Pro
 
 bool ProcessorIMU::voteForKeyFrame()
 {
-    if(!isVotingActive())
-        return false;
     // time span
     if (getBuffer().get().back().ts_ - getBuffer().get().front().ts_ > params_motion_IMU_->max_time_span)
     {
diff --git a/src/processor/processor_base.cpp b/src/processor/processor_base.cpp
index 0679909164d86a96ac609a930619f35ff6a97fe3..77e00b83580074483b286457655c8b08edf534d3 100644
--- a/src/processor/processor_base.cpp
+++ b/src/processor/processor_base.cpp
@@ -26,9 +26,14 @@ bool ProcessorBase::permittedKeyFrame()
     return isVotingActive() && getProblem()->permitKeyFrame(shared_from_this());
 }
 
+bool ProcessorBase::permittedAuxFrame()
+{
+    return isVotingAuxActive() && getProblem()->permitAuxFrame(shared_from_this());
+}
+
 FrameBasePtr ProcessorBase::emplaceFrame(FrameType _type, CaptureBasePtr _capture_ptr)
 {
-    std::cout << "Making " << (_type == KEY_FRAME? "key-" : "") << "frame" << std::endl;
+    std::cout << "Making " << (_type == KEY ? "key-" : (_type == AUXILIARY ? "aux-" : "")) << "frame" << std::endl;
 
     FrameBasePtr new_frame_ptr = getProblem()->emplaceFrame(_type, _capture_ptr->getTimeStamp());
     new_frame_ptr->addCapture(_capture_ptr);
diff --git a/src/processor/processor_motion.cpp b/src/processor/processor_motion.cpp
index 66b4616fc442045e9b5c3ca4650b73707773f7e3..1206d10fcae85f653ff6c523a01de30fb1d3f5a3 100644
--- a/src/processor/processor_motion.cpp
+++ b/src/processor/processor_motion.cpp
@@ -209,7 +209,7 @@ void ProcessorMotion::process(CaptureBasePtr _incoming_ptr)
     last_ptr_->getFrame()->setTimeStamp(getCurrentTimeStamp());
     last_ptr_->getFrame()->setState(getCurrentState());
 
-    if (voteForKeyFrame() && permittedKeyFrame())
+    if (permittedKeyFrame() && voteForKeyFrame())
     {
         // Set the frame of last_ptr as key
         auto key_frame_ptr = last_ptr_->getFrame();
@@ -222,7 +222,7 @@ void ProcessorMotion::process(CaptureBasePtr _incoming_ptr)
         auto fac_ptr = emplaceFactor(key_feature_ptr, origin_ptr_);
 
         // create a new frame
-        auto new_frame_ptr = getProblem()->emplaceFrame(NON_KEY_FRAME,
+        auto new_frame_ptr = getProblem()->emplaceFrame(NON_ESTIMATED,
                                                         getCurrentState(),
                                                         getCurrentTimeStamp());
         // create a new capture
@@ -303,7 +303,7 @@ bool ProcessorMotion::getState(const TimeStamp& _ts, Eigen::VectorXs& _x)
 
 FrameBasePtr ProcessorMotion::setOrigin(const Eigen::VectorXs& _x_origin, const TimeStamp& _ts_origin)
 {
-    FrameBasePtr key_frame_ptr = getProblem()->emplaceFrame(KEY_FRAME, _x_origin, _ts_origin);
+    FrameBasePtr key_frame_ptr = getProblem()->emplaceFrame(KEY, _x_origin, _ts_origin);
     setOrigin(key_frame_ptr);
 
     return key_frame_ptr;
@@ -329,7 +329,7 @@ void ProcessorMotion::setOrigin(FrameBasePtr _origin_frame)
 
     // ---------- LAST ----------
     // Make non-key-frame for last Capture
-    auto new_frame_ptr = getProblem()->emplaceFrame(NON_KEY_FRAME,
+    auto new_frame_ptr = getProblem()->emplaceFrame(NON_ESTIMATED,
                                                     _origin_frame->getState(),
                                                     _origin_frame->getTimeStamp());
     // emplace (emtpy) last Capture
diff --git a/src/processor/processor_tracker.cpp b/src/processor/processor_tracker.cpp
index d2ff8055c15f6573f7e7d1e0b915f27f91fea702..9c6e0d6c93fca62476364d1f8744fcc9eaf01576 100644
--- a/src/processor/processor_tracker.cpp
+++ b/src/processor/processor_tracker.cpp
@@ -75,7 +75,7 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
         }
         case FIRST_TIME_WITHOUT_PACK :
         {
-            FrameBasePtr kfrm = getProblem()->emplaceFrame(KEY_FRAME, incoming_ptr_->getTimeStamp());
+            FrameBasePtr kfrm = getProblem()->emplaceFrame(KEY, incoming_ptr_->getTimeStamp());
             kfrm->addCapture(incoming_ptr_);
 
             // Process info
@@ -101,7 +101,7 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
         } // @suppress("No break at end of case")
         case SECOND_TIME_WITHOUT_PACK :
         {
-            FrameBasePtr frm = getProblem()->emplaceFrame(NON_KEY_FRAME, incoming_ptr_->getTimeStamp());
+            FrameBasePtr frm = getProblem()->emplaceFrame(NON_ESTIMATED, incoming_ptr_->getTimeStamp());
             frm->addCapture(incoming_ptr_);
 
             // We have a last_ Capture with no features, so we do not process known features, and we do not vote for KF.
@@ -137,7 +137,7 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
             pack->key_frame->addCapture(last_ptr_);
 
             // Create new frame
-            FrameBasePtr frm = getProblem()->emplaceFrame(NON_KEY_FRAME, incoming_ptr_->getTimeStamp());
+            FrameBasePtr frm = getProblem()->emplaceFrame(NON_ESTIMATED, incoming_ptr_->getTimeStamp());
             frm->addCapture(incoming_ptr_);
 
             // Detect new Features, initialize Landmarks, create Factors, ...
@@ -174,15 +174,12 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
                 last_ptr_->getFrame()->setKey();
 
                 // make F; append incoming to new F
-                FrameBasePtr frm = getProblem()->emplaceFrame(NON_KEY_FRAME, incoming_ptr_->getTimeStamp());
+                FrameBasePtr frm = getProblem()->emplaceFrame(NON_ESTIMATED, incoming_ptr_->getTimeStamp());
                 frm->addCapture(incoming_ptr_);
 
                 // process
                 processNew(params_tracker_->max_new_features);
 
-                //                // Set key
-                //                last_ptr_->getFrame()->setKey();
-                //
                 // Set state to the keyframe
                 last_ptr_->getFrame()->setState(getProblem()->getState(last_ptr_->getTimeStamp()));
 
@@ -199,6 +196,38 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr)
                 incoming_ptr_ = nullptr;
 
             }
+            /* TODO: create an auxiliary frame
+            else if (voteForAuxFrame() && permittedAuxFrame())
+            {
+                // We create an Auxiliary Frame
+
+                // set AuxF on last
+                last_ptr_->getFrame()->setState(getProblem()->getState(last_ptr_->getTimeStamp()));
+                last_ptr_->getFrame()->setAuxiliary();
+
+                // make F; append incoming to new F
+                FrameBasePtr frm = getProblem()->emplaceFrame(NON_ESTIMATED, incoming_ptr_->getTimeStamp());
+                frm->addCapture(incoming_ptr_);
+
+                // Set state to the keyframe
+                last_ptr_->getFrame()->setState(getProblem()->getState(last_ptr_->getTimeStamp()));
+
+                // Establish factors
+                establishFactors();
+
+                // Call the new auxframe callback in order to let the ProcessorMotion to establish their factors
+                getProblem()->auxFrameCallback(last_ptr_->getFrame(), std::static_pointer_cast<ProcessorBase>(shared_from_this()), params_tracker_->time_tolerance);
+
+                // Advance this
+                last_ptr_->getFrame()->addCapture(incoming_ptr_); // Add incoming Capture to the tracker's last Frame
+                // do not remove! last_ptr_->remove();
+                incoming_ptr_->getFrame()->setTimeStamp(incoming_ptr_->getTimeStamp());
+
+                // Update pointers
+                advanceDerived();
+                last_ptr_   = incoming_ptr_;
+                incoming_ptr_ = nullptr;
+            }*/
             else
             {
                 // We do not create a KF
diff --git a/src/trajectory/trajectory_base.cpp b/src/trajectory/trajectory_base.cpp
index ce169fed8a58367867495db130ef29daba23ddb2..e28e18cdea2cc5c8cfd88d55a2d311d81a22a6b0 100644
--- a/src/trajectory/trajectory_base.cpp
+++ b/src/trajectory/trajectory_base.cpp
@@ -6,7 +6,8 @@ namespace wolf {
 TrajectoryBase::TrajectoryBase(const std::string& _frame_structure) :
     NodeBase("TRAJECTORY", "Base"),
     frame_structure_(_frame_structure),
-    last_key_frame_ptr_(nullptr)
+    last_key_frame_ptr_(nullptr),
+    last_key_or_aux_frame_ptr_(nullptr)
 {
 //    WOLF_DEBUG("constructed T");
 }
@@ -22,17 +23,19 @@ FrameBasePtr TrajectoryBase::addFrame(FrameBasePtr _frame_ptr)
     _frame_ptr->setTrajectory(shared_from_this());
     _frame_ptr->setProblem(getProblem());
 
-    if (_frame_ptr->isKey())
+    // add to list
+    frame_list_.push_back(_frame_ptr);
+
+    if (_frame_ptr->isKeyOrAux())
     {
+        // register state blocks
         _frame_ptr->registerNewStateBlocks();
-        if (last_key_frame_ptr_ == nullptr || last_key_frame_ptr_->getTimeStamp() < _frame_ptr->getTimeStamp())
-            last_key_frame_ptr_ = _frame_ptr;
 
-        frame_list_.insert(computeFrameOrder(_frame_ptr), _frame_ptr);
-    }
-    else
-    {
-        frame_list_.push_back(_frame_ptr);
+        // sort
+        sortFrame(_frame_ptr);
+
+        // update last_estimated and last_key
+        updateLastFrames();
     }
 
     return _frame_ptr;
@@ -47,7 +50,6 @@ void TrajectoryBase::getFactorList(FactorBasePtrList & _fac_list)
 void TrajectoryBase::sortFrame(FrameBasePtr _frame_ptr)
 {
     moveFrame(_frame_ptr, computeFrameOrder(_frame_ptr));
-    //    last_key_frame_ptr_ = findLastKeyFrame(); // done in moveFrame() just above
 }
 
 void TrajectoryBase::moveFrame(FrameBasePtr _frm_ptr, FrameBaseIter _place)
@@ -56,34 +58,46 @@ void TrajectoryBase::moveFrame(FrameBasePtr _frm_ptr, FrameBaseIter _place)
     {
         frame_list_.remove(_frm_ptr);
         frame_list_.insert(_place, _frm_ptr);
-        last_key_frame_ptr_ = findLastKeyFrame();
+        updateLastFrames();
     }
 }
 
 FrameBaseIter TrajectoryBase::computeFrameOrder(FrameBasePtr _frame_ptr)
 {
     for (auto frm_rit = getFrameList().rbegin(); frm_rit != getFrameList().rend(); frm_rit++)
-        if ((*frm_rit)!= _frame_ptr && (*frm_rit)->isKey() && (*frm_rit)->getTimeStamp() <= _frame_ptr->getTimeStamp())
+        if ((*frm_rit)!= _frame_ptr && (*frm_rit)->isKeyOrAux() && (*frm_rit)->getTimeStamp() <= _frame_ptr->getTimeStamp())
             return frm_rit.base();
     return getFrameList().begin();
 }
 
-FrameBasePtr TrajectoryBase::findLastKeyFrame()
+void TrajectoryBase::updateLastFrames()
 {
-    // NOTE: Assumes keyframes are sorted by timestamp
-    for (auto frm_rit = getFrameList().rbegin(); frm_rit != getFrameList().rend(); ++frm_rit)
-        if ((*frm_rit)->isKey())
-            return (*frm_rit);
+    bool last_estimated_set = false;
 
-    return nullptr;
+    // NOTE: Assumes estimated (key or auxiliary) frames are sorted by timestamp
+    for (auto frm_rit = getFrameList().rbegin(); frm_rit != getFrameList().rend(); ++frm_rit)
+        if ((*frm_rit)->isKeyOrAux())
+        {
+            if (!last_estimated_set)
+            {
+                last_key_or_aux_frame_ptr_ = (*frm_rit);
+                last_estimated_set = true;
+            }
+            if ((*frm_rit)->isKey())
+            {
+                last_key_frame_ptr_ = (*frm_rit);
+                break;
+            }
+        }
 }
 
-FrameBasePtr TrajectoryBase::closestKeyFrameToTimeStamp(const TimeStamp& _ts)
+FrameBasePtr TrajectoryBase::closestKeyFrameToTimeStamp(const TimeStamp& _ts) const
 {
+    // NOTE: Assumes estimated (key or auxiliary) frames are sorted by timestamp
     FrameBasePtr closest_kf = nullptr;
     Scalar min_dt = 1e9;
-    
-    for (auto frm_rit = getFrameList().rbegin(); frm_rit != getFrameList().rend(); frm_rit++)
+
+    for (auto frm_rit = frame_list_.rbegin(); frm_rit != frame_list_.rend(); frm_rit++)
         if ((*frm_rit)->isKey())
         {
             Scalar dt = std::fabs((*frm_rit)->getTimeStamp() - _ts);
@@ -98,4 +112,25 @@ FrameBasePtr TrajectoryBase::closestKeyFrameToTimeStamp(const TimeStamp& _ts)
     return closest_kf;
 }
 
+FrameBasePtr TrajectoryBase::closestKeyOrAuxFrameToTimeStamp(const TimeStamp& _ts) const
+{
+    // NOTE: Assumes estimated (key or auxiliary) frames are sorted by timestamp
+    FrameBasePtr closest_kf = nullptr;
+    Scalar min_dt = 1e9;
+
+    for (auto frm_rit = frame_list_.rbegin(); frm_rit != frame_list_.rend(); frm_rit++)
+        if ((*frm_rit)->isKeyOrAux())
+        {
+            Scalar dt = std::fabs((*frm_rit)->getTimeStamp() - _ts);
+            if (dt < min_dt)
+            {
+                min_dt = dt;
+                closest_kf = *frm_rit;
+            }
+            else
+                break;
+        }
+    return closest_kf;
+}
+
 } // namespace wolf
diff --git a/test/gtest_IMU.cpp b/test/gtest_IMU.cpp
index d2657e4156cf6991d3342505cb558712837cb344..253c7da0cba0aebdcbff3d30521b9511987d075f 100644
--- a/test/gtest_IMU.cpp
+++ b/test/gtest_IMU.cpp
@@ -480,7 +480,7 @@ class Process_Factor_IMU : public testing::Test
         virtual void buildProblem()
         {
             // ===================================== SET KF in Wolf tree
-            FrameBasePtr KF = problem->emplaceFrame(KEY_FRAME, x1_exact, t);
+            FrameBasePtr KF = problem->emplaceFrame(KEY, x1_exact, t);
 
             // ===================================== IMU CALLBACK
             problem->keyFrameCallback(KF, nullptr, dt/2);
diff --git a/test/gtest_ceres_manager.cpp b/test/gtest_ceres_manager.cpp
index 9b096f7c82d24aa1b2b939919f46a5190f8a65c0..3c5f2502cbce65184e2d63d59b85145776a86f5c 100644
--- a/test/gtest_ceres_manager.cpp
+++ b/test/gtest_ceres_manager.cpp
@@ -318,7 +318,7 @@ TEST(CeresManager, AddFactor)
     CeresManagerWrapperPtr ceres_manager_ptr = std::make_shared<CeresManagerWrapper>(P);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
@@ -340,7 +340,7 @@ TEST(CeresManager, DoubleAddFactor)
     CeresManagerWrapperPtr ceres_manager_ptr = std::make_shared<CeresManagerWrapper>(P);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
@@ -365,7 +365,7 @@ TEST(CeresManager, RemoveFactor)
     CeresManagerWrapperPtr ceres_manager_ptr = std::make_shared<CeresManagerWrapper>(P);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
@@ -393,7 +393,7 @@ TEST(CeresManager, AddRemoveFactor)
     CeresManagerWrapperPtr ceres_manager_ptr = std::make_shared<CeresManagerWrapper>(P);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
@@ -401,7 +401,7 @@ TEST(CeresManager, AddRemoveFactor)
     // remove factor
     P->removeFactor(c);
 
-    ASSERT_TRUE(P->consumeFactorNotificationMap().empty()); // add+remove = empty
+    ASSERT_TRUE(P->getFactorNotificationMapSize() == 0); // add+remove = empty
 
     // update solver
     ceres_manager_ptr->update();
@@ -420,7 +420,7 @@ TEST(CeresManager, DoubleRemoveFactor)
     CeresManagerWrapperPtr ceres_manager_ptr = std::make_shared<CeresManagerWrapper>(P);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
@@ -547,7 +547,7 @@ TEST(CeresManager, FactorsRemoveLocalParam)
     CeresManagerWrapperPtr ceres_manager_ptr = std::make_shared<CeresManagerWrapper>(P);
 
     // Create (and add) 2 factors quaternion
-    FrameBasePtr                    F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr                    F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr                  C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr                  f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorQuaternionAbsolutePtr c1 = std::static_pointer_cast<FactorQuaternionAbsolute>(f->addFactor(std::make_shared<FactorQuaternionAbsolute>(F->getO())));
@@ -589,7 +589,7 @@ TEST(CeresManager, FactorsUpdateLocalParam)
     CeresManagerWrapperPtr ceres_manager_ptr = std::make_shared<CeresManagerWrapper>(P);
 
     // Create (and add) 2 factors quaternion
-    FrameBasePtr                    F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr                    F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr                  C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr                  f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorQuaternionAbsolutePtr c1 = std::static_pointer_cast<FactorQuaternionAbsolute>(f->addFactor(std::make_shared<FactorQuaternionAbsolute>(F->getO())));
diff --git a/test/gtest_factor_absolute.cpp b/test/gtest_factor_absolute.cpp
index 204c6ce633a36380d46eacbc65d66abe1a7747fe..fd9650de70d970b9336d62e8471f3c5a090c0221 100644
--- a/test/gtest_factor_absolute.cpp
+++ b/test/gtest_factor_absolute.cpp
@@ -35,7 +35,7 @@ ProblemPtr problem_ptr = Problem::create("POV 3D");
 CeresManager ceres_mgr(problem_ptr);
 
 // Two frames
-FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY_FRAME, problem_ptr->zeroState(), TimeStamp(0));
+FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY, problem_ptr->zeroState(), TimeStamp(0));
 
 // Capture, feature and factor
 CaptureBasePtr cap0 = frm0->addCapture(std::make_shared<CaptureMotion>("IMU ABS", 0, nullptr, pose10, 10, 9, nullptr));
diff --git a/test/gtest_factor_autodiff_distance_3D.cpp b/test/gtest_factor_autodiff_distance_3D.cpp
index 5c508f89d0de0ebddc7e4ce306dddf9aeee5efed..f22c65a51ed5b22cbf57f22aafbc6a81ee52e281 100644
--- a/test/gtest_factor_autodiff_distance_3D.cpp
+++ b/test/gtest_factor_autodiff_distance_3D.cpp
@@ -55,9 +55,9 @@ class FactorAutodiffDistance3D_Test : public testing::Test
             problem = Problem::create("PO 3D");
             ceres_manager = std::make_shared<CeresManager>(problem);
 
-            F1 = problem->emplaceFrame        (KEY_FRAME, pose1, 1.0);
+            F1 = problem->emplaceFrame        (KEY, pose1, 1.0);
 
-            F2 = problem->emplaceFrame        (KEY_FRAME, pose2, 2.0);
+            F2 = problem->emplaceFrame        (KEY, pose2, 2.0);
             C2 = std::make_shared<CaptureBase>("Base", 1.0);
             F2->addCapture(C2);
             f2 = std::make_shared<FeatureBase>("Dist", dist, dist_cov);
diff --git a/test/gtest_factor_autodiff_trifocal.cpp b/test/gtest_factor_autodiff_trifocal.cpp
index 98af13f6e834f73bd4bbab7e524cf8928d0467af..78223c6020f9241c9a4faa7d24db5346c06e9c6d 100644
--- a/test/gtest_factor_autodiff_trifocal.cpp
+++ b/test/gtest_factor_autodiff_trifocal.cpp
@@ -133,19 +133,19 @@ class FactorAutodiffTrifocalTest : public testing::Test{
             Vector2s pix(0,0);
             Matrix2s pix_cov; pix_cov.setIdentity();
 
-            F1 = problem->emplaceFrame(KEY_FRAME, pose1, 1.0);
+            F1 = problem->emplaceFrame(KEY, pose1, 1.0);
             I1 = std::make_shared<CaptureImage>(1.0, camera, cv::Mat(2,2,CV_8UC1));
             F1-> addCapture(I1);
             f1 = std::make_shared<FeatureBase>("PIXEL", pix, pix_cov); // pixel at origin
             I1-> addFeature(f1);
 
-            F2 = problem->emplaceFrame(KEY_FRAME, pose2, 2.0);
+            F2 = problem->emplaceFrame(KEY, pose2, 2.0);
             I2 = std::make_shared<CaptureImage>(2.0, camera, cv::Mat(2,2,CV_8UC1));
             F2-> addCapture(I2);
             f2 = std::make_shared<FeatureBase>("PIXEL", pix, pix_cov); // pixel at origin
             I2-> addFeature(f2);
 
-            F3 = problem->emplaceFrame(KEY_FRAME, pose3, 3.0);
+            F3 = problem->emplaceFrame(KEY, pose3, 3.0);
             I3 = std::make_shared<CaptureImage>(3.0, camera, cv::Mat(2,2,CV_8UC1));
             F3-> addCapture(I3);
             f3 = std::make_shared<FeatureBase>("PIXEL", pix, pix_cov); // pixel at origin
diff --git a/test/gtest_factor_odom_3D.cpp b/test/gtest_factor_odom_3D.cpp
index c3f767d56ea04682d2e33651c4e4e1a89f865585..2b8a6d20160d9464ffa7b48ff9044b66b03d50d9 100644
--- a/test/gtest_factor_odom_3D.cpp
+++ b/test/gtest_factor_odom_3D.cpp
@@ -37,8 +37,8 @@ ProblemPtr problem_ptr = Problem::create("PO 3D");
 CeresManager ceres_mgr(problem_ptr);
 
 // Two frames
-FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY_FRAME, problem_ptr->zeroState(), TimeStamp(0));
-FrameBasePtr frm1 = problem_ptr->emplaceFrame(KEY_FRAME, delta, TimeStamp(1));
+FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY, problem_ptr->zeroState(), TimeStamp(0));
+FrameBasePtr frm1 = problem_ptr->emplaceFrame(KEY, delta, TimeStamp(1));
 
 // Capture, feature and factor from frm1 to frm0
 CaptureBasePtr cap1 = frm1->addCapture(std::make_shared<CaptureMotion>("ODOM 3D", 1, nullptr, delta, 7, 6, nullptr));
diff --git a/test/gtest_factor_pose_2D.cpp b/test/gtest_factor_pose_2D.cpp
index d7bce0c84f734613f1a2f143bebf2690897149f2..d07b564a3caeed5dd34bb9e107776bc769f3d85d 100644
--- a/test/gtest_factor_pose_2D.cpp
+++ b/test/gtest_factor_pose_2D.cpp
@@ -30,7 +30,7 @@ ProblemPtr problem = Problem::create("PO 2D");
 CeresManager ceres_mgr(problem);
 
 // Two frames
-FrameBasePtr frm0 = problem->emplaceFrame(KEY_FRAME, problem->zeroState(), TimeStamp(0));
+FrameBasePtr frm0 = problem->emplaceFrame(KEY, problem->zeroState(), TimeStamp(0));
 
 // Capture, feature and factor from frm1 to frm0
 CaptureBasePtr cap0 = frm0->addCapture(std::make_shared<CaptureMotion>("ODOM 2D", 0, nullptr, pose, 3, 3, nullptr));
diff --git a/test/gtest_factor_pose_3D.cpp b/test/gtest_factor_pose_3D.cpp
index 0af4c3c406f02c9c87cabb35b5e43fd7137fe28b..620e389c6b5a483f84250584cbe6d318e62ec55b 100644
--- a/test/gtest_factor_pose_3D.cpp
+++ b/test/gtest_factor_pose_3D.cpp
@@ -36,7 +36,7 @@ ProblemPtr problem = Problem::create("PO 3D");
 CeresManager ceres_mgr(problem);
 
 // Two frames
-FrameBasePtr frm0 = problem->emplaceFrame(KEY_FRAME, problem->zeroState(), TimeStamp(0));
+FrameBasePtr frm0 = problem->emplaceFrame(KEY, problem->zeroState(), TimeStamp(0));
 
 // Capture, feature and factor
 CaptureBasePtr cap0 = frm0->addCapture(std::make_shared<CaptureMotion>("ODOM 3D", 0, nullptr, pose7, 7, 6, nullptr));
diff --git a/test/gtest_feature_IMU.cpp b/test/gtest_feature_IMU.cpp
index 082e438d0b799e1ed32075f28e6f61b7450da8e0..c9d894e9ff3a8fafdee13087ef7364bf7173277f 100644
--- a/test/gtest_feature_IMU.cpp
+++ b/test/gtest_feature_IMU.cpp
@@ -77,7 +77,7 @@ class FeatureIMU_test : public testing::Test
     //create Frame
         ts = problem->getProcessorMotion()->getBuffer().get().back().ts_;
         state_vec = problem->getProcessorMotion()->getCurrentState();
-   	    last_frame = std::make_shared<FrameBase>(KEY_FRAME, ts, std::make_shared<StateBlock>(state_vec.head(3)), std::make_shared<StateBlock>(state_vec.segment(3,4)), std::make_shared<StateBlock>(state_vec.head(3)));
+   	    last_frame = std::make_shared<FrameBase>(KEY, ts, std::make_shared<StateBlock>(state_vec.head(3)), std::make_shared<StateBlock>(state_vec.segment(3,4)), std::make_shared<StateBlock>(state_vec.head(3)));
         problem->getTrajectory()->addFrame(last_frame);
         
     //create a feature
diff --git a/test/gtest_frame_base.cpp b/test/gtest_frame_base.cpp
index 9b4c7b6cf882b1f8104fa71ac3d60e12d8580137..9984c258de1026f68debd1cf4ccd072d4cdbd3c5 100644
--- a/test/gtest_frame_base.cpp
+++ b/test/gtest_frame_base.cpp
@@ -32,6 +32,7 @@ TEST(FrameBase, GettersAndSetters)
     ASSERT_EQ(t, 1);
     ASSERT_FALSE(F->isFixed());
     ASSERT_EQ(F->isKey(), false);
+    ASSERT_EQ(F->isKeyOrAux(), false);
 }
 
 TEST(FrameBase, StateBlocks)
@@ -123,6 +124,7 @@ TEST(FrameBase, LinksToTree)
     // set key
     F1->setKey();
     ASSERT_TRUE(F1->isKey());
+    ASSERT_TRUE(F1->isKeyOrAux());
 
     // Unlink
     F1->unlinkCapture(C);
diff --git a/test/gtest_odom_2D.cpp b/test/gtest_odom_2D.cpp
index 604ef489478f5779ac4b79a14095c37436c81be4..feafb83e98ce51caf43aea88d2a192b00fff78e8 100644
--- a/test/gtest_odom_2D.cpp
+++ b/test/gtest_odom_2D.cpp
@@ -131,7 +131,7 @@ TEST(Odom2D, FactorFix_and_FactorOdom2D)
 
     // KF1 and motion from KF0
     t += dt;
-    FrameBasePtr        F1 = Pr->emplaceFrame(KEY_FRAME, Vector3s::Zero(), t);
+    FrameBasePtr        F1 = Pr->emplaceFrame(KEY, Vector3s::Zero(), t);
     CaptureBasePtr      C1 = F1->addCapture(std::make_shared<CaptureBase>("ODOM 2D", t));
     FeatureBasePtr      f1 = C1->addFeature(std::make_shared<FeatureBase>("ODOM 2D", delta, delta_cov));
     FactorBasePtr   c1 = f1->addFactor(std::make_shared<FactorOdom2D>(f1, F0, nullptr));
@@ -139,7 +139,7 @@ TEST(Odom2D, FactorFix_and_FactorOdom2D)
 
     // KF2 and motion from KF1
     t += dt;
-    FrameBasePtr        F2 = Pr->emplaceFrame(KEY_FRAME, Vector3s::Zero(), t);
+    FrameBasePtr        F2 = Pr->emplaceFrame(KEY, Vector3s::Zero(), t);
     CaptureBasePtr      C2 = F2->addCapture(std::make_shared<CaptureBase>("ODOM 2D", t));
     FeatureBasePtr      f2 = C2->addFeature(std::make_shared<FeatureBase>("ODOM 2D", delta, delta_cov));
     FactorBasePtr   c2 = f2->addFactor(std::make_shared<FactorOdom2D>(f2, F1, nullptr));
@@ -404,7 +404,7 @@ TEST(Odom2D, KF_callback)
     std::cout << "-----------------------------\nSplit after last KF; time: " << t_split << std::endl;
 
     Vector3s x_split = processor_odom2d->getState(t_split);
-    FrameBasePtr keyframe_2 = problem->emplaceFrame(KEY_FRAME, x_split, t_split);
+    FrameBasePtr keyframe_2 = problem->emplaceFrame(KEY, x_split, t_split);
 
     ASSERT_TRUE(problem->check(0));
     processor_odom2d->keyFrameCallback(keyframe_2, dt/2);
@@ -436,7 +436,7 @@ TEST(Odom2D, KF_callback)
     problem->print(4,1,1,1);
 
     x_split = processor_odom2d->getState(t_split);
-    FrameBasePtr keyframe_1 = problem->emplaceFrame(KEY_FRAME, x_split, t_split);
+    FrameBasePtr keyframe_1 = problem->emplaceFrame(KEY, x_split, t_split);
 
     ASSERT_TRUE(problem->check(0));
     processor_odom2d->keyFrameCallback(keyframe_1, dt/2);
diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp
index b65bea49219ff2fa5e2c29233d3e4d21a8e35704..143b66549f99b4d385bb3f61c5250a19979be257 100644
--- a/test/gtest_problem.cpp
+++ b/test/gtest_problem.cpp
@@ -9,6 +9,7 @@
 #include "base/utils/logging.h"
 
 #include "base/problem/problem.h"
+#include "base/solver/solver_manager.h"
 #include "base/sensor/sensor_base.h"
 #include "base/sensor/sensor_odom_3D.h"
 #include "base/processor/processor_odom_3D.h"
@@ -19,11 +20,36 @@
 using namespace wolf;
 using namespace Eigen;
 
+
+WOLF_PTR_TYPEDEFS(DummySolverManager);
+
+struct DummySolverManager : public SolverManager
+{
+  DummySolverManager(const ProblemPtr& _problem)
+    : SolverManager(_problem)
+  {
+    //
+  }
+  virtual void computeCovariances(const CovarianceBlocksToBeComputed blocks){};
+  virtual void computeCovariances(const std::vector<StateBlockPtr>& st_list){};
+  virtual bool hasConverged(){return true;};
+  virtual SizeStd iterations(){return 0;};
+  virtual Scalar initialCost(){return 0;};
+  virtual Scalar finalCost(){return 0;};
+  virtual std::string solveImpl(const ReportVerbosity report_level){return std::string("");};
+  virtual void addFactor(const FactorBasePtr& fac_ptr){};
+  virtual void removeFactor(const FactorBasePtr& fac_ptr){};
+  virtual void addStateBlock(const StateBlockPtr& state_ptr){};
+  virtual void removeStateBlock(const StateBlockPtr& state_ptr){};
+  virtual void updateStateBlockStatus(const StateBlockPtr& state_ptr){};
+  virtual void updateStateBlockLocalParametrization(const StateBlockPtr& state_ptr){};
+};
+
 TEST(Problem, create)
 {
     ProblemPtr P = Problem::create("POV 3D");
 
-    // check double ointers to branches
+    // check double pointers to branches
     ASSERT_EQ(P, P->getHardware()->getProblem());
     ASSERT_EQ(P, P->getTrajectory()->getProblem());
     ASSERT_EQ(P, P->getMap()->getProblem());
@@ -109,20 +135,20 @@ TEST(Problem, SetOrigin_PO_2D)
     P->setPrior(x0, P0, t0, 1.0);
 
     // check that no sensor has been added
-    ASSERT_EQ(P->getHardware()->getSensorList().size(), (unsigned int) 0);
+    ASSERT_EQ(P->getHardware()->getSensorList().size(), (SizeStd) 0);
 
     // check that the state is correct
-    ASSERT_TRUE((x0 - P->getCurrentState()).isMuchSmallerThan(1, Constants::EPS_SMALL));
+    ASSERT_MATRIX_APPROX(x0, P->getCurrentState(), Constants::EPS_SMALL );
 
     // check that we have one frame, one capture, one feature, one factor
     TrajectoryBasePtr T = P->getTrajectory();
-    ASSERT_EQ(T->getFrameList().size(), (unsigned int) 1);
+    ASSERT_EQ(T->getFrameList().size(), (SizeStd) 1);
     FrameBasePtr F = P->getLastFrame();
-    ASSERT_EQ(F->getCaptureList().size(), (unsigned int) 1);
+    ASSERT_EQ(F->getCaptureList().size(), (SizeStd) 1);
     CaptureBasePtr C = F->getCaptureList().front();
-    ASSERT_EQ(C->getFeatureList().size(), (unsigned int) 1);
+    ASSERT_EQ(C->getFeatureList().size(), (SizeStd) 1);
     FeatureBasePtr f = C->getFeatureList().front();
-    ASSERT_EQ(f->getFactorList().size(), (unsigned int) 1);
+    ASSERT_EQ(f->getFactorList().size(), (SizeStd) 1);
 
     // check that the factor is absolute (no pointers to other F, f, or L)
     FactorBasePtr c = f->getFactorList().front();
@@ -130,8 +156,8 @@ TEST(Problem, SetOrigin_PO_2D)
     ASSERT_FALSE(c->getLandmarkOther());
 
     // check that the Feature measurement and covariance are the ones provided
-    ASSERT_TRUE((x0 - f->getMeasurement()).isMuchSmallerThan(1, Constants::EPS_SMALL));
-    ASSERT_TRUE((P0 - f->getMeasurementCovariance()).isMuchSmallerThan(1, Constants::EPS_SMALL));
+    ASSERT_MATRIX_APPROX(x0, f->getMeasurement(), Constants::EPS_SMALL );
+    ASSERT_MATRIX_APPROX(P0, f->getMeasurementCovariance(), Constants::EPS_SMALL );
 
     //    P->print(4,1,1,1);
 }
@@ -146,20 +172,20 @@ TEST(Problem, SetOrigin_PO_3D)
     P->setPrior(x0, P0, t0, 1.0);
 
     // check that no sensor has been added
-    ASSERT_EQ(P->getHardware()->getSensorList().size(), (unsigned int) 0);
+    ASSERT_EQ(P->getHardware()->getSensorList().size(), (SizeStd) 0);
 
     // check that the state is correct
     ASSERT_TRUE((x0 - P->getCurrentState()).isMuchSmallerThan(1, Constants::EPS_SMALL));
 
     // check that we have one frame, one capture, one feature, one factor
     TrajectoryBasePtr T = P->getTrajectory();
-    ASSERT_EQ(T->getFrameList().size(), (unsigned int) 1);
+    ASSERT_EQ(T->getFrameList().size(), (SizeStd) 1);
     FrameBasePtr F = P->getLastFrame();
-    ASSERT_EQ(F->getCaptureList().size(), (unsigned int) 1);
+    ASSERT_EQ(F->getCaptureList().size(), (SizeStd) 1);
     CaptureBasePtr C = F->getCaptureList().front();
-    ASSERT_EQ(C->getFeatureList().size(), (unsigned int) 1);
+    ASSERT_EQ(C->getFeatureList().size(), (SizeStd) 1);
     FeatureBasePtr f = C->getFeatureList().front();
-    ASSERT_EQ(f->getFactorList().size(), (unsigned int) 1);
+    ASSERT_EQ(f->getFactorList().size(), (SizeStd) 1);
 
     // check that the factor is absolute (no pointers to other F, f, or L)
     FactorBasePtr c = f->getFactorList().front();
@@ -177,9 +203,9 @@ TEST(Problem, emplaceFrame_factory)
 {
     ProblemPtr P = Problem::create("PO 2D");
 
-    FrameBasePtr f0 = P->emplaceFrame("PO 2D",    KEY_FRAME, VectorXs(3),  TimeStamp(0.0));
-    FrameBasePtr f1 = P->emplaceFrame("PO 3D",    KEY_FRAME, VectorXs(7),  TimeStamp(1.0));
-    FrameBasePtr f2 = P->emplaceFrame("POV 3D",   KEY_FRAME, VectorXs(10), TimeStamp(2.0));
+    FrameBasePtr f0 = P->emplaceFrame("PO 2D",    KEY, VectorXs(3),  TimeStamp(0.0));
+    FrameBasePtr f1 = P->emplaceFrame("PO 3D",    KEY, VectorXs(7),  TimeStamp(1.0));
+    FrameBasePtr f2 = P->emplaceFrame("POV 3D",   KEY, VectorXs(10), TimeStamp(2.0));
 
     //    std::cout << "f0: type PO 2D?    "  << f0->getType() << std::endl;
     //    std::cout << "f1: type PO 3D?    "  << f1->getType() << std::endl;
@@ -190,7 +216,7 @@ TEST(Problem, emplaceFrame_factory)
     ASSERT_EQ(f2->getType().compare("POV 3D"), 0);
 
     // check that all frames are effectively in the trajectory
-    ASSERT_EQ(P->getTrajectory()->getFrameList().size(), (unsigned int) 3);
+    ASSERT_EQ(P->getTrajectory()->getFrameList().size(), (SizeStd) 3);
 
     // check that all frames are linked to Problem
     ASSERT_EQ(f0->getProblem(), P);
@@ -207,11 +233,11 @@ TEST(Problem, StateBlocks)
 
     // 2 state blocks, fixed
     SensorBasePtr    Sm = P->installSensor   ("ODOM 3D", "odometer",xs, wolf_root + "/src/examples/sensor_odom_3D.yaml");
-    ASSERT_EQ(P->consumeStateBlockNotificationMap().size(), (unsigned int) 2);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 2);
 
     // 3 state blocks, fixed
     SensorBasePtr    St = P->installSensor   ("CAMERA", "camera",   xs, wolf_root + "/src/examples/camera_params_ueye_sim.yaml");
-    ASSERT_EQ(P->consumeStateBlockNotificationMap().size(), (unsigned int) (/*2 + */3)); // consume empties the notification map, so only should contain notification since last call
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) (2 + 3));
 
     ProcessorParamsTrackerFeaturePtr params = std::make_shared<ProcessorParamsTrackerFeature>();
     params->time_tolerance            = 0.1;
@@ -223,16 +249,40 @@ TEST(Problem, StateBlocks)
     ProcessorBasePtr pm = P->installProcessor("ODOM 3D",            "odom integrator",      "odometer", wolf_root + "/src/examples/processor_odom_3D.yaml");
 
     // 2 state blocks, estimated
-    P->emplaceFrame("PO 3D", KEY_FRAME, xs, 0);
-    ASSERT_EQ(P->consumeStateBlockNotificationMap().size(), (unsigned int)(/*2 + 3*/ + 2)); // consume empties the notification map, so only should contain notification since last call
+    auto KF = P->emplaceFrame("PO 3D", KEY, xs, 0);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd)(2 + 3 + 2));
+
+    // Notifications
+    Notification notif;
+    ASSERT_TRUE(P->getStateBlockNotification(KF->getP(), notif));
+    ASSERT_EQ(notif, ADD);
+    ASSERT_TRUE(P->getStateBlockNotification(KF->getO(), notif));
+    ASSERT_EQ(notif, ADD);
 
     //    P->print(4,1,1,1);
 
     // change some SB properties
     St->unfixExtrinsics();
-    ASSERT_TRUE(P->consumeStateBlockNotificationMap().empty()); // changes in state_blocks status (fix/state/localparam) does not raise a notification in problem, only ADD/REMOVE
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd)(2 + 3 + 2)); // changes in state_blocks status (fix/state/localparam) does not raise a notification in problem, only ADD/REMOVE
 
     //    P->print(4,1,1,1);
+
+    // consume notifications
+    DummySolverManagerPtr SM = std::make_shared<DummySolverManager>(P);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd)(2 + 3 + 2));
+    SM->update(); // calls P->consumeStateBlockNotificationMap();
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) (0)); // consume empties the notification map
+
+    // remove frame
+    auto SB_P = KF->getP();
+    auto SB_O = KF->getO();
+    KF->remove();
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd)(2));
+    ASSERT_TRUE(P->getStateBlockNotification(SB_P, notif));
+    ASSERT_EQ(notif, REMOVE);
+    ASSERT_TRUE(P->getStateBlockNotification(SB_O, notif));
+    ASSERT_EQ(notif, REMOVE);
+
 }
 
 TEST(Problem, Covariances)
@@ -256,7 +306,7 @@ TEST(Problem, Covariances)
 
     // 4 state blocks, estimated
     St->unfixExtrinsics();
-    FrameBasePtr F = P->emplaceFrame("PO 3D", KEY_FRAME, xs, 0);
+    FrameBasePtr F = P->emplaceFrame("PO 3D", KEY, xs, 0);
 
     // set covariance (they are not computed without a solver)
     P->addCovarianceBlock(F->getP(), Eigen::Matrix3s::Identity());
diff --git a/test/gtest_processor_base.cpp b/test/gtest_processor_base.cpp
index 904dfd7646f1194892e0845b003cd20d17916c4b..34128f0db287f152a36074fe16b2e61db9a37153 100644
--- a/test/gtest_processor_base.cpp
+++ b/test/gtest_processor_base.cpp
@@ -59,7 +59,7 @@ TEST(ProcessorBase, KeyFrameCallback)
 
     std::cout << "sensor & processor created and added to wolf problem" << std::endl;
 
-    // Sequence to test KeyFrame creations (callback calls)
+    // Sequence to test Key Frame creations (callback calls)
 
     // initialize
     TimeStamp   t(0.0);
diff --git a/test/gtest_processor_frame_nearest_neighbor_filter_2D.cpp b/test/gtest_processor_frame_nearest_neighbor_filter_2D.cpp
index cfbdd69e0f978d8822bf0e707ff48a2a3fcefbbd..75a0cdefbb70da4d75edb2d1e4a7e5d79d13a29c 100644
--- a/test/gtest_processor_frame_nearest_neighbor_filter_2D.cpp
+++ b/test/gtest_processor_frame_nearest_neighbor_filter_2D.cpp
@@ -72,19 +72,19 @@ TEST(ProcessorFrameNearestNeighborFilter, PointInEllipseRotated)
   auto stateblock_optr4 = std::make_shared<wolf::StateBlock>(state4.tail<1>());
 
   // create Keyframes
-  F1 = std::make_shared<wolf::FrameBase>(wolf::KEY_FRAME,
+  F1 = std::make_shared<wolf::FrameBase>(wolf::KEY,
                                          1,
                                          stateblock_pptr1,
                                          stateblock_optr1);
-  F2 = std::make_shared<wolf::FrameBase>(wolf::KEY_FRAME,
+  F2 = std::make_shared<wolf::FrameBase>(wolf::KEY,
                                          1,
                                          stateblock_pptr2,
                                          stateblock_optr2);
-  F3 = std::make_shared<wolf::FrameBase>(wolf::KEY_FRAME,
+  F3 = std::make_shared<wolf::FrameBase>(wolf::KEY,
                                          1,
                                          stateblock_pptr3,
                                          stateblock_optr3);
-  F4 = std::make_shared<wolf::FrameBase>(wolf::KEY_FRAME,
+  F4 = std::make_shared<wolf::FrameBase>(wolf::KEY,
                                          1,
                                          stateblock_pptr4,
                                          stateblock_optr4);
@@ -147,8 +147,9 @@ TEST(ProcessorFrameNearestNeighborFilter, PointInEllipseRotated)
   incomming_dummy = std::make_shared<wolf::CaptureBase>("DUMMY",
                                                         1.2,
                                                         sensor_ptr);
-  // Make 3rd frame last Keyframe
-  problem->getTrajectory()->setLastKeyFrame(F3);
+  // Make 3rd frame last Key frame
+  F3->setTimeStamp(wolf::TimeStamp(2.0));
+  problem->getTrajectory()->sortFrame(F3);
 
   // trigger search for loopclosure
   processor_ptr_point2d->process(incomming_dummy);
@@ -180,8 +181,9 @@ TEST(ProcessorFrameNearestNeighborFilter, EllipseEllipseRotatedCrosscovariance)
   problem->addCovarianceBlock( F4->getP(), F4->getP(),
                                position_covariance_matrix);
 
-  // Make 3rd frame last Keyframe
-  problem->getTrajectory()->setLastKeyFrame(F3);
+  // Make 3rd frame last Key frame
+  F3->setTimeStamp(wolf::TimeStamp(2.0));
+  problem->getTrajectory()->sortFrame(F3);
 
   // trigger search for loopclosure
   processor_ptr_ellipse2d->process(incomming_dummy);
@@ -192,8 +194,9 @@ TEST(ProcessorFrameNearestNeighborFilter, EllipseEllipseRotatedCrosscovariance)
   ASSERT_EQ(testloops[0]->id(), (unsigned int) 1);
   ASSERT_EQ(testloops[1]->id(), (unsigned int) 2);
 
-  // Make 4th frame last Keyframe
-  problem->getTrajectory()->setLastKeyFrame(F4);
+  // Make 4th frame last Key frame
+  F4->setTimeStamp(wolf::TimeStamp(3.0));
+  problem->getTrajectory()->sortFrame(F4);
 
   // trigger search for loopclosure again
   processor_ptr_ellipse2d->process(incomming_dummy);
diff --git a/test/gtest_solver_manager.cpp b/test/gtest_solver_manager.cpp
index 1928d5a30fc7cd7c5a63cfcefb684b17fa675709..91ec5dba639cc2a89dc99a94de23e5483adf981b 100644
--- a/test/gtest_solver_manager.cpp
+++ b/test/gtest_solver_manager.cpp
@@ -450,9 +450,10 @@ TEST(SolverManager, AddUpdatedStateBlock)
     // add state_block
     P->addStateBlock(sb_ptr);
 
-    auto state_block_notification_map = P->consumeStateBlockNotificationMap();
-    ASSERT_EQ(state_block_notification_map.size(),1);
-    ASSERT_EQ(state_block_notification_map.begin()->second,ADD);
+    Notification notif;
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(),1);
+    ASSERT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    ASSERT_EQ(notif, ADD);
 
     // == Insert OTHER notifications ==
 
@@ -463,21 +464,25 @@ TEST(SolverManager, AddUpdatedStateBlock)
     // Fix --> FLAG
     sb_ptr->unfix();
 
-    ASSERT_TRUE(P->consumeStateBlockNotificationMap().empty()); // No new notifications (fix and set state are flags in sb)
+    ASSERT_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();
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(),0);
 
     // == When an REMOVE is notified: a REMOVE notification should be stored ==
 
     // remove state_block
     P->removeStateBlock(sb_ptr);
 
-    state_block_notification_map = P->consumeStateBlockNotificationMap();
-    ASSERT_EQ(state_block_notification_map.size(),1);
-    ASSERT_EQ(state_block_notification_map.begin()->second,REMOVE);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(),1);
+    ASSERT_TRUE(P->getStateBlockNotification(sb_ptr, notif));
+    ASSERT_EQ(notif, REMOVE);
 
     // == ADD + REMOVE: notification map should be empty ==
     P->addStateBlock(sb_ptr);
     P->removeStateBlock(sb_ptr);
-    ASSERT_TRUE(P->consumeStateBlockNotificationMap().empty());
+    ASSERT_TRUE(P->getStateBlockNotificationMapSize() == 0);
 
     // == UPDATES should clear the list of notifications ==
     // add state_block
@@ -486,7 +491,7 @@ TEST(SolverManager, AddUpdatedStateBlock)
     // update solver
     solver_manager_ptr->update();
 
-    ASSERT_TRUE(P->consumeStateBlockNotificationMap().empty()); // After solver_manager->update, notifications should be empty
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(),0); // After solver_manager->update, notifications should be empty
 }
 
 TEST(SolverManager, AddFactor)
@@ -499,11 +504,16 @@ TEST(SolverManager, AddFactor)
     StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
 
+    // notification
+    Notification notif;
+    ASSERT_TRUE(P->getFactorNotification(c,notif));
+    ASSERT_EQ(notif, ADD);
+
     // update solver
     solver_manager_ptr->update();
 
@@ -521,7 +531,7 @@ TEST(SolverManager, RemoveFactor)
     StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
@@ -532,6 +542,11 @@ TEST(SolverManager, RemoveFactor)
     // add factor
     P->removeFactor(c);
 
+    // notification
+    Notification notif;
+    ASSERT_TRUE(P->getFactorNotification(c,notif));
+    ASSERT_EQ(notif, REMOVE);
+
     // update solver
     solver_manager_ptr->update();
 
@@ -549,15 +564,22 @@ TEST(SolverManager, AddRemoveFactor)
     StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
 
+    // notification
+    Notification notif;
+    ASSERT_TRUE(P->getFactorNotification(c,notif));
+    ASSERT_EQ(notif, ADD);
+
     // add factor
     P->removeFactor(c);
 
-    ASSERT_TRUE(P->consumeFactorNotificationMap().empty()); // ADD+REMOVE = empty
+    // notification
+    ASSERT_EQ(P->getFactorNotificationMapSize(), 0); // ADD+REMOVE cancels out
+    ASSERT_FALSE(P->getFactorNotification(c, notif)); // ADD+REMOVE cancels out
 
     // update solver
     solver_manager_ptr->update();
@@ -576,7 +598,7 @@ TEST(SolverManager, DoubleRemoveFactor)
     StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state);
 
     // Create (and add) factor point 2d
-    FrameBasePtr        F = P->emplaceFrame(KEY_FRAME, P->zeroState(), TimeStamp(0));
+    FrameBasePtr        F = P->emplaceFrame(KEY, P->zeroState(), TimeStamp(0));
     CaptureBasePtr      C = F->addCapture(std::make_shared<CaptureVoid>(0, nullptr));
     FeatureBasePtr      f = C->addFeature(std::make_shared<FeatureBase>("ODOM 2D", Vector3s::Zero(), Matrix3s::Identity()));
     FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(f->addFactor(std::make_shared<FactorPose2D>(f)));
diff --git a/test/gtest_trajectory.cpp b/test/gtest_trajectory.cpp
index de582e26b0e3fbfa6ca61876e82d3b9870ea0ff8..1cd7c1a201806e04b59d56b33b83ab2681aa4e1f 100644
--- a/test/gtest_trajectory.cpp
+++ b/test/gtest_trajectory.cpp
@@ -9,6 +9,7 @@
 #include "base/utils/logging.h"
 
 #include "base/problem/problem.h"
+#include "base/solver/solver_manager.h"
 #include "base/trajectory/trajectory_base.h"
 #include "base/frame/frame_base.h"
 
@@ -16,45 +17,26 @@
 
 using namespace wolf;
 
-struct DummyNotificationProcessor
+struct DummySolverManager : public SolverManager
 {
-  DummyNotificationProcessor(ProblemPtr _problem)
-    : problem_(_problem)
+  DummySolverManager(const ProblemPtr& _problem)
+    : SolverManager(_problem)
   {
     //
   }
-
-  void update()
-  {
-    if (problem_ == nullptr)
-    {
-      FAIL() << "problem_ is nullptr !";
-    }
-
-    auto sb_noti_map = problem_->consumeStateBlockNotificationMap();
-    ASSERT_TRUE(problem_->consumeStateBlockNotificationMap().empty()); // consume should empty the notification map
-
-    while (!sb_noti_map.empty())
-    {
-        switch (sb_noti_map.begin()->second)
-        {
-          case ADD:
-          {
-            break;
-          }
-          case REMOVE:
-          {
-            break;
-          }
-          default:
-            throw std::runtime_error("SolverManager::update: State Block notification must be ADD or REMOVE.");
-        }
-        sb_noti_map.erase(sb_noti_map.begin());
-    }
-    ASSERT_TRUE(sb_noti_map.empty());
-  }
-
-  ProblemPtr problem_;
+  virtual void computeCovariances(const CovarianceBlocksToBeComputed blocks){};
+  virtual void computeCovariances(const std::vector<StateBlockPtr>& st_list){};
+  virtual bool hasConverged(){return true;};
+  virtual SizeStd iterations(){return 0;};
+  virtual Scalar initialCost(){return 0;};
+  virtual Scalar finalCost(){return 0;};
+  virtual std::string solveImpl(const ReportVerbosity report_level){return std::string("");};
+  virtual void addFactor(const FactorBasePtr& fac_ptr){};
+  virtual void removeFactor(const FactorBasePtr& fac_ptr){};
+  virtual void addStateBlock(const StateBlockPtr& state_ptr){};
+  virtual void removeStateBlock(const StateBlockPtr& state_ptr){};
+  virtual void updateStateBlockStatus(const StateBlockPtr& state_ptr){};
+  virtual void updateStateBlockLocalParametrization(const StateBlockPtr& state_ptr){};
 };
 
 /// Set to true if you want debug info
@@ -67,33 +49,74 @@ TEST(TrajectoryBase, ClosestKeyFrame)
     TrajectoryBasePtr T = P->getTrajectory();
 
     // Trajectory status:
-    //  kf1   kf2    f3      frames
+    //  KF1   KF2  AuxF3  F4       frames
+    //   1     2     3     4       time stamps
+    // --+-----+-----+-----+--->   time
+
+    FrameBasePtr F1 = std::make_shared<FrameBase>(KEY,     1, nullptr, nullptr);
+    FrameBasePtr F2 = std::make_shared<FrameBase>(KEY,     2, nullptr, nullptr);
+    FrameBasePtr F3 = std::make_shared<FrameBase>(AUXILIARY,     3, nullptr, nullptr);
+    FrameBasePtr F4 = std::make_shared<FrameBase>(NON_ESTIMATED, 4, nullptr, nullptr);
+    T->addFrame(F1);
+    T->addFrame(F2);
+    T->addFrame(F3);
+    T->addFrame(F4);
+
+    FrameBasePtr KF; // closest key-frame queried
+
+    KF = T->closestKeyFrameToTimeStamp(-0.8);                // before all keyframes    --> return F1
+    ASSERT_EQ(KF->id(), F1->id());                           // same id!
+
+    KF = T->closestKeyFrameToTimeStamp(1.1);                 // between keyframes       --> return F1
+    ASSERT_EQ(KF->id(), F1->id());                           // same id!
+
+    KF = T->closestKeyFrameToTimeStamp(1.9);                 // between keyframes       --> return F2
+    ASSERT_EQ(KF->id(), F2->id());                           // same id!
+
+    KF = T->closestKeyFrameToTimeStamp(2.6);                 // between keyframe and auxiliary frame, but closer to auxiliary frame --> return F2
+    ASSERT_EQ(KF->id(), F2->id());                           // same id!
+
+    KF = T->closestKeyFrameToTimeStamp(3.2);                 // after the auxiliary frame, between closer to frame --> return F2
+    ASSERT_EQ(KF->id(), F2->id());                           // same id!
+
+    KF = T->closestKeyFrameToTimeStamp(4.2);                 // after the last frame --> return F2
+    ASSERT_EQ(KF->id(), F2->id());                           // same id!
+}
+
+TEST(TrajectoryBase, ClosestKeyOrAuxFrame)
+{
+
+    ProblemPtr P = Problem::create("PO 2D");
+    TrajectoryBasePtr T = P->getTrajectory();
+
+    // Trajectory status:
+    //  KF1   KF2    F3      frames
     //   1     2     3       time stamps
     // --+-----+-----+--->   time
 
-    FrameBasePtr f1 = std::make_shared<FrameBase>(KEY_FRAME,     1, nullptr, nullptr);
-    FrameBasePtr f2 = std::make_shared<FrameBase>(KEY_FRAME,     2, nullptr, nullptr);
-    FrameBasePtr f3 = std::make_shared<FrameBase>(NON_KEY_FRAME, 3, nullptr, nullptr);
-    T->addFrame(f1);
-    T->addFrame(f2);
-    T->addFrame(f3);
+    FrameBasePtr F1 = std::make_shared<FrameBase>(KEY,           1, nullptr, nullptr);
+    FrameBasePtr F2 = std::make_shared<FrameBase>(AUXILIARY,     2, nullptr, nullptr);
+    FrameBasePtr F3 = std::make_shared<FrameBase>(NON_ESTIMATED, 3, nullptr, nullptr);
+    T->addFrame(F1);
+    T->addFrame(F2);
+    T->addFrame(F3);
 
-    FrameBasePtr kf; // closest key-frame queried
+    FrameBasePtr KF; // closest key-frame queried
 
-    kf = T->closestKeyFrameToTimeStamp(-0.8);                // before all keyframes    --> return f0
-    ASSERT_EQ(kf->id(), f1->id());                           // same id!
+    KF = T->closestKeyOrAuxFrameToTimeStamp(-0.8);          // before all keyframes    --> return f0
+    ASSERT_EQ(KF->id(), F1->id());                           // same id!
 
-    kf = T->closestKeyFrameToTimeStamp(1.1);                 // between keyframes       --> return f1
-    ASSERT_EQ(kf->id(), f1->id());                           // same id!
+    KF = T->closestKeyOrAuxFrameToTimeStamp(1.1);           // between keyframes       --> return F1
+    ASSERT_EQ(KF->id(), F1->id());                           // same id!
 
-    kf = T->closestKeyFrameToTimeStamp(1.9);                 // between keyframes       --> return f2
-    ASSERT_EQ(kf->id(), f2->id());                           // same id!
+    KF = T->closestKeyOrAuxFrameToTimeStamp(1.9);           // between keyframes       --> return F2
+    ASSERT_EQ(KF->id(), F2->id());                           // same id!
 
-    kf = T->closestKeyFrameToTimeStamp(2.6);                 // between keyframe and frame, but closer to frame --> return f2
-    ASSERT_EQ(kf->id(), f2->id());                           // same id!
+    KF = T->closestKeyOrAuxFrameToTimeStamp(2.6);           // between keyframe and frame, but closer to frame --> return F2
+    ASSERT_EQ(KF->id(), F2->id());                           // same id!
 
-    kf = T->closestKeyFrameToTimeStamp(3.2);                 // after the last frame    --> return f2
-    ASSERT_EQ(kf->id(), f2->id());                           // same id!
+    KF = T->closestKeyOrAuxFrameToTimeStamp(3.2);           // after the last frame    --> return F2
+    ASSERT_EQ(KF->id(), F2->id());                           // same id!
 }
 
 TEST(TrajectoryBase, Add_Remove_Frame)
@@ -103,71 +126,72 @@ TEST(TrajectoryBase, Add_Remove_Frame)
     ProblemPtr P = Problem::create("PO 2D");
     TrajectoryBasePtr T = P->getTrajectory();
 
-    DummyNotificationProcessor N(P);
+    DummySolverManager N(P);
 
     // Trajectory status:
-    //  kf1   kf2    f3      frames
+    //  KF1   KF2    F3      frames
     //   1     2     3       time stamps
     // --+-----+-----+--->   time
 
-    FrameBasePtr f1 = std::make_shared<FrameBase>(KEY_FRAME,     1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // 2 non-fixed
-    FrameBasePtr f2 = std::make_shared<FrameBase>(KEY_FRAME,     2, make_shared<StateBlock>(2), make_shared<StateBlock>(1, true)); // 1 fixed, 1 not
-    FrameBasePtr f3 = std::make_shared<FrameBase>(NON_KEY_FRAME, 3, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame
+    FrameBasePtr F1 = std::make_shared<FrameBase>(KEY,     1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // 2 non-fixed
+    FrameBasePtr F2 = std::make_shared<FrameBase>(KEY,     2, make_shared<StateBlock>(2), make_shared<StateBlock>(1, true)); // 1 fixed, 1 not
+    FrameBasePtr F3 = std::make_shared<FrameBase>(NON_ESTIMATED, 3, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame
 
     std::cout << __LINE__ << std::endl;
 
     // add frames and keyframes
-    T->addFrame(f1); // KF
+    T->addFrame(F1); // KF
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getFrameList().                 size(), (unsigned int) 1);
-    ASSERT_EQ(P->consumeStateBlockNotificationMap(). size(), (unsigned int) 2);
+    ASSERT_EQ(T->getFrameList().             size(), (SizeStd) 1);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 2);
     std::cout << __LINE__ << std::endl;
 
-    T->addFrame(f2); // KF
+    T->addFrame(F2); // KF
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getFrameList().                 size(), (unsigned int) 2);
+    ASSERT_EQ(T->getFrameList().             size(), (SizeStd) 2);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 4);
     std::cout << __LINE__ << std::endl;
 
-    T->addFrame(f3); // F (not KF so state blocks are not notified)
+    T->addFrame(F3); // F (not KF so state blocks are not notified)
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getFrameList().                 size(), (unsigned int) 3);
-    ASSERT_EQ(P->consumeStateBlockNotificationMap(). size(), (unsigned int) 2); // consumeStateBlockNotificationMap empties the notification map, 2 state blocks were notified since last call to consumeStateBlockNotificationMap
+    ASSERT_EQ(T->getFrameList().             size(), (SizeStd) 3);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 4);
     std::cout << __LINE__ << std::endl;
 
-    ASSERT_EQ(T->getLastFrame()->id(), f3->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f2->id());
+    ASSERT_EQ(T->getLastFrame()->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyFrame()->id(), F2->id());
     std::cout << __LINE__ << std::endl;
 
     N.update();
-    ASSERT_TRUE(P->consumeStateBlockNotificationMap().empty()); // consumeStateBlockNotificationMap was called in update() so it should be empty
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 0); // consumeStateBlockNotificationMap was called in update() so it should be empty
     std::cout << __LINE__ << std::endl;
 
     // remove frames and keyframes
-    f2->remove(); // KF
+    F2->remove(); // KF
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getFrameList().                 size(), (unsigned int) 2);
-    ASSERT_EQ(P->consumeStateBlockNotificationMap(). size(), (unsigned int) 2); // consumeStateBlockNotificationMap empties the notification map, 2 state blocks were notified since last call to consumeStateBlockNotificationMap
+    ASSERT_EQ(T->getFrameList().             size(), (SizeStd) 2);
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 2);
     std::cout << __LINE__ << std::endl;
 
-    ASSERT_EQ(T->getLastFrame()->id(), f3->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f1->id());
+    ASSERT_EQ(T->getLastFrame()->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyFrame()->id(), F1->id());
     std::cout << __LINE__ << std::endl;
 
-    f3->remove(); // F
+    F3->remove(); // F
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getFrameList().                 size(), (unsigned int) 1);
+    ASSERT_EQ(T->getFrameList().             size(), (SizeStd) 1);
     std::cout << __LINE__ << std::endl;
 
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f1->id());
+    ASSERT_EQ(T->getLastKeyFrame()->id(), F1->id());
 
-    f1->remove(); // KF
+    F1->remove(); // KF
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getFrameList().                 size(), (unsigned int) 0);
+    ASSERT_EQ(T->getFrameList().             size(), (SizeStd) 0);
     std::cout << __LINE__ << std::endl;
 
     N.update();
 
-    ASSERT_TRUE(P->consumeStateBlockNotificationMap().empty()); // consumeStateBlockNotificationMap was called in update() so it should be empty
+    ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 0); // consumeStateBlockNotificationMap was called in update() so it should be empty
     std::cout << __LINE__ << std::endl;
 }
 
@@ -179,70 +203,109 @@ TEST(TrajectoryBase, KeyFramesAreSorted)
     TrajectoryBasePtr T = P->getTrajectory();
 
     // Trajectory status:
-    //  kf1   kf2    f3      frames
+    //  KF1   KF2    F3      frames
     //   1     2     3       time stamps
     // --+-----+-----+--->   time
 
-    FrameBasePtr f1 = std::make_shared<FrameBase>(KEY_FRAME,     1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // 2 non-fixed
-    FrameBasePtr f2 = std::make_shared<FrameBase>(KEY_FRAME,     2, make_shared<StateBlock>(2), make_shared<StateBlock>(1, true)); // 1 fixed, 1 not
-    FrameBasePtr f3 = std::make_shared<FrameBase>(NON_KEY_FRAME, 3, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame
+    FrameBasePtr F1 = std::make_shared<FrameBase>(KEY,     1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // 2 non-fixed
+    FrameBasePtr F2 = std::make_shared<FrameBase>(KEY,     2, make_shared<StateBlock>(2), make_shared<StateBlock>(1, true)); // 1 fixed, 1 not
+    FrameBasePtr F3 = std::make_shared<FrameBase>(NON_ESTIMATED, 3, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame
 
     // add frames and keyframes in random order --> keyframes must be sorted after that
-    T->addFrame(f2); // KF2
+    T->addFrame(F2); // KF2
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getLastFrame()   ->id(), f2->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f2->id());
+    ASSERT_EQ(T->getLastFrame()         ->id(), F2->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F2->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F2->id());
 
-    T->addFrame(f3); // F3
+    T->addFrame(F3); // F3
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getLastFrame()   ->id(), f3->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f2->id());
+    ASSERT_EQ(T->getLastFrame()         ->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F2->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F2->id());
 
-    T->addFrame(f1); // KF1
+    T->addFrame(F1); // KF1
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getLastFrame()   ->id(), f3->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f2->id());
+    ASSERT_EQ(T->getLastFrame()         ->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F2->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F2->id());
 
-    f3->setKey(); // set KF3
+    F3->setKey(); // set KF3
     if (debug) P->print(2,0,0,0);
-    ASSERT_EQ(T->getLastFrame()   ->id(), f3->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f3->id());
+    ASSERT_EQ(T->getLastFrame()         ->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F3->id());
 
-    FrameBasePtr f4 = std::make_shared<FrameBase>(NON_KEY_FRAME, 1.5, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame
-    T->addFrame(f4);
+    FrameBasePtr F4 = std::make_shared<FrameBase>(NON_ESTIMATED, 1.5, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame
+    T->addFrame(F4);
     // Trajectory status:
-    //  kf1   kf2   kf3     f4       frames
+    //  KF1   KF2   KF3     F4       frames
     //   1     2     3     1.5       time stamps
     // --+-----+-----+------+--->    time
     if (debug) P->print(2,0,1,0);
-    ASSERT_EQ(T->getLastFrame()   ->id(), f4->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f3->id());
+    ASSERT_EQ(T->getLastFrame()         ->id(), F4->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F3->id());
 
-    f4->setKey();
+    F4->setKey();
     // Trajectory status:
-    //  kf1   kf4   kf2    kf3       frames
+    //  KF1   KF4   KF2    KF3       frames
     //   1    1.5    2      3        time stamps
     // --+-----+-----+------+--->    time
     if (debug) P->print(2,0,1,0);
-    ASSERT_EQ(T->getLastFrame()   ->id(), f3->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f3->id());
+    ASSERT_EQ(T->getLastFrame()         ->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F3->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F3->id());
 
-    f2->setTimeStamp(4);
+    F2->setTimeStamp(4);
     // Trajectory status:
-    //  kf1   kf4   kf3    kf2       frames
+    //  KF1   KF4   KF3    KF2       frames
     //   1    1.5    3      4        time stamps
     // --+-----+-----+------+--->    time
     if (debug) P->print(2,0,1,0);
-    ASSERT_EQ(T->getLastFrame()   ->id(), f2->id());
-    ASSERT_EQ(T->getLastKeyFrame()->id(), f2->id());
+    ASSERT_EQ(T->getLastFrame()         ->id(), F2->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F2->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F2->id());
 
-    f4->setTimeStamp(0.5);
+    F4->setTimeStamp(0.5);
     // Trajectory status:
-    //  kf4   kf2   kf3    kf2       frames
+    //  KF4   KF2   KF3    KF2       frames
     //  0.5    1     3      4        time stamps
     // --+-----+-----+------+--->    time
     if (debug) P->print(2,0,1,0);
-    ASSERT_EQ(T->getFrameList().front()->id(), f4->id());
+    ASSERT_EQ(T->getFrameList().front()->id(), F4->id());
+
+    FrameBasePtr F5 = std::make_shared<FrameBase>(AUXILIARY, 1.5, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame
+    T->addFrame(F5);
+    // Trajectory status:
+    //  KF4   KF2  AuxF5  KF3   KF2       frames
+    //  0.5    1    1.5    3     4        time stamps
+    // --+-----+-----+-----+-----+--->    time
+    if (debug) P->print(2,0,1,0);
+    ASSERT_EQ(T->getLastFrame()         ->id(), F2->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F2->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F2->id());
+
+    F5->setTimeStamp(5);
+    // Trajectory status:
+    //  KF4   KF2   KF3   KF2   AuxF5     frames
+    //  0.5    1     3     4     5        time stamps
+    // --+-----+-----+-----+-----+--->    time
+    if (debug) P->print(2,0,1,0);
+    ASSERT_EQ(T->getLastFrame()         ->id(), F5->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F5->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F2->id());
+
+    FrameBasePtr F6 = std::make_shared<FrameBase>(NON_ESTIMATED, 1.5, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame
+    T->addFrame(F6);
+    // Trajectory status:
+    //  KF4   KF2   KF3   KF2   AuxF5  F6       frames
+    //  0.5    1     3     4     5     6        time stamps
+    // --+-----+-----+-----+-----+-----+--->    time
+    if (debug) P->print(2,0,1,0);
+    ASSERT_EQ(T->getLastFrame()         ->id(), F6->id());
+    ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F5->id());
+    ASSERT_EQ(T->getLastKeyFrame()      ->id(), F2->id());
 
 }