docs: private void handleRules(TSDB tsdb, HttpQuery query) {
      int tree_id = 0;
      List<TreeRule> rules = null;
      if (query.hasContent()) {
        rules = query.serializer().parseTreeRulesV1();
        if (rules == null || rules.isEmpty()) {
          throw new BadRequestException("Missing tree rules");
        }
        
        // validate that they all belong to the same tree
        tree_id = rules.get(0).getTreeId();
        for (TreeRule rule : rules) {
          if (rule.getTreeId() != tree_id) {
            throw new BadRequestException(
                "All rules must belong to the same tree");
          }
        }
      } else {
        tree_id = parseTreeId(query, false);
      }
      
      // make sure the tree exists
      try {
        if (Tree.fetchTree(tsdb, tree_id).joinUninterruptibly() == null) {
          throw new BadRequestException(HttpResponseStatus.NOT_FOUND, 
              "Unable to locate tree: " + tree_id);
        }
      
        if (query.getAPIMethod() == HttpMethod.POST || query.getAPIMethod() == HttpMethod.PUT) {
          if (rules == null || rules.isEmpty()) {
            if (rules == null || rules.isEmpty()) {
              throw new BadRequestException("Missing tree rules");
            }
          }
          
          // purge the existing tree rules if we're told to PUT
          if (query.getAPIMethod() == HttpMethod.PUT) {
            TreeRule.deleteAllRules(tsdb, tree_id).joinUninterruptibly();
          }
          for (TreeRule rule : rules) {
            rule.syncToStorage(tsdb, query.getAPIMethod() == HttpMethod.PUT)
              .joinUninterruptibly();
          }
          query.sendStatusOnly(HttpResponseStatus.NO_CONTENT);
    
        } else if (query.getAPIMethod() == HttpMethod.DELETE) {
    
          TreeRule.deleteAllRules(tsdb, tree_id).joinUninterruptibly();
          query.sendStatusOnly(HttpResponseStatus.NO_CONTENT);
    
        } else {
          throw new BadRequestException(HttpResponseStatus.BAD_REQUEST, 
            "Unsupported HTTP request method");
        }
      
      } catch (BadRequestException e) {
        throw e;
      } catch (IllegalArgumentException e) {
        throw new BadRequestException(e);
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }