diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6ff7ae3..f6e69bc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,8 +37,6 @@ add_library(${PROJECT_NAME}
   src/get_mtc_raw_stage.cpp
   src/initialize_mtc_task.cpp
   src/moveit_msgs.cpp
-  src/move_mtc_stage_to_container.cpp
-  src/move_mtc_container_to_parent_container.cpp
   src/plan_mtc_task.cpp
 )
 
@@ -52,51 +50,56 @@ ament_target_dependencies(${PROJECT_NAME}
 )
 
 add_executable(bt_allow_collisions examples/bt_allow_collisions.cpp)
-target_link_libraries(bt_allow_collisions ${PROJECT_NAME} )
-
-add_executable(bt_create_collision_object examples/bt_create_collision_object.cpp)
-target_link_libraries(bt_create_collision_object ${PROJECT_NAME} )
-
 add_executable(bt_compute_ik examples/bt_compute_ik.cpp)
-target_link_libraries(bt_compute_ik ${PROJECT_NAME} )
-
+add_executable(bt_create_collision_object examples/bt_create_collision_object.cpp)
 add_executable(bt_demo examples/bt_demo.cpp)
-target_link_libraries(bt_demo ${PROJECT_NAME} )
-
 add_executable(bt_generate_place_pose examples/bt_generate_place_pose.cpp)
-target_link_libraries(bt_generate_place_pose ${PROJECT_NAME} )
-
 add_executable(bt_joint_interpolation_solver examples/bt_joint_interpolation_solver.cpp)
-target_link_libraries(bt_joint_interpolation_solver ${PROJECT_NAME} )
-
 add_executable(bt_move_relative examples/bt_move_relative.cpp)
-target_link_libraries(bt_move_relative ${PROJECT_NAME} )
-
 add_executable(bt_move_to examples/bt_move_to.cpp)
-target_link_libraries(bt_move_to ${PROJECT_NAME} )
-
+add_executable(bt_pick_place examples/bt_pick_place.cpp)
 add_executable(bt_serial_container examples/bt_serial_container.cpp)
-target_link_libraries(bt_serial_container ${PROJECT_NAME} )
+add_executable(generate_xml_model src/generate_xml_model.cpp)
+
+target_link_libraries(bt_allow_collisions ${PROJECT_NAME})
+target_link_libraries(bt_compute_ik ${PROJECT_NAME})
+target_link_libraries(bt_create_collision_object ${PROJECT_NAME})
+target_link_libraries(bt_demo ${PROJECT_NAME})
+target_link_libraries(bt_generate_place_pose ${PROJECT_NAME} )
+target_link_libraries(bt_joint_interpolation_solver ${PROJECT_NAME})
+target_link_libraries(bt_move_relative ${PROJECT_NAME})
+target_link_libraries(bt_move_to ${PROJECT_NAME})
+target_link_libraries(bt_pick_place ${PROJECT_NAME})
+target_link_libraries(bt_serial_container ${PROJECT_NAME})
+target_link_libraries(generate_xml_model ${PROJECT_NAME})
+
+
+add_subdirectory(tests)
 
-if(BUILD_TESTING)
-  add_subdirectory(tests)
-endif()
 
 install(
   DIRECTORY include/${PROJECT_NAME}
   DESTINATION include
 )
 
+install(DIRECTORY
+  config
+  launch
+  DESTINATION share/${PROJECT_NAME}/
+)
+
 install(TARGETS 
   bt_allow_collisions
-  bt_create_collision_object
   bt_compute_ik
+  bt_create_collision_object
   bt_demo
   bt_generate_place_pose
   bt_joint_interpolation_solver
   bt_move_relative
   bt_move_to
+  bt_pick_place
   bt_serial_container
+  generate_xml_model
   DESTINATION lib/${PROJECT_NAME}
 )
 
