// Path: core/domain/src/main/java/org/hesperides/core/domain/templatecontainers/queries/IterablePropertyView.java
// @Value
// @EqualsAndHashCode(callSuper = true)
// public class IterablePropertyView extends AbstractPropertyView {
// 
//     List<AbstractPropertyView> properties;
// 
//     public IterablePropertyView(String name, List<AbstractPropertyView> properties) {
//         super(name);
//         this.properties = properties;
//     }
// 
//     @Override
//     protected Stream<PropertyView> flattenProperties() {
//         return Optional.ofNullable(properties)
//                 .orElseGet(Collections::emptyList)
//                 .stream()
//                 .map(AbstractPropertyView::flattenProperties)
//                 .flatMap(Function.identity());
//     }
// }


import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.*;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Value;
import org.hesperides.core.domain.templatecontainers.queries.AbstractPropertyView;
import org.hesperides.core.domain.templatecontainers.queries.IterablePropertyView;
import org.hesperides.core.domain.templatecontainers.queries.PropertyView;
import java.lang.reflect.Type;
import java.util.*;
import java.util.stream.Collectors;
            jsonObject.remove("fields");
            if (src.getProperties() != null) {
                // Cas d'une propriété itérable : seuls les champs "name" & "fields" ont du sens
                JsonArray jsonArray = new JsonArray();
                for (PropertyOutput propertyOutput : src.getProperties()) {
                    jsonArray.add(context.serialize(propertyOutput, PropertyOutput.class));
                }
                jsonObject.add("fields", jsonArray);
                jsonObject.remove("required");
                jsonObject.remove("comment");
                jsonObject.remove("defaultValue");
                jsonObject.remove("pattern");
                jsonObject.remove("password");
            }
            return jsonObject;
        }
    }

    PropertyOutput(AbstractPropertyView abstractPropertyView) {
        this.name = abstractPropertyView.getName();

        if (abstractPropertyView instanceof PropertyView) {
            final PropertyView propertyView = (PropertyView) abstractPropertyView;
            this.isRequired = propertyView.isRequired();
            this.comment = propertyView.getComment();
            this.defaultValue = propertyView.getDefaultValue();
            this.pattern = propertyView.getPattern();
            this.isPassword = propertyView.isPassword();
            this.properties = null;

// Path: core/domain/src/main/java/org/hesperides/core/domain/templatecontainers/queries/IterablePropertyView.java
// @Value
// @EqualsAndHashCode(callSuper = true)
// public class IterablePropertyView extends AbstractPropertyView {
// 
//     List<AbstractPropertyView> properties;
// 
//     public IterablePropertyView(String name, List<AbstractPropertyView> properties) {
//         super(name);
//         this.properties = properties;
//     }
// 
//     @Override
//     protected Stream<PropertyView> flattenProperties() {
//         return Optional.ofNullable(properties)
//                 .orElseGet(Collections::emptyList)
//                 .stream()
//                 .map(AbstractPropertyView::flattenProperties)
//                 .flatMap(Function.identity());
//     }
// }


// Path: core/presentation/src/main/java/org/hesperides/core/presentation/io/templatecontainers/PropertyOutput.java
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.*;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Value;
import org.hesperides.core.domain.templatecontainers.queries.AbstractPropertyView;
import org.hesperides.core.domain.templatecontainers.queries.IterablePropertyView;
import org.hesperides.core.domain.templatecontainers.queries.PropertyView;
import java.lang.reflect.Type;
import java.util.*;
import java.util.stream.Collectors;

            jsonObject.remove("fields");
            if (src.getProperties() != null) {
                // Cas d'une propriété itérable : seuls les champs "name" & "fields" ont du sens
                JsonArray jsonArray = new JsonArray();
                for (PropertyOutput propertyOutput : src.getProperties()) {
                    jsonArray.add(context.serialize(propertyOutput, PropertyOutput.class));
                }
                jsonObject.add("fields", jsonArray);
                jsonObject.remove("required");
                jsonObject.remove("comment");
                jsonObject.remove("defaultValue");
                jsonObject.remove("pattern");
                jsonObject.remove("password");
            }
            return jsonObject;
        }
    }

    PropertyOutput(AbstractPropertyView abstractPropertyView) {
        this.name = abstractPropertyView.getName();

        if (abstractPropertyView instanceof PropertyView) {
            final PropertyView propertyView = (PropertyView) abstractPropertyView;
            this.isRequired = propertyView.isRequired();
            this.comment = propertyView.getComment();
            this.defaultValue = propertyView.getDefaultValue();
            this.pattern = propertyView.getPattern();
            this.isPassword = propertyView.isPassword();
            this.properties = null;

        } else if (abstractPropertyView instanceof IterablePropertyView) {