public FlagData partialResolve(FetchVector fetchVector) {
        // Note:  As a result of partialResolve, there could be e.g. two identical rules, and the latter will always be ignored by resolve().
        // Consider deduping.  Deduping is actually not specific to partialResolve and could be done e.g. at construction time.

        List<Rule> newRules = new ArrayList<>();
        for (var rule : rules) {
            Optional<Rule> partialRule = rule.partialResolve(fetchVector);
            if (partialRule.isPresent()) {
                newRules.add(partialRule.get());
                if (partialRule.get().conditions().isEmpty()) {
                    // Any following rule will always be ignored during resolution.
                    break;
                }
            }
        }
        newRules = optimizeRules(newRules);

        FetchVector newDefaultFetchVector = defaultFetchVector.without(fetchVector.dimensions());

        return new FlagData(id, newDefaultFetchVector, newRules);
    }
@Test
    void testPartialResolve() {
        FlagData data = FlagData.deserialize(json);
        assertEquals(data.partialResolve(vector), data);
        assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app1")),
                     FlagData.deserialize("""
                                {
                                    "id": "id1",
                                    "rules": [
                                        {
                                            "conditions": [
                                                {
                                                    "type": "whitelist",
                                                    "dimension": "zone",
                                                    "values": [ "zone1", "zone2" ]
                                                }
                                            ],
                                            "value": false
                                        }
                                    ],
                                    "attributes": {
                                        "zone": "zone1"
                                    }
                                }"""));

        assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app1")),
                     FlagData.deserialize("""
                                {
                                    "id": "id1",
                                    "rules": [
                                        {
                                            "conditions": [
                                                {
                                                    "type": "whitelist",
                                                    "dimension": "zone",
                                                    "values": [ "zone1", "zone2" ]
                                                }
                                            ],
                                            "value": false
                                        }
                                    ],
                                    "attributes": {
                                        "zone": "zone1"
                                    }
                                }"""));

        assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")),
                     FlagData.deserialize("""
                                {
                                    "id": "id1",
                                    "rules": [
                                        {
                                            "conditions": [
                                                {
                                                    "type": "whitelist",
                                                    "dimension": "hostname",
                                                    "values": [ "host1", "host2" ]
                                                }
                                            ],
                                            "value": true
                                        },
                                        {
                                            "conditions": [
                                                {
                                                    "type": "whitelist",
                                                    "dimension": "zone",
                                                    "values": [ "zone1", "zone2" ]
                                                }
                                            ],
                                            "value": false
                                        }
                                    ],
                                    "attributes": {
                                        "zone": "zone1"
                                    }
                                }"""));

        assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")
                                               .with(Dimension.HOSTNAME, "host1")),
                     FlagData.deserialize("""
                                {
                                    "id": "id1",
                                    "rules": [
                                        {
                                            "value": true
                                        }
                                    ],
                                    "attributes": {
                                        "zone": "zone1"
                                    }
                                }"""));

        assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")
                                               .with(Dimension.HOSTNAME, "host3")),
                     FlagData.deserialize("""
                                {
                                    "id": "id1",
                                    "rules": [
                                        {
                                            "conditions": [
                                                {
                                                    "type": "whitelist",
                                                    "dimension": "zone",
                                                    "values": [ "zone1", "zone2" ]
                                                }
                                            ],
                                            "value": false
                                        }
                                    ],
                                    "attributes": {
                                        "zone": "zone1"
                                    }
                                }"""));

        assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")
                                               .with(Dimension.HOSTNAME, "host3")
                                               .with(Dimension.ZONE_ID, "zone2")),
                     FlagData.deserialize("""
                                {
                                    "id": "id1",
                                    "rules": [
                                        {
                                            "value": false
                                        }
                                    ]
                                }"""));

        FlagData fullyResolved = data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")
                                                           .with(Dimension.HOSTNAME, "host3")
                                                           .with(Dimension.ZONE_ID, "zone3"));
        assertEquals(fullyResolved, FlagData.deserialize("""
                                {
                                    "id": "id1"
                                }"""));
        assertTrue(fullyResolved.isEmpty());
    }

    @Test
    void testRemovalOfSentinelRuleWithNullValue() {
        FlagData data = FlagData.deserialize("""
                                             {
                                                 "id": "id1",
                                                 "rules": [
                                                     {
                                                         "conditions": [
                                                             {
                                                                 "type": "whitelist",
                                                                 "dimension": "zone",
                                                                 "values": [ "zone1", "zone2" ]
                                                             }
                                                         ],
                                                         "value": null
                                                     }
                                                 ]
                                             }""");
        assertEquals(data, new FlagData(data.id(), new FetchVector(), List.of()));
        assertTrue(data.isEmpty());
    }

    @Test
    void testRemovalOfSentinelRuleWithoutValue() {
        String json = """
                        {
                            "id": "id1",
                            "rules": [
                                {
                                    "conditions": [
                                        {
                                            "type": "whitelist",
                                            "dimension": "zone",
                                            "values": [ "zone1", "zone2" ]
                                        }
                                    ]
                                },
                                {
                                    "conditions": [
                                        {
                                            "type": "whitelist",
                                            "dimension": "cloud",
                                            "values": [ "aws" ]
                                        }
                                    ],
                                    "value": true
                                }
                            ]
                        }""";
        FlagData data = FlagData.deserialize(json);
        assertTrue(JSON.equals(data.serializeToJson(), json));
        FlagData flagData = data.partialResolve(vector.with(Dimension.CLOUD, "gcp"));
        assertEquals(flagData, new FlagData(data.id(), new FetchVector(), List.of()));
        assertTrue(flagData.isEmpty());
    }

    private void verify(Optional<String> expectedValue, FetchVector vector) {
        FlagData data = FlagData.deserialize(json);
        assertEquals("id1", data.id().toString());
        Optional<RawFlag> rawFlag = data.resolve(vector);

        if (expectedValue.isPresent()) {
            assertTrue(rawFlag.isPresent());
            assertEquals(expectedValue.get(), rawFlag.get().asJson());
        } else {
            assertFalse(rawFlag.isPresent());
        }

    }