public static UnboundBooleanFlag defineFeatureFlag(String flagId, boolean defaultValue, List<String> owners,
                                                       String createdAt, String expiresAt, String description,
                                                       String modificationEffect, Dimension... dimensions) {
        return define(UnboundBooleanFlag::new, flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions);
    }
@Test
    void testBoolean() {
        final boolean defaultValue = false;
        FlagSource source = mock(FlagSource.class);
        BooleanFlag booleanFlag = Flags.defineFeatureFlag("id", defaultValue, List.of("owner"), "1970-01-01", "2100-01-01", "description",
                                                          "modification effect", Dimension.ZONE_ID, Dimension.HOSTNAME)
                .with(Dimension.ZONE_ID, "a-zone")
                .bindTo(source);
        assertThat(booleanFlag.id().toString(), equalTo("id"));

        when(source.fetch(eq(new FlagId("id")), any())).thenReturn(Optional.empty());
        // default value without raw flag
        assertThat(booleanFlag.value(), equalTo(defaultValue));

        ArgumentCaptor<FetchVector> vector = ArgumentCaptor.forClass(FetchVector.class);
        verify(source).fetch(any(), vector.capture());
        // hostname is set by default
        Optional<String> hostname = vector.getValue().getValue(Dimension.HOSTNAME);
        assertTrue(hostname.isPresent());
        assertFalse(hostname.get().isEmpty());
        // zone is set because it was set on the unbound flag above
        assertThat(vector.getValue().getValue(Dimension.ZONE_ID), is(Optional.of("a-zone")));
        // application and node type are not set
        assertThat(vector.getValue().getValue(Dimension.INSTANCE_ID), is(Optional.empty()));
        assertThat(vector.getValue().getValue(Dimension.NODE_TYPE), is(Optional.empty()));

        RawFlag rawFlag = mock(RawFlag.class);
        when(source.fetch(eq(new FlagId("id")), any())).thenReturn(Optional.of(rawFlag));
        when(rawFlag.asJsonNode()).thenReturn(BooleanNode.getTrue());

        // raw flag deserializes to true
        assertThat(booleanFlag.with(Dimension.INSTANCE_ID, "an-app").value(), equalTo(true));

        verify(source, times(2)).fetch(any(), vector.capture());
        // application was set on the (bound) flag.
        assertThat(vector.getValue().getValue(Dimension.INSTANCE_ID), is(Optional.of("an-app")));
    }