private static Stream<Property> list(
		final PathValue<?> root,
		final Description description
	) {
		final var enclosure = root.value();

		return switch (description) {
			case SimpleDescription desc -> {
				final var param = new PropParam(
					root.path().append(desc.path().element()),
					enclosure,
					desc.access().getter().get(root.value()),
					toRawType(description.type()),
					desc.access().getter(),
					switch (desc.access()) {
						case Access.Readonly access -> null;
						case Access.Writable access -> access.setter();
					}
				);

				final Property prop = switch (PropertyType.of(desc.type())) {
					case ElementType t -> new SimpleProperty(param);
					case RecordType t -> new RecordProperty(param);
					case BeanType t -> new BeanProperty(param);
					case OptionalType t -> new OptionalProperty(param);
					case ArrayType t -> new ArrayProperty(param);
					case ListType t -> new ListProperty(param);
				};

				yield Stream.of(prop);
			}
			case IndexedDescription desc -> {
				final var path = desc.path().element() instanceof Path.Index
					? root.path()
					: root.path().append(desc.path().element());

				final int size = desc.size().get(enclosure);

				yield IntStream.range(0, size).mapToObj(i -> {
					final Object value = desc.access().getter().get(enclosure, i);
					final Class<?> type = value != null
						? value.getClass()
						: toRawType(desc.type());

					final var param = new PropParam(
						path.append(new Path.Index(i)),
						enclosure,
						desc.access().getter().get(enclosure, i),
						type,
						object -> desc.access().getter().get(object, i),
						switch (desc.access()) {
							case IndexedAccess.Readonly access -> null;
							case IndexedAccess.Writable access -> (object, val) ->
								access.setter().set(object, i, val);
						}
					);

					return new IndexProperty(param, i);
				});
			}
		};
	}
This method extracts the direct properties of the given {@code root}
object.

{@snippet class="PropertySnippets" region="list(PathValue)"}

The code snippet above will create the following output
<pre>{@code
SimpleProperty[path=author.forename, value=Jonathan, mutable=false, type=java.lang.String, enclosure=Author]
SimpleProperty[path=author.surname, value=Franzen, mutable=false, type=java.lang.String, enclosure=Author]
SimpleProperty[path=author.birthDate, value=1959-08-17, mutable=false, type=java.time.LocalDate, enclosure=Author]
ListProperty[path=author.books, value=[], mutable=false, type=java.util.List, enclosure=Author]
}</pre>

@param root the root object from which the properties are extracted
@return all direct properties of the given {@code root} object
jenetics.incubator/src/main/java/io/jenetics/incubator/beans/property/Properties.java