diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 000000000..d757cdcb6
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,2 @@
+# This file was generated by https://github.com/audrow/update-ros2-repos
+* @adityapande-1995 @audrow @mjeronimo
diff --git a/action_tutorials/README.md b/action_tutorials/README.md
new file mode 100644
index 000000000..6422a7440
--- /dev/null
+++ b/action_tutorials/README.md
@@ -0,0 +1,21 @@
+# ROS2 Action Tutorials
+
+This tutorial demonstrates implementing ROS action servers and action clients.
+
+The action server in this case takes in an integer value between 0 and 45 named *order* and returns the Fibonacci sequence, a sequence with the form:
+$$F_0 = 0$$
+$$F_1 = 1$$
+$$F_{order}=F_{order-1} + F_{order-2}$$
+
+The action server calculates each number in the sequence one at a time and returns a partial sequence as feedback at each iteration. 
+If the action is cancelled before the entire sequence is calculated, the server stops calculating the sequence and no result is returned.
+The action client in this tutorial sends a goal to the action server with an order of 10.
+It logs each partial sequence returned as feedback. 
+Once the action is finished executing, the action client logs the resulting sequence.
+
+## Packages
+
+- [action_tutorials_cpp](./action_tutorials_cpp) implements the described action server and client using the rclcpp library in C++.
+- [action_tutorials_py](./action_tutorials_py) implements the described action server and client using the rclpy library in Python.
+- [action_tutorials_interfaces](./action_tutorials_interfaces) defines the interface for the Fibonacci action.
+This interface takes an *order* as a goal, returns a *partial sequence* as feedback and a *sequence* as a result.
diff --git a/action_tutorials/action_tutorials_cpp/CHANGELOG.rst b/action_tutorials/action_tutorials_cpp/CHANGELOG.rst
index 904a1d736..275ea435e 100644
--- a/action_tutorials/action_tutorials_cpp/CHANGELOG.rst
+++ b/action_tutorials/action_tutorials_cpp/CHANGELOG.rst
@@ -2,6 +2,14 @@
 Changelog for package action_tutorials_cpp
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+* Fix two small bugs in the fibonacci C++ tutorial. (`#564 <https://github.com/ros2/demos/issues/564>`_)
+* Contributors: Chris Lalancette
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/action_tutorials/action_tutorials_cpp/CMakeLists.txt b/action_tutorials/action_tutorials_cpp/CMakeLists.txt
index a3f012b08..56fa71897 100644
--- a/action_tutorials/action_tutorials_cpp/CMakeLists.txt
+++ b/action_tutorials/action_tutorials_cpp/CMakeLists.txt
@@ -6,9 +6,10 @@ if(NOT CMAKE_C_STANDARD)
   set(CMAKE_C_STANDARD 99)
 endif()
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/action_tutorials/action_tutorials_cpp/README.md b/action_tutorials/action_tutorials_cpp/README.md
new file mode 100644
index 000000000..742dd71ad
--- /dev/null
+++ b/action_tutorials/action_tutorials_cpp/README.md
@@ -0,0 +1,67 @@
+# Action Server
+
+In the constructor for `FibonacciActionServer`, an action server is created with callbacks that are called when a goal is received, when the goal is cancelled, and when the goal is accepted:
+
+```cpp
+this->action_server_ = rclcpp_action::create_server<Fibonacci>(
+  ...
+  "fibonacci",
+  std::bind(&FibonacciActionServer::handle_goal, this, _1, _2),
+  std::bind(&FibonacciActionServer::handle_cancel, this, _1),
+  std::bind(&FibonacciActionServer::handle_accepted, this, _1));
+```
+
+The `handle_goal` callback is called whenever a goal is sent to the action server by an action client.
+In the example code, the goal is accepted as long as the order is less than or equal to 46, otherwise it is rejected.
+This is to prevent potential [integer overflow](https://en.wikipedia.org/wiki/Integer_overflow):
+```cpp
+if (goal->order > 46) {
+  return rclcpp_action::GoalResponse::REJECT;
+}
+return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
+```
+
+The `handle_cancelled` callback is called whenever an action client requests to cancel the goal being executed.
+In this case, the goal cancel request is always accepted.
+
+The `handle_accepted` callback is called following the action server's acceptance of a goal. In this example, a thread is started to execute the goal:
+```cpp
+std::thread{std::bind(&FibonacciActionServer::execute, this, _1), goal_handle}.detach();
+```
+
+The execution thread calculates the Fibonacci sequence up to *order* and publishes partial sequences as feedback as each item is added to the sequence. 
+
+A `rclcpp::Rate` object is used to sleep between the calculation of each item in order to represent a long-running task.
+
+When execution is complete, the full sequence is returned to the action client.
+If the goal is cancelled during execution, no result is returned, however the caller may have received partial sequences as feedback up until cancelling.
+
+# Action Client
+
+In the constructor for `FibonacciActionClient`, and action client for the `fibonacci` action is created:
+
+```cpp
+this->client_ptr_ = rclcpp_action::create_client<Fibonacci>(
+      ...
+      "fibonacci");
+```
+
+A goal of type `Fibonacci` is created with order 10. 
+The goal is sent asynchronously with callbacks registered for the goal response, the feedback, and the goal result:
+
+```cpp
+auto send_goal_options = rclcpp_action::Client<Fibonacci>::SendGoalOptions();
+send_goal_options.goal_response_callback =
+  std::bind(&FibonacciActionClient::goal_response_callback, this, _1);
+send_goal_options.feedback_callback =
+  std::bind(&FibonacciActionClient::feedback_callback, this, _1, _2);
+send_goal_options.result_callback =
+  std::bind(&FibonacciActionClient::result_callback, this, _1);
+this->client_ptr_->async_send_goal(goal_msg, send_goal_options);
+```
+
+There are three types of callback functions:
+
+- The `goal_response_callback` is called when the action server accepts or rejects the goal.
+- The `feedback_callback` is called whenever the action server sends goal execution feedback.
+- The `goal_result_callback` is called when the action server is finished executing the goal and returns the result of the goal which is the full or partial Fibonacci sequence.
diff --git a/action_tutorials/action_tutorials_cpp/package.xml b/action_tutorials/action_tutorials_cpp/package.xml
index a5ab4188b..d0da62aa1 100644
--- a/action_tutorials/action_tutorials_cpp/package.xml
+++ b/action_tutorials/action_tutorials_cpp/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>action_tutorials_cpp</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>C++ action tutorial cpp code</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/action_tutorials/action_tutorials_interfaces/CHANGELOG.rst b/action_tutorials/action_tutorials_interfaces/CHANGELOG.rst
index 9e806d0e4..c77135d75 100644
--- a/action_tutorials/action_tutorials_interfaces/CHANGELOG.rst
+++ b/action_tutorials/action_tutorials_interfaces/CHANGELOG.rst
@@ -2,6 +2,14 @@
 Changelog for package action_tutorials_interfaces
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+* Remove action_msgs dependency (`#580 <https://github.com/ros2/demos/issues/580>`_)
+* Contributors: Jacob Perron
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/action_tutorials/action_tutorials_interfaces/README.md b/action_tutorials/action_tutorials_interfaces/README.md
new file mode 100644
index 000000000..aa858b789
--- /dev/null
+++ b/action_tutorials/action_tutorials_interfaces/README.md
@@ -0,0 +1,10 @@
+# Action Tutorials ROS2 Interface
+
+This tutorial defines the Fibonacci action for use with the action tutorials.
+There are three parts of the action:
+
+- The goal contains an *order* field which determines the length of the returned Fibonacci sequence.
+For example, order 2 should return sequence [0, 1] and order 5 should return sequence [0, 1, 1, 2, 3].
+- The feedback consists of a partial sequence that is returned as the Fibonacci sequence is calculated.
+For example, for order 5 at some point the partial sequence [0, 1, 1] will be returned.
+- The result consists of the complete Fibonacci sequence (ex. [0, 1, 1, 2, ..., 165580141]).
diff --git a/action_tutorials/action_tutorials_interfaces/package.xml b/action_tutorials/action_tutorials_interfaces/package.xml
index 43e1ab2b7..99bbed563 100644
--- a/action_tutorials/action_tutorials_interfaces/package.xml
+++ b/action_tutorials/action_tutorials_interfaces/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>action_tutorials_interfaces</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Action tutorials action</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
@@ -16,8 +17,6 @@
   <buildtool_depend>ament_cmake</buildtool_depend>
   <buildtool_depend>rosidl_default_generators</buildtool_depend>
 
-  <depend>action_msgs</depend>
-
   <exec_depend>rosidl_default_runtime</exec_depend>
 
   <test_depend>ament_lint_auto</test_depend>
diff --git a/action_tutorials/action_tutorials_py/CHANGELOG.rst b/action_tutorials/action_tutorials_py/CHANGELOG.rst
index 453d53f49..92de7761f 100644
--- a/action_tutorials/action_tutorials_py/CHANGELOG.rst
+++ b/action_tutorials/action_tutorials_py/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package action_tutorials_py
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/action_tutorials/action_tutorials_py/README.md b/action_tutorials/action_tutorials_py/README.md
new file mode 100644
index 000000000..c6b5f84ec
--- /dev/null
+++ b/action_tutorials/action_tutorials_py/README.md
@@ -0,0 +1,51 @@
+# Action Server
+
+In the constructor for `FibonacciActionServer`, an action server is created with a callback that is called when a goal is accepted.
+```python
+self._action_server = ActionServer(
+            self,
+            Fibonacci,
+            'fibonacci',
+            self.execute_callback)
+```
+
+There are three types of callbacks:
+
+- A `goal_callback` can optionally be added to conditionally accept or reject the goal, however, by default the goal is accepted.
+- A `cancel_callback` can also optionally be added to conditionally accept or reject the cancel goal request, however, by default the cancel goal request is accepted.
+- The `execute_callback` calculates the Fibonacci sequence up to *order* and publishes partial sequences as feedback as each item is added to the sequence.
+
+The thread sleeps for 1 second between the calculation of each item in order to represent a long-running task.
+When execution is complete, the full sequence is returned to the action client.
+
+# Action Client
+
+In the constructor for `FibonacciActionClient`, an action client for the `fibonacci` action is created:
+
+```python
+self._action_client = ActionClient(self, Fibonacci, 'fibonacci')
+```
+
+A goal of type `Fibonacci` is created with order 10.
+The goal is sent asynchronously with callbacks registered for the goal response and the feedback:
+
+```python
+self._send_goal_future = self._action_client.send_goal_async(
+            goal_msg,
+            feedback_callback=self.feedback_callback)
+
+self._send_goal_future.add_done_callback(self.goal_response_callback)
+```
+
+Within the `goal_response_callback`, if the goal is accepted, the goal result is requested asynchronously.
+A callback is registered for receiving the result:
+```python
+self._get_result_future = goal_handle.get_result_async()
+
+self._get_result_future.add_done_callback(self.get_result_callback)
+```
+
+There are two types of callbacks:
+
+- The `feedback_callback` logs the partial sequences as they are received.
+- The `get_result_callback` logs the full Fibonacci sequence.
diff --git a/action_tutorials/action_tutorials_py/package.xml b/action_tutorials/action_tutorials_py/package.xml
index 7501b8a8d..f30f10828 100644
--- a/action_tutorials/action_tutorials_py/package.xml
+++ b/action_tutorials/action_tutorials_py/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>action_tutorials_py</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Python action tutorial code</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/action_tutorials/action_tutorials_py/setup.py b/action_tutorials/action_tutorials_py/setup.py
index a37b9f131..1a3d13df5 100644
--- a/action_tutorials/action_tutorials_py/setup.py
+++ b/action_tutorials/action_tutorials_py/setup.py
@@ -4,7 +4,7 @@
 
 setup(
     name=package_name,
-    version='0.21.0',
+    version='0.23.0',
     packages=[package_name],
     data_files=[
         ('share/ament_index/resource_index/packages',
@@ -15,8 +15,8 @@
     zip_safe=True,
     author='Jacob Perron',
     author_email='jacob@openrobotics.org',
-    maintainer='Audrow Nash, Michael Jeronimo',
-    maintainer_email='audrow@openrobotics.org, michael.jeronimo@openrobotics.org',
+    maintainer='Aditya Pande, Audrow Nash, Michael Jeronimo',
+    maintainer_email='aditya.pande@openrobotics.org, audrow@openrobotics.org, michael.jeronimo@openrobotics.org',  # noqa: E501
     keywords=['ROS'],
     classifiers=[
         'Intended Audience :: Developers',
diff --git a/composition/CHANGELOG.rst b/composition/CHANGELOG.rst
index b48cc4fad..e15a6547d 100644
--- a/composition/CHANGELOG.rst
+++ b/composition/CHANGELOG.rst
@@ -2,6 +2,14 @@
 Changelog for package composition
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+* fix memory leak (`#585 <https://github.com/ros2/demos/issues/585>`_)
+* Contributors: Chen Lihui
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/composition/CMakeLists.txt b/composition/CMakeLists.txt
index a98ff1864..db1ab116d 100644
--- a/composition/CMakeLists.txt
+++ b/composition/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(composition)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/composition/package.xml b/composition/package.xml
index bfb1c66d1..a4c28be2f 100644
--- a/composition/package.xml
+++ b/composition/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>composition</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Examples for composing multiple nodes in a single process.</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/composition/src/dlopen_composition.cpp b/composition/src/dlopen_composition.cpp
index 6f5a5509e..52a950ae8 100644
--- a/composition/src/dlopen_composition.cpp
+++ b/composition/src/dlopen_composition.cpp
@@ -14,6 +14,7 @@
 
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "class_loader/class_loader.hpp"
@@ -35,7 +36,7 @@ int main(int argc, char * argv[])
   rclcpp::Logger logger = rclcpp::get_logger(DLOPEN_COMPOSITION_LOGGER_NAME);
   rclcpp::executors::SingleThreadedExecutor exec;
   rclcpp::NodeOptions options;
-  std::vector<class_loader::ClassLoader *> loaders;
+  std::vector<std::unique_ptr<class_loader::ClassLoader>> loaders;
   std::vector<rclcpp_components::NodeInstanceWrapper> node_wrappers;
 
   std::vector<std::string> libraries;
@@ -44,7 +45,7 @@ int main(int argc, char * argv[])
   }
   for (auto library : libraries) {
     RCLCPP_INFO(logger, "Load library %s", library.c_str());
-    auto loader = new class_loader::ClassLoader(library);
+    auto loader = std::make_unique<class_loader::ClassLoader>(library);
     auto classes = loader->getAvailableClasses<rclcpp_components::NodeFactory>();
     for (auto clazz : classes) {
       RCLCPP_INFO(logger, "Instantiate class %s", clazz.c_str());
@@ -54,7 +55,7 @@ int main(int argc, char * argv[])
       node_wrappers.push_back(wrapper);
       exec.add_node(node);
     }
-    loaders.push_back(loader);
+    loaders.push_back(std::move(loader));
   }
 
   exec.spin();
diff --git a/demo_nodes_cpp/CHANGELOG.rst b/demo_nodes_cpp/CHANGELOG.rst
index 8a533c7d6..4d55834a4 100644
--- a/demo_nodes_cpp/CHANGELOG.rst
+++ b/demo_nodes_cpp/CHANGELOG.rst
@@ -2,6 +2,18 @@
 Changelog for package demo_nodes_cpp
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+* Demo for pre and post set parameter callback support (`#565 <https://github.com/ros2/demos/issues/565>`_)
+  * local parameter callback support
+* Contributors: Deepanshu Bansal
+
+0.22.0 (2022-09-13)
+-------------------
+* counter starts from 1, not 2. (`#562 <https://github.com/ros2/demos/issues/562>`_)
+* add a demo of content filter listener (`#557 <https://github.com/ros2/demos/issues/557>`_)
+* Contributors: Chen Lihui, Tomoya Fujita
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/demo_nodes_cpp/CMakeLists.txt b/demo_nodes_cpp/CMakeLists.txt
index a1ee6b246..8e708ea75 100644
--- a/demo_nodes_cpp/CMakeLists.txt
+++ b/demo_nodes_cpp/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(demo_nodes_cpp)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
@@ -66,7 +67,8 @@ add_library(parameters_library SHARED
   src/parameters/parameter_blackboard.cpp
   src/parameters/set_and_get_parameters.cpp
   src/parameters/parameter_events_async.cpp
-  src/parameters/even_parameters_node.cpp)
+  src/parameters/even_parameters_node.cpp
+  src/parameters/set_parameters_callback.cpp)
 add_library(topics_library SHARED
   src/topics/content_filtering_publisher.cpp
   src/topics/content_filtering_subscriber.cpp
@@ -110,6 +112,9 @@ rclcpp_components_register_node(parameters_library
 rclcpp_components_register_node(parameters_library
   PLUGIN "demo_nodes_cpp::EvenParameterNode"
   EXECUTABLE even_parameters_node)
+rclcpp_components_register_node(parameters_library
+  PLUGIN "demo_nodes_cpp::SetParametersCallback"
+  EXECUTABLE set_parameters_callback)
 
 rclcpp_components_register_node(topics_library
   PLUGIN "demo_nodes_cpp::ContentFilteringPublisher"
diff --git a/demo_nodes_cpp/package.xml b/demo_nodes_cpp/package.xml
index e070ed4b9..8ce5d96e4 100644
--- a/demo_nodes_cpp/package.xml
+++ b/demo_nodes_cpp/package.xml
@@ -2,11 +2,12 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>demo_nodes_cpp</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>
     C++ nodes which were previously in the ros2/examples repository but are now just used for demo purposes.
   </description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/demo_nodes_cpp/src/parameters/set_parameters_callback.cpp b/demo_nodes_cpp/src/parameters/set_parameters_callback.cpp
new file mode 100644
index 000000000..1ca340745
--- /dev/null
+++ b/demo_nodes_cpp/src/parameters/set_parameters_callback.cpp
@@ -0,0 +1,114 @@
+// Copyright 2022 Open Source Robotics Foundation, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * Example usage: changing param1 successfully will result in setting of param2.
+ * ros2 service call /set_parameters_callback/set_parameters rcl_interfaces/srv/SetParameters
+                    "{parameters: [{name: "param1", value: {type: 3, double_value: 1.0}}]}"
+ */
+
+#include <string>
+
+#include "rclcpp/rclcpp.hpp"
+#include "rcl_interfaces/msg/set_parameters_result.hpp"
+#include "rclcpp_components/register_node_macro.hpp"
+
+#include "demo_nodes_cpp/visibility_control.h"
+
+/**
+ * node for demonstrating correct usage of pre_set, on_set
+ * and post_set parameter callbacks
+ */
+namespace demo_nodes_cpp
+{
+class SetParametersCallback : public rclcpp::Node
+{
+public:
+  DEMO_NODES_CPP_PUBLIC
+  explicit SetParametersCallback(const rclcpp::NodeOptions & options)
+  : Node("set_parameters_callback", options)
+  {
+    // tracks "param1" value
+    internal_tracked_class_parameter_1_ = this->declare_parameter("param1", 0.0);
+    // tracks "param2" value
+    internal_tracked_class_parameter_2_ = this->declare_parameter("param2", 0.0);
+
+    // setting another parameter from the callback is possible
+    // we expect the callback to be called for param2
+    auto pre_set_parameter_callback =
+      [this](std::vector<rclcpp::Parameter> & parameters) {
+        for (auto & param : parameters) {
+          // if "param1" is being set try setting "param2" as well.
+          if (param.get_name() == "param1") {
+            parameters.push_back(rclcpp::Parameter("param2", 4.0));
+          }
+        }
+      };
+
+    // validation callback
+    auto on_set_parameter_callback =
+      [this](std::vector<rclcpp::Parameter> parameters) {
+        rcl_interfaces::msg::SetParametersResult result;
+        for (const auto & param : parameters) {
+          if (param.get_name() == "param1") {
+            result.successful = true;
+            result.reason = "success param1";
+          }
+          if (param.get_name() == "param2") {
+            result.successful = true;
+            result.reason = "success param2";
+          }
+        }
+
+        return result;
+      };
+
+    // can change internally tracked class attributes
+    auto post_set_parameter_callback =
+      [this](const std::vector<rclcpp::Parameter> & parameters) {
+        for (const auto & param : parameters) {
+          if (param.get_name() == "param1") {
+            internal_tracked_class_parameter_1_ = param.get_value<double>();
+          }
+
+          // the class member can be changed after successful set to param2.
+          if (param.get_name() == "param2") {
+            internal_tracked_class_parameter_2_ = param.get_value<double>();
+          }
+        }
+      };
+
+    pre_set_parameters_callback_handle_ = this->add_pre_set_parameters_callback(
+      pre_set_parameter_callback);
+    on_set_parameters_callback_handle_ = this->add_on_set_parameters_callback(
+      on_set_parameter_callback);
+    post_set_parameters_callback_handle_ = this->add_post_set_parameters_callback(
+      post_set_parameter_callback);
+  }
+
+private:
+  rclcpp::node_interfaces::PreSetParametersCallbackHandle::SharedPtr
+    pre_set_parameters_callback_handle_;
+  rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr
+    on_set_parameters_callback_handle_;
+  rclcpp::node_interfaces::PostSetParametersCallbackHandle::SharedPtr
+    post_set_parameters_callback_handle_;
+
+  double internal_tracked_class_parameter_1_;
+  double internal_tracked_class_parameter_2_;
+};
+
+}  // namespace demo_nodes_cpp
+
+RCLCPP_COMPONENTS_REGISTER_NODE(demo_nodes_cpp::SetParametersCallback)
diff --git a/demo_nodes_cpp_native/CHANGELOG.rst b/demo_nodes_cpp_native/CHANGELOG.rst
index 97cb2e042..21e1f7883 100644
--- a/demo_nodes_cpp_native/CHANGELOG.rst
+++ b/demo_nodes_cpp_native/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package demo_nodes_cpp_native
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/demo_nodes_cpp_native/CMakeLists.txt b/demo_nodes_cpp_native/CMakeLists.txt
index 2cd3322ce..2bccfe5ff 100644
--- a/demo_nodes_cpp_native/CMakeLists.txt
+++ b/demo_nodes_cpp_native/CMakeLists.txt
@@ -2,9 +2,16 @@ cmake_minimum_required(VERSION 3.5)
 
 project(demo_nodes_cpp_native)
 
-# Default to C++14
+find_package(rmw_fastrtps_cpp QUIET)
+if(NOT rmw_fastrtps_cpp_FOUND)
+  message(STATUS "Could not find rmw_fastrtps_cpp - skipping")
+  return()
+endif()
+
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
@@ -16,71 +23,68 @@ find_package(rclcpp REQUIRED)
 find_package(rclcpp_components REQUIRED)
 find_package(rmw REQUIRED)
 find_package(std_msgs REQUIRED)
-find_package(rmw_fastrtps_cpp QUIET)
 
 include_directories(include)
 
-if(rmw_fastrtps_cpp_FOUND)
-  add_library(talker_native SHARED
-    src/talker.cpp)
-  target_compile_definitions(talker_native
-    PRIVATE "DEMO_NODES_CPP_NATIVE_BUILDING_DLL")
-  ament_target_dependencies(talker_native
-    "rclcpp"
-    "std_msgs"
-    "rclcpp_components"
-    "rmw_fastrtps_cpp")
-  rclcpp_components_register_node(talker_native PLUGIN "demo_nodes_cpp_native::Talker" EXECUTABLE talker)
-  install(TARGETS
-    talker_native
-    ARCHIVE DESTINATION lib
-    LIBRARY DESTINATION lib
-    RUNTIME DESTINATION bin)
+add_library(talker_native SHARED
+  src/talker.cpp)
+target_compile_definitions(talker_native
+  PRIVATE "DEMO_NODES_CPP_NATIVE_BUILDING_DLL")
+ament_target_dependencies(talker_native
+  "rclcpp"
+  "std_msgs"
+  "rclcpp_components"
+  "rmw_fastrtps_cpp")
+rclcpp_components_register_node(talker_native PLUGIN "demo_nodes_cpp_native::Talker" EXECUTABLE talker)
+install(TARGETS
+  talker_native
+  ARCHIVE DESTINATION lib
+  LIBRARY DESTINATION lib
+  RUNTIME DESTINATION bin)
 
-  if(BUILD_TESTING)
-    find_package(ament_lint_auto REQUIRED)
-    ament_lint_auto_find_test_dependencies()
+if(BUILD_TESTING)
+  find_package(ament_lint_auto REQUIRED)
+  ament_lint_auto_find_test_dependencies()
 
-    find_package(ament_cmake_pytest REQUIRED)
-    find_package(launch_testing_ament_cmake REQUIRED)
+  find_package(ament_cmake_pytest REQUIRED)
+  find_package(launch_testing_ament_cmake REQUIRED)
 
-    set(tutorial_executables "talker")
+  set(tutorial_executables "talker")
 
-    set(DEMO_NODES_CPP_EXPECTED_OUTPUT "")
-    foreach(executable ${tutorial_executables})
-      list(APPEND DEMO_NODES_CPP_EXPECTED_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/test/${executable}")
-    endforeach()
+  set(DEMO_NODES_CPP_EXPECTED_OUTPUT "")
+  foreach(executable ${tutorial_executables})
+    list(APPEND DEMO_NODES_CPP_EXPECTED_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/test/${executable}")
+  endforeach()
 
-    set(DEMO_NODES_CPP_EXECUTABLE "")
-    foreach(executable ${tutorial_executables})
-      list(APPEND DEMO_NODES_CPP_EXECUTABLE "$<TARGET_FILE:${executable}>")
-    endforeach()
+  set(DEMO_NODES_CPP_EXECUTABLE "")
+  foreach(executable ${tutorial_executables})
+    list(APPEND DEMO_NODES_CPP_EXECUTABLE "$<TARGET_FILE:${executable}>")
+  endforeach()
 
-    string(REPLACE ";" "_" exe_list_underscore "${tutorial_executables}")
-    configure_file(
-      test/test_executables_tutorial.py.in
-      test_${exe_list_underscore}.py.configured
-      @ONLY
-    )
-    file(GENERATE
-      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test_${exe_list_underscore}_$<CONFIG>.py"
-      INPUT "${CMAKE_CURRENT_BINARY_DIR}/test_${exe_list_underscore}.py.configured"
-    )
+  string(REPLACE ";" "_" exe_list_underscore "${tutorial_executables}")
+  configure_file(
+    test/test_executables_tutorial.py.in
+    test_${exe_list_underscore}.py.configured
+    @ONLY
+  )
+  file(GENERATE
+    OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/test_${exe_list_underscore}_$<CONFIG>.py"
+    INPUT "${CMAKE_CURRENT_BINARY_DIR}/test_${exe_list_underscore}.py.configured"
+  )
 
-    add_launch_test(
-      "${CMAKE_CURRENT_BINARY_DIR}/test_${exe_list_underscore}_$<CONFIG>.py"
-      TARGET test_tutorial_${exe_list_underscore}
-      TIMEOUT 30
-      ENV
-      RCL_ASSERT_RMW_ID_MATCHES=rmw_fastrtps_cpp
-      RMW_IMPLEMENTATION=rmw_fastrtps_cpp
-    )
-    foreach(executable ${tutorial_executables})
-      set_property(
-        TEST test_tutorial_${exe_list_underscore}
-        APPEND PROPERTY DEPENDS ${executable})
-    endforeach()
-  endif()
+  add_launch_test(
+    "${CMAKE_CURRENT_BINARY_DIR}/test_${exe_list_underscore}_$<CONFIG>.py"
+    TARGET test_tutorial_${exe_list_underscore}
+    TIMEOUT 30
+    ENV
+    RCL_ASSERT_RMW_ID_MATCHES=rmw_fastrtps_cpp
+    RMW_IMPLEMENTATION=rmw_fastrtps_cpp
+  )
+  foreach(executable ${tutorial_executables})
+    set_property(
+      TEST test_tutorial_${exe_list_underscore}
+      APPEND PROPERTY DEPENDS ${executable})
+  endforeach()
 endif()
 
 ament_package()
diff --git a/demo_nodes_cpp_native/package.xml b/demo_nodes_cpp_native/package.xml
index eda9d518e..9a44f7acf 100644
--- a/demo_nodes_cpp_native/package.xml
+++ b/demo_nodes_cpp_native/package.xml
@@ -2,11 +2,12 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>demo_nodes_cpp_native</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>
     C++ nodes which access the native handles of the rmw implementation.
   </description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/demo_nodes_py/CHANGELOG.rst b/demo_nodes_py/CHANGELOG.rst
index 10ec7dd27..379a0ec56 100644
--- a/demo_nodes_py/CHANGELOG.rst
+++ b/demo_nodes_py/CHANGELOG.rst
@@ -2,6 +2,17 @@
 Changelog for package demo_nodes_py
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+* Demo for pre and post set parameter callback support (`#565 <https://github.com/ros2/demos/issues/565>`_)
+* Contributors: Deepanshu Bansal
+
+0.22.0 (2022-09-13)
+-------------------
+* Add demo for rclpy parameter client (`#566 <https://github.com/ros2/demos/issues/566>`_)
+* Exit with code 0 if ExternalShutdownException is raised (`#581 <https://github.com/ros2/demos/issues/581>`_)
+* Contributors: Brian, Jacob Perron
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/demo_nodes_py/demo_nodes_py/parameters/__init__.py b/demo_nodes_py/demo_nodes_py/parameters/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/demo_nodes_py/demo_nodes_py/parameters/async_param_client.py b/demo_nodes_py/demo_nodes_py/parameters/async_param_client.py
new file mode 100644
index 000000000..1893d29e1
--- /dev/null
+++ b/demo_nodes_py/demo_nodes_py/parameters/async_param_client.py
@@ -0,0 +1,103 @@
+# Copyright 2022 Open Source Robotics Foundation, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import os
+
+from ament_index_python import get_package_share_directory
+import rclpy
+import rclpy.context
+from rclpy.parameter import Parameter
+from rclpy.parameter import parameter_dict_from_yaml_file
+from rclpy.parameter import parameter_value_to_python
+from rclpy.parameter_client import AsyncParameterClient
+
+
+def main(args=None):
+    rclpy.init()
+    node = rclpy.create_node('async_param_client')
+    client = AsyncParameterClient(node, 'parameter_blackboard')
+    if not client.wait_for_services(3.0):
+        raise RuntimeError(
+            'parameter_blackboard is not available, start parameter blackboard with '
+            '`ros2 run demo_nodes_cpp parameter_blackboard` before running this demo')
+    param_list = ['int_parameter', 'bool_parameter', 'string_parameter']
+
+    node.get_logger().info('Setting parameters:')
+    future = client.set_parameters([
+        Parameter('int_parameter', Parameter.Type.INTEGER, 10),
+        Parameter('bool_parameter', Parameter.Type.BOOL, False),
+        Parameter('string_parameter', Parameter.Type.STRING, 'Fee Fi Fo Fum'), ])
+    rclpy.spin_until_future_complete(node, future)
+    set_parameters_result = future.result()
+    if set_parameters_result is not None:
+        for i, v in enumerate(set_parameters_result.results):
+            node.get_logger().info(f'    {param_list[i]}:')
+            node.get_logger().info(f'        successful: {v.successful}')
+    else:
+        node.get_logger().error(f'Error setting parameters: {future.exception()}')
+
+    node.get_logger().info('Listing Parameters:')
+    future = client.list_parameters(param_list, 10)
+    rclpy.spin_until_future_complete(node, future)
+    list_parameters_result = future.result()
+    if list_parameters_result is not None:
+        for param_name in list_parameters_result.result.names:
+            node.get_logger().info(f'    - {param_name}')
+    else:
+        node.get_logger().error(f'Error listing parameters: {future.exception()}')
+
+    node.get_logger().info('Getting parameters:')
+    future = client.get_parameters(param_list)
+    rclpy.spin_until_future_complete(node, future)
+    get_parameters_result = future.result()
+    if get_parameters_result is not None:
+        for i, v in enumerate(get_parameters_result.values):
+            node.get_logger().info(f'    - {param_list[i]}: {parameter_value_to_python(v)}')
+    else:
+        node.get_logger().error(f'Error getting parameters: {future.exception()}')
+
+    node.get_logger().info('Loading parameters: ')
+    param_dir = get_package_share_directory('demo_nodes_py')
+    param_file_path = os.path.join(param_dir, 'params.yaml')
+    future = client.load_parameter_file(param_file_path)
+    rclpy.spin_until_future_complete(node, future)
+    load_parameter_results = future.result()
+    if load_parameter_results is not None:
+        param_file_dict = parameter_dict_from_yaml_file(param_file_path)
+        for i, v in enumerate(param_file_dict.keys()):
+            node.get_logger().info(f'    {v}:')
+            node.get_logger().info(f'        successful: '
+                                   f'{load_parameter_results.results[i].successful}')
+            node.get_logger().info(f'        value: '
+                                   f'{parameter_value_to_python(param_file_dict[v].value)}')
+    else:
+        node.get_logger().error(f'Error loading parameters: {future.exception()}')
+
+    node.get_logger().info('Deleting parameters: ')
+    params_to_delete = ['other_int_parameter', 'other_string_parameter', 'string_parameter']
+    future = client.delete_parameters(params_to_delete)
+    rclpy.spin_until_future_complete(node, future)
+    delete_parameters_result = future.result()
+    if delete_parameters_result is not None:
+        for i, v in enumerate(delete_parameters_result.results):
+            node.get_logger().info(f'    {params_to_delete[i]}:')
+            node.get_logger().info(f'        successful: {v.successful}')
+            node.get_logger().info(f'        reason: {v.reason}')
+    else:
+        node.get_logger().error(f'Error deleting parameters: {future.exception()}')
+
+    rclpy.shutdown()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/demo_nodes_py/demo_nodes_py/parameters/params.yaml b/demo_nodes_py/demo_nodes_py/parameters/params.yaml
new file mode 100644
index 000000000..768ddfd8e
--- /dev/null
+++ b/demo_nodes_py/demo_nodes_py/parameters/params.yaml
@@ -0,0 +1,7 @@
+/param_test_target:
+  ros__parameters:
+    other_int_parameter: 0
+    int_parameter: 12
+    string_parameter: I smell the blood of an Englishman
+    other_string_parameter: One fish, two fish, Red fish, blue fish
+    bool_parameter: False
diff --git a/demo_nodes_py/demo_nodes_py/parameters/set_parameters_callback.py b/demo_nodes_py/demo_nodes_py/parameters/set_parameters_callback.py
new file mode 100644
index 000000000..2e9c815ef
--- /dev/null
+++ b/demo_nodes_py/demo_nodes_py/parameters/set_parameters_callback.py
@@ -0,0 +1,90 @@
+# Copyright 2022 Open Source Robotics Foundation, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from rcl_interfaces.msg import SetParametersResult
+
+import rclpy
+from rclpy.executors import ExternalShutdownException
+from rclpy.node import Node
+from rclpy.parameter import Parameter
+
+
+# Example usage: changing param1 successfully will result in setting of param2.
+# ros2 service call /set_parameters_callback/set_parameters rcl_interfaces/srv/SetParameters
+#       "{parameters: [{name: "param1", value: {type: 3, double_value: 1.0}}]}"
+
+# node for demonstrating correct usage of pre_set, on_set
+# and post_set parameter callbacks
+class SetParametersCallback(Node):
+
+    def __init__(self):
+        super().__init__('set_parameters_callback')
+
+        # tracks 'param1' value
+        self.internal_tracked_param_1 = self.declare_parameter('param1', 0.0).value
+        # tracks 'param2' value
+        self.internal_tracked_param_2 = self.declare_parameter('param2', 0.0).value
+
+        # setting another parameter from the callback is possible
+        # we expect the callback to be called for param2
+        def pre_set_parameter_callback(parameter_list):
+            modified_parameters = parameter_list.copy()
+            for param in parameter_list:
+                if param.name == 'param1':
+                    modified_parameters.append(Parameter('param2', Parameter.Type.DOUBLE, 4.0))
+
+            return modified_parameters
+
+        # validation callback
+        def on_set_parameter_callback(parameter_list):
+            result = SetParametersResult()
+            for param in parameter_list:
+                if param.name == 'param1':
+                    result.successful = True
+                    result.reason = 'success param1'
+                elif param.name == 'param2':
+                    result.successful = True
+                    result.reason = 'success param2'
+
+            return result
+
+        # can change internally tracked class attributes
+        def post_set_parameter_callback(parameter_list):
+            for param in parameter_list:
+                if param.name == 'param1':
+                    self.internal_tracked_param_1 = param.value
+                elif param.name == 'param2':
+                    self.internal_tracked_param_2 = param.value
+
+        self.add_pre_set_parameters_callback(pre_set_parameter_callback)
+        self.add_on_set_parameters_callback(on_set_parameter_callback)
+        self.add_post_set_parameters_callback(post_set_parameter_callback)
+
+
+def main(args=None):
+    rclpy.init(args=args)
+
+    node = SetParametersCallback()
+
+    try:
+        rclpy.spin(node)
+    except (KeyboardInterrupt, ExternalShutdownException):
+        pass
+    finally:
+        node.destroy_node()
+        rclpy.try_shutdown()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/demo_nodes_py/demo_nodes_py/services/add_two_ints_server.py b/demo_nodes_py/demo_nodes_py/services/add_two_ints_server.py
index d67f193d1..806e41bc5 100644
--- a/demo_nodes_py/demo_nodes_py/services/add_two_ints_server.py
+++ b/demo_nodes_py/demo_nodes_py/services/add_two_ints_server.py
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import sys
-
 from example_interfaces.srv import AddTwoInts
 
 import rclpy
@@ -41,10 +39,8 @@ def main(args=None):
 
     try:
         rclpy.spin(node)
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         # Destroy the node explicitly
         # (optional - Done automatically when node is garbage collected)
diff --git a/demo_nodes_py/demo_nodes_py/topics/listener.py b/demo_nodes_py/demo_nodes_py/topics/listener.py
index f355af9b6..e52354a2b 100644
--- a/demo_nodes_py/demo_nodes_py/topics/listener.py
+++ b/demo_nodes_py/demo_nodes_py/topics/listener.py
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import sys
-
 import rclpy
 from rclpy.executors import ExternalShutdownException
 from rclpy.node import Node
@@ -37,10 +35,8 @@ def main(args=None):
     node = Listener()
     try:
         rclpy.spin(node)
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         node.destroy_node()
         rclpy.try_shutdown()
diff --git a/demo_nodes_py/demo_nodes_py/topics/listener_qos.py b/demo_nodes_py/demo_nodes_py/topics/listener_qos.py
index 64ec5de5c..5c9ce74d9 100644
--- a/demo_nodes_py/demo_nodes_py/topics/listener_qos.py
+++ b/demo_nodes_py/demo_nodes_py/topics/listener_qos.py
@@ -68,10 +68,8 @@ def main(argv=sys.argv[1:]):
         while rclpy.ok() and cycle_count < args.number_of_cycles:
             rclpy.spin_once(node)
             cycle_count += 1
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         node.destroy_node()
         rclpy.try_shutdown()
diff --git a/demo_nodes_py/demo_nodes_py/topics/listener_serialized.py b/demo_nodes_py/demo_nodes_py/topics/listener_serialized.py
index 0d8919718..d768cf23e 100644
--- a/demo_nodes_py/demo_nodes_py/topics/listener_serialized.py
+++ b/demo_nodes_py/demo_nodes_py/topics/listener_serialized.py
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import sys
-
 import rclpy
 from rclpy.executors import ExternalShutdownException
 from rclpy.node import Node
@@ -43,10 +41,8 @@ def main(args=None):
 
     try:
         rclpy.spin(serialized_subscriber)
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         # Destroy the node explicitly
         # (optional - otherwise it will be done automatically
diff --git a/demo_nodes_py/demo_nodes_py/topics/talker.py b/demo_nodes_py/demo_nodes_py/topics/talker.py
index fb1e707e8..119c342a0 100644
--- a/demo_nodes_py/demo_nodes_py/topics/talker.py
+++ b/demo_nodes_py/demo_nodes_py/topics/talker.py
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import sys
-
 import rclpy
 from rclpy.executors import ExternalShutdownException
 from rclpy.node import Node
@@ -45,10 +43,8 @@ def main(args=None):
 
     try:
         rclpy.spin(node)
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         node.destroy_node()
         rclpy.try_shutdown()
diff --git a/demo_nodes_py/demo_nodes_py/topics/talker_qos.py b/demo_nodes_py/demo_nodes_py/topics/talker_qos.py
index 4fd03c68e..ee2b9a166 100644
--- a/demo_nodes_py/demo_nodes_py/topics/talker_qos.py
+++ b/demo_nodes_py/demo_nodes_py/topics/talker_qos.py
@@ -75,10 +75,8 @@ def main(argv=sys.argv[1:]):
         while rclpy.ok() and cycle_count < args.number_of_cycles:
             rclpy.spin_once(node)
             cycle_count += 1
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         node.destroy_node()
         rclpy.try_shutdown()
diff --git a/demo_nodes_py/package.xml b/demo_nodes_py/package.xml
index 40fc4b011..46659041b 100644
--- a/demo_nodes_py/package.xml
+++ b/demo_nodes_py/package.xml
@@ -2,11 +2,12 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>demo_nodes_py</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>
     Python nodes which were previously in the ros2/examples repository but are now just used for demo purposes.
   </description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/demo_nodes_py/setup.py b/demo_nodes_py/setup.py
index d4e0cc012..d26f9d506 100644
--- a/demo_nodes_py/setup.py
+++ b/demo_nodes_py/setup.py
@@ -5,19 +5,18 @@
 
 setup(
     name=package_name,
-    version='0.21.0',
+    version='0.23.0',
     packages=find_packages(exclude=['test']),
     data_files=[
-        ('share/ament_index/resource_index/packages',
-            ['resource/' + package_name]),
-        ('share/' + package_name, ['package.xml']),
+        ('share/ament_index/resource_index/packages', ['resource/' + package_name]),
+        ('share/' + package_name, ['package.xml', 'demo_nodes_py/parameters/params.yaml']),
     ],
     install_requires=['setuptools'],
     zip_safe=True,
     author='Esteve Fernandez',
     author_email='esteve@osrfoundation.org',
-    maintainer='Audrow Nash, Michael Jeronimo',
-    maintainer_email='audrow@openrobotics.org, michael.jeronimo@openrobotics.org',
+    maintainer='Aditya Pande, Audrow Nash, Michael Jeronimo',
+    maintainer_email='aditya.pande@openrobotics.org, audrow@openrobotics.org, michael.jeronimo@openrobotics.org',  # noqa: E501
     keywords=['ROS'],
     classifiers=[
         'Intended Audience :: Developers',
@@ -40,7 +39,9 @@
             'listener_serialized = demo_nodes_py.topics.listener_serialized:main',
             'add_two_ints_client = demo_nodes_py.services.add_two_ints_client:main',
             'add_two_ints_client_async = demo_nodes_py.services.add_two_ints_client_async:main',
-            'add_two_ints_server = demo_nodes_py.services.add_two_ints_server:main'
+            'add_two_ints_server = demo_nodes_py.services.add_two_ints_server:main',
+            'async_param_client = demo_nodes_py.parameters.async_param_client:main',
+            'set_parameters_callback = demo_nodes_py.parameters.set_parameters_callback:main'
         ],
     },
 )
diff --git a/dummy_robot/dummy_map_server/CHANGELOG.rst b/dummy_robot/dummy_map_server/CHANGELOG.rst
index d4eccc82e..00a0a87dc 100644
--- a/dummy_robot/dummy_map_server/CHANGELOG.rst
+++ b/dummy_robot/dummy_map_server/CHANGELOG.rst
@@ -2,6 +2,14 @@
 Changelog for package dummy_map_server
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+* Added README.md for dummy_map_server (`#572 <https://github.com/ros2/demos/issues/572>`_)
+* Contributors: Gary Bey
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/dummy_robot/dummy_map_server/CMakeLists.txt b/dummy_robot/dummy_map_server/CMakeLists.txt
index 83a6ecdcc..66576a109 100644
--- a/dummy_robot/dummy_map_server/CMakeLists.txt
+++ b/dummy_robot/dummy_map_server/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(dummy_map_server)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
   add_compile_options(-Wall -Wextra -Wpedantic)
diff --git a/dummy_robot/dummy_map_server/README.md b/dummy_robot/dummy_map_server/README.md
new file mode 100644
index 000000000..fad59911a
--- /dev/null
+++ b/dummy_robot/dummy_map_server/README.md
@@ -0,0 +1,90 @@
+## **What Is This?**
+
+This demo creates and runs a ROS2 **node**, `dummy_map_server`, that publishes `nav_msgs::msg::OccupancyGrid` on a ROS2 publisher topic, `/map`.
+
+**dummy_map_server** is also a dependency of **dummy_robot_bringup**.
+
+Please refer to [dummy_robot_bringup](https://github.com/ros2/demos/tree/rolling/dummy_robot/dummy_robot_bringup).
+
+## **What Is An Occupancy Grid?**
+
+An occupancy grid can be thought of as a map of an environment that has been divided into grid cells, where each grid cell is either occupied or unoccupied (in advanced applications, they can have other states, too).
+
+This map of occupied and unoccupied grid cells can be used to help a robot navigate a space, for example to drive through a room with furniture.
+
+If a robot is navigating a new room, however, there may also be grid cells that are marked as unknown, until that area is explored.
+
+These different states are often stored in the occupancy grid as integers, for example:
+
+:warning: Note that the integer within a cell is application-specific and can go beyond `-1` and `1`.
+
+![](img/occupancy_grid.png)
+`-1` represents **unknown** spaces.
+`0` represents **unoccupied** spaces.
+`1` represents **occupied** spaces.
+
+The illustration above shows an example of an occupancy grid where the **bolded integer** indicates the position of a robot with a lidar sensor mounted on top of it and the red-colored grid cells indicate an obstacle such as a wall.
+
+## **Build**
+
+```bash
+colcon build --packages-up-to dummy_map_server
+```
+
+## **Run**
+
+```bash
+ros2 run dummy_map_server dummy_map_server
+```
+
+## **Verify**
+
+A similar terminal output should be seen after running `ros2 run dummy_map_server` and the following commands:
+
+```bash
+ros2 topic echo /map
+```
+
+
+```bash
+# Terminal Output
+header:
+  stamp:
+    sec: 1658559453
+    nanosec: 308405010
+  frame_id: world
+info:
+  map_load_time:
+    sec: 0
+    nanosec: 0
+  resolution: 0.10000000149011612
+  width: 100
+  height: 100
+  origin:
+    position:
+      x: -5.0
+      y: -5.0
+      z: 0.0
+    orientation:
+      x: 0.0
+      y: 0.0
+      z: 0.0
+      w: 1.0
+data:
+- -1
+- -1
+- -1
+- -1
+- -1
+- -1
+- -1
+- -1
+- -1
+- '...'
+---
+
+```
+
+## **References**
+
+- `nav_msgs::msg::OccupancyGrid` Message Format: https://github.com/ros2/common_interfaces/blob/rolling/nav_msgs/msg/OccupancyGrid.msg 
diff --git a/dummy_robot/dummy_map_server/img/occupancy_grid.png b/dummy_robot/dummy_map_server/img/occupancy_grid.png
new file mode 100644
index 000000000..4a218c854
Binary files /dev/null and b/dummy_robot/dummy_map_server/img/occupancy_grid.png differ
diff --git a/dummy_robot/dummy_map_server/package.xml b/dummy_robot/dummy_map_server/package.xml
index d3176b3dd..adceb0ef0 100644
--- a/dummy_robot/dummy_map_server/package.xml
+++ b/dummy_robot/dummy_map_server/package.xml
@@ -2,11 +2,12 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>dummy_map_server</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>
     dummy map server node
   </description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/dummy_robot/dummy_robot_bringup/CHANGELOG.rst b/dummy_robot/dummy_robot_bringup/CHANGELOG.rst
index 492fc3a7c..6282fe8ec 100644
--- a/dummy_robot/dummy_robot_bringup/CHANGELOG.rst
+++ b/dummy_robot/dummy_robot_bringup/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package dummy_robot_bringup
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/dummy_robot/dummy_robot_bringup/package.xml b/dummy_robot/dummy_robot_bringup/package.xml
index 5a1dab97a..a8a711071 100644
--- a/dummy_robot/dummy_robot_bringup/package.xml
+++ b/dummy_robot/dummy_robot_bringup/package.xml
@@ -2,11 +2,12 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>dummy_robot_bringup</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>
     dummy robot bringup
   </description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/dummy_robot/dummy_sensors/CHANGELOG.rst b/dummy_robot/dummy_sensors/CHANGELOG.rst
index 2763fb449..ba07505af 100644
--- a/dummy_robot/dummy_sensors/CHANGELOG.rst
+++ b/dummy_robot/dummy_sensors/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package dummy_sensors
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/dummy_robot/dummy_sensors/CMakeLists.txt b/dummy_robot/dummy_sensors/CMakeLists.txt
index 22688ed3e..e1ac906e1 100644
--- a/dummy_robot/dummy_sensors/CMakeLists.txt
+++ b/dummy_robot/dummy_sensors/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(dummy_sensors)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
   add_compile_options(-Wall -Wextra -Wpedantic)
diff --git a/dummy_robot/dummy_sensors/package.xml b/dummy_robot/dummy_sensors/package.xml
index d3d6db4f7..19e696a54 100644
--- a/dummy_robot/dummy_sensors/package.xml
+++ b/dummy_robot/dummy_sensors/package.xml
@@ -2,11 +2,12 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>dummy_sensors</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>
     dummy sensor nodes
   </description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/image_tools/CHANGELOG.rst b/image_tools/CHANGELOG.rst
index 58415ef48..b64949276 100644
--- a/image_tools/CHANGELOG.rst
+++ b/image_tools/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package image_tools
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/image_tools/CMakeLists.txt b/image_tools/CMakeLists.txt
index 8d6931e51..d38c9d22e 100644
--- a/image_tools/CMakeLists.txt
+++ b/image_tools/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(image_tools)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/image_tools/README.md b/image_tools/README.md
new file mode 100644
index 000000000..4722f784d
--- /dev/null
+++ b/image_tools/README.md
@@ -0,0 +1,32 @@
+## **What Is This?**
+
+This demo provides a simple utility to **connect to a workstation default camera device** and **display** it in an **OpenCV** window like below:
+
+![](img/result.png)
+
+## **Build**
+
+```bash
+colcon build --package-select image_tools
+```
+
+## **Run**
+
+In `image_tools` ROS2 package, 2 executables are provided, namely `cam2image` and `showimage` with different functions.
+
+## **1 - cam2image**
+Running this executable connects to your workstation's default camera device's video stream and publishes the images on '/image' and '/flipimage' topics using a ROS2 publisher.
+
+```bash
+# Open new terminal
+ros2 run image_tools cam2image
+```
+
+## **2 - showimage**
+Running this executable creates a ROS 2 node, `showimage`, which subscribes to the `sensor_msgs::msg::Image` topic, `/image` and displays the image messages in an **OpenCV** window.  
+
+```bash
+# Open new terminal
+# Run showimage ROS2 node to display the cam2image sensor_msg::msg::Image messages.
+ros2 run image_tools showimage
+```
diff --git a/image_tools/img/result.png b/image_tools/img/result.png
new file mode 100644
index 000000000..b45b85f4a
Binary files /dev/null and b/image_tools/img/result.png differ
diff --git a/image_tools/package.xml b/image_tools/package.xml
index 614da99c0..10a1de5f0 100644
--- a/image_tools/package.xml
+++ b/image_tools/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>image_tools</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Tools to capture and play back images to and from DDS subscriptions and publications.</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/intra_process_demo/CHANGELOG.rst b/intra_process_demo/CHANGELOG.rst
index e4f8f1122..8caf4283e 100644
--- a/intra_process_demo/CHANGELOG.rst
+++ b/intra_process_demo/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package intra_process_demo
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/intra_process_demo/CMakeLists.txt b/intra_process_demo/CMakeLists.txt
index 9f4458822..83c0ad8ea 100644
--- a/intra_process_demo/CMakeLists.txt
+++ b/intra_process_demo/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(intra_process_demo)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/intra_process_demo/package.xml b/intra_process_demo/package.xml
index 5a0dbb675..b7f6aa169 100644
--- a/intra_process_demo/package.xml
+++ b/intra_process_demo/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>intra_process_demo</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Demonstrations of intra process communication.</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/lifecycle/CHANGELOG.rst b/lifecycle/CHANGELOG.rst
index 699b864c1..88c816031 100644
--- a/lifecycle/CHANGELOG.rst
+++ b/lifecycle/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package lifecycle
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/lifecycle/CMakeLists.txt b/lifecycle/CMakeLists.txt
index 26f265b2c..ccf7f82cd 100644
--- a/lifecycle/CMakeLists.txt
+++ b/lifecycle/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(lifecycle)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/lifecycle/package.xml b/lifecycle/package.xml
index 07764c8f7..9a720c8b7 100644
--- a/lifecycle/package.xml
+++ b/lifecycle/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>lifecycle</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Package containing demos for lifecycle implementation</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/lifecycle_py/CHANGELOG.rst b/lifecycle_py/CHANGELOG.rst
index 7b9d86ef0..33b1c061f 100644
--- a/lifecycle_py/CHANGELOG.rst
+++ b/lifecycle_py/CHANGELOG.rst
@@ -2,6 +2,14 @@
 Changelog for package lifecycle_py
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+* Install the launch file for lifecycle_py. (`#586 <https://github.com/ros2/demos/issues/586>`_)
+* Contributors: Chris Lalancette
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/lifecycle_py/package.xml b/lifecycle_py/package.xml
index 379515f41..6fa63d6de 100644
--- a/lifecycle_py/package.xml
+++ b/lifecycle_py/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>lifecycle_py</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Package containing demos for rclpy lifecycle implementation</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/lifecycle_py/setup.py b/lifecycle_py/setup.py
index a0d874276..c68ce37f0 100644
--- a/lifecycle_py/setup.py
+++ b/lifecycle_py/setup.py
@@ -1,3 +1,6 @@
+import glob
+import os
+
 from setuptools import find_packages
 from setuptools import setup
 
@@ -5,19 +8,21 @@
 
 setup(
     name=package_name,
-    version='0.21.0',
+    version='0.23.0',
     packages=find_packages(exclude=['test']),
     data_files=[
         ('share/ament_index/resource_index/packages',
             ['resource/' + package_name]),
         ('share/' + package_name, ['package.xml']),
+        ('share/lifecycle_py/launch',
+            glob.glob(os.path.join('launch', '*.launch.py'))),
     ],
     install_requires=['setuptools'],
     zip_safe=True,
     author='Ivan Santiago Paunovic',
     author_email='ivanpauno@ekumenlabs.com',
-    maintainer='Ivan Santiago Paunovic',
-    maintainer_email='ivanpauno@ekumenlabs.com',
+    maintainer='Aditya Pande, Audrow Nash, Michael Jeronimo',
+    maintainer_email='aditya.pande@openrobotics.org, audrow@openrobotics.org, michael.jeronimo@openrobotics.org',  # noqa: E501
     keywords=['ROS'],
     classifiers=[
         'Intended Audience :: Developers',
diff --git a/logging_demo/CHANGELOG.rst b/logging_demo/CHANGELOG.rst
index b49a53a69..307b28b0b 100644
--- a/logging_demo/CHANGELOG.rst
+++ b/logging_demo/CHANGELOG.rst
@@ -2,6 +2,14 @@
 Changelog for package logging_demo
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+* Change dependency from 'rosidl_cmake' to 'rosidl_default_generators' (`#578 <https://github.com/ros2/demos/issues/578>`_)
+* Contributors: Jacob Perron
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/logging_demo/CMakeLists.txt b/logging_demo/CMakeLists.txt
index e18a88eec..7df09d989 100644
--- a/logging_demo/CMakeLists.txt
+++ b/logging_demo/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(logging_demo)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/logging_demo/package.xml b/logging_demo/package.xml
index 37b57ee20..d1e32a6f4 100644
--- a/logging_demo/package.xml
+++ b/logging_demo/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>logging_demo</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Examples for using and configuring loggers.</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
@@ -20,7 +21,7 @@
   <build_depend>rclcpp</build_depend>
   <build_depend>rclcpp_components</build_depend>
   <build_depend>rcutils</build_depend>
-  <build_depend>rosidl_cmake</build_depend>
+  <build_depend>rosidl_default_generators</build_depend>
   <build_depend>std_msgs</build_depend>
 
   <exec_depend>rclcpp</exec_depend>
diff --git a/pendulum_control/CHANGELOG.rst b/pendulum_control/CHANGELOG.rst
index aa98bf22c..bdd1849be 100644
--- a/pendulum_control/CHANGELOG.rst
+++ b/pendulum_control/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package pendulum_control
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/pendulum_control/CMakeLists.txt b/pendulum_control/CMakeLists.txt
index f04bd876e..d42d29a63 100644
--- a/pendulum_control/CMakeLists.txt
+++ b/pendulum_control/CMakeLists.txt
@@ -9,9 +9,10 @@ endif()
 
 find_package(ament_cmake REQUIRED)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/pendulum_control/package.xml b/pendulum_control/package.xml
index 092d153db..4104b9108 100644
--- a/pendulum_control/package.xml
+++ b/pendulum_control/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>pendulum_control</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Demonstrates ROS 2's realtime capabilities with a simulated inverted pendulum.</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/pendulum_msgs/CHANGELOG.rst b/pendulum_msgs/CHANGELOG.rst
index 62a0859a5..756715280 100644
--- a/pendulum_msgs/CHANGELOG.rst
+++ b/pendulum_msgs/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package pendulum_msgs
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/pendulum_msgs/package.xml b/pendulum_msgs/package.xml
index f94196fda..3b77030a3 100644
--- a/pendulum_msgs/package.xml
+++ b/pendulum_msgs/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>pendulum_msgs</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Custom messages for real-time pendulum control.</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/quality_of_service_demo/rclcpp/CHANGELOG.rst b/quality_of_service_demo/rclcpp/CHANGELOG.rst
index 2f1de1c90..302f697b9 100644
--- a/quality_of_service_demo/rclcpp/CHANGELOG.rst
+++ b/quality_of_service_demo/rclcpp/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package quality_of_service_demo_cpp
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/quality_of_service_demo/rclcpp/CMakeLists.txt b/quality_of_service_demo/rclcpp/CMakeLists.txt
index f1af978ff..53f048a3c 100644
--- a/quality_of_service_demo/rclcpp/CMakeLists.txt
+++ b/quality_of_service_demo/rclcpp/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(quality_of_service_demo_cpp)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/quality_of_service_demo/rclcpp/package.xml b/quality_of_service_demo/rclcpp/package.xml
index c1a573ca0..b6109c327 100644
--- a/quality_of_service_demo/rclcpp/package.xml
+++ b/quality_of_service_demo/rclcpp/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>quality_of_service_demo_cpp</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>C++ Demo applications for Quality of Service features</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/quality_of_service_demo/rclpy/CHANGELOG.rst b/quality_of_service_demo/rclpy/CHANGELOG.rst
index e97d5fd94..a0d02cbd8 100644
--- a/quality_of_service_demo/rclpy/CHANGELOG.rst
+++ b/quality_of_service_demo/rclpy/CHANGELOG.rst
@@ -2,6 +2,14 @@
 Changelog for package quality_of_service_demo_py
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+* Exit with code 0 if ExternalShutdownException is raised (`#581 <https://github.com/ros2/demos/issues/581>`_)
+* Contributors: Jacob Perron
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/quality_of_service_demo/rclpy/package.xml b/quality_of_service_demo/rclpy/package.xml
index 36f5d393f..685e3ce8e 100644
--- a/quality_of_service_demo/rclpy/package.xml
+++ b/quality_of_service_demo/rclpy/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>quality_of_service_demo_py</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Python Demo applications for Quality of Service features</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/quality_of_service_demo/rclpy/quality_of_service_demo_py/deadline.py b/quality_of_service_demo/rclpy/quality_of_service_demo_py/deadline.py
index 79b2abe2a..5c6de8450 100644
--- a/quality_of_service_demo/rclpy/quality_of_service_demo_py/deadline.py
+++ b/quality_of_service_demo/rclpy/quality_of_service_demo_py/deadline.py
@@ -12,7 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 import argparse
-import sys
 
 from quality_of_service_demo_py.common_nodes import Listener
 from quality_of_service_demo_py.common_nodes import Talker
@@ -72,10 +71,8 @@ def main(args=None):
     executor.add_node(talker)
     try:
         executor.spin()
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         rclpy.try_shutdown()
 
diff --git a/quality_of_service_demo/rclpy/quality_of_service_demo_py/incompatible_qos.py b/quality_of_service_demo/rclpy/quality_of_service_demo_py/incompatible_qos.py
index e1724a85e..0610a60b4 100644
--- a/quality_of_service_demo/rclpy/quality_of_service_demo_py/incompatible_qos.py
+++ b/quality_of_service_demo/rclpy/quality_of_service_demo_py/incompatible_qos.py
@@ -141,10 +141,8 @@ def main(args=None):
     try:
         while talker.publish_count < num_msgs:
             executor.spin_once()
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        return 1
     finally:
         rclpy.try_shutdown()
 
diff --git a/quality_of_service_demo/rclpy/quality_of_service_demo_py/message_lost_listener.py b/quality_of_service_demo/rclpy/quality_of_service_demo_py/message_lost_listener.py
index 82dd23bae..5ca9ec123 100644
--- a/quality_of_service_demo/rclpy/quality_of_service_demo_py/message_lost_listener.py
+++ b/quality_of_service_demo/rclpy/quality_of_service_demo_py/message_lost_listener.py
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import sys
-
 import rclpy
 from rclpy.executors import ExternalShutdownException
 from rclpy.executors import SingleThreadedExecutor
@@ -69,10 +67,8 @@ def main():
 
     try:
         executor.spin()
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         rclpy.try_shutdown()
 
diff --git a/quality_of_service_demo/rclpy/quality_of_service_demo_py/qos_overrides_listener.py b/quality_of_service_demo/rclpy/quality_of_service_demo_py/qos_overrides_listener.py
index 24106aa85..c0e63b6fe 100644
--- a/quality_of_service_demo/rclpy/quality_of_service_demo_py/qos_overrides_listener.py
+++ b/quality_of_service_demo/rclpy/quality_of_service_demo_py/qos_overrides_listener.py
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import sys
-
 import rclpy
 from rclpy.executors import ExternalShutdownException
 from rclpy.node import Node
@@ -53,10 +51,8 @@ def main(args=None):
     node = Listener()
     try:
         rclpy.spin(node)
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         rclpy.try_shutdown()
         node.destroy_node()
diff --git a/quality_of_service_demo/rclpy/quality_of_service_demo_py/qos_overrides_talker.py b/quality_of_service_demo/rclpy/quality_of_service_demo_py/qos_overrides_talker.py
index 7872a17ab..1d0e164ab 100644
--- a/quality_of_service_demo/rclpy/quality_of_service_demo_py/qos_overrides_talker.py
+++ b/quality_of_service_demo/rclpy/quality_of_service_demo_py/qos_overrides_talker.py
@@ -12,8 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import sys
-
 import rclpy
 from rclpy.executors import ExternalShutdownException
 from rclpy.node import Node
@@ -61,10 +59,8 @@ def main(args=None):
 
     try:
         rclpy.spin(node)
-    except KeyboardInterrupt:
+    except (KeyboardInterrupt, ExternalShutdownException):
         pass
-    except ExternalShutdownException:
-        sys.exit(1)
     finally:
         rclpy.try_shutdown()
         node.destroy_node()
diff --git a/quality_of_service_demo/rclpy/setup.py b/quality_of_service_demo/rclpy/setup.py
index 64b6f9d16..0d29b15a1 100644
--- a/quality_of_service_demo/rclpy/setup.py
+++ b/quality_of_service_demo/rclpy/setup.py
@@ -4,7 +4,7 @@
 
 setup(
     name=package_name,
-    version='0.21.0',
+    version='0.23.0',
     packages=[package_name],
     data_files=[
         ('share/ament_index/resource_index/packages', ['resource/' + package_name]),
@@ -13,8 +13,8 @@
     install_requires=['setuptools'],
     zip_safe=True,
     author='Emerson Knapp',
-    maintainer='Audrow Nash, Michael Jeronimo',
-    maintainer_email='audrow@openrobotics.org, michael.jeronimo@openrobotics.org',
+    maintainer='Aditya Pande, Audrow Nash, Michael Jeronimo',
+    maintainer_email='aditya.pande@openrobotics.org, audrow@openrobotics.org, michael.jeronimo@openrobotics.org',  # noqa: E501
     keywords=['ROS'],
     classifiers=[
         'Intended Audience :: Developers',
diff --git a/topic_monitor/CHANGELOG.rst b/topic_monitor/CHANGELOG.rst
index f3374ec73..c232ebf51 100644
--- a/topic_monitor/CHANGELOG.rst
+++ b/topic_monitor/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package topic_monitor
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/topic_monitor/package.xml b/topic_monitor/package.xml
index 4f7670f2b..602884ca9 100644
--- a/topic_monitor/package.xml
+++ b/topic_monitor/package.xml
@@ -2,9 +2,10 @@
 <?xml-model href="http://download.ros.org/schema/package_format2.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="2">
   <name>topic_monitor</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>Package containing tools for monitoring ROS 2 topics.</description>
 
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
   <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
 
diff --git a/topic_monitor/setup.py b/topic_monitor/setup.py
index 290cf2a41..f37b0e282 100644
--- a/topic_monitor/setup.py
+++ b/topic_monitor/setup.py
@@ -8,7 +8,7 @@
 
 setup(
     name=package_name,
-    version='0.21.0',
+    version='0.23.0',
     packages=find_packages(exclude=['test']),
     data_files=[
         ('share/ament_index/resource_index/packages',
@@ -22,6 +22,8 @@
         'setuptools',
     ],
     zip_safe=True,
+    maintainer='Aditya Pande, Audrow Nash, Michael Jeronimo',
+    maintainer_email='aditya.pande@openrobotics.org, audrow@openrobotics.org, michael.jeronimo@openrobotics.org',  # noqa: E501
     keywords=['ROS'],
     classifiers=[
         'Intended Audience :: Developers',
diff --git a/topic_statistics_demo/CHANGELOG.rst b/topic_statistics_demo/CHANGELOG.rst
index 6a54335d4..4e7d29989 100644
--- a/topic_statistics_demo/CHANGELOG.rst
+++ b/topic_statistics_demo/CHANGELOG.rst
@@ -2,6 +2,12 @@
 Changelog for package topic_statistics_demo
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+0.23.0 (2022-11-02)
+-------------------
+
+0.22.0 (2022-09-13)
+-------------------
+
 0.21.0 (2022-04-29)
 -------------------
 
diff --git a/topic_statistics_demo/CMakeLists.txt b/topic_statistics_demo/CMakeLists.txt
index 4443a58ef..99c6f368e 100644
--- a/topic_statistics_demo/CMakeLists.txt
+++ b/topic_statistics_demo/CMakeLists.txt
@@ -2,9 +2,10 @@ cmake_minimum_required(VERSION 3.5)
 
 project(topic_statistics_demo)
 
-# Default to C++14
+# Default to C++17
 if(NOT CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 17)
+  set(CMAKE_CXX_STANDARD_REQUIRED ON)
 endif()
 
 if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/topic_statistics_demo/package.xml b/topic_statistics_demo/package.xml
index 8d6fd9003..11f9ee4de 100644
--- a/topic_statistics_demo/package.xml
+++ b/topic_statistics_demo/package.xml
@@ -2,15 +2,19 @@
 <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
 <package format="3">
   <name>topic_statistics_demo</name>
-  <version>0.21.0</version>
+  <version>0.23.0</version>
   <description>C++ demo application for topic statistics feature.</description>
 
-  <maintainer email="mabel@openrobotics.org">Mabel Zhang</maintainer>
+  <maintainer email="aditya.pande@openrobotics.org">Aditya Pande</maintainer>
+  <maintainer email="audrow@openrobotics.org">Audrow Nash</maintainer>
   <maintainer email="michael.jeronimo@openrobotics.org">Michael Jeronimo</maintainer>
-  <maintainer email="ros-contributions@amazon.com">Amazon ROS Contributions</maintainer>
 
   <license>Apache License 2.0</license>
 
+  <author email="ros-contributions@amazon.com">Amazon ROS Contributions</author>
+  <author email="mabel@openrobotics.org">Mabel Zhang</author>
+  <author email="michael.jeronimo@openrobotics.org">Michael Jeronimo</author>
+
   <buildtool_depend>ament_cmake</buildtool_depend>
 
   <build_depend>rclcpp</build_depend>