class ExposedThing extends Thing<ExposedThingProperty<Object>, ExposedThingAction<Object, Object>, ExposedThingEvent<Object>> {

    public CompletableFuture<Map<String, Object>> readProperties() {
        // read all properties async
        List<CompletableFuture> futures = new ArrayList<>();

        Map<String, Object> values = new HashMap<>();
        getProperties().forEach((name, property) -> {
            CompletableFuture<Object> readFuture = property.read();
            CompletableFuture<Object> putValuesFuture = readFuture.thenApply(value -> values.put(name, value));
            futures.add(putValuesFuture);
        });

        // wait until all properties have been read
        return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).thenApply(f -> values);
    }

    @SuppressWarnings("squid:S107")  ExposedThing(Servient servient,
                 Subject subject,
                 String objectType,
                 Context objectContext,
                 String id,
                 String title,
                 Map<String, String> titles,
                 String description,
                 Map<String, String> descriptions,
                 List<Form> forms,
                 List<String> security,
                 Map<String, SecurityScheme> securityDefinitions,
                 String base,
                 Map<String, ExposedThingProperty<Object>> properties,
                 Map<String, ExposedThingAction<Object, Object>> actions,
                 Map<String, ExposedThingEvent<Object>> events);
    public  ExposedThing(Servient servient, Thing thing);
    public  ExposedThing(Servient servient);

}