tree schema FEATURE functions for schema iteration including inout
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 2edc493..7ef044b 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -1477,10 +1477,8 @@
     const char *node_name;
 
     /* compare with the module of the node */
-    if ((*node)->nodetype == LYS_INPUT) {
-        node_mod = ((struct lysc_node *)(((char *)*node) - offsetof(struct lysc_action, input)))->module;
-    } else if ((*node)->nodetype == LYS_OUTPUT) {
-        node_mod = ((struct lysc_node *)(((char *)*node) - offsetof(struct lysc_action, output)))->module;
+    if ((*node)->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
+        node_mod = lysc_node_parent_all(*node)->module;
     } else {
         node_mod = (*node)->module;
     }
@@ -1500,24 +1498,8 @@
         return 0;
     }
 
-    if ((*node)->nodetype & (LYS_INPUT | LYS_OUTPUT)) {
-        /* move up from input/output */
-        if ((*node)->nodetype == LYS_INPUT) {
-            (*node) = (struct lysc_node *)(((char *)*node) - offsetof(struct lysc_action, input));
-        } else {
-            (*node) = (struct lysc_node *)(((char *)*node) - offsetof(struct lysc_action, output));
-        }
-    } else if ((*node)->parent && ((*node)->parent->nodetype & (LYS_RPC | LYS_ACTION))) {
-        /* move to the input/output */
-        if ((*node)->flags & LYS_CONFIG_W) {
-            *node = (struct lysc_node *)&((struct lysc_action *)(*node)->parent)->input;
-        } else {
-            *node = (struct lysc_node *)&((struct lysc_action *)(*node)->parent)->output;
-        }
-    } else {
-        /* move to next parent */
-        *node = (*node)->parent;
-    }
+    /* move to next parent */
+    *node = lysc_node_parent_all(*node);
 
     return 1;
 }
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 32fb073..f65f985 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -101,6 +101,8 @@
  * - ::lysc_set_private()
  *
  * - ::lysc_node_children()
+ * - ::lysc_node_children_all()
+ * - ::lysc_node_parent_all()
  * - ::lysc_node_actions()
  * - ::lysc_node_notifs()
  *
@@ -1857,7 +1859,8 @@
 
 /**
  * @brief Get the children linked list of the given (compiled) schema node.
- * Decides the node's type and in case it has a children list, returns it.
+ * Skips over input and output nodes.
+ *
  * @param[in] node Node to examine.
  * @param[in] flags Config flag to distinguish input (LYS_CONFIG_W) and output (LYS_CONFIG_R) data in case of RPC/action node.
  * @return The node's children linked list if any, NULL otherwise.
@@ -1865,6 +1868,27 @@
 const struct lysc_node *lysc_node_children(const struct lysc_node *node, uint16_t flags);
 
 /**
+ * @brief Get the children linked list of the given (compiled) schema node.
+ * Returns all children node types including input and output.
+ *
+ * @param[in] node Node to examine.
+ * @param[in] flags Config flag to distinguish input (LYS_CONFIG_W) and output (LYS_CONFIG_R) child in case of RPC/action node.
+ * @return Children linked list if any,
+ * @return NULL otherwise.
+ */
+const struct lysc_node *lysc_node_children_all(const struct lysc_node *node, uint16_t flags);
+
+/**
+ * @brief Get the parent pointer from any type of (compiled) schema node.
+ * Returns input or output for direct descendants of these nodes.
+ *
+ * @param[in] node Node whose parent to get.
+ * @return Node parent.
+ * @return NULL is there is none.
+ */
+const struct lysc_node *lysc_node_parent_all(const struct lysc_node *node);
+
+/**
  * @brief Examine whether a node is user-ordered list or leaf-list.
  *
  * @param[in] schema Schema node to examine.
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 3ea2659..19ad8e2 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -1238,6 +1238,56 @@
     }
 }
 
+API const struct lysc_node *
+lysc_node_children_all(const struct lysc_node *node, uint16_t flags)
+{
+    switch (node->nodetype) {
+    case LYS_CONTAINER:
+        return ((struct lysc_node_container *)node)->child;
+    case LYS_CHOICE:
+        return (struct lysc_node *)((struct lysc_node_choice *)node)->cases;
+    case LYS_CASE:
+        return ((struct lysc_node_case *)node)->child;
+    case LYS_LIST:
+        return ((struct lysc_node_list *)node)->child;
+    case LYS_RPC:
+    case LYS_ACTION:
+        if (flags & LYS_CONFIG_R) {
+            return (struct lysc_node *)&((struct lysc_action *)node)->output;
+        } else {
+            /* LYS_CONFIG_W, but also the default case */
+            return (struct lysc_node *)&((struct lysc_action *)node)->input;
+        }
+    case LYS_INPUT:
+    case LYS_OUTPUT:
+        return ((struct lysc_action_inout *)node)->data;
+    case LYS_NOTIF:
+        return ((struct lysc_notif *)node)->data;
+    default:
+        return NULL;
+    }
+}
+
+API const struct lysc_node *
+lysc_node_parent_all(const struct lysc_node *node)
+{
+    if (!node) {
+        return NULL;
+    } else if (node->nodetype == LYS_INPUT) {
+        return (struct lysc_node *)(((char *)node) - offsetof(struct lysc_action, input));
+    } else if (node->nodetype == LYS_OUTPUT) {
+        return (struct lysc_node *)(((char *)node) - offsetof(struct lysc_action, output));
+    } else if (node->parent && (node->parent->nodetype & (LYS_RPC | LYS_ACTION))) {
+        if (node->flags & LYS_CONFIG_W) {
+            return (struct lysc_node *)&((struct lysc_action *)node->parent)->input;
+        } else {
+            return (struct lysc_node *)&((struct lysc_action *)node->parent)->output;
+        }
+    } else {
+        return node->parent;
+    }
+}
+
 struct lys_module *
 lysp_find_module(struct ly_ctx *ctx, const struct lysp_module *mod)
 {