diff --git a/README.md b/README.md
index 384da12..4ff5e48 100644
--- a/README.md
+++ b/README.md
@@ -4,5 +4,26 @@
 
 This project is compatible with version 4.X of [BehaviorTree.CPP](https://github.com/BehaviorTree/BehaviorTree.CPP).
 
+It is recommanded that the [Moveit Task Constructor](https://github.com/moveit/moveit_task_constructor) library commit version `>=` [fdc06c3](https://github.com/moveit/moveit_task_constructor/commit/fdc06c3b9105dadec2f44ee3e4b3133986945e86). This is to ensure that one can preempt a plan gracefully.
+
+## Demo
+Check the available [examples](./examples).
+
+Running the Pick and Place MTC demo using BT's:
+
+``` sh
+# In one terminal
+$ ros2 launch moveit_task_constructor_demo demo.launch.py
+# ALTERNATE: Use the one supplied with MTC
+#            Don't forget to change the task solution topic
+
+# In another terminal
+$ ros2 launch behaviortree_mtc run.launch.py
+
+
+# OPTIONAL: Connect from Groot2 to visualize the BT's on port 1667
+$ ros2 launch behaviortree_mtc run.launch.py delay_ms:=5000
+```
+
 ## Roadmap
-We plan to release version `1.0.0` by the end of summer 2024. Check the [roadmap](https://github.com/captain-yoshi/BehaviorTree.MTC/issues/15) for more details.
+We plan to release version `1.0.0` by the end of Christmas 2024. Check the [roadmap](https://github.com/captain-yoshi/BehaviorTree.MTC/issues/15) for more details.
diff --git a/config/bt_mtc_model.xml b/config/bt_mtc_model.xml
new file mode 100644
index 0000000..c6a8e09
--- /dev/null
+++ b/config/bt_mtc_model.xml
@@ -0,0 +1,269 @@
+<root BTCPP_format="4">
+    <TreeNodesModel>
+        <Action ID="AddObjectToPlanningScene">
+            <input_port name="collision_object" type="std::shared_ptr&lt;moveit_msgs::CollisionObject_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+            <input_port name="planning_scene_interface" type="std::shared_ptr&lt;moveit::planning_interface::PlanningSceneInterface&gt;"/>
+        </Action>
+        <Action ID="AllowAllCollisions">
+            <input_port name="objects" type="std::shared_ptr&lt;std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;">allow/forbid all collisions for given object/s</input_port>
+            <input_port name="stage_name" type="std::string"/>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">ModifyPlanningScene stage</output_port>
+        </Action>
+        <Action ID="AllowCollisionPairs">
+            <input_port name="second" type="std::shared_ptr&lt;std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;">second object of collision pair</input_port>
+            <input_port name="first" type="std::shared_ptr&lt;std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;">first object of collision pair</input_port>
+            <input_port name="stage_name" type="std::string"/>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">ModifyPlanningScene stage</output_port>
+        </Action>
+        <Action ID="AllowCollisionsJointModelGroup">
+            <input_port name="jmg_name" type="std::string">joint model group name</input_port>
+            <input_port name="objects" type="std::shared_ptr&lt;std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;">allow/forbid collisions with joint model group links</input_port>
+            <input_port name="stage_name" type="std::string"/>
+            <input_port name="task" type="std::shared_ptr&lt;moveit::task_constructor::Task&gt;">MTC task</input_port>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">ModifyPlanningScene stage</output_port>
+        </Action>
+        <Action ID="ConfigureInitFromMTCProperties">
+            <inout_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;"/>
+            <input_port name="property_names" type="std::shared_ptr&lt;std::set&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::less&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;"/>
+            <input_port name="source_flag" type="moveit::task_constructor::Stage::PropertyInitializerSource">Name for property initialization sources. {DEFAULT, MANUAL, PARENT, INTERFACE}</input_port>
+        </Action>
+        <Action ID="CreateMTCCartesianPath">
+            <input_port name="step_size" type="double" default="0.010000">step size between consecutive waypoints</input_port>
+            <output_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;" default="{solver}">Planner interface using pipeline motion solver</output_port>
+            <input_port name="precision" type="moveit::core::CartesianPrecision" default="">linear and rotational precision</input_port>
+            <input_port name="min_fraction" type="double" default="1.000000">fraction of motion required for success</input_port>
+            <input_port name="max_acceleration_scaling_factor" type="double" default="0.100000">scale down max acceleration by this factor</input_port>
+            <input_port name="max_velocity_scaling_factor" type="double" default="0.100000">scale down max velocity by this factor</input_port>
+        </Action>
+        <Action ID="CreateMTCComputeIK">
+            <input_port name="ik_frame" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+            <input_port name="min_solution_distance" type="double" default="0.100000">minimum distance between seperate IK solutions for the same target</input_port>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;"/>
+            <input_port name="wrapped_stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;"/>
+            <input_port name="max_ik_solutions" type="unsigned int" default="1">max ik solutions</input_port>
+            <input_port name="ignore_collisions" type="bool" default="false">ignore collisions, true or false</input_port>
+            <input_port name="group" type="std::string">name of active group (derived from eef if not provided)</input_port>
+            <input_port name="eef" type="std::string">name of end-effector</input_port>
+            <input_port name="stage_name" type="std::string"/>
+        </Action>
+        <Action ID="CreateMTCConnect">
+            <input_port name="merge_mode" type="unsigned char" default="1">0 = SEQUENTIAL, 1 = WAYPOINTS</input_port>
+            <input_port name="group" type="std::string"/>
+            <input_port name="stage_name" type="std::string">connect</input_port>
+            <input_port name="planner" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;"/>
+            <input_port name="max_distance" type="double" default="0.000100">maximally accepted joint configuration distance between trajectory endpoint and goal state</input_port>
+            <input_port name="timeout" type="double" default="1.000000">timeout</input_port>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;" default="{connect_stage}">Connect stage</output_port>
+        </Action>
+        <Action ID="CreateMTCCurrentState">
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;" default="{mtc_stage}">MoveIt Task Constructor stage.</output_port>
+        </Action>
+        <Action ID="CreateMTCGenerateGraspPose">
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;" default="{generate_grasp_pose}">GenerateGraspPose Stage</output_port>
+            <input_port name="monitored_stage" type="moveit::task_constructor::Stage*"/>
+            <input_port name="stage_name" type="std::string"/>
+            <input_port name="pregrasp_pose" type="std::string">pregrasp posture</input_port>
+            <input_port name="object" type="std::string">object on which we generate the grasp poses</input_port>
+            <input_port name="angle_delta" type="double" default="0.100000">angular steps (rad)</input_port>
+            <input_port name="rotation_axis" type="Vector3D" default="0,0,1">rotate object pose about given axis</input_port>
+            <input_port name="eef" type="std::string">name of end-effector</input_port>
+        </Action>
+        <Action ID="CreateMTCGeneratePlacePose">
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;" default="{generate_grasp_pose}">GenerateGraspPose Stage</output_port>
+            <input_port name="pose" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">target pose to pass on in spawned states</input_port>
+            <input_port name="allow_z_flip" type="bool" default="false">allow placing objects upside down</input_port>
+            <input_port name="monitored_stage" type="moveit::task_constructor::Stage*"/>
+            <input_port name="stage_name" type="std::string"/>
+            <input_port name="object" type="std::string">object on which we generate the place poses</input_port>
+        </Action>
+        <Action ID="CreateMTCJointInterpolation">
+            <output_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;" default="{solver}">plan using simple interpolation in joint-space</output_port>
+            <input_port name="max_step" type="double" default="0.100000">max joint step</input_port>
+            <input_port name="max_acceleration_scaling_factor" type="double" default="0.100000">scale down max acceleration by this factor</input_port>
+            <input_port name="max_velocity_scaling_factor" type="double" default="0.100000">scale down max velocity by this factor</input_port>
+        </Action>
+        <Action ID="CreateMTCModifyPlanningSceneAttachObjects">
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">ModifyPlanningScene stage</output_port>
+            <input_port name="object_names" type="std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt;">list of object names/id's.</input_port>
+            <input_port name="link_name" type="std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt;">attach or detach a list of objects to the given link</input_port>
+            <input_port name="stage_name" type="std::string"/>
+        </Action>
+        <Action ID="CreateMTCModifyPlanningSceneDetachObjects">
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">ModifyPlanningScene stage</output_port>
+            <input_port name="object_names" type="std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt;">list of object names/id's.</input_port>
+            <input_port name="link_name" type="std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt;">attach or detach a list of objects to the given link</input_port>
+            <input_port name="stage_name" type="std::string"/>
+        </Action>
+        <Action ID="CreateMTCMoveRelativeJoint">
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">MoveRelative stage</output_port>
+            <input_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;">planner interface</input_port>
+            <input_port name="direction" type="std::shared_ptr&lt;std::map&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, double, std::less&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt;, std::allocator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const, double&gt; &gt; &gt; &gt;">move specified joint variables by given amount</input_port>
+            <input_port name="max_distance" type="double" default="0.000000">maximum distance to move</input_port>
+            <input_port name="ik_frame" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">frame to be moved in Cartesian direction</input_port>
+            <input_port name="min_distance" type="double" default="-1.000000">minimum distance to move</input_port>
+            <input_port name="timeout" type="double" default="1.000000"/>
+            <input_port name="group" type="std::string">name of planning group</input_port>
+            <input_port name="stage_name" type="std::string" default="move relative">stage name</input_port>
+        </Action>
+        <Action ID="CreateMTCMoveRelativeTranslate">
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">MoveRelative stage</output_port>
+            <input_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;">planner interface</input_port>
+            <input_port name="direction" type="std::shared_ptr&lt;geometry_msgs::Vector3Stamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">translate link along given direction</input_port>
+            <input_port name="max_distance" type="double" default="0.000000">maximum distance to move</input_port>
+            <input_port name="ik_frame" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">frame to be moved in Cartesian direction</input_port>
+            <input_port name="min_distance" type="double" default="-1.000000">minimum distance to move</input_port>
+            <input_port name="timeout" type="double" default="1.000000"/>
+            <input_port name="group" type="std::string">name of planning group</input_port>
+            <input_port name="stage_name" type="std::string" default="move relative">stage name</input_port>
+        </Action>
+        <Action ID="CreateMTCMoveRelativeTwist">
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">MoveRelative stage</output_port>
+            <input_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;">planner interface</input_port>
+            <input_port name="direction" type="std::shared_ptr&lt;geometry_msgs::TwistStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">perform twist motion on specified link</input_port>
+            <input_port name="max_distance" type="double" default="0.000000">maximum distance to move</input_port>
+            <input_port name="ik_frame" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">frame to be moved in Cartesian direction</input_port>
+            <input_port name="min_distance" type="double" default="-1.000000">minimum distance to move</input_port>
+            <input_port name="timeout" type="double" default="1.000000"/>
+            <input_port name="group" type="std::string">name of planning group</input_port>
+            <input_port name="stage_name" type="std::string" default="move relative">stage name</input_port>
+        </Action>
+        <Action ID="CreateMTCMoveToJoint">
+            <input_port name="goal" type="std::shared_ptr&lt;std::map&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, double, std::less&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt;, std::allocator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const, double&gt; &gt; &gt; &gt;">move joints by name to their mapped target value</input_port>
+            <input_port name="stage_name" type="std::string" default="move to">stage name</input_port>
+            <input_port name="group" type="std::string">name of planning group</input_port>
+            <input_port name="timeout" type="double" default="1.000000"/>
+            <input_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;">planner interface</input_port>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">MoveTo stage</output_port>
+        </Action>
+        <Action ID="CreateMTCMoveToNamedJointPose">
+            <input_port name="goal" type="std::string">move joint model group to given named pose</input_port>
+            <input_port name="stage_name" type="std::string" default="move to">stage name</input_port>
+            <input_port name="group" type="std::string">name of planning group</input_port>
+            <input_port name="timeout" type="double" default="1.000000"/>
+            <input_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;">planner interface</input_port>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">MoveTo stage</output_port>
+        </Action>
+        <Action ID="CreateMTCMoveToPoint">
+            <input_port name="goal" type="std::shared_ptr&lt;geometry_msgs::PointStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">move link to given point, keeping current orientation</input_port>
+            <input_port name="ik_frame" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">frame to be moved in Cartesian direction</input_port>
+            <input_port name="stage_name" type="std::string" default="move to">stage name</input_port>
+            <input_port name="group" type="std::string">name of planning group</input_port>
+            <input_port name="timeout" type="double" default="1.000000"/>
+            <input_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;">planner interface</input_port>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">MoveTo stage</output_port>
+        </Action>
+        <Action ID="CreateMTCMoveToPose">
+            <input_port name="goal" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">move link to a given pose</input_port>
+            <input_port name="ik_frame" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;">frame to be moved in Cartesian direction</input_port>
+            <input_port name="stage_name" type="std::string" default="move to">stage name</input_port>
+            <input_port name="group" type="std::string">name of planning group</input_port>
+            <input_port name="timeout" type="double" default="1.000000"/>
+            <input_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;">planner interface</input_port>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">MoveTo stage</output_port>
+        </Action>
+        <Action ID="CreateMTCPipelinePlanner">
+            <input_port name="max_acceleration_scaling_factor" type="double" default="0.100000">scale down max acceleration by this factor</input_port>
+            <input_port name="num_planning_attempts" type="unsigned int" default="1u">number of planning attempts</input_port>
+            <input_port name="pipeline_id" type="std::string"/>
+            <input_port name="max_velocity_scaling_factor" type="double" default="0.100000">scale down max velocity by this factor</input_port>
+            <input_port name="planner_id" type="std::string"/>
+            <input_port name="display_motion_plans" type="bool" default="false">publish generated solutions on topic display_planned_path</input_port>
+            <input_port name="goal_orientation_tolerance" type="double" default="1e-4">tolerance for reaching orientation goals</input_port>
+            <input_port name="goal_position_tolerance" type="double" default="1e-4">tolerance for reaching position goals</input_port>
+            <input_port name="goal_joint_tolerance" type="double" default="1e-4">tolerance for reaching joint goals</input_port>
+            <input_port name="publish_planning_requests" type="bool" default="false">publish motion planning requests on topic motion_plan_request</input_port>
+            <output_port name="solver" type="std::shared_ptr&lt;moveit::task_constructor::solvers::PlannerInterface&gt;" default="{solver}">Planner interface using pipeline motion solver</output_port>
+        </Action>
+        <Action ID="CreateMTCSerialContainer">
+            <output_port name="container" type="std::shared_ptr&lt;moveit::task_constructor::ContainerBase&gt;">serial container</output_port>
+            <input_port name="container_name" type="std::string">serial container name</input_port>
+        </Action>
+        <Action ID="CreatePlanningSceneInterface">
+            <output_port name="planning_scene_interface" type="std::shared_ptr&lt;moveit::planning_interface::PlanningSceneInterface&gt;">{planning_scene_interface}</output_port>
+        </Action>
+        <Action ID="ForbidAllCollisions">
+            <input_port name="objects" type="std::shared_ptr&lt;std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;">allow/forbid all collisions for given object/s</input_port>
+            <input_port name="stage_name" type="std::string"/>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">ModifyPlanningScene stage</output_port>
+        </Action>
+        <Action ID="ForbidCollisionPairs">
+            <input_port name="second" type="std::shared_ptr&lt;std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;">second object of collision pair</input_port>
+            <input_port name="first" type="std::shared_ptr&lt;std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;">first object of collision pair</input_port>
+            <input_port name="stage_name" type="std::string"/>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">ModifyPlanningScene stage</output_port>
+        </Action>
+        <Action ID="ForbidCollisionsJointModelGroup">
+            <input_port name="jmg_name" type="std::string">joint model group name</input_port>
+            <input_port name="objects" type="std::shared_ptr&lt;std::vector&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;">allow/forbid collisions with joint model group links</input_port>
+            <input_port name="stage_name" type="std::string"/>
+            <input_port name="task" type="std::shared_ptr&lt;moveit::task_constructor::Task&gt;">MTC task</input_port>
+            <output_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">ModifyPlanningScene stage</output_port>
+        </Action>
+        <Action ID="GeometryMsgsPose">
+            <output_port name="pose" type="std::shared_ptr&lt;geometry_msgs::Pose_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+            <input_port name="quaternion" type="Vector4D"/>
+            <input_port name="position" type="Vector3D"/>
+        </Action>
+        <Action ID="GeometryMsgsPoseStamped">
+            <input_port name="quaternion" type="Vector4D"/>
+            <input_port name="position" type="Vector3D"/>
+            <output_port name="pose_stamped" type="std::shared_ptr&lt;geometry_msgs::PoseStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+            <input_port name="frame_id" type="std::string"/>
+        </Action>
+        <Action ID="GeometryMsgsTwistStamped">
+            <output_port name="twist_stamped" type="std::shared_ptr&lt;geometry_msgs::TwistStamped_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+            <input_port name="angular_velocity" type="Vector3D"/>
+            <input_port name="linear_velocity" type="Vector3D"/>
+            <input_port name="frame_id" type="std::string"/>
+        </Action>
+        <Action ID="GeometryMsgsVector3Stamped">
+            <output_port name="vector3_stamped" type="std::shared_ptr&lt;geometry_msgs::Vector3Stamped_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+            <input_port name="vector" type="Vector3D"/>
+            <input_port name="frame_id" type="std::string"/>
+        </Action>
+        <Action ID="GetMTCRawStage">
+            <output_port name="raw_stage" type="moveit::task_constructor::Stage*">MTC stage raw pointer</output_port>
+            <input_port name="stage" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;">MTC stage</input_port>
+        </Action>
+        <Action ID="InitializeMTCTask">
+            <output_port name="task" type="std::shared_ptr&lt;moveit::task_constructor::Task&gt;" default="{mtc_task}">MoveIt Task Constructor task.</output_port>
+        </Action>
+        <Action ID="MoveItMsgsCollisionObjectBox">
+            <input_port name="height" type="double" default="1.0">Box's size along Z axis (m)</input_port>
+            <input_port name="length" type="double" default="1.0">Box's size along X axis (m)</input_port>
+            <input_port name="object_id" type="std::string"/>
+            <input_port name="frame_id" type="std::string"/>
+            <output_port name="collision_object" type="std::shared_ptr&lt;moveit_msgs::CollisionObject_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+            <input_port name="width" type="double" default="1.0">Box's size along Y axis (m)</input_port>
+            <input_port name="pose" type="std::shared_ptr&lt;geometry_msgs::Pose_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+        </Action>
+        <Action ID="MoveItMsgsCollisionObjectCylinder">
+            <input_port name="height" type="double" default="1.0">cylinder height (m)</input_port>
+            <input_port name="object_id" type="std::string"/>
+            <input_port name="frame_id" type="std::string"/>
+            <output_port name="collision_object" type="std::shared_ptr&lt;moveit_msgs::CollisionObject_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+            <input_port name="radius" type="double" default="1.0">cylinder radius (m)</input_port>
+            <input_port name="pose" type="std::shared_ptr&lt;geometry_msgs::Pose_&lt;std::allocator&lt;void&gt; &gt; &gt;"/>
+        </Action>
+        <Action ID="MoveMTCContainerToContainer">
+            <inout_port name="parent" type="std::shared_ptr&lt;moveit::task_constructor::ContainerBase&gt;"/>
+            <input_port name="child" type="std::shared_ptr&lt;moveit::task_constructor::ContainerBase&gt;"/>
+        </Action>
+        <Action ID="MoveMTCContainerToTask">
+            <inout_port name="parent" type="std::shared_ptr&lt;moveit::task_constructor::Task&gt;"/>
+            <input_port name="child" type="std::shared_ptr&lt;moveit::task_constructor::ContainerBase&gt;"/>
+        </Action>
+        <Action ID="MoveMTCStageToContainer">
+            <inout_port name="parent" type="std::shared_ptr&lt;moveit::task_constructor::ContainerBase&gt;"/>
+            <input_port name="child" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;"/>
+        </Action>
+        <Action ID="MoveMTCStageToTask">
+            <inout_port name="parent" type="std::shared_ptr&lt;moveit::task_constructor::Task&gt;"/>
+            <input_port name="child" type="std::shared_ptr&lt;moveit::task_constructor::Stage&gt;"/>
+        </Action>
+        <Action ID="PlanMTCTask">
+            <inout_port name="task" type="std::shared_ptr&lt;moveit::task_constructor::Task&gt;"/>
+            <input_port name="max_solutions" type="unsigned long"/>
+        </Action>
+    </TreeNodesModel>
+</root>
diff --git a/examples/bt_allow_collisions.cpp b/examples/bt_allow_collisions.cpp
index d52ab61..076c2e2 100644
--- a/examples/bt_allow_collisions.cpp
+++ b/examples/bt_allow_collisions.cpp
@@ -2,7 +2,7 @@
 
 #include <behaviortree_mtc/initialize_mtc_task.h>
 #include <behaviortree_mtc/create_mtc_current_state.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
 #include <behaviortree_mtc/plan_mtc_task.h>
 #include <behaviortree_mtc/moveit_msgs.h>
 #include <behaviortree_mtc/geometry_msgs.h>
@@ -62,23 +62,23 @@ static const char* xml_text = R"(
                                                 collision_object="{cylinder}"  />
             <AddObjectToPlanningScene  planning_scene_interface="{psi}" 
                                        collision_object="{cylinder}"/> 
-            <InitializeMTCTask        task="{mtc_task}" container="{task_container}" />
+            <InitializeMTCTask        task="{mtc_task}" />
             <CreateMTCPipelinePlanner pipeline_id="ompl"
                                  planner_id="RRTConnect"
                                  solver="{rrt_connect}"
                                  goal_joint_tolerance="1e-5" />
             <CreateMTCCurrentState    stage="{current_state}" />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{current_state}" />
+            <MoveMTCStageToTask  child="{current_state}" parent="{mtc_task}" />
             <AllowCollisionsJointModelGroup stage_name="allow collisions -> hand,object"
                                             stage="{allow_collisions}"
                                             objects="{object_name}"
                                             jmg_name="{hand_group_name}"
                                             task="{mtc_task}" />
-            <MoveMTCStageToContainer  container="{task_container}"  stage="{allow_collisions}" />
+            <MoveMTCStageToTask  child="{allow_collisions}" parent="{mtc_task}" />
             <ForbidAllCollisions  stage_name="forbid collisions -> hand,object"
                                   stage="{forbid_collisions}"
                                   objects="{object_name}" />
-            <MoveMTCStageToContainer  container="{task_container}"  stage="{forbid_collisions}" />
+            <MoveMTCStageToTask  child="{forbid_collisions}" parent="{mtc_task}" />
             <PlanMTCTask              task="{mtc_task}" max_solutions="5" />
         </Sequence>
      </BehaviorTree>
@@ -95,19 +95,18 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
-
   factory.registerNodeType<GeometryMsgsPose>("GeometryMsgsPose");
   factory.registerNodeType<MoveItMsgsCollisionObjectCylinder>("MoveItMsgsCollisionObjectCylinder");
   factory.registerNodeType<MoveItMsgsCollisionObjectBox>("MoveItMsgsCollisionObjectBox");
   factory.registerNodeType<CreatePlanningSceneInterface>("CreatePlanningSceneInterface");
   factory.registerNodeType<AddObjectToPlanningScene>("AddObjectToPlanningScene");
-  factory.registerNodeType<MoveMTCStageToContainer>("MoveMTCStageToContainer");
   factory.registerNodeType<InitializeMTCTask>("InitializeMTCTask", BT::RosNodeParams(node));
   factory.registerNodeType<CreateMTCCurrentState>("CreateMTCCurrentState");
   factory.registerNodeType<CreateMTCPipelinePlanner>("CreateMTCPipelinePlanner", BT::RosNodeParams(node));
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
   factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
   factory.registerNodeType<AllowCollisionPairs>("AllowCollisionPairs");
   factory.registerNodeType<ForbidAllCollisions>("ForbidAllCollisions");
@@ -127,12 +126,16 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::cout << "======================" << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
-
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
+
+  // Start ticking the Tree
   std::cout << "Starting Behavior Tree" << std::endl;
   std::cout << "======================" << std::endl;
 
diff --git a/examples/bt_compute_ik.cpp b/examples/bt_compute_ik.cpp
index 0f75809..4f90af2 100644
--- a/examples/bt_compute_ik.cpp
+++ b/examples/bt_compute_ik.cpp
@@ -2,8 +2,7 @@
 
 #include <behaviortree_mtc/initialize_mtc_task.h>
 #include <behaviortree_mtc/create_mtc_current_state.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
-#include <behaviortree_mtc/move_mtc_container_to_parent_container.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
 #include <behaviortree_mtc/create_mtc_serial_container.h>
 #include <behaviortree_mtc/plan_mtc_task.h>
 #include <behaviortree_mtc/moveit_msgs.h>
@@ -69,33 +68,33 @@ static const char* xml_text = R"(
                                                 collision_object="{cylinder}"  />
             <AddObjectToPlanningScene  planning_scene_interface="{psi}" 
                          collision_object="{cylinder}"/> 
-            <InitializeMTCTask        task="{mtc_task}" container="{task_container}" />
+            <InitializeMTCTask        task="{mtc_task}" />
             <CreateMTCPipelinePlanner pipeline_id="ompl"
                                  planner_id="RRTConnect"
                                  solver="{rrt_connect}"
                                  goal_joint_tolerance="1e-5" />
             <CreateMTCCurrentState    stage="{current_state}" />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{current_state}" />
+            <MoveMTCStageToTask  child="{current_state}" parent="{mtc_task}" />
             <GeometryMsgsPoseStamped  frame_id="{hand_frame}" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}"/>
             <CreateMTCMoveToNamedJointPose name="move to -> close_hand motion"
                                       group="{hand_group_name}"
                                       solver="{rrt_connect}"
                                       goal="close"
                                       stage="{stage_move_to_close_hand}" />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{stage_move_to_close_hand}" />
+            <MoveMTCStageToTask  child="{stage_move_to_close_hand}" parent="{mtc_task}" />
             <CreateMTCMoveToNamedJointPose name="move to -> open_hand motion"
                                       group="{hand_group_name}"
                                       solver="{rrt_connect}"
                                       goal="open"
                                       stage="{stage_move_to_open_hand}" />
-            <GetMTCRawStage  stage="{stage_move_to_open_hand}" raw_stage="{raw_stage}"  />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{stage_move_to_open_hand}" />
+            <GetMTCRawStage  stage="{stage_move_to_open_hand}" raw_stage="{raw_stage}" />
+            <MoveMTCStageToTask  child="{stage_move_to_open_hand}" parent="{mtc_task}" />
             <CreateMTCConnect  stage_name="MoveToPick"
                                timeout="5.0"
                                group="{arm_group_name}"
                                planner="{rrt_connect}"
                                stage="{connect}" />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{connect}" />  
+            <MoveMTCStageToTask  child="{connect}" parent="{mtc_task}" />
             <CreateMTCSerialContainer  container_name="pick object"
                                        container="{pick_object}" />
             <GeometryMsgsVector3Stamped  frame_id="{hand_frame}" vector="0,0,1" vector3_stamped="{tcp_translate}"/>
@@ -107,7 +106,7 @@ static const char* xml_text = R"(
                                              direction="{tcp_translate}"
                                              min_distance="0.1"
                                              max_distance="0.15" />
-            <MoveMTCStageToContainer  container="{pick_object}" stage="{approach_object}" />    
+            <MoveMTCStageToContainer  child="{approach_object}" parent="{pick_object}" />
             <CreateMTCGenerateGraspPose  stage_name="generate_grasp_pose"
                                          eef="{eef}"
                                          object="{object_name}"
@@ -127,8 +126,8 @@ static const char* xml_text = R"(
             <ConfigureInitFromMTCProperties  stage="{grasp_pose_IK}"
                                              property_names="target_pose"
                                              source_flag="INTERFACE" />
-            <MoveMTCStageToContainer  container="{pick_object}" stage="{grasp_pose_IK}" />
-            <MoveMTCContainerToParentContainer parent_container="{task_container}"  child_container="{pick_object}" />
+            <MoveMTCStageToContainer child="{grasp_pose_IK}" parent="{pick_object}" />
+            <MoveMTCContainerToTask  child="{pick_object}" parent="{mtc_task}" />
             <PlanMTCTask              task="{mtc_task}" max_solutions="5" />
         </Sequence>
      </BehaviorTree>
@@ -144,10 +143,9 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
-
   factory.registerNodeType<GeometryMsgsPose>("GeometryMsgsPose");
   factory.registerNodeType<GeometryMsgsPoseStamped>("GeometryMsgsPoseStamped");
   factory.registerNodeType<GeometryMsgsVector3Stamped>("GeometryMsgsVector3Stamped");
@@ -156,7 +154,6 @@ int main(int argc, char** argv)
   factory.registerNodeType<CreatePlanningSceneInterface>("CreatePlanningSceneInterface");
   factory.registerNodeType<AddObjectToPlanningScene>("AddObjectToPlanningScene");
   factory.registerNodeType<CreateMTCGenerateGraspPose>("CreateMTCGenerateGraspPose");
-  factory.registerNodeType<MoveMTCStageToContainer>("MoveMTCStageToContainer");
   factory.registerNodeType<InitializeMTCTask>("InitializeMTCTask", BT::RosNodeParams(node));
   factory.registerNodeType<CreateMTCCurrentState>("CreateMTCCurrentState");
   factory.registerNodeType<CreateMTCPipelinePlanner>("CreateMTCPipelinePlanner", BT::RosNodeParams(node));
@@ -164,7 +161,9 @@ int main(int argc, char** argv)
   factory.registerNodeType<GetMTCRawStage>("GetMTCRawStage");
   factory.registerNodeType<CreateMTCMoveToNamedJointPose>("CreateMTCMoveToNamedJointPose");
   factory.registerNodeType<CreateMTCConnect>("CreateMTCConnect");
-  factory.registerNodeType<MoveMTCContainerToParentContainer>("MoveMTCContainerToParentContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::ContainerBase>>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::ContainerBase, moveit::task_constructor::Task>>("MoveMTCContainerToTask");
   factory.registerNodeType<CreateMTCSerialContainer>("CreateMTCSerialContainer");
   factory.registerNodeType<CreateMTCMoveRelativeTranslate>("CreateMTCMoveRelativeTranslate");
   factory.registerNodeType<CreateMTCComputeIK>("CreateMTCComputeIK");
@@ -185,12 +184,16 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::cout << "======================" << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
-
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
+
+  // Start ticking the Tree
   std::cout << "Starting Behavior Tree" << std::endl;
   std::cout << "======================" << std::endl;
 
diff --git a/examples/bt_create_collision_object.cpp b/examples/bt_create_collision_object.cpp
index 46a7cb4..5cb8fb5 100644
--- a/examples/bt_create_collision_object.cpp
+++ b/examples/bt_create_collision_object.cpp
@@ -1,9 +1,5 @@
 #include <rclcpp/rclcpp.hpp>
 
-#include <behaviortree_mtc/initialize_mtc_task.h>
-#include <behaviortree_mtc/create_mtc_current_state.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
-#include <behaviortree_mtc/plan_mtc_task.h>
 #include <behaviortree_mtc/moveit_msgs.h>
 #include <behaviortree_mtc/geometry_msgs.h>
 #include <behaviortree_mtc/create_planning_scene_interface.h>
@@ -65,10 +61,9 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
-
   factory.registerNodeType<GeometryMsgsPose>("GeometryMsgsPose");
   factory.registerNodeType<MoveItMsgsCollisionObjectCylinder>("MoveItMsgsCollisionObjectCylinder");
   factory.registerNodeType<MoveItMsgsCollisionObjectBox>("MoveItMsgsCollisionObjectBox");
@@ -89,12 +84,16 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::cout << "======================" << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
-
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
+
+  // Start ticking the Tree
   std::cout << "Starting Behavior Tree" << std::endl;
   std::cout << "======================" << std::endl;
 
diff --git a/examples/bt_demo.cpp b/examples/bt_demo.cpp
index e21ae25..f648804 100644
--- a/examples/bt_demo.cpp
+++ b/examples/bt_demo.cpp
@@ -1,8 +1,8 @@
 #include <rclcpp/rclcpp.hpp>
 
-#include <behaviortree_mtc/create_mtc_current_state.h>
 #include <behaviortree_mtc/initialize_mtc_task.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
+#include <behaviortree_mtc/create_mtc_current_state.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
 #include <behaviortree_mtc/plan_mtc_task.h>
 
 #include "behaviortree_cpp/bt_factory.h"
@@ -19,9 +19,9 @@ static const char* xml_text = R"(
 
      <BehaviorTree ID="MainTree">
         <Sequence name="root">
-            <InitializeMTCTask        task="{mtc_task}" container="{container}" />
+            <InitializeMTCTask        task="{mtc_task}" />
             <CreateMTCCurrentState    stage="{stage}" />
-            <MoveMTCStageToContainer  container="{container}" stage="{stage}" />
+            <MoveMTCStageToTask       child="{stage}" parent="{mtc_task}" />
             <PlanMTCTask              task="{mtc_task}" max_solutions="5" />
         </Sequence>
      </BehaviorTree>
@@ -37,13 +37,13 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
 
   factory.registerNodeType<InitializeMTCTask>("InitializeMTCTask", BT::RosNodeParams(node));
   factory.registerNodeType<CreateMTCCurrentState>("CreateMTCCurrentState");
-  factory.registerNodeType<MoveMTCStageToContainer>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
   factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
 
   auto tree = factory.createTreeFromText(xml_text);
@@ -60,11 +60,14 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::cout << "======================" << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
 
   NodeStatus status = NodeStatus::IDLE;
 
diff --git a/examples/bt_generate_place_pose.cpp b/examples/bt_generate_place_pose.cpp
index 3df58ce..8ff65c7 100644
--- a/examples/bt_generate_place_pose.cpp
+++ b/examples/bt_generate_place_pose.cpp
@@ -2,8 +2,7 @@
 
 #include <behaviortree_mtc/initialize_mtc_task.h>
 #include <behaviortree_mtc/create_mtc_current_state.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
-#include <behaviortree_mtc/move_mtc_container_to_parent_container.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
 #include <behaviortree_mtc/create_mtc_serial_container.h>
 #include <behaviortree_mtc/plan_mtc_task.h>
 #include <behaviortree_mtc/moveit_msgs.h>
@@ -72,7 +71,7 @@ static const char* xml_text = R"(
                                                 collision_object="{cylinder}"  />
             <AddObjectToPlanningScene  planning_scene_interface="{psi}" 
                          collision_object="{cylinder}"/> 
-            <InitializeMTCTask        task="{mtc_task}" container="{task_container}" />
+            <InitializeMTCTask        task="{mtc_task}" />
             <CreateMTCPipelinePlanner pipeline_id="ompl"
                                  planner_id="RRTConnect"
                                  solver="{rrt_connect}"
@@ -81,7 +80,7 @@ static const char* xml_text = R"(
                                      max_velocity_scaling_factor="1.0"
                                      max_acceleration_scaling_factor="1.0" />
             <CreateMTCCurrentState    stage="{current_state}" />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{current_state}" />
+            <MoveMTCStageToTask child="{current_state}" parent="{mtc_task}"  />
             <GeometryMsgsPoseStamped  frame_id="{hand_frame}" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}"/>
             <CreateMTCMoveToNamedJointPose name="move to -> open_hand motion"
                                       group="{hand_group_name}"
@@ -89,13 +88,13 @@ static const char* xml_text = R"(
                                       goal="open"
                                       stage="{stage_move_to_open_hand}" />
             <GetMTCRawStage  stage="{stage_move_to_open_hand}" raw_stage="{raw_stage}"  />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{stage_move_to_open_hand}" />
+            <MoveMTCStageToTask child="{stage_move_to_open_hand}" parent="{mtc_task}"  />
             <CreateMTCConnect  stage_name="MoveToPick"
                                timeout="5.0"
                                group="{arm_group_name}"
                                planner="{rrt_connect}"
                                stage="{connect}" />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{connect}" />  
+            <MoveMTCStageToTask child="{connect}" parent="{mtc_task}"  />
             <CreateMTCSerialContainer  container_name="pick object"
                                        container="{pick_object}" />
             <GeometryMsgsVector3Stamped  frame_id="{hand_frame}" vector="0,0,1" vector3_stamped="{tcp_translate}"/>
@@ -107,7 +106,7 @@ static const char* xml_text = R"(
                                              direction="{tcp_translate}"
                                              min_distance="0.1"
                                              max_distance="0.15" />
-            <MoveMTCStageToContainer  container="{pick_object}" stage="{approach_object}" />    
+            <MoveMTCStageToContainer child="{approach_object}" parent="{pick_object}" />
             <CreateMTCGenerateGraspPose  stage_name="generate_grasp_pose"
                                          eef="{eef}"
                                          object="{object_name}"
@@ -127,31 +126,31 @@ static const char* xml_text = R"(
             <ConfigureInitFromMTCProperties  stage="{grasp_pose_IK}"
                                              property_names="target_pose"
                                              source_flag="INTERFACE" />
-            <MoveMTCStageToContainer  container="{pick_object}" stage="{grasp_pose_IK}" />
+            <MoveMTCStageToContainer child="{grasp_pose_IK}" parent="{pick_object}" />
             <AllowCollisionsJointModelGroup stage_name="allow collisions -> hand,object"
                                             stage="{allow_collisions}"
                                             objects="{object_name}"
                                             jmg_name="{hand_group_name}"
                                             task="{mtc_task}" />
-            <MoveMTCStageToContainer  container="{pick_object}"  stage="{allow_collisions}" />
+            <MoveMTCStageToContainer child="{allow_collisions}" parent="{pick_object}" />
             <CreateMTCMoveToNamedJointPose name="close hand"
-                                          group="{hand_group_name}"         
-                                          solver="{rrt_connect}"
+                                           group="{hand_group_name}"
+                                           solver="{rrt_connect}"
                                            goal="close"
-                                            stage="{stage_move_to_close_hand}" />
-             <MoveMTCStageToContainer  container="{pick_object}" stage="{stage_move_to_close_hand}" />
-             <CreateMTCModifyPlanningSceneAttachObjects  stage_name="attach object"
+                                           stage="{stage_move_to_close_hand}" />
+            <MoveMTCStageToContainer child="{stage_move_to_close_hand}" parent="{pick_object}" />
+            <CreateMTCModifyPlanningSceneAttachObjects  stage_name="attach object"
                                                          stage="{attach_object}"
                                                          object_names="{object_name}"
                                                          link_name="{hand_frame}" />
-            <MoveMTCStageToContainer  container="{pick_object}"  stage="{attach_object}" />
+            <MoveMTCStageToContainer child="{attach_object}" parent="{pick_object}" />
             <AllowCollisionPairs  stage_name="allow collisions -> object,support"
                                   stage="{allow_collisions_table}"
                                   first="{object_name}"
                                   second="table" /> 
-            <MoveMTCStageToContainer  container="{pick_object}"  stage="{allow_collisions_table}" />
+            <MoveMTCStageToContainer child="{allow_collisions_table}" parent="{pick_object}" />
             <GeometryMsgsVector3Stamped  frame_id="{reference_frame}" vector="0,0,1" vector3_stamped="{tcp_translate}"/>
-          <CreateMTCMoveRelativeTranslate  stage_name="lift object"
+            <CreateMTCMoveRelativeTranslate  stage_name="lift object"
                                            stage="{lift_object}"
                                            group="{arm_group_name}"
                                            solver="{cartesian}"
@@ -159,24 +158,24 @@ static const char* xml_text = R"(
                                            direction="{tcp_translate}"
                                            min_distance="0.01"
                                            max_distance="0.1" />
-            <MoveMTCStageToContainer  container="{pick_object}" stage="{lift_object}" />
+            <MoveMTCStageToContainer child="{lift_object}" parent="{pick_object}" />
             <ForbidCollisionPairs  stage_name="forbid collisions -> object,support"
                                    stage="{forbid_collisions_table}"
                                    first="{object_name}"
                                    second="table" />
-             <GetMTCRawStage  stage="{forbid_collisions_table}" raw_stage="{raw_forbid_collisions_table}"  /> 
-             <MoveMTCStageToContainer  container="{pick_object}"  stage="{forbid_collisions_table}" />
-            <MoveMTCContainerToParentContainer parent_container="{task_container}"  child_container="{pick_object}" />
-             <CreateMTCConnect  stage_name="Move To Place"
+            <GetMTCRawStage  stage="{forbid_collisions_table}" raw_stage="{raw_forbid_collisions_table}"  />
+            <MoveMTCStageToContainer child="{forbid_collisions_table}" parent="{pick_object}" />
+            <MoveMTCContainerToTask child="{pick_object}" parent="{mtc_task}" />
+            <CreateMTCConnect  stage_name="Move To Place"
                                 timeout="5.0"
                                 group="{arm_group_name}"
                                 planner="{rrt_connect}"
                                 stage="{connectPlace}" />
-             <MoveMTCStageToContainer  container="{task_container}" stage="{connectPlace}" />
-             <CreateMTCSerialContainer  container_name="place object"
-                                        container="{place_object}" />
-             <GeometryMsgsVector3Stamped  frame_id="{reference_frame}" vector="0,0,-1" vector3_stamped="{tcp_translate2}"/>
-             <CreateMTCMoveRelativeTranslate  stage_name="lower object"
+            <MoveMTCStageToTask child="{connectPlace}" parent="{mtc_task}"  />
+            <CreateMTCSerialContainer  container_name="place object"
+                                       container="{place_object}" />
+            <GeometryMsgsVector3Stamped  frame_id="{reference_frame}" vector="0,0,-1" vector3_stamped="{tcp_translate2}"/>
+            <CreateMTCMoveRelativeTranslate  stage_name="lower object"
                                               stage="{lower_object}"
                                               group="{arm_group_name}"
                                               solver="{cartesian}"
@@ -184,7 +183,7 @@ static const char* xml_text = R"(
                                               direction="{tcp_translate2}"
                                               min_distance="0.03"
                                               max_distance="0.13" />
-            <MoveMTCStageToContainer  container="{place_object}" stage="{lower_object}" />
+            <MoveMTCStageToContainer child="{lower_object}"  parent="{place_object}" />
             <GeometryMsgsPoseStamped  frame_id="world" position="0.6,-0.15,0.1251" quaternion="1,0,0,0" pose_stamped="{place_pose}" />
             <CreateMTCGeneratePlacePose  stage="{generate_place_pose}"
                                          stage_name="generate place pose"
@@ -201,8 +200,8 @@ static const char* xml_text = R"(
             <ConfigureInitFromMTCProperties  stage="{place_pose_IK}"
                                              property_names="target_pose"
                                              source_flag="INTERFACE" />
-            <MoveMTCStageToContainer  container="{place_object}" stage="{place_pose_IK}" />
-            <MoveMTCContainerToParentContainer  parent_container="{task_container}"  child_container="{place_object}" />
+            <MoveMTCStageToContainer child="{place_pose_IK}"  parent="{place_object}" />
+            <MoveMTCContainerToTask child="{place_object}" parent="{mtc_task}" />
             <PlanMTCTask              task="{mtc_task}" max_solutions="5" />
         </Sequence>
      </BehaviorTree>
@@ -218,10 +217,9 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
-
   factory.registerNodeType<GeometryMsgsPose>("GeometryMsgsPose");
   factory.registerNodeType<GeometryMsgsPoseStamped>("GeometryMsgsPoseStamped");
   factory.registerNodeType<GeometryMsgsVector3Stamped>("GeometryMsgsVector3Stamped");
@@ -230,7 +228,6 @@ int main(int argc, char** argv)
   factory.registerNodeType<CreatePlanningSceneInterface>("CreatePlanningSceneInterface");
   factory.registerNodeType<AddObjectToPlanningScene>("AddObjectToPlanningScene");
   factory.registerNodeType<CreateMTCGenerateGraspPose>("CreateMTCGenerateGraspPose");
-  factory.registerNodeType<MoveMTCStageToContainer>("MoveMTCStageToContainer");
   factory.registerNodeType<InitializeMTCTask>("InitializeMTCTask", BT::RosNodeParams(node));
   factory.registerNodeType<CreateMTCCurrentState>("CreateMTCCurrentState");
   factory.registerNodeType<CreateMTCPipelinePlanner>("CreateMTCPipelinePlanner", BT::RosNodeParams(node));
@@ -238,7 +235,9 @@ int main(int argc, char** argv)
   factory.registerNodeType<GetMTCRawStage>("GetMTCRawStage");
   factory.registerNodeType<CreateMTCMoveToNamedJointPose>("CreateMTCMoveToNamedJointPose");
   factory.registerNodeType<CreateMTCConnect>("CreateMTCConnect");
-  factory.registerNodeType<MoveMTCContainerToParentContainer>("MoveMTCContainerToParentContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::ContainerBase>>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::ContainerBase, moveit::task_constructor::Task>>("MoveMTCContainerToTask");
   factory.registerNodeType<CreateMTCSerialContainer>("CreateMTCSerialContainer");
   factory.registerNodeType<CreateMTCMoveRelativeTranslate>("CreateMTCMoveRelativeTranslate");
   factory.registerNodeType<CreateMTCComputeIK>("CreateMTCComputeIK");
@@ -266,12 +265,16 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::cout << "======================" << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
 
+  // Start ticking the Tree
   std::cout << "Starting Behavior Tree" << std::endl;
   std::cout << "======================" << std::endl;
 
@@ -297,70 +300,3 @@ int main(int argc, char** argv)
 
   return 0;
 }
-
-/**
- * 
-            <CreateMTCModifyPlanningSceneAttachObjects  stage_name="attach object"
-                                                        stage="{attach_object}"
-                                                        object_names="{object_name}"
-                                                        link_name="{hand_frame}" />
-            <MoveMTCStageToContainer  container="{pick_object}"  stage="{attach_object}" />
-            <AllowCollisionPairs  stage_name="allow collisions -> object,support"
-                                  stage="{allow_collisions_table}"
-                                  first="{object_name}"
-                                  second="table" /> 
-            <MoveMTCStageToContainer  container="{pick_object}"  stage="{allow_collisions_table}" />
-            <GeometryMsgsVector3Stamped  frame_id="{reference_frame}" vector="0,0,1" vector3_stamped="{tcp_translate}"/>
-            <CreateMTCMoveRelativeTranslate  stage_name="lift object"
-                                             stage="{lift_object}"
-                                             group="{arm_group_name}"
-                                             solver="{cartesian}"
-                                             ik_frame="{ik_frame}"
-                                             direction="{tcp_translate}"
-                                             min_distance="0.01"
-                                             max_distance="0.1" />
-            <MoveMTCStageToContainer  container="{pick_object}" stage="{lift_object}" />
-            <ForbidCollisionPairs  stage_name="forbid collisions -> object,support"
-                                          stage="{forbid_collisions_table}"
-                                          first="{object_name}"
-                                          second="table" />
-            <GetMTCRawStage  stage="{forbid_collisions_table}" raw_stage="{raw_forbid_collisions_table}}"  /> 
-            <MoveMTCStageToContainer  container="{pick_object}"  stage="{forbid_collisions_table}" />    
-            <MoveMTCContainerToParentContainer parent_container="{task_container}"  child_container="{pick_object}" />
-            <CreateMTCConnect  stage_name="Move To Place"
-                               timeout="5.0"
-                               group="{arm_group_name}"
-                               planner="{rrt_connect}"
-                               stage="{connectPlace}" />
-            <MoveMTCStageToContainer  container="{task_container}" stage="{connectPlace}" />
-            <CreateMTCSerialContainer  container_name="place object"
-                                       serial_container="{place_object}" />
-            <GeometryMsgsVector3Stamped  frame_id="{reference_frame}" vector="0,0,-1" vector3_stamped="{tcp_translate}"/>
-            <CreateMTCMoveRelativeTranslate  stage_name="lower object"
-                                             stage="{lower_object}"
-                                             group="{arm_group_name}"
-                                             solver="{cartesian}"
-                                             ik_frame="{ik_frame}"
-                                             direction="{tcp_translate}"
-                                             min_distance="0.03"
-                                             max_distance="0.13" />
-            <MoveMTCStageToContainer  container="{place_object}" stage="{lower_object}" />
- */
-
-//
-
-//
-
-//
-//             <CreateMTCSerialContainer  container_name="place object"
-//                                        serial_container="{place_object}" />
-//             <GeometryMsgsVector3Stamped  frame_id="{reference_frame}" vector="0,0,-1" vector3_stamped="{tcp_translate}"/>
-//             <CreateMTCMoveRelativeTranslate  stage_name="lower object"
-//                                              stage="{lower_object}"
-//                                              group="{arm_group_name}"
-//                                              solver="{cartesian}"
-//                                              ik_frame="{ik_frame}"
-//                                              direction="{tcp_translate}"
-//                                              min_distance="0.03"
-//                                              max_distance="0.13" />
-//             <MoveMTCStageToContainer  container="{place_object}" stage="{lower_object}" />
diff --git a/examples/bt_joint_interpolation_solver.cpp b/examples/bt_joint_interpolation_solver.cpp
index a5928cf..a364e64 100644
--- a/examples/bt_joint_interpolation_solver.cpp
+++ b/examples/bt_joint_interpolation_solver.cpp
@@ -3,7 +3,7 @@
 #include <behaviortree_mtc/initialize_mtc_task.h>
 #include <behaviortree_mtc/create_mtc_current_state.h>
 #include <behaviortree_mtc/create_mtc_move_relative.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
 #include <behaviortree_mtc/create_mtc_joint_interpolation.h>
 #include <behaviortree_mtc/plan_mtc_task.h>
 
@@ -23,10 +23,10 @@ static const char* xml_text = R"(
 
    <BehaviorTree ID="MainTree">
      <Sequence name="root">
-       <InitializeMTCTask        task="{mtc_task}" container="{container}" />
+       <InitializeMTCTask        task="{mtc_task}" />
        <CreateMTCJointInterpolation  solver="{joint_solver}" />
        <CreateMTCCurrentState        stage="{stage}" />
-       <MoveMTCStageToContainer      container="{container}" stage="{stage}" />
+       <MoveMTCStageToTask      child="{stage}" parent="{mtc_task}" />
        <!-- Joint Motion -> return end joint to default value -->
        <GeometryMsgsPoseStamped  frame_id="panda_link8" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}"/>
        <CreateMTCMoveRelativeJoint name="move relative -> joint motion"
@@ -35,8 +35,8 @@ static const char* xml_text = R"(
                                    ik_frame="{ik_frame}"
                                    direction="panda_joint7:-1.57079632679"
                                    stage="{stage_move_rel_joint}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage_move_rel_joint}" />
-       <PlanMTCTask              task="{mtc_task}" max_solutions="5" />
+       <MoveMTCStageToTask         child="{stage_move_rel_joint}" parent="{mtc_task}" />
+       <PlanMTCTask                task="{mtc_task}" max_solutions="5" />
      </Sequence>
    </BehaviorTree>
 
@@ -51,7 +51,7 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
 
@@ -59,7 +59,7 @@ int main(int argc, char** argv)
   factory.registerNodeType<CreateMTCJointInterpolation>("CreateMTCJointInterpolation");
   factory.registerNodeType<CreateMTCCurrentState>("CreateMTCCurrentState");
   factory.registerNodeType<CreateMTCMoveRelativeJoint>("CreateMTCMoveRelativeJoint");
-  factory.registerNodeType<MoveMTCStageToContainer>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
   factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
 
   factory.registerNodeType<GeometryMsgsPoseStamped>("GeometryMsgsPoseStamped");
@@ -78,11 +78,16 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
-
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
+
+  // Start ticking the Tree
   std::cout << "Starting Behavior Tree" << std::endl;
   std::cout << "======================" << std::endl;
 
diff --git a/examples/bt_move_relative.cpp b/examples/bt_move_relative.cpp
index 76b3d35..bab3807 100644
--- a/examples/bt_move_relative.cpp
+++ b/examples/bt_move_relative.cpp
@@ -4,7 +4,7 @@
 #include <behaviortree_mtc/create_mtc_current_state.h>
 #include <behaviortree_mtc/create_mtc_move_relative.h>
 #include <behaviortree_mtc/create_mtc_pipeline_planner.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
 #include <behaviortree_mtc/plan_mtc_task.h>
 
 #include <behaviortree_mtc/geometry_msgs.h>
@@ -23,12 +23,12 @@ static const char* xml_text = R"(
 
    <BehaviorTree ID="MainTree">
      <Sequence name="root">
-       <InitializeMTCTask        task="{mtc_task}" container="{container}" />
+       <InitializeMTCTask        task="{mtc_task}" />
        <CreateMTCPipelinePlanner pipeline_id="ompl"
                                  planner_id="RRTConnect"
                                  solver="{rrt_connect}" />
        <CreateMTCCurrentState    stage="{stage}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage}" />
+       <MoveMTCStageToTask  child="{stage}" parent="{mtc_task}" />
 
        <!-- Translate Motion -> 200mm towards x axis wrt. panda_link8 -->
        <GeometryMsgsPoseStamped  frame_id="panda_link8" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}"/>
@@ -39,7 +39,7 @@ static const char* xml_text = R"(
                                        ik_frame="{ik_frame}"
                                        direction="{tcp_translate}"
                                        stage="{stage_move_rel_translate}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage_move_rel_translate}" />
+       <MoveMTCStageToTask  child="{stage_move_rel_translate}" parent="{mtc_task}" />
 
        <!-- Twist Motion -->
        <GeometryMsgsPoseStamped  frame_id="panda_link8" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}"/>
