docs: void executeBulkDelete(final TSDB tsdb, HttpQuery query) {
      try {
        final AnnotationBulkDelete delete_request;
        if (query.hasContent()) {
          delete_request = query.serializer().parseAnnotationBulkDeleteV1();
        } else {
          delete_request = parseBulkDeleteQS(query);
        }
        
        // validate the start time on the string. Users could request a timestamp of
        // 0 to delete all annotations, BUT we don't want them doing that accidentally
        if (delete_request.start_time == null || delete_request.start_time.isEmpty()) {
          throw new BadRequestException(HttpResponseStatus.BAD_REQUEST, 
              "Missing the start time value");
        }
        if (!delete_request.global && 
            (delete_request.tsuids == null || delete_request.tsuids.isEmpty())) {
          throw new BadRequestException(HttpResponseStatus.BAD_REQUEST, 
              "Missing the TSUIDs or global annotations flag");
        }
        
        final int pre_allocate = delete_request.tsuids != null ? 
            delete_request.tsuids.size() + 1 : 1;
        List<Deferred<Integer>> deletes = new ArrayList<Deferred<Integer>>(pre_allocate);
        if (delete_request.global) {
          deletes.add(Annotation.deleteRange(tsdb, null, 
              delete_request.getStartTime(), delete_request.getEndTime()));
        }
        if (delete_request.tsuids != null) {
          for (String tsuid : delete_request.tsuids) {
            deletes.add(Annotation.deleteRange(tsdb, UniqueId.stringToUid(tsuid), 
                delete_request.getStartTime(), delete_request.getEndTime()));
          }
        }
        
        Deferred.group(deletes).joinUninterruptibly();
        delete_request.total_deleted = 0; // just in case the caller set it
        for (Deferred<Integer> count : deletes) {
          delete_request.total_deleted += count.joinUninterruptibly();
        }
        query.sendReply(query.serializer()
            .formatAnnotationBulkDeleteV1(delete_request));
      } catch (BadRequestException e) {
        throw e;
      } catch (IllegalArgumentException e) {
        throw new BadRequestException(e);
      } catch (RuntimeException e) {
        throw new BadRequestException(e);
      } catch (Exception e) {
        throw new RuntimeException("Shouldn't be here", e);
      }
    }