docs: boolean canRemoveAllChildren( Name primaryTypeNameOfParent,
                                    Collection<Name> mixinTypeNamesOfParent,
                                    Name childName,
                                    boolean skipProtected ) {
          // First look in the primary type ...
          JcrNodeType primaryType = getNodeType(primaryTypeNameOfParent);
          if (primaryType != null) {
              for (JcrNodeDefinition definition : primaryType.allChildNodeDefinitions(childName)) {
                  // Skip protected definitions ...
                  if (skipProtected && definition.isProtected()) continue;
                  // If this definition is not mandatory, then we have found that we CAN remove all children ...
                  return !definition.isMandatory();
              }
          }
  
          // Then, look in the mixin types ...
          if (mixinTypeNamesOfParent != null) {
              for (Name mixinTypeName : mixinTypeNamesOfParent) {
                  JcrNodeType mixinType = getNodeType(mixinTypeName);
                  if (mixinType == null) continue;
                  for (JcrNodeDefinition definition : mixinType.allChildNodeDefinitions(childName)) {
                      // Skip protected definitions ...
                      if (skipProtected && definition.isProtected()) continue;
                      // If this definition is not mandatory, then we have found that we CAN remove all children ...
                      return !definition.isMandatory();
                  }
              }
          }
  
          // Nothing was found, so look for residual node definitions ...
          if (!childName.equals(JcrNodeType.RESIDUAL_NAME)) return canRemoveAllChildren(primaryTypeNameOfParent,
                                                                                        mixinTypeNamesOfParent,
                                                                                        JcrNodeType.RESIDUAL_NAME, skipProtected);
          return false;
      }