@@ -50,7 +50,7 @@ static const char* xml_text = R"(
                                    ik_frame="{ik_frame}"
                                    direction="{tcp_twist}"
                                    stage="{stage_move_rel_twist}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage_move_rel_twist}" />
+       <MoveMTCStageToTask  child="{stage_move_rel_twist}" parent="{mtc_task}" />
 
        <!-- Joint Motion -> return end joint to default value -->
        <GeometryMsgsPoseStamped  frame_id="panda_link8" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}"/>
@@ -60,7 +60,7 @@ static const char* xml_text = R"(
                                    ik_frame="{ik_frame}"
                                    direction="panda_joint7:-1.57079632679"
                                    stage="{stage_move_rel_joint}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage_move_rel_joint}" />
+       <MoveMTCStageToTask  child="{stage_move_rel_joint}" parent="{mtc_task}" />
 
 
        <PlanMTCTask              task="{mtc_task}" max_solutions="5" />
@@ -78,7 +78,7 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
 
@@ -88,7 +88,7 @@ int main(int argc, char** argv)
   factory.registerNodeType<CreateMTCMoveRelativeTranslate>("CreateMTCMoveRelativeTranslate");
   factory.registerNodeType<CreateMTCMoveRelativeTwist>("CreateMTCMoveRelativeTwist");
   factory.registerNodeType<CreateMTCMoveRelativeJoint>("CreateMTCMoveRelativeJoint");
-  factory.registerNodeType<MoveMTCStageToContainer>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
   factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
 
   factory.registerNodeType<GeometryMsgsPoseStamped>("GeometryMsgsPoseStamped");
@@ -109,11 +109,16 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
-
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
+
+  // Start ticking the Tree
   std::cout << "Starting Behavior Tree" << std::endl;
   std::cout << "======================" << std::endl;
 
diff --git a/examples/bt_move_to.cpp b/examples/bt_move_to.cpp
index 3617440..d7ce64f 100644
--- a/examples/bt_move_to.cpp
+++ b/examples/bt_move_to.cpp
@@ -4,7 +4,7 @@
 #include <behaviortree_mtc/create_mtc_current_state.h>
 #include <behaviortree_mtc/create_mtc_move_to.h>
 #include <behaviortree_mtc/create_mtc_pipeline_planner.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
 #include <behaviortree_mtc/plan_mtc_task.h>
 
 #include <behaviortree_mtc/geometry_msgs.h>
@@ -23,12 +23,12 @@ static const char* xml_text = R"(
 
    <BehaviorTree ID="MainTree">
      <Sequence name="root">
-       <InitializeMTCTask        task="{mtc_task}" container="{container}" />
+       <InitializeMTCTask        task="{mtc_task}" />
        <CreateMTCPipelinePlanner pipeline_id="ompl"
                                  planner_id="RRTConnect"
                                  solver="{rrt_connect}"/>
        <CreateMTCCurrentState    stage="{stage}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage}" />
+       <MoveMTCStageToTask child="{stage}" parent="{mtc_task}" />
 
        <!-- joint named position motion -->
        <CreateMTCMoveToNamedJointPose name="move to -> close_hand motion"
@@ -36,13 +36,14 @@ static const char* xml_text = R"(
                                       solver="{rrt_connect}"
                                       goal="close"
                                       stage="{stage_move_to_close_hand}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage_move_to_close_hand}" />
+       <MoveMTCStageToTask  parent="{mtc_task}" child="{stage_move_to_close_hand}" />
+
        <CreateMTCMoveToNamedJointPose name="move to -> open_hand motion"
                                       group="hand"
                                       solver="{rrt_connect}"
                                       goal="open"
                                       stage="{stage_move_to_open_hand}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage_move_to_open_hand}" />
+       <MoveMTCStageToTask  child="{stage_move_to_open_hand}" parent="{mtc_task}" />
        
        <!-- joint motion -->
        <CreateMTCMoveToJoint       name="move to -> joint motion"
@@ -50,7 +51,7 @@ static const char* xml_text = R"(
                                    solver="{rrt_connect}"
                                    goal="panda_joint7:-1.57079632679,panda_joint6:3.14"
                                    stage="{stage_move_to_joint}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage_move_to_joint}" />
+       <MoveMTCStageToTask  parent="{mtc_task}" child="{stage_move_to_joint}" />
        
        <!-- cartesian pose motion -->
        <GeometryMsgsPoseStamped frame_id="panda_link8" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}"/>
@@ -61,9 +62,9 @@ static const char* xml_text = R"(
                                 ik_frame="{ik_frame}"
                                 goal="{goal_pose}"
                                 stage="{stage_move_to_pose}" />
-      <MoveMTCStageToContainer  container="{container}" stage="{stage_move_to_pose}" />
+       <MoveMTCStageToTask      child="{stage_move_to_pose}" parent="{mtc_task}" />
       
-      <!-- cartesian point motion -->
+       <!-- cartesian point motion -->
        <GeometryMsgsPointStamped frame_id="panda_link8" point="0,0.05,0" point_stamped="{goal_point}"/>
        <CreateMTCMoveToPoint     name="move to -> cartesian point motion"
                                  group="panda_arm"
@@ -71,7 +72,7 @@ static const char* xml_text = R"(
                                  ik_frame="{ik_frame}"
                                  goal="{goal_point}"
                                  stage="{stage_move_to_point}" />
-      <MoveMTCStageToContainer  container="{container}" stage="{stage_move_to_point}" />
+       <MoveMTCStageToTask  child="{stage_move_to_point}" parent="{mtc_task}" />
        <PlanMTCTask              task="{mtc_task}" max_solutions="5" />
      </Sequence>
    </BehaviorTree>
@@ -87,7 +88,7 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
 
@@ -98,7 +99,7 @@ int main(int argc, char** argv)
   factory.registerNodeType<CreateMTCMoveToJoint>("CreateMTCMoveToJoint");
   factory.registerNodeType<CreateMTCMoveToPose>("CreateMTCMoveToPose");
   factory.registerNodeType<CreateMTCMoveToPoint>("CreateMTCMoveToPoint");
-  factory.registerNodeType<MoveMTCStageToContainer>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
   factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
 
   factory.registerNodeType<GeometryMsgsPoseStamped>("GeometryMsgsPoseStamped");
@@ -118,12 +119,16 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
-
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
+
+  // Start ticking the Tree
   std::cout << "Starting Behavior Tree" << std::endl;
   std::cout << "======================" << std::endl;
 
diff --git a/examples/bt_pick_place.cpp b/examples/bt_pick_place.cpp
new file mode 100644
index 0000000..81ceebc
--- /dev/null
+++ b/examples/bt_pick_place.cpp
@@ -0,0 +1,395 @@
+#include <rclcpp/rclcpp.hpp>
+
+#include <behaviortree_mtc/initialize_mtc_task.h>
+#include <behaviortree_mtc/create_mtc_current_state.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
+#include <behaviortree_mtc/create_mtc_serial_container.h>
+#include <behaviortree_mtc/plan_mtc_task.h>
+#include <behaviortree_mtc/moveit_msgs.h>
+#include <behaviortree_mtc/geometry_msgs.h>
+#include <behaviortree_mtc/create_mtc_pipeline_planner.h>
+#include <behaviortree_mtc/create_planning_scene_interface.h>
+#include <behaviortree_mtc/add_object_to_planning_scene.h>
+#include <behaviortree_mtc/plan_mtc_task.h>
+#include <behaviortree_mtc/create_mtc_generate_grasp_pose.h>
+#include <behaviortree_mtc/get_mtc_raw_stage.h>
+#include <behaviortree_mtc/create_mtc_move_to.h>
+#include <behaviortree_mtc/create_mtc_connect.h>
+#include <behaviortree_mtc/create_mtc_move_relative.h>
+#include <behaviortree_mtc/create_mtc_compute_ik.h>
+#include <behaviortree_mtc/configure_init_from_mtc_properties.h>
+#include <behaviortree_mtc/std_containers.h>
+#include <behaviortree_mtc/create_mtc_cartesian_path.h>
+#include <behaviortree_mtc/create_mtc_modify_planning_scene.h>
+#include <behaviortree_mtc/create_mtc_generate_place_pose.h>
+#include <behaviortree_mtc/expose_mtc_properties.h>
+#include <behaviortree_mtc/set_mtc_properties.h>
+
+#include "behaviortree_cpp/bt_factory.h"
+#include "behaviortree_cpp/loggers/bt_file_logger_v2.h"
+#include "behaviortree_cpp/loggers/groot2_publisher.h"
+
+using namespace BT;
+using namespace BT::MTC;
+
+// clang-format off
+
+static const char* xml_text = R"(
+
+ <root BTCPP_format="4" >
+
+     <BehaviorTree ID="MainTree">
+        <Sequence name="root">
+
+            <!-- Set Parameters -->
+            <Script code="object_name:='object' " />
+            <Script code="table_name:='table' " />
+            <Script code="reference_frame:='world' " />
+            <Script code="eef:='hand' " />
+            <Script code="angle:=3.141592653589793/12 " />
+            <Script code="arm_group_name:='panda_arm'" />
+            <Script code="hand_group_name:='hand'" />
+            <Script code="hand_frame:='panda_link8'" />
+
+            <!-- PlanningSceneInterface -->
+            <CreatePlanningSceneInterface  planning_scene_interface="{psi}" />
+
+            <!-- Create Table -->
+            <GeometryMsgsPose name="box's pose" position="0.5,-0.25,-0.05" quaternion="1,0,0,0" pose="{box_pose}" />
+            <MoveItMsgsCollisionObjectBox object_id="{table_name}" length="0.4" width="0.5" height="0.1" pose="{box_pose}" frame_id="{reference_frame}" collision_object="{box}" />
+            <AddObjectToPlanningScene planning_scene_interface="{psi}" collision_object="{box}" />
+
+            <!-- Create Cylinder -->
+            <GeometryMsgsPose name="cylinder's pose" position="0.5,-0.25,0.125" quaternion="1,0,0,0" pose="{cylinder_pose}" />
+            <MoveItMsgsCollisionObjectCylinder object_id="{object_name}"
+                                               radius="0.02"
+                                               height="0.25"
+                                               pose="{cylinder_pose}"
+                                               frame_id="{reference_frame}"
+                                               collision_object="{cylinder}" />
+            <AddObjectToPlanningScene planning_scene_interface="{psi}" collision_object="{cylinder}" />
+
+            <!-- Create Task -->
+            <InitializeMTCTask task="{mtc_task}" />
+
+            <!-- Add properpties to the Task -->
+            <SetMTCTaskPropertyString  stage="{mtc_task}"  property_name="eef"  property="{eef}" />
+            <SetMTCTaskPropertyString  stage="{mtc_task}"  property_name="group"  property="{arm_group_name}" />
+            <SetMTCTaskPropertyString  stage="{mtc_task}"  property_name="hand"  property="{hand_group_name}" />
+            <SetMTCTaskPropertyString  stage="{mtc_task}"  property_name="hand_grasping_frame"  property="{hand_frame}" />
+            <SetMTCTaskPropertyString  stage="{mtc_task}"  property_name="ik_frame"  property="{hand_frame}" />
+
+            <!-- Create Solvers -->
+            <CreateMTCPipelinePlanner pipeline_id="ompl" planner_id="RRTConnect" solver="{rrt_connect}" goal_joint_tolerance="1e-5" />
+            <CreateMTCCartesianPath solver="{cartesian_planner}" max_velocity_scaling_factor="1.0" max_acceleration_scaling_factor="1.0" />
+
+            <!-- Current State -->
+            <CreateMTCCurrentState stage="{current_state}" />
+            <MoveMTCStageToTask child="{current_state}" parent="{mtc_task}" />
+
+
+            <!-- Open Hand -->
+            <GeometryMsgsPoseStamped  frame_id="{hand_frame}" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}" />
+            <CreateMTCMoveToNamedJointPose name="move to -> open_hand motion"
+                                           group="{hand_group_name}"
+                                           solver="{rrt_connect}"
+                                           goal="open"
+                                           stage="{stage_move_to_open_hand}" />
+            <GetMTCRawStage stage="{stage_move_to_open_hand}" raw_stage="{raw_stage}" />
+            <MoveMTCStageToTask child="{stage_move_to_open_hand}" parent="{mtc_task}" />
+
+
+            <!-- Move to Pick -->
+            <CreateMTCConnect stage_name="MoveToPick"
+                              timeout="5.0"
+                              group="{arm_group_name}"
+                              planner="{rrt_connect}"
+                              stage="{connect}" />
+            <StageConfigureInitFromMTCProperties stage="{connect}" property_names="" source_flag="PARENT" />
+            <MoveMTCStageToTask child="{connect}" parent="{mtc_task}" />
+
+            <!-- Pick Object-->
+            <CreateMTCSerialContainer container_name="pick object" container="{pick_object}" />
+            <ExposeMTCTaskPropertiesToContainer from="{mtc_task}" to="{pick_object}" property_names="group,eef,hand,ik_frame" />
+            <ContainerConfigureInitFromMTCProperties stage="{pick_object}" property_names="group,eef,hand,ik_frame" source_flag="PARENT" />
+
+                <!-- Approach Object -->
+                <GeometryMsgsVector3Stamped frame_id="{hand_frame}" vector="0,0,1" vector3_stamped="{tcp_translate}"/>
+                <CreateMTCMoveRelativeTranslate stage_name="approach object"
+                                                stage="{approach_object}"
+                                                solver="{cartesian_planner}"
+                                                ik_frame="{ik_frame}"
+                                                direction="{tcp_translate}"
+                                                min_distance="0.1"
+                                                max_distance="0.15" />
+                <StageConfigureInitFromMTCProperties stage="{approach_object}" property_names="group" source_flag="PARENT" />
+                <MoveMTCStageToContainer child="{approach_object}" parent="{pick_object}" />
+
+                <!-- Generate Grasp Pose -->
+                <CreateMTCGenerateGraspPose stage_name="generate_grasp_pose"
+                                            object="{object_name}"
+                                            angle_delta="{angle}"
+                                            pregrasp_pose="open"
+                                            monitored_stage="{raw_stage}"
+                                            stage="{generate_pose}" />
+                <StageConfigureInitFromMTCProperties stage="{generate_pose}" property_names="" source_flag="PARENT" />
+                <GeometryMsgsPoseStamped frame_id="{hand_frame}" position="0,0,0.1" quaternion="0.270595,0.653228,-0.270861,0.653228" pose_stamped="{ik_frame2}"/>
+                <CreateMTCComputeIK stage_name="grasp pose IK"
+                                    wrapped_stage="{generate_pose}"
+                                    max_ik_solutions="8"
+                                    min_solution_distance="1.0"
+                                    stage="{grasp_pose_IK}"
+                                    ik_frame="{ik_frame2}"  />
+                <StageConfigureInitFromMTCProperties  stage="{grasp_pose_IK}" property_names="eef,group" source_flag="PARENT" />
+                <StageConfigureInitFromMTCProperties  stage="{grasp_pose_IK}" property_names="target_pose" source_flag="INTERFACE" />
+                <MoveMTCStageToContainer child="{grasp_pose_IK}" parent="{pick_object}" />
+
+                <!-- Allow Collisions (hand object) -->
+                <AllowCollisionsJointModelGroup stage_name="allow collisions -> hand,object"
+                                                            stage="{allow_collisions_object_robot}"
+                                                            objects="{object_name}"
+                                                            jmg_name="{hand_group_name}"
+                                                            task="{mtc_task}" />
+                <MoveMTCStageToContainer child="{allow_collisions_object_robot}" parent="{pick_object}" />
+
+                <!-- Close Hand -->
+                <CreateMTCMoveToNamedJointPose name="close hand"
+                                               group="{hand_group_name}"
+                                               solver="{rrt_connect}"
+                                               goal="close"
+                                               stage="{stage_move_to_close_hand}" />
+                <MoveMTCStageToContainer child="{stage_move_to_close_hand}" parent="{pick_object}" />
+
+                <!-- Attach Object -->
+                <CreateMTCModifyPlanningSceneAttachObjects stage_name="attach object"
+                                                           stage="{attach_object}"
+                                                           object_names="{object_name}"
+                                                           link_name="{hand_frame}" />
+                <MoveMTCStageToContainer child="{attach_object}" parent="{pick_object}" />
+
+                <!-- Allow Collision (object support) -->
+                <AllowCollisionPairs stage_name="allow collisions -> object,support"
+                                     stage="{allow_collisions_table}"
+                                     first="{object_name}"
+                                     second="table" />
+                <MoveMTCStageToContainer child="{allow_collisions_table}" parent="{pick_object}" />
+
+                <!-- Lift Object -->
+                <GeometryMsgsVector3Stamped frame_id="{reference_frame}" vector="0,0,1" vector3_stamped="{tcp_translate}"/>
+                <CreateMTCMoveRelativeTranslate stage_name="lift object"
+                                                stage="{lift_object}"
+                                                solver="{cartesian_planner}"
+                                                ik_frame="{ik_frame}"
+                                                direction="{tcp_translate}"
+                                                min_distance="0.01"
+                                                max_distance="0.1" />
+                <StageConfigureInitFromMTCProperties stage="{lift_object}" property_names="group" source_flag="PARENT" />
+                <MoveMTCStageToContainer child="{lift_object}" parent="{pick_object}" />
+
+                <!-- Forbid Collision (object support) -->
+                <ForbidCollisionPairs  stage_name="forbid collisions -> object,support"
+                                       stage="{forbid_collisions_table}"
+                                       first="{object_name}"
+                                       second="table" />
+                <GetMTCRawStage  stage="{forbid_collisions_table}" raw_stage="{raw_forbid_collisions_table}"  />
+                <MoveMTCStageToContainer child="{forbid_collisions_table}" parent="{pick_object}" />
+
+                <!-- Add 'pick_object' Container to Task -->
+                <MoveMTCContainerToTask child="{pick_object}" parent="{mtc_task}" />
+
+            <!-- Move to Place -->
+            <CreateMTCConnect stage_name="Move To Place"
+                              timeout="5.0"
+                              group="{arm_group_name}"
+                              planner="{rrt_connect}"
+                              stage="{connectPlace}" />
+            <StageConfigureInitFromMTCProperties stage="{connectPlace}" property_names="" source_flag="PARENT" />
+            <MoveMTCStageToTask child="{connectPlace}" parent="{mtc_task}" />
+
+            <!-- Place Object -->
+            <CreateMTCSerialContainer container_name="place object" container="{place_object}" />
+            <ExposeMTCTaskPropertiesToContainer from="{mtc_task}" to="{place_object}" property_names="group,eef,hand" />
+            <ContainerConfigureInitFromMTCProperties stage="{place_object}" property_names="group,eef,hand" source_flag="PARENT" />
+
+
+                <!-- Lower Object -->
+                <GeometryMsgsVector3Stamped frame_id="{reference_frame}" vector="0,0,-1" vector3_stamped="{tcp_translate2}" />
+                <CreateMTCMoveRelativeTranslate stage_name="lower object"
+                                                stage="{lower_object}"
+                                                solver="{cartesian_planner}"
+                                                ik_frame="{ik_frame}"
+                                                direction="{tcp_translate2}"
+                                                min_distance="0.03"
+                                                max_distance="0.13" />
+                <StageConfigureInitFromMTCProperties stage="{lower_object}" property_names="group" source_flag="PARENT" />
+                <MoveMTCStageToContainer child="{lower_object}" parent="{place_object}" />
+
+                <!-- Generate Place Pose -->
+                <GeometryMsgsPoseStamped frame_id="world" position="0.6,-0.15,0.1251" quaternion="1,0,0,0" pose_stamped="{place_pose}" />
+                <CreateMTCGeneratePlacePose stage="{generate_place_pose}"
+                                            stage_name="generate place pose"
+                                            object="{object_name}"
+                                            pose="{place_pose}"
+                                            monitored_stage="{raw_forbid_collisions_table}" />
+                <CreateMTCComputeIK stage_name="place pose IK"
+                                    wrapped_stage="{generate_place_pose}"
+                                    max_ik_solutions="2"
+                                    stage="{place_pose_IK}"
+                                    ik_frame="{ik_frame2}"  />
+                <StageConfigureInitFromMTCProperties  stage="{place_pose_IK}" property_names="eef,group" source_flag="PARENT" />
+                <StageConfigureInitFromMTCProperties  stage="{place_pose_IK}" property_names="target_pose" source_flag="INTERFACE" />
+                <MoveMTCStageToContainer child="{place_pose_IK}" parent="{place_object}" />
+
+                <!-- Open Hand -->
+                <CreateMTCMoveToNamedJointPose name="move to -> open_hand motion"
+                                          group="{hand_group_name}"
+                                          solver="{rrt_connect}"
+                                          goal="open"
+                                          stage="{stage_move_to_open_hand2}" />
+                <MoveMTCStageToContainer child="{stage_move_to_open_hand2}" parent="{place_object}" />
+
+                <!-- Forbid Collision (hand, object) -->
+                <ForbidCollisionsJointModelGroup stage_name="forbid collisions -> hand,object"
+                                                 stage="{forbid_collisions_object_robot}"
+                                                 objects="{object_name}"
+                                                 jmg_name="{hand_group_name}"
+                                                 task="{mtc_task}" />
+                <MoveMTCStageToContainer child="{forbid_collisions_object_robot}" parent="{place_object}" />
+
+                <!-- Detach Object -->
+                <CreateMTCModifyPlanningSceneDetachObjects stage_name="detach object"
+                                                           stage="{detach_object}"
+                                                           object_names="{object_name}"
+                                                           link_name="{hand_frame}" />
+                <MoveMTCStageToContainer child="{detach_object}" parent="{place_object}" />
+
+                <!-- Retreat Motion -->
+                <GeometryMsgsVector3Stamped frame_id="{hand_frame}" vector="0,0,-1" vector3_stamped="{tcp_translate3}" />
+                <CreateMTCMoveRelativeTranslate stage_name="retreat after place"
+                                                stage="{retreat_after_place}"
+                                                solver="{cartesian_planner}"
+                                                ik_frame="{ik_frame}"
+                                                direction="{tcp_translate3}"
+                                                min_distance="0.12"
+                                                max_distance="0.25" />
+                <StageConfigureInitFromMTCProperties stage="{retreat_after_place}" property_names="group" source_flag="PARENT" />
+                <MoveMTCStageToContainer child="{retreat_after_place}" parent="{place_object}" />
+
+                <!-- Add 'place_object' Container to Task -->
+                <MoveMTCContainerToTask child="{place_object}" parent="{mtc_task}" />
+
+            <!-- Move to Home -->
+            <CreateMTCMoveToNamedJointPose name="move home"
+                                           solver="{rrt_connect}"
+                                           goal="ready"
+                                           stage="{stage_move_to_home}" />
+            <StageConfigureInitFromMTCProperties stage="{stage_move_to_home}" property_names="group" source_flag="PARENT" />
+            <MoveMTCStageToTask child="{stage_move_to_home}" parent="{mtc_task}" />
+
+            <!-- Plan the Task -->
+            <PlanMTCTask task="{mtc_task}" max_solutions="10" />
+        </Sequence>
+     </BehaviorTree>
+
+ </root>
+ )";
+
+// clang-format on
+
+int main(int argc, char** argv)
+{
+  rclcpp::init(argc, argv);
+  rclcpp::NodeOptions options;
+  
+  // Declare parameters passed by a launch file
+  options.automatically_declare_parameters_from_overrides(true);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
+
+  BehaviorTreeFactory factory;
+  factory.registerNodeType<GeometryMsgsPose>("GeometryMsgsPose");
+  factory.registerNodeType<GeometryMsgsPoseStamped>("GeometryMsgsPoseStamped");
+  factory.registerNodeType<GeometryMsgsVector3Stamped>("GeometryMsgsVector3Stamped");
+  factory.registerNodeType<MoveItMsgsCollisionObjectCylinder>("MoveItMsgsCollisionObjectCylinder");
+  factory.registerNodeType<MoveItMsgsCollisionObjectBox>("MoveItMsgsCollisionObjectBox");
+  factory.registerNodeType<CreatePlanningSceneInterface>("CreatePlanningSceneInterface");
+  factory.registerNodeType<AddObjectToPlanningScene>("AddObjectToPlanningScene");
+  factory.registerNodeType<CreateMTCGenerateGraspPose>("CreateMTCGenerateGraspPose");
+  factory.registerNodeType<InitializeMTCTask>("InitializeMTCTask", BT::RosNodeParams(node));
+  factory.registerNodeType<CreateMTCCurrentState>("CreateMTCCurrentState");
+  factory.registerNodeType<CreateMTCPipelinePlanner>("CreateMTCPipelinePlanner", BT::RosNodeParams(node));
+  factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
+  factory.registerNodeType<GetMTCRawStage>("GetMTCRawStage");
+  factory.registerNodeType<CreateMTCMoveToNamedJointPose>("CreateMTCMoveToNamedJointPose");
+  factory.registerNodeType<CreateMTCConnect>("CreateMTCConnect");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::ContainerBase>>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::ContainerBase, moveit::task_constructor::ContainerBase>>("MoveMTCContainerToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::ContainerBase, moveit::task_constructor::Task>>("MoveMTCContainerToTask");
+  factory.registerNodeType<CreateMTCSerialContainer>("CreateMTCSerialContainer");
+  factory.registerNodeType<CreateMTCMoveRelativeTranslate>("CreateMTCMoveRelativeTranslate");
+  factory.registerNodeType<CreateMTCComputeIK>("CreateMTCComputeIK");
+  factory.registerNodeType<ExposeMTCProperties<moveit::task_constructor::ContainerBase, moveit::task_constructor::ContainerBase>>("ExposeMTCContainerPropertiesToContainer");
+  factory.registerNodeType<ExposeMTCProperties<moveit::task_constructor::Task, moveit::task_constructor::ContainerBase>>("ExposeMTCTaskPropertiesToContainer");
+  factory.registerNodeType<ConfigureInitFromMTCProperties<moveit::task_constructor::Stage>>("StageConfigureInitFromMTCProperties");
+  factory.registerNodeType<ConfigureInitFromMTCProperties<moveit::task_constructor::ContainerBase>>("ContainerConfigureInitFromMTCProperties");
+  factory.registerNodeType<SetMTCProperties<moveit::task_constructor::Stage, std::string>>("SetMTCStagePropertyString");
+  factory.registerNodeType<SetMTCProperties<moveit::task_constructor::Task, std::string>>("SetMTCTaskPropertyString");
+  factory.registerScriptingEnums<moveit::task_constructor::Stage::PropertyInitializerSource>();
+  factory.registerNodeType<CreateMTCCartesianPath>("CreateMTCCartesianPath");
+  factory.registerNodeType<CreateMTCModifyPlanningSceneAttachObjects>("CreateMTCModifyPlanningSceneAttachObjects");
+  factory.registerNodeType<CreateMTCModifyPlanningSceneDetachObjects>("CreateMTCModifyPlanningSceneDetachObjects");
+  factory.registerNodeType<AllowCollisionPairs>("AllowCollisionPairs");
+  factory.registerNodeType<AllowCollisionsJointModelGroup>("AllowCollisionsJointModelGroup");
+  factory.registerNodeType<ForbidCollisionsJointModelGroup>("ForbidCollisionsJointModelGroup");
+  factory.registerNodeType<ForbidCollisionPairs>("ForbidCollisionPairs");
+  factory.registerNodeType<CreateMTCGeneratePlacePose>("CreateMTCGeneratePlacePose");
+
+  auto tree = factory.createTreeFromText(xml_text);
+
+  // Connect the Groot2Publisher. This will allow Groot2 to
+  // get the tree and poll status updates.
+  const unsigned port = 1667;
+  BT::Groot2Publisher publisher(tree, port);
+
+  // Add two more loggers, to save the transitions into a file.
+  // Both formats are compatible with Groot2
+
+  // Logging with lightweight serialization
+  BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
+
+  // Gives the user time to connect to Groot2
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
+
+  // Start ticking the Tree
+  std::cout << "Starting Behavior Tree" << std::endl;
+  std::cout << "======================" << std::endl;
+
+  NodeStatus status = NodeStatus::IDLE;
+
+  // Lambda function for the timer callback to tick the behavior tree
+  auto tick_tree = [&tree, &status]() {
+    if (status == NodeStatus::IDLE || status == NodeStatus::RUNNING)
+    {
+      status = tree.tickExactlyOnce();
+      std::cout << "Status = " << status << std::endl;
+    }
+  };
+
+  // Timer to tick the behavior tree
+  auto timer = node->create_wall_timer(std::chrono::milliseconds(10), tick_tree);
+
+  // Spin the node (this will process callbacks including the timer)
+  rclcpp::spin(node);
+
+  // Shutdown when user press CTRL-C
+  rclcpp::shutdown();
+
+  return 0;
+}
diff --git a/examples/bt_serial_container.cpp b/examples/bt_serial_container.cpp
index 912a019..0728293 100644
--- a/examples/bt_serial_container.cpp
+++ b/examples/bt_serial_container.cpp
@@ -5,8 +5,7 @@
 #include <behaviortree_mtc/create_mtc_move_relative.h>
 #include <behaviortree_mtc/create_mtc_serial_container.h>
 #include <behaviortree_mtc/create_mtc_pipeline_planner.h>
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
-#include <behaviortree_mtc/move_mtc_container_to_parent_container.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
 #include <behaviortree_mtc/plan_mtc_task.h>
 
 #include <behaviortree_mtc/geometry_msgs.h>
@@ -25,12 +24,12 @@ static const char* xml_text = R"(
 
    <BehaviorTree ID="MainTree">
      <Sequence name="root">
-       <InitializeMTCTask        task="{mtc_task}" container="{container}" />
+       <InitializeMTCTask        task="{mtc_task}" />
        <CreateMTCPipelinePlanner pipeline_id="ompl"
                                  planner_id="RRTConnect"
                                  solver="{rrt_connect}" />
        <CreateMTCCurrentState    stage="{stage}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage}" />
+       <MoveMTCStageToTask child="{stage}" parent="{mtc_task}" />
 
        <!-- Translate Motion -> 200mm towards x axis wrt. panda_link8 -->
        <GeometryMsgsPoseStamped  frame_id="panda_link8" position="0,0,0" quaternion="1,0,0,0" pose_stamped="{ik_frame}"/>
@@ -41,7 +40,7 @@ static const char* xml_text = R"(
                                        ik_frame="{ik_frame}"
                                        direction="{tcp_translate}"
                                        stage="{stage_move_rel_translate}" />
-       <MoveMTCStageToContainer  container="{container}" stage="{stage_move_rel_translate}" />
+       <MoveMTCStageToTask child="{stage_move_rel_translate}" parent="{mtc_task}" />
        <CreateMTCSerialContainer container_name="approach_object"
                                  container="{serial_container}"/>
        <!-- Translate Motion-->
@@ -52,8 +51,8 @@ static const char* xml_text = R"(
                                        ik_frame="{ik_frame}"
                                        direction="{tcp_translate}"
                                        stage="{stage_move_rel_translate2}" />
-       <MoveMTCStageToContainer  container="{serial_container}" stage="{stage_move_rel_translate2}" />
-       <MoveMTCContainerToParentContainer  parent_container="{container}" child_container="{serial_container}" />
+       <MoveMTCStageToContainer  child="{stage_move_rel_translate2}" parent="{serial_container}" />
+       <MoveMTCContainerToTask   child="{serial_container}" parent="{mtc_task}" />
        <PlanMTCTask              task="{mtc_task}" max_solutions="5" />
      </Sequence>
    </BehaviorTree>
@@ -69,7 +68,7 @@ int main(int argc, char** argv)
   
   // Declare parameters passed by a launch file
   options.automatically_declare_parameters_from_overrides(true);
-  auto node = rclcpp::Node::make_shared("test_behavior_tree", options);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
 
   BehaviorTreeFactory factory;
 
@@ -78,8 +77,9 @@ int main(int argc, char** argv)
   factory.registerNodeType<CreateMTCSerialContainer>("CreateMTCSerialContainer");
   factory.registerNodeType<CreateMTCMoveRelativeTranslate>("CreateMTCMoveRelativeTranslate");
   factory.registerNodeType<CreateMTCCurrentState>("CreateMTCCurrentState");
-  factory.registerNodeType<MoveMTCStageToContainer>("MoveMTCStageToContainer");
-  factory.registerNodeType<MoveMTCContainerToParentContainer>("MoveMTCContainerToParentContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::ContainerBase>>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::ContainerBase, moveit::task_constructor::Task>>("MoveMTCContainerToTask");
   factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
 
   factory.registerNodeType<GeometryMsgsPoseStamped>("GeometryMsgsPoseStamped");
@@ -99,11 +99,16 @@ int main(int argc, char** argv)
   BT::FileLogger2 logger2(tree, "t12_logger2.btlog");
 
   // Gives the user time to connect to Groot2
-  int wait_time = 5000;
-  std::cout << "Waiting " << wait_time << " msec for connection with Groot2...\n\n"
-            << std::endl;
-  std::this_thread::sleep_for(std::chrono::milliseconds(wait_time));
-
+  int delay_ms = node->get_parameter("delay_ms").as_int();
+  if(delay_ms)
+  {
+    std::cout << "Waiting " << delay_ms << " msec for connection with Groot2...\n\n"
+              << std::endl;
+    std::cout << "======================" << std::endl;
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
+  }
+
+  // Start ticking the Tree
   std::cout << "Starting Behavior Tree" << std::endl;
   std::cout << "======================" << std::endl;
 
diff --git a/include/behaviortree_mtc/move_mtc_container_to_parent_container.h b/include/behaviortree_mtc/move_mtc_container_to_parent_container.h
deleted file mode 100644
index cfd909f..0000000
--- a/include/behaviortree_mtc/move_mtc_container_to_parent_container.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <behaviortree_cpp/bt_factory.h>
-
-namespace BT {
-namespace MTC {
-
-class MoveMTCContainerToParentContainer : public BT::SyncActionNode
-{
-public:
-  MoveMTCContainerToParentContainer(const std::string& name, const BT::NodeConfig& config);
-
-  BT::NodeStatus tick() override;
-  static BT::PortsList providedPorts();
-};
-
-}  // namespace MTC
-}  // namespace BT
diff --git a/include/behaviortree_mtc/move_mtc_stage.h b/include/behaviortree_mtc/move_mtc_stage.h
new file mode 100644
index 0000000..6314c74
--- /dev/null
+++ b/include/behaviortree_mtc/move_mtc_stage.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <behaviortree_cpp/bt_factory.h>
+#include <behaviortree_mtc/shared_to_unique.h>
+
+#include <moveit/task_constructor/task.h>
+
+namespace BT {
+namespace MTC {
+
+/// Move MTC child stage/container to parent container/task
+template <typename C, typename P>
+class MoveMTCStage : public BT::SyncActionNode
+{
+  static_assert(std::is_base_of<moveit::task_constructor::Stage, C>::value, "C must inherit from moveit::task_constructor::Stage");
+  static_assert(std::is_base_of<moveit::task_constructor::Stage, P>::value, "P must inherit from moveit::task_constructor::Stage");
+
+public:
+  MoveMTCStage(const std::string& name, const BT::NodeConfig& config)
+    : SyncActionNode(name, config)
+  {}
+
+  BT::NodeStatus tick() override
+  {
+    // Transform stage from shared to unique
+    moveit::task_constructor::Stage::pointer unique_child{ nullptr };
+    if(auto any_child_ptr = getLockedPortContent("child"))
+    {
+      if(auto* stage_ptr = any_child_ptr->template castPtr<std::shared_ptr<C>>())
+      {
+        auto& stage = *stage_ptr;
+
+        unique_child = sharedToUnique(stage);
+        any_child_ptr.assign(nullptr);  // set blackboard value to nullptr
+      }
+    }
+
+    if(auto any_parent_ptr = getLockedPortContent("parent"); unique_child)
+    {
+      if(auto* parent_ptr = any_parent_ptr->template castPtr<std::shared_ptr<P>>())
+      {
+        auto& parent = *parent_ptr;
+
+        parent->add(std::move(unique_child));
+
+        return NodeStatus::SUCCESS;
+      }
+    }
+
+    return NodeStatus::FAILURE;
+  }
+
+  static BT::PortsList providedPorts()
+  {
+    return {
+      BT::InputPort<std::shared_ptr<C>>("child"),
+      BT::BidirectionalPort<std::shared_ptr<P>>("parent"),
+    };
+  }
+};
+
+}  // namespace MTC
+}  // namespace BT
diff --git a/include/behaviortree_mtc/move_mtc_stage_to_container.h b/include/behaviortree_mtc/move_mtc_stage_to_container.h
deleted file mode 100644
index 99f1162..0000000
--- a/include/behaviortree_mtc/move_mtc_stage_to_container.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <behaviortree_cpp/bt_factory.h>
-
-namespace BT {
-namespace MTC {
-
-class MoveMTCStageToContainer : public BT::SyncActionNode
-{
-public:
-  MoveMTCStageToContainer(const std::string& name, const BT::NodeConfig& config);
-
-  BT::NodeStatus tick() override;
-  static BT::PortsList providedPorts();
-};
-
-}  // namespace MTC
-}  // namespace BT
diff --git a/include/behaviortree_mtc/plan_mtc_task.h b/include/behaviortree_mtc/plan_mtc_task.h
index da37688..1879eec 100644
--- a/include/behaviortree_mtc/plan_mtc_task.h
+++ b/include/behaviortree_mtc/plan_mtc_task.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <behaviortree_cpp/bt_factory.h>
+#include <moveit/task_constructor/task.h>
 
 namespace BT {
 namespace MTC {
@@ -11,7 +12,13 @@ class PlanMTCTask : public BT::ThreadedAction
   PlanMTCTask(const std::string& name, const BT::NodeConfig& config);
 
   BT::NodeStatus tick() override;
+  void halt() override;
   static BT::PortsList providedPorts();
+
+private:
+  moveit::task_constructor::TaskPtr task_;
+
+  std::mutex task_mutex_;
 };
 
 }  // namespace MTC
diff --git a/launch/run.launch.py b/launch/run.launch.py
new file mode 100644
index 0000000..5c4bb38
--- /dev/null
+++ b/launch/run.launch.py
@@ -0,0 +1,38 @@
+import os
+from ament_index_python.packages import get_package_share_directory
+from launch import LaunchDescription
+from launch.actions import DeclareLaunchArgument
+from launch.substitutions import LaunchConfiguration
+from launch_ros.actions import Node
+from moveit_configs_utils import MoveItConfigsBuilder
+
+
+def generate_launch_description():
+    delay_ms_arg = DeclareLaunchArgument(
+        'delay_ms',
+        default_value='0',
+        description='Delay (in milliseconds) to give the user time to connect to Groot2'
+    )
+
+    moveit_config = (
+        MoveItConfigsBuilder("moveit_resources_panda")
+        .robot_description(file_path="config/panda.urdf.xacro")
+        .to_moveit_configs()
+    )
+
+    node = Node(
+        package="behaviortree_mtc",
+        executable="bt_pick_place",
+        output="screen",
+        parameters=[
+            moveit_config.robot_description,
+            moveit_config.robot_description_semantic,
+            moveit_config.robot_description_kinematics,
+            moveit_config.joint_limits,
+            moveit_config.planning_pipelines,
+            os.path.join(get_package_share_directory("moveit_task_constructor_demo"), "config", "panda_config.yaml"),
+            {'delay_ms': LaunchConfiguration('delay_ms')}
+        ],
+    )
+
+    return LaunchDescription([delay_ms_arg, node])
\ No newline at end of file
diff --git a/package.xml b/package.xml
index 964b8af..0b0c076 100644
--- a/package.xml
+++ b/package.xml
@@ -11,6 +11,7 @@
   <buildtool_depend>ament_cmake</buildtool_depend>
 
   <depend>behaviortree_cpp</depend>
+  <depend>behaviortree_ros2</depend>
   <depend>geometry_msgs</depend>
   <depend>moveit_msgs</depend>
   <depend>moveit_ros_planning_interface</depend>
diff --git a/src/create_mtc_cartesian_path.cpp b/src/create_mtc_cartesian_path.cpp
index 5a621c3..0267279 100644
--- a/src/create_mtc_cartesian_path.cpp
+++ b/src/create_mtc_cartesian_path.cpp
@@ -18,23 +18,24 @@ BT::NodeStatus CreateMTCCartesianPath::tick()
   double max_velocity_scaling_factor;
   double max_acceleration_scaling_factor;
   double step_size;
-  double jump_treshold;
   double min_fraction;
+  moveit::core::CartesianPrecision precision;
 
   if(!getInput("max_velocity_scaling_factor", max_velocity_scaling_factor) ||
      !getInput("max_acceleration_scaling_factor", max_acceleration_scaling_factor) ||
      !getInput("step_size", step_size) ||
      !getInput("min_fraction", min_fraction) ||
-     !getInput("jump_threshold", jump_treshold))
+     !getInput("precision", precision))
     return NodeStatus::FAILURE;
 
-  //build solver
+  // Build solver
   auto solver = std::make_shared<moveit::task_constructor::solvers::CartesianPath>();
   solver->setMaxVelocityScalingFactor(max_velocity_scaling_factor);
   solver->setMaxAccelerationScalingFactor(max_acceleration_scaling_factor);
   solver->setStepSize(step_size);
-  solver->setJumpThreshold(jump_treshold);
   solver->setMinFraction(min_fraction);
+  solver->setPrecision(precision);
+
   // Upcast to base class
   moveit::task_constructor::solvers::PlannerInterfacePtr base_solver = solver;
 
@@ -47,9 +48,9 @@ BT::PortsList CreateMTCCartesianPath::providedPorts()
   return {
     BT::InputPort<double>("max_velocity_scaling_factor", 0.1, "scale down max velocity by this factor"),
     BT::InputPort<double>("max_acceleration_scaling_factor", 0.1, "scale down max acceleration by this factor"),
-    BT::InputPort<double>("step_size", 0.01, "step size between consecutive waypoints"),
     BT::InputPort<double>("min_fraction", 1.0, "fraction of motion required for success"),
-    BT::InputPort<double>("jump_threshold", 1.5, "acceptable fraction of mean joint motion per step"),
+    BT::InputPort<moveit::core::CartesianPrecision>("precision", moveit::core::CartesianPrecision({ .translational = 0.001, .rotational = 0.01, .max_resolution = 1e-5 }), "linear and rotational precision"),
+    BT::InputPort<double>("step_size", 0.01, "step size between consecutive waypoints"),
     BT::OutputPort<moveit::task_constructor::solvers::PlannerInterfacePtr>("solver", "{solver}", "Planner interface using pipeline motion solver"),
   };
 }
diff --git a/src/create_mtc_compute_ik.cpp b/src/create_mtc_compute_ik.cpp
index aeef324..a32b96f 100644
--- a/src/create_mtc_compute_ik.cpp
+++ b/src/create_mtc_compute_ik.cpp
@@ -26,8 +26,6 @@ BT::NodeStatus CreateMTCComputeIK::tick()
   std::shared_ptr<geometry_msgs::msg::PoseStamped> ik_frame{ nullptr };
 
   if(!getInput("stage_name", name) ||
-     !getInput("eef", eef) ||
-     !getInput("group", group) ||
      !getInput("ignore_collisions", ignore_collisions) ||
      !getInput("min_solution_distance", min_solution_distance) ||
      !getInput("max_ik_solutions", max_ik_solutions) ||
@@ -43,8 +41,13 @@ BT::NodeStatus CreateMTCComputeIK::tick()
     new moveit::task_constructor::stages::ComputeIK(name, std::move(unique_stage)),
     dirty::fake_deleter{}
   };
-  wrapper->setEndEffector(eef);
-  wrapper->setGroup(group);
+
+  // Optionnal
+  if(getInput("group", group))
+    wrapper->setGroup(group);
+  if(getInput("eef", eef))
+    wrapper->setEndEffector(eef);  
+
   wrapper->setMaxIKSolutions(max_ik_solutions);
   wrapper->setIgnoreCollisions(ignore_collisions);
   wrapper->setMinSolutionDistance(min_solution_distance);
diff --git a/src/create_mtc_generate_grasp_pose.cpp b/src/create_mtc_generate_grasp_pose.cpp
index ee5bc6f..823e7f1 100644
--- a/src/create_mtc_generate_grasp_pose.cpp
+++ b/src/create_mtc_generate_grasp_pose.cpp
@@ -21,7 +21,6 @@ BT::NodeStatus CreateMTCGenerateGraspPose::tick()
   Eigen::Vector3d rotation_axis;
   moveit::task_constructor::Stage* monitored_stage;
   if(!getInput("stage_name", name) ||
-     !getInput("eef", eef) ||
      !getInput("angle_delta", angle_delta) ||
      !getInput("object", object) ||
      !getInput("pregrasp_pose", pregrasp_pose) ||
@@ -35,10 +34,14 @@ BT::NodeStatus CreateMTCGenerateGraspPose::tick()
     new moveit::task_constructor::stages::GenerateGraspPose(name),
     dirty::fake_deleter{}
   };
+
+  //Optionnal
+  if(getInput("eef", eef))
+    stage->setEndEffector(eef);
+  
   rotation_axis[0] = rotation_axis_input.x;
   rotation_axis[1] = rotation_axis_input.y;
   rotation_axis[2] = rotation_axis_input.z;
-  stage->setEndEffector(eef);
   stage->setObject(object);
   stage->setAngleDelta(angle_delta);
   stage->setRotationAxis(rotation_axis);
diff --git a/src/create_mtc_move_relative.cpp b/src/create_mtc_move_relative.cpp
index 289e274..b049120 100644
--- a/src/create_mtc_move_relative.cpp
+++ b/src/create_mtc_move_relative.cpp
@@ -23,7 +23,6 @@ BT::NodeStatus CreateMTCMoveRelativeBase::tick(std::shared_ptr<moveit::task_cons
   double timeout;
 
   if(!getInput("stage_name", name) ||
-     !getInput("group", group) ||
      !getInput("solver", solver) ||
      !getInput("ik_frame", ik_frame) ||
      !getInput("min_distance", min_distance) ||
@@ -37,7 +36,10 @@ BT::NodeStatus CreateMTCMoveRelativeBase::tick(std::shared_ptr<moveit::task_cons
     dirty::fake_deleter{}
   };
 
-  stage->setGroup(group);
+  //Optionnal
+  if(getInput("group", group))
+    stage->setGroup(group);
+
   stage->setIKFrame(*ik_frame);
   stage->setMinMaxDistance(min_distance, max_distance);
   stage->setTimeout(timeout);
diff --git a/src/create_mtc_move_to.cpp b/src/create_mtc_move_to.cpp
index b2726db..97fddcd 100644
--- a/src/create_mtc_move_to.cpp
+++ b/src/create_mtc_move_to.cpp
@@ -22,7 +22,6 @@ BT::NodeStatus CreateMTCMoveToBase::tick(std::shared_ptr<moveit::task_constructo
   double timeout;
 
   if(!getInput("stage_name", name) ||
-     !getInput("group", group) ||
      !getInput("solver", solver) ||
      !getInput("timeout", timeout))
     return NodeStatus::FAILURE;
@@ -32,8 +31,10 @@ BT::NodeStatus CreateMTCMoveToBase::tick(std::shared_ptr<moveit::task_constructo
     new moveit::task_constructor::stages::MoveTo(name, solver),
     dirty::fake_deleter{}
   };
+  // Optionnal
+  if(getInput("group", group))
+    stage->setGroup(group);
 
-  stage->setGroup(group);
   stage->setTimeout(timeout);
 
   return NodeStatus::SUCCESS;
diff --git a/src/create_mtc_pipeline_planner.cpp b/src/create_mtc_pipeline_planner.cpp
index 88c901e..7d77650 100644
--- a/src/create_mtc_pipeline_planner.cpp
+++ b/src/create_mtc_pipeline_planner.cpp
@@ -42,8 +42,7 @@ BT::NodeStatus CreateMTCPipelinePlanner::tick()
      !getInput("num_planning_attempts", num_planning_attemps))
     return NodeStatus::FAILURE;
   //build solver
-  auto solver = std::make_shared<moveit::task_constructor::solvers::PipelinePlanner>(node_, pipeline_id);
-  solver->setPlannerId(planner_id);
+  auto solver = std::make_shared<moveit::task_constructor::solvers::PipelinePlanner>(node_, pipeline_id, planner_id);
   solver->setMaxVelocityScalingFactor(max_velocity_scaling_factor);
   solver->setMaxAccelerationScalingFactor(max_acceleration_scaling_factor);
   solver->setProperty("goal_joint_tolerance", goal_joint_tolerance);
@@ -68,8 +67,8 @@ BT::PortsList CreateMTCPipelinePlanner::providedPorts()
     BT::InputPort<double>("goal_joint_tolerance", "1e-4", "tolerance for reaching joint goals"),
     BT::InputPort<double>("goal_position_tolerance", "1e-4", "tolerance for reaching position goals"),
     BT::InputPort<double>("goal_orientation_tolerance", "1e-4", "tolerance for reaching orientation goals"),
-    BT::InputPort<bool>("display_motion_plans", false, "publish generated solutions on topic " + planning_pipeline::PlanningPipeline::DISPLAY_PATH_TOPIC),
-    BT::InputPort<bool>("publish_planning_requests", false, "publish motion planning requests on topic " + planning_pipeline::PlanningPipeline::MOTION_PLAN_REQUEST_TOPIC),
+    BT::InputPort<bool>("display_motion_plans", false, "publish generated solutions on topic "),
+    BT::InputPort<bool>("publish_planning_requests", false, "publish motion planning requests on topic "),
     BT::InputPort<std::string>("planner_id"),
     BT::InputPort<std::string>("pipeline_id"),
     BT::InputPort<uint>("num_planning_attempts", "1u", "number of planning attempts"),
diff --git a/src/generate_xml_model.cpp b/src/generate_xml_model.cpp
new file mode 100644
index 0000000..3fbbd5e
--- /dev/null
+++ b/src/generate_xml_model.cpp
@@ -0,0 +1,101 @@
+#include <behaviortree_mtc/initialize_mtc_task.h>
+#include <behaviortree_mtc/create_mtc_current_state.h>
+#include <behaviortree_mtc/move_mtc_stage.h>
+#include <behaviortree_mtc/create_mtc_serial_container.h>
+#include <behaviortree_mtc/plan_mtc_task.h>
+#include <behaviortree_mtc/moveit_msgs.h>
+#include <behaviortree_mtc/geometry_msgs.h>
+#include <behaviortree_mtc/create_mtc_pipeline_planner.h>
+#include <behaviortree_mtc/create_planning_scene_interface.h>
+#include <behaviortree_mtc/add_object_to_planning_scene.h>
+#include <behaviortree_mtc/plan_mtc_task.h>
+#include <behaviortree_mtc/create_mtc_generate_grasp_pose.h>
+#include <behaviortree_mtc/get_mtc_raw_stage.h>
+#include <behaviortree_mtc/create_mtc_move_to.h>
+#include <behaviortree_mtc/create_mtc_connect.h>
+#include <behaviortree_mtc/create_mtc_move_relative.h>
+#include <behaviortree_mtc/create_mtc_compute_ik.h>
+#include <behaviortree_mtc/configure_init_from_mtc_properties.h>
+#include <behaviortree_mtc/std_containers.h>
+#include <behaviortree_mtc/create_mtc_cartesian_path.h>
+#include <behaviortree_mtc/create_mtc_modify_planning_scene.h>
+#include <behaviortree_mtc/create_mtc_generate_place_pose.h>
+#include <behaviortree_mtc/create_mtc_joint_interpolation.h>
+
+#include "behaviortree_cpp/bt_factory.h"
+#include "behaviortree_cpp/loggers/bt_file_logger_v2.h"
+#include "behaviortree_cpp/loggers/groot2_publisher.h"
+#include "behaviortree_cpp/xml_parsing.h"
+
+using namespace BT;
+using namespace BT::MTC;
+
+int main(int argc, char** argv)
+{
+  rclcpp::init(argc, argv);
+  rclcpp::NodeOptions options;
+  
+  // Declare parameters passed by a launch file
+  options.automatically_declare_parameters_from_overrides(true);
+  auto node = rclcpp::Node::make_shared("bt_mtc_demo", options);
+
+  BehaviorTreeFactory factory;
+
+  factory.registerNodeType<GeometryMsgsPose>("GeometryMsgsPose");
+  factory.registerNodeType<GeometryMsgsTwistStamped>("GeometryMsgsTwistStamped");
+  factory.registerNodeType<GeometryMsgsPoseStamped>("GeometryMsgsPoseStamped");
+  factory.registerNodeType<GeometryMsgsVector3Stamped>("GeometryMsgsVector3Stamped");
+  factory.registerNodeType<MoveItMsgsCollisionObjectCylinder>("MoveItMsgsCollisionObjectCylinder");
+  factory.registerNodeType<MoveItMsgsCollisionObjectBox>("MoveItMsgsCollisionObjectBox");
+  factory.registerNodeType<CreatePlanningSceneInterface>("CreatePlanningSceneInterface");
+  factory.registerNodeType<AddObjectToPlanningScene>("AddObjectToPlanningScene");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::ContainerBase>>("MoveMTCStageToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::Stage, moveit::task_constructor::Task>>("MoveMTCStageToTask");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::ContainerBase, moveit::task_constructor::ContainerBase>>("MoveMTCContainerToContainer");
+  factory.registerNodeType<MoveMTCStage<moveit::task_constructor::ContainerBase, moveit::task_constructor::Task>>("MoveMTCContainerToTask");
+  factory.registerNodeType<InitializeMTCTask>("InitializeMTCTask", BT::RosNodeParams(node));
+  factory.registerNodeType<CreateMTCCurrentState>("CreateMTCCurrentState");
+  factory.registerNodeType<CreateMTCPipelinePlanner>("CreateMTCPipelinePlanner", BT::RosNodeParams(node));
+  factory.registerNodeType<CreateMTCCartesianPath>("CreateMTCCartesianPath");
+  factory.registerNodeType<CreateMTCJointInterpolation>("CreateMTCJointInterpolation");
+  factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
+  factory.registerNodeType<GetMTCRawStage>("GetMTCRawStage");
+  factory.registerNodeType<CreateMTCMoveToNamedJointPose>("CreateMTCMoveToNamedJointPose");
+  factory.registerNodeType<CreateMTCMoveToJoint>("CreateMTCMoveToJoint");
+  factory.registerNodeType<CreateMTCMoveToPoint>("CreateMTCMoveToPoint");
+  factory.registerNodeType<CreateMTCMoveToPose>("CreateMTCMoveToPose");
+  factory.registerNodeType<CreateMTCMoveRelativeTranslate>("CreateMTCMoveRelativeTranslate");
+  factory.registerNodeType<CreateMTCMoveRelativeJoint>("CreateMTCMoveRelativeJoint");
+  factory.registerNodeType<CreateMTCMoveRelativeTwist>("CreateMTCMoveRelativeTwist");
+  factory.registerNodeType<CreateMTCConnect>("CreateMTCConnect");
+  factory.registerNodeType<CreateMTCSerialContainer>("CreateMTCSerialContainer");
+  factory.registerNodeType<CreateMTCComputeIK>("CreateMTCComputeIK");
+  factory.registerNodeType<ConfigureInitFromMTCProperties<moveit::task_constructor::Stage>>("ConfigureInitFromMTCProperties");
+  factory.registerScriptingEnums<moveit::task_constructor::Stage::PropertyInitializerSource>();
+  factory.registerNodeType<CreateMTCModifyPlanningSceneAttachObjects>("CreateMTCModifyPlanningSceneAttachObjects");
+  factory.registerNodeType<CreateMTCModifyPlanningSceneDetachObjects>("CreateMTCModifyPlanningSceneDetachObjects");
+  factory.registerNodeType<ForbidCollisionPairs>("ForbidCollisionPairs");
+  factory.registerNodeType<AllowCollisionPairs>("AllowCollisionPairs");
+  factory.registerNodeType<AllowAllCollisions>("AllowAllCollisions");
+  factory.registerNodeType<ForbidAllCollisions>("ForbidAllCollisions");
+  factory.registerNodeType<AllowCollisionsJointModelGroup>("AllowCollisionsJointModelGroup");
+  factory.registerNodeType<ForbidCollisionsJointModelGroup>("ForbidCollisionsJointModelGroup");
+  factory.registerNodeType<CreateMTCGenerateGraspPose>("CreateMTCGenerateGraspPose");
+  factory.registerNodeType<CreateMTCGeneratePlacePose>("CreateMTCGeneratePlacePose");
+
+  std::string xml_models = BT::writeTreeNodesModelXML(factory);
+  std::string filePath = "./config/bt_mtc_model.xml";
+  std::ofstream file(filePath);
+  if(file.is_open())
+  {
+    file << xml_models;
+    file.close();
+    std::cout << "File saved successfully: " << filePath << std::endl;
+  }
+  else
+  {
+    std::cerr << "Unable to open file: " << filePath << std::endl;
+  }
+
+  return 0;
+}
diff --git a/src/initialize_mtc_task.cpp b/src/initialize_mtc_task.cpp
index 0467606..f4b2167 100644
--- a/src/initialize_mtc_task.cpp
+++ b/src/initialize_mtc_task.cpp
@@ -16,11 +16,7 @@ BT::NodeStatus InitializeMTCTask::tick()
   auto task = std::make_shared<moveit::task_constructor::Task>();
   task->loadRobotModel(node_);
 
-  //Convert raw pointer to share pointer
-  auto container = std::shared_ptr<moveit::task_constructor::ContainerBase>(task->stages());
-
   setOutput("task", task);
-  setOutput("container", container);
 
   return NodeStatus::SUCCESS;
 }
@@ -30,8 +26,6 @@ BT::PortsList InitializeMTCTask::providedPorts()
   return {
     BT::OutputPort<moveit::task_constructor::TaskPtr>("task", "{mtc_task}",
                                                       "MoveIt Task Constructor task."),
-    BT::OutputPort<moveit::task_constructor::ContainerBasePtr>("container"),
-
   };
 }
 
diff --git a/src/move_mtc_container_to_parent_container.cpp b/src/move_mtc_container_to_parent_container.cpp
deleted file mode 100644
index 41bfd51..0000000
--- a/src/move_mtc_container_to_parent_container.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <behaviortree_mtc/move_mtc_container_to_parent_container.h>
-#include <behaviortree_mtc/shared_to_unique.h>
-
-#include <moveit/task_constructor/container.h>
-#include <moveit/task_constructor/task.h>
-
-namespace BT {
-namespace MTC {
-
-MoveMTCContainerToParentContainer::MoveMTCContainerToParentContainer(const std::string& name,
-                                                                     const BT::NodeConfig& config)
-  : SyncActionNode(name, config)
-{}
-
-BT::NodeStatus MoveMTCContainerToParentContainer::tick()
-{
-  // Transform container from shared to unique
-  moveit::task_constructor::ContainerBase::pointer unique_child_container{ nullptr };
-  if(auto any_container_ptr = getLockedPortContent("child_container"))
-  {
-    if(auto* container_ptr = any_container_ptr->castPtr<moveit::task_constructor::ContainerBasePtr>())
-    {
-      auto& child_container = *container_ptr;
-
-      unique_child_container = sharedToUnique(child_container);
-      any_container_ptr.assign(nullptr);  // set blackboard value to nullptr
-    }
-  }
-
-  if(auto any_container_ptr = getLockedPortContent("parent_container"); unique_child_container)
-  {
-    if(auto* container_ptr = any_container_ptr->castPtr<moveit::task_constructor::ContainerBasePtr>())
-    {
-      auto& parent_container = *container_ptr;
-
-      parent_container->add(std::move(unique_child_container));
-
-      return NodeStatus::SUCCESS;
-    }
-  }
-
-  return NodeStatus::SUCCESS;
-}
-
-BT::PortsList MoveMTCContainerToParentContainer::providedPorts()
-{
-  return {
-    BT::InputPort<moveit::task_constructor::ContainerBasePtr>("child_container"),
-    BT::BidirectionalPort<moveit::task_constructor::ContainerBasePtr>("parent_container"),
-  };
-}
-
-}  // namespace MTC
-}  // namespace BT
diff --git a/src/move_mtc_stage_to_container.cpp b/src/move_mtc_stage_to_container.cpp
deleted file mode 100644
index db082d5..0000000
--- a/src/move_mtc_stage_to_container.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <behaviortree_mtc/move_mtc_stage_to_container.h>
-#include <behaviortree_mtc/shared_to_unique.h>
-
-#include <moveit/task_constructor/container.h>
-#include <moveit/task_constructor/task.h>
-
-namespace BT {
-namespace MTC {
-
-MoveMTCStageToContainer::MoveMTCStageToContainer(const std::string& name,
-                                                 const BT::NodeConfig& config)
-  : SyncActionNode(name, config)
-{}
-
-BT::NodeStatus MoveMTCStageToContainer::tick()
-{
-  // Transform stage from shared to unique
-  moveit::task_constructor::Stage::pointer unique_stage{ nullptr };
-  if(auto any_stage_ptr = getLockedPortContent("stage"))
-  {
-    if(auto* stage_ptr = any_stage_ptr->castPtr<moveit::task_constructor::StagePtr>())
-    {
-      auto& stage = *stage_ptr;
-
-      unique_stage = sharedToUnique(stage);
-      any_stage_ptr.assign(nullptr);  // set blackboard value to nullptr
-    }
-  }
-
-  if(auto any_container_ptr = getLockedPortContent("container"); unique_stage)
-  {
-    if(auto* container_ptr = any_container_ptr->castPtr<moveit::task_constructor::ContainerBasePtr>())
-    {
-      auto& container = *container_ptr;
-
-      container->add(std::move(unique_stage));
-
-      return NodeStatus::SUCCESS;
-    }
-  }
-
-  return NodeStatus::FAILURE;
-}
-
-BT::PortsList MoveMTCStageToContainer::providedPorts()
-{
-  return {
-    BT::InputPort<moveit::task_constructor::StagePtr>("stage"),
-    BT::BidirectionalPort<moveit::task_constructor::ContainerBasePtr>("container"),
-  };
-}
-
-}  // namespace MTC
-}  // namespace BT
diff --git a/src/plan_mtc_task.cpp b/src/plan_mtc_task.cpp
index 3d38db1..1da60f7 100644
--- a/src/plan_mtc_task.cpp
+++ b/src/plan_mtc_task.cpp
@@ -1,6 +1,5 @@
 #include <behaviortree_mtc/plan_mtc_task.h>
-
-#include <moveit/task_constructor/task.h>
+#include <moveit/utils/moveit_error_code.h>
 
 namespace BT {
 namespace MTC {
@@ -11,21 +10,64 @@ PlanMTCTask::PlanMTCTask(const std::string& name, const BT::NodeConfig& config)
 
 BT::NodeStatus PlanMTCTask::tick()
 {
+  // Inputs
   const size_t max_solutions = getInput<size_t>("max_solutions").value();
   if(auto any_ptr = getLockedPortContent("task"))
   {
     if(auto* task_ptr = any_ptr->castPtr<moveit::task_constructor::TaskPtr>())
     {
       auto& task = *task_ptr;
-      if(task->plan(max_solutions))
+
+      // copy task internally
       {
-        return NodeStatus::SUCCESS;
+        std::unique_lock<std::mutex> lock{ task_mutex_ };
+        task_ = task;
       }
     }
   }
+
+  if(task_)
+  {
+    moveit::core::MoveItErrorCode ec;
+    try
+    {
+      task_->resetPreemptRequest();  // should not be needed
+      ec = task_->plan(max_solutions);
+      std::cout << moveit::core::errorCodeToString(ec) << std::endl;
+    }
+    catch(moveit::task_constructor::InitStageException e)
+    {
+      std::cout << e << std::endl;
+      return NodeStatus::FAILURE;
+    }
+
+    {
+      std::unique_lock<std::mutex> lock{ task_mutex_ };
+      task_ = nullptr;
+    }
+
+    if(ec.val == ec.SUCCESS)
+      return NodeStatus::SUCCESS;
+  }
+
   return NodeStatus::FAILURE;
 }
 
+void PlanMTCTask::halt()
+{
+  {
+    std::unique_lock<std::mutex> lock{ task_mutex_ };
+
+    if(task_)
+    {
+      task_->preempt();
+    }
+  }
+
+  // halt base class
+  ThreadedAction::halt();
+}
+
 BT::PortsList PlanMTCTask::providedPorts()
 {
   return {
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index d7e8421..945a7eb 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -2,14 +2,19 @@
 # TESTS
 
 set(BT_MTC_TESTS
-  gtest_mtc_properties.cpp
   gtest_mtc_modify_planning_scene.cpp
+  gtest_mtc_properties.cpp
+  gtest_plan_mtc_task.cpp
 )
 
 set(TEST_DEPENDENCIES
+    gtest_utils
     ${PROJECT_NAME}
 )
 
+add_library(gtest_utils models.cpp stage_mockups.cpp)
+target_link_libraries(gtest_utils ${PROJECT_NAME} ${moveit_task_constructor_LIBRARIES})
+
 # Enable testing and find necessary packages
 if(BUILD_TESTING)
     find_package(ament_cmake_gtest REQUIRED)
@@ -20,4 +25,4 @@ if(BUILD_TESTING)
             ${TEST_DEPENDENCIES}
         )
     endif()
-endif()
+endif()
\ No newline at end of file
diff --git a/tests/gtest_plan_mtc_task.cpp b/tests/gtest_plan_mtc_task.cpp
new file mode 100644
index 0000000..cfd24ed
--- /dev/null
+++ b/tests/gtest_plan_mtc_task.cpp
@@ -0,0 +1,57 @@
+#include <gtest/gtest.h>
+// #include <ros/ros.h>
+#include <behaviortree_cpp/bt_factory.h>
+#include <behaviortree_mtc/plan_mtc_task.h>
+#include "stage_mockups.h"
+#include "models.h"
+
+using namespace BT;
+using namespace BT::MTC;
+
+TEST(PlanMTCTask, Preempt)
+{
+  BT::BehaviorTreeFactory factory;
+
+  // clang-format off
+
+  static const char* xml_text = R"(
+
+   <root BTCPP_format="4" >
+       <BehaviorTree ID="MainTree">
+           <Sequence>
+               <Script code="force_failure := false"/>
+
+               <ReactiveSequence name="root">
+
+                   <AlwaysSuccess _failureIf="force_failure==true" _onSuccess="force_failure=true"/>
+                   <PlanMTCTask task="{mtc_task}" max_solutions="1"/>
+         </ReactiveSequence>
+
+       </Sequence>
+
+     </BehaviorTree>
+   </root>)";
+
+  // clang-format off
+
+  factory.registerNodeType<PlanMTCTask>("PlanMTCTask");
+
+
+  // setup mtc task to be preempted
+  moveit::task_constructor::TaskPtr task = std::make_shared<moveit::task_constructor::Task>();
+  task->setRobotModel(getModel());
+
+  auto timeout = std::chrono::milliseconds(10);
+  task->add(std::make_unique<moveit::task_constructor::GeneratorMockup>(moveit::task_constructor::PredefinedCosts::constant(0.0)));
+  task->add(std::make_unique<moveit::task_constructor::TimedForwardMockup>(timeout));
+
+  // setup blackbaord
+  auto bb = BT::Blackboard::create();
+  bb->set("mtc_task", task);
+
+
+  // test
+  auto tree = factory.createTreeFromText(xml_text, bb);
+  EXPECT_EQ(tree.tickExactlyOnce(), NodeStatus::RUNNING);
+  EXPECT_EQ(tree.tickExactlyOnce(), NodeStatus::FAILURE);
+}
diff --git a/tests/models.cpp b/tests/models.cpp
new file mode 100644
index 0000000..a75208f
--- /dev/null
+++ b/tests/models.cpp
@@ -0,0 +1,29 @@
+#include "models.h"
+#include <moveit/utils/robot_model_test_utils.h>
+#include <moveit/robot_model_loader/robot_model_loader.h>
+#include <rclcpp/rclcpp.hpp>
+
+using namespace moveit::core;
+
+RobotModelPtr getModel()
+{
+  // suppress RobotModel errors and warnings
+  rclcpp::Logger logger = rclcpp::get_logger("moveit_core.robot_model");
+  logger.set_level(rclcpp::Logger::Level::Fatal);
+
+  // create dummy robot model
+  moveit::core::RobotModelBuilder builder("robot", "base");
+  builder.addChain("base->link1->link2->tip", "continuous");
+  builder.addGroupChain("base", "link2", "group");
+  builder.addGroupChain("link2", "tip", "eef_group");
+  builder.addEndEffector("eef", "link2", "group", "eef_group");
+  return builder.build();
+}
+
+moveit::core::RobotModelPtr loadModel()
+{
+  auto node = rclcpp::Node::make_shared("robot_model_loader_node");
+  robot_model_loader::RobotModelLoader::Options options;
+  robot_model_loader::RobotModelLoader loader(node, options);
+  return loader.getModel();
+}
diff --git a/tests/models.h b/tests/models.h
new file mode 100644
index 0000000..11cfcdb
--- /dev/null
+++ b/tests/models.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <moveit/macros/class_forward.h>
+
+namespace moveit {
+namespace core {
+MOVEIT_CLASS_FORWARD(RobotModel);
+}
+}  // namespace moveit
+
+// get a hard-coded model
+moveit::core::RobotModelPtr getModel();
+
+// load a model from robot_description
+moveit::core::RobotModelPtr loadModel();
diff --git a/tests/stage_mockups.cpp b/tests/stage_mockups.cpp
new file mode 100644
index 0000000..0fd9c26
--- /dev/null
+++ b/tests/stage_mockups.cpp
@@ -0,0 +1,163 @@
+#include <moveit/task_constructor/stage.h>
+#include <moveit/planning_scene/planning_scene.h>
+
+#include "stage_mockups.h"
+
+namespace moveit {
+namespace task_constructor {
+
+unsigned int GeneratorMockup::id_ = 0;
+unsigned int MonitoringGeneratorMockup::id_ = 0;
+unsigned int ConnectMockup::id_ = 0;
+unsigned int PropagatorMockup::id_ = 0;
+unsigned int ForwardMockup::id_ = 0;
+unsigned int BackwardMockup::id_ = 0;
+
+void resetMockupIds()
+{
+  GeneratorMockup::id_ = 0;
+  MonitoringGeneratorMockup::id_ = 0;
+  ConnectMockup::id_ = 0;
+  PropagatorMockup::id_ = 0;
+  ForwardMockup::id_ = 0;
+  BackwardMockup::id_ = 0;
+}
+
+PredefinedCosts::PredefinedCosts(std::list<double>&& costs, bool finite)
+  : costs_{ std::move(costs) }, finite_{ finite }
+{}
+
+bool PredefinedCosts::exhausted() const
+{
+  return costs_.empty();
+}
+
+double PredefinedCosts::cost() const
+{
+  // keep the tests going, but this should not happen
+  EXPECT_GT(costs_.size(), 0u);
+  if(costs_.empty())
+    return 0.0;
+
+  double c{ costs_.front() };
+
+  if(finite_ || costs_.size() > 1)
+  {
+    costs_.pop_front();
+  }
+
+  return c;
+}
+
+void DelayingWrapper::compute()
+{
+  if(!delay_.empty())
+  {  // if empty, we don't delay
+    if(delay_.front() == 0)
+      delay_.pop_front();  // we can compute() now
+    else
+    {
+      --delay_.front();  // continue delaying
+      return;
+    }
+  }
+  // forward to child, eventually generating multiple solutions at once
+  WrapperBase::compute();
+}
+
+GeneratorMockup::GeneratorMockup(PredefinedCosts&& costs, std::size_t solutions_per_compute)
+  : Generator{ "GEN" + std::to_string(++id_) }
+  , costs_{ std::move(costs) }
+  , solutions_per_compute_{ solutions_per_compute }
+{}
+
+void GeneratorMockup::init(const moveit::core::RobotModelConstPtr& robot_model)
+{
+  ps_.reset(new planning_scene::PlanningScene(robot_model));
+  Generator::init(robot_model);
+}
+
+bool GeneratorMockup::canCompute() const
+{
+  // check if runs are being used and if there are still runs left (costs are then never exhausted) or if costs
+  // are being used and they are not exhausted yet
+  return !costs_.exhausted();
+}
+
+void GeneratorMockup::compute()
+{
+  ++runs_;
+
+  for(std::size_t i = 0; canCompute() && i < solutions_per_compute_; ++i)
+    spawn(InterfaceState(ps_), costs_.cost());
+}
+
+MonitoringGeneratorMockup::MonitoringGeneratorMockup(Stage* monitored, PredefinedCosts&& costs)
+  : MonitoringGenerator{ "MON" + std::to_string(++id_), monitored }, costs_{ std::move(costs) }
+{}
+
+void MonitoringGeneratorMockup::onNewSolution(const SolutionBase& s)
+{
+  ++runs_;
+
+  spawn(InterfaceState{ s.end()->scene()->diff() }, SubTrajectory{});
+}
+
+ConnectMockup::ConnectMockup(PredefinedCosts&& costs)
+  : Connecting{ "CON" + std::to_string(++id_) }, costs_{ std::move(costs) }
+{}
+
+void ConnectMockup::compute(const InterfaceState& from, const InterfaceState& to)
+{
+  ++runs_;
+
+  auto solution{ std::make_shared<SubTrajectory>() };
+  solution->setCost(costs_.cost());
+  solution->setComment(std::to_string(from.priority().cost()) + " -> " + std::to_string(to.priority().cost()));
+  connect(from, to, solution);
+}
+
+PropagatorMockup::PropagatorMockup(PredefinedCosts&& costs, std::size_t solutions_per_compute)
+  : PropagatingEitherWay{ "PRO" + std::to_string(++id_) }
+  , costs_{ std::move(costs) }
+  , solutions_per_compute_{ solutions_per_compute }
+{}
+
+void PropagatorMockup::computeForward(const InterfaceState& from)
+{
+  ++runs_;
+
+  for(std::size_t i = 0; i < solutions_per_compute_; ++i)
+  {
+    SubTrajectory solution{ robot_trajectory::RobotTrajectoryConstPtr(), costs_.cost() };
+    sendForward(from, InterfaceState{ from.scene()->diff() }, std::move(solution));
+  }
+}
+
+void PropagatorMockup::computeBackward(const InterfaceState& to)
+{
+  ++runs_;
+
+  for(std::size_t i = 0; i < solutions_per_compute_; ++i)
+  {
+    SubTrajectory solution(robot_trajectory::RobotTrajectoryConstPtr(), costs_.cost());
+    sendBackward(InterfaceState(to.scene()->diff()), to, std::move(solution));
+  }
+}
+
+ForwardMockup::ForwardMockup(PredefinedCosts&& costs, std::size_t solutions_per_compute)
+  : PropagatorMockup{ std::move(costs), solutions_per_compute }
+{
+  restrictDirection(FORWARD);
+  setName("FWD" + std::to_string(++id_));
+}
+
+BackwardMockup::BackwardMockup(PredefinedCosts&& costs, std::size_t solutions_per_compute)
+  : PropagatorMockup{ std::move(costs), solutions_per_compute }
+{
+  restrictDirection(BACKWARD);
+  setName("BWD" + std::to_string(++id_));
+}
+
+}  // namespace task_constructor
+}  // namespace moveit
diff --git a/tests/stage_mockups.h b/tests/stage_mockups.h
new file mode 100644
index 0000000..e2e9b01
--- /dev/null
+++ b/tests/stage_mockups.h
@@ -0,0 +1,201 @@
+#pragma once
+
+#include <thread>
+
+#include <moveit/task_constructor/task.h>
+#include <moveit/task_constructor/cost_terms.h>
+
+#include <moveit/planning_scene/planning_scene.h>
+
+#include <gtest/gtest.h>
+/* #include <gmock/gmock.h> */
+
+namespace moveit {
+namespace task_constructor {
+
+MOVEIT_STRUCT_FORWARD(PredefinedCosts);
+struct PredefinedCosts : CostTerm
+{
+  mutable std::list<double> costs_;  // list of costs to assign
+  mutable bool finite_;
+
+  PredefinedCosts(std::list<double>&& costs, bool finite = true);
+
+  static PredefinedCosts constant(double c)
+  {
+    return PredefinedCosts{ std::list<double>{ c }, false };
+  }
+  static PredefinedCosts single(double c)
+  {
+    return PredefinedCosts{ std::list<double>{ c }, true };
+  }
+
+  bool exhausted() const;
+  double cost() const;
+
+  double operator()(const SubTrajectory& /*s*/, std::string& /*comment*/) const override
+  {
+    return cost();
+  }
+  double operator()(const SolutionSequence& /*s*/, std::string& /*comment*/) const override
+  {
+    return cost();
+  }
+  double operator()(const WrappedSolution& /*s*/, std::string& /*comment*/) const override
+  {
+    return cost();
+  }
+};
+
+constexpr double INF{ std::numeric_limits<double>::infinity() };
+
+/* wrapper stage to delay solutions by a given number of steps */
+struct DelayingWrapper : public WrapperBase
+{
+  std::list<unsigned int> delay_;
+  /* delay list specifies the number of steps each received solution should be delayed */
+  DelayingWrapper(std::list<unsigned int> delay, Stage::pointer&& child)
+    : WrapperBase("delayer", std::move(child)), delay_{ std::move(delay) }
+  {}
+
+  void compute() override;
+  void onNewSolution(const SolutionBase& s) override
+  {
+    liftSolution(s);
+  }
+};
+
+struct GeneratorMockup : public Generator
+{
+  planning_scene::PlanningScenePtr ps_;
+
+  PredefinedCosts costs_;
+  size_t runs_{ 0 };
+  std::size_t solutions_per_compute_;
+
+  static unsigned int id_;
+
+  // default to one solution to avoid infinity loops
+  GeneratorMockup(PredefinedCosts&& costs = PredefinedCosts{ std::list<double>{ 0.0 }, true },
+                  std::size_t solutions_per_compute = 1);
+  GeneratorMockup(std::initializer_list<double> costs, std::size_t solutions_per_compute = 1)
+    : GeneratorMockup{ PredefinedCosts{ std::list<double>{ costs }, true }, solutions_per_compute }
+  {}
+
+  void init(const moveit::core::RobotModelConstPtr& robot_model) override;
+  bool canCompute() const override;
+  void compute() override;
+  virtual void reset() override
+  {
+    runs_ = 0;
+  };
+};
+
+struct MonitoringGeneratorMockup : public MonitoringGenerator
+{
+  PredefinedCosts costs_;
+  size_t runs_{ 0 };
+
+  static unsigned int id_;
+
+  MonitoringGeneratorMockup(Stage* monitored, PredefinedCosts&& costs = PredefinedCosts::constant(0.0));
+  MonitoringGeneratorMockup(Stage* monitored, std::initializer_list<double> costs)
+    : MonitoringGeneratorMockup{ monitored, PredefinedCosts{ std::list<double>{ costs }, true } }
+  {}
+
+  bool canCompute() const override
+  {
+    return false;
+  }
+  void compute() override
+  {}
+  void onNewSolution(const SolutionBase& s) override;
+  virtual void reset() override
+  {
+    runs_ = 0;
+  };
+};
+
+struct ConnectMockup : public Connecting
+{
+  PredefinedCosts costs_;
+  size_t runs_{ 0 };
+
+  static unsigned int id_;
+
+  ConnectMockup(PredefinedCosts&& costs = PredefinedCosts::constant(0.0));
+  ConnectMockup(std::initializer_list<double> costs)
+    : ConnectMockup{ PredefinedCosts{ std::list<double>{ costs }, true } }
+  {}
+
+  using Connecting::compatible;  // make this accessible for testing
+
+  void compute(const InterfaceState& from, const InterfaceState& to) override;
+  virtual void reset() override
+  {
+    runs_ = 0;
+  };
+};
+
+struct PropagatorMockup : public PropagatingEitherWay
+{
+  PredefinedCosts costs_;
+  size_t runs_{ 0 };
+  std::size_t solutions_per_compute_;
+
+  static unsigned int id_;
+
+  PropagatorMockup(PredefinedCosts&& costs = PredefinedCosts::constant(0.0), std::size_t solutions_per_compute = 1);
+  PropagatorMockup(std::initializer_list<double> costs)
+    : PropagatorMockup{ PredefinedCosts{ std::list<double>{ costs }, true } }
+  {}
+
+  void computeForward(const InterfaceState& from) override;
+  void computeBackward(const InterfaceState& to) override;
+  virtual void reset() override
+  {
+    runs_ = 0;
+  };
+};
+
+struct ForwardMockup : public PropagatorMockup
+{
+  static unsigned int id_;
+
+  ForwardMockup(PredefinedCosts&& costs = PredefinedCosts::constant(0.0), std::size_t solutions_per_compute = 1);
+  ForwardMockup(std::initializer_list<double> costs)
+    : ForwardMockup{ PredefinedCosts{ std::list<double>{ costs }, true } }
+  {}
+};
+
+struct BackwardMockup : public PropagatorMockup
+{
+  static unsigned int id_;
+
+  BackwardMockup(PredefinedCosts&& costs = PredefinedCosts::constant(0.0), std::size_t solutions_per_compute = 1);
+  BackwardMockup(std::initializer_list<double> costs)
+    : BackwardMockup{ PredefinedCosts{ std::list<double>{ costs }, true } }
+  {}
+};
+
+// ForwardMockup that takes a while for its computation
+class TimedForwardMockup : public ForwardMockup
+{
+  std::chrono::milliseconds duration_;
+
+public:
+  TimedForwardMockup(std::chrono::milliseconds duration)
+    : ForwardMockup{}, duration_{ duration }
+  {}
+  void computeForward(const InterfaceState& from) override
+  {
+    std::this_thread::sleep_for(duration_);
+    ForwardMockup::computeForward(from);
+  }
+};
+
+// reset ids of all Mockup types (used to generate unique stage names)
+void resetMockupIds();
+
+}  // namespace task_constructor
+}  // namespace moveit