public void parseJsonQuery(
            String json, FeatureHandler<String> featureHandler, FeatureHandler<Long> rangeFeatureHandler)
    throws IllegalArgumentException {

        try (JsonParser parser = factory.createParser(json)) {
            skipToken(parser, JsonToken.START_OBJECT);
            while (parser.nextToken() != JsonToken.END_OBJECT) {
                String fieldName = parser.currentName();
                switch (fieldName) {
                    case "features":
                        parseFeatures(parser, JsonParser::getText, featureHandler);
                        break;
                    case "rangeFeatures":
                        parseFeatures(parser, JsonParser::getLongValue, rangeFeatureHandler);
                        break;
                    default:
                        throw new IllegalArgumentException("Invalid field name: " + fieldName);
                }
            }
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (IOException e) {
            throw new AssertionError("This should never happen when parsing from a String", e);
        } catch (Exception e) {
            throw new IllegalArgumentException(String.format("Parsing query from JSON failed: '%s'", json), e);
        }
    }
@Test
    void require_that_json_is_correctly_parsed() {
        String json =
                "{" +
                        "   \"features\":[" +
                        "       {\"k\":\"k1\",\"v\":\"value1\",\"s\":\"0x1\"}," +
                        "       {\"k\":\"k2\",\"v\":\"value2\",\"s\":\"0x3\"}" +
                        "   ],\"rangeFeatures\":[" +
                        "       {\"k\":\"range1\",\"v\":123456789123,\"s\":\"0xffff\"}," +
                        "       {\"k\":\"range2\",\"v\":0,\"s\":\"0xffffffffffffffff\"}" +
                        "   ]" +
                        "}";

        PredicateQueryParser parser = new PredicateQueryParser();
        List<String> result = new ArrayList<>();
        parser.parseJsonQuery(
                json,
                (k, v, s) -> result.add(String.format("%s:%s:%#x", k, v, s)),
                (k, v, s) -> result.add(String.format("%s:%d:%#x", k, v, s)));

        assertEquals(result, List.of(
                "k1:value1:0x1", "k2:value2:0x3",
                "range1:123456789123:0xffff", "range2:0:0xffffffffffffffff"));
    }