schema tree FEATURE force feature enable and disable
diff --git a/src/tree_schema.c b/src/tree_schema.c
index e89cd01..a840121 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -495,7 +495,7 @@
  * @return LY_ERR value.
  */
 static LY_ERR
-lys_feature_change(const struct lys_module *mod, const char *name, int value)
+lys_feature_change(const struct lys_module *mod, const char *name, int value, int skip_checks)
 {
     int all = 0;
     LY_ARRAY_COUNT_TYPE u, disabled_count;
@@ -521,7 +521,7 @@
             return LY_SUCCESS;
         }
         LOGERR(ctx, LY_EINVAL, "Unable to switch feature since the module \"%s\" has no features.", mod->name);
-        return LY_EINVAL;
+        return LY_ENOTFOUND;
     }
 
     changed = ly_set_new();
@@ -543,18 +543,20 @@
             }
 
             if (value) { /* enable */
-                /* check referenced features if they are enabled */
-                LY_ARRAY_FOR(f->iffeatures, struct lysc_iffeature, iff) {
-                    if (lysc_iffeature_value(iff) == LY_ENOT) {
-                        if (all) {
-                            ++disabled_count;
-                            goto next;
-                        } else {
-                            LOGERR(ctx, LY_EDENIED,
-                                   "Feature \"%s\" cannot be enabled since it is disabled by its if-feature condition(s).",
-                                   f->name);
-                            ly_set_free(changed, NULL);
-                            return LY_EDENIED;
+                if (!skip_checks) {
+                    /* check referenced features if they are enabled */
+                    LY_ARRAY_FOR(f->iffeatures, struct lysc_iffeature, iff) {
+                        if (lysc_iffeature_value(iff) == LY_ENOT) {
+                            if (all) {
+                                ++disabled_count;
+                                goto next;
+                            } else {
+                                LOGERR(ctx, LY_EDENIED,
+                                    "Feature \"%s\" cannot be enabled since it is disabled by its if-feature condition(s).",
+                                    f->name);
+                                ly_set_free(changed, NULL);
+                                return LY_EDENIED;
+                            }
                         }
                     }
                 }
@@ -580,7 +582,7 @@
     if (!all && !changed->count) {
         LOGERR(ctx, LY_EINVAL, "Feature \"%s\" not found in module \"%s\".", name, mod->name);
         ly_set_free(changed, NULL);
-        return LY_EINVAL;
+        return LY_ENOTFOUND;
     }
 
     if (value && all && disabled_count) {
@@ -612,7 +614,7 @@
     }
 
     /* reflect change(s) in the dependent features */
-    for (u = 0; u < changed->count; ++u) {
+    for (u = 0; !skip_checks && (u < changed->count); ++u) {
         /* If a dependent feature is enabled, it can be now changed by the change (to false) of the value of
          * its if-feature statements. The reverse logic, automatically enable feature when its feature is enabled
          * is not done - by default, features are disabled and must be explicitely enabled. */
@@ -644,7 +646,7 @@
 {
     LY_CHECK_ARG_RET(NULL, module, feature, LY_EINVAL);
 
-    return lys_feature_change((struct lys_module*)module, feature, 1);
+    return lys_feature_change((struct lys_module*)module, feature, 1, 0);
 }
 
 API LY_ERR
@@ -652,13 +654,29 @@
 {
     LY_CHECK_ARG_RET(NULL, module, feature, LY_EINVAL);
 
-    return lys_feature_change((struct lys_module*)module, feature, 0);
+    return lys_feature_change((struct lys_module*)module, feature, 0, 0);
 }
 
-API int
+API LY_ERR
+lys_feature_enable_force(const struct lys_module *module, const char *feature)
+{
+    LY_CHECK_ARG_RET(NULL, module, feature, LY_EINVAL);
+
+    return lys_feature_change((struct lys_module*)module, feature, 1, 1);
+}
+
+API LY_ERR
+lys_feature_disable_force(const struct lys_module *module, const char *feature)
+{
+    LY_CHECK_ARG_RET(NULL, module, feature, LY_EINVAL);
+
+    return lys_feature_change((struct lys_module*)module, feature, 0, 1);
+}
+
+API LY_ERR
 lys_feature_value(const struct lys_module *module, const char *feature)
 {
-    struct lysc_feature *f;
+    struct lysc_feature *f = NULL;
     struct lysc_module *mod;
     LY_ARRAY_COUNT_TYPE u;
 
@@ -666,19 +684,33 @@
     mod = module->compiled;
 
     /* search for the specified feature */
-    for (u = 0; u < LY_ARRAY_COUNT(mod->features); ++u) {
+    LY_ARRAY_FOR(mod->features, u) {
         f = &mod->features[u];
         if (!strcmp(f->name, feature)) {
-            if (f->flags & LYS_FENABLED) {
-                return 1;
-            } else {
-                return 0;
-            }
+            break;
         }
     }
 
     /* feature definition not found */
-    return -1;
+    if (!f) {
+        return LY_ENOTFOUND;
+    }
+
+    /* feature disabled */
+    if (!(f->flags & LYS_FENABLED)) {
+        return LY_ENOT;
+    }
+
+    /* check referenced features if they are enabled */
+    LY_ARRAY_FOR(f->iffeatures, u) {
+        if (lysc_iffeature_value(&f->iffeatures[u]) == LY_ENOT) {
+            /* if-feature disabled */
+            return LY_ENOT;
+        }
+    }
+
+    /* feature enabled */
+    return LY_SUCCESS;
 }
 
 API const struct lysc_node *
diff --git a/src/tree_schema.h b/src/tree_schema.h
index 5410de4..5c4a4c3 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -1855,7 +1855,10 @@
  *
  * @param[in] module Module where the feature will be enabled.
  * @param[in] feature Name of the feature to enable. To enable all features at once, use asterisk (`*`) character.
- * @return LY_ERR value.
+ * @return LY_SUCCESS on success,
+ * @return LY_EINVAL if @p module is not implemented,
+ * @return LY_ENOTFOUND if @p feature was not found,
+ * @return LY_EDENIED if @p feature could not be enabled because it has some false if-feature statements.
  */
 LY_ERR lys_feature_enable(const struct lys_module *module, const char *feature);
 
@@ -1864,23 +1867,53 @@
  *
  * By default, when the module is loaded by libyang parser, all features are disabled.
  *
+ * If disabling a feature causes some other features that depend on this feature to become disabled.
+ *
  * @param[in] module Module where the feature will be disabled.
  * @param[in] feature Name of the feature to disable. To disable all features at once, use asterisk (`*`) character.
- * @return LY_ERR value
+ * @return LY_SUCCESS on success,
+ * @return LY_EINVAL if @p module is not implemented,
+ * @return LY_ENOTFOUND if @p feature was not found.
  */
 LY_ERR lys_feature_disable(const struct lys_module *module, const char *feature);
 
 /**
- * @brief Get the current status of the specified feature in the module.
+ * @brief Enable specified feature in the module disregarding its if-features.
+ *
+ * @param[in] module Module where the feature will be enabled.
+ * @param[in] feature Name of the feature to enable. To enable all features at once, use asterisk character.
+ * @return LY_SUCCESS on success,
+ * @return LY_EINVAL if @p module is not implemented,
+ * @return LY_ENOTFOUND if @p feature was not found.
+ */
+LY_ERR lys_feature_enable_force(const struct lys_module *module, const char *feature);
+
+/**
+ * @brief Disable specified feature in the module disregarding dependant features.
+ *
+ * By default, when the module is loaded by libyang parser, all features are disabled.
+ *
+ * @param[in] module Module where the feature will be disabled.
+ * @param[in] feature Name of the feature to disable. To disable all features at once, use asterisk character.
+ * @return LY_SUCCESS on success,
+ * @return LY_EINVAL if @p module is not implemented,
+ * @return LY_ENOTFOUND if @p feature was not found.
+ */
+LY_ERR lys_feature_disable_force(const struct lys_module *module, const char *feature);
+
+/**
+ * @brief Get the current real status of the specified feature in the module.
+ *
+ * If the feature is enabled, but some of its if-features are false, the feature is considered
+ * disabled.
  *
  * @param[in] module Module where the feature is defined.
  * @param[in] feature Name of the feature to inspect.
- * @return
- * - 1 if feature is enabled,
- * - 0 if feature is disabled,
- * - -1 in case of error (e.g. feature is not defined or invalid arguments)
+ * @return LY_SUCCESS if the feature is enabled,
+ * @return LY_ENOT if the feature is disabled,
+ * @return LY_ENOTFOUND if the feature was not found.
  */
-int lys_feature_value(const struct lys_module *module, const char *feature);
+LY_ERR lys_feature_value(const struct lys_module *module, const char *feature);
 
 /**
  * @brief Get next schema tree (sibling) node element that can be instantiated in a data tree. Returned node can