diff --git a/jgvariant-core/pom.xml b/jgvariant-core/pom.xml
new file mode 100644
index 0000000..29f6742
--- /dev/null
+++ b/jgvariant-core/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
+  xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <version>0.1.4-SNAPSHOT</version>
+
+  <artifactId>jgvariant-core</artifactId>
+  <packaging>jar</packaging>
+
+  <name>JGVariant Core</name>
+  <url>https://gerrit.benkard.de/plugins/gitiles/jgvariant</url>
+
+  <description>
+    GVariant serialization and deserialization.
+  </description>
+
+  <parent>
+    <groupId>eu.mulk.jgvariant</groupId>
+    <artifactId>jgvariant-parent</artifactId>
+    <version>0.1.4-SNAPSHOT</version>
+    <relativePath>../jgvariant-parent/pom.xml</relativePath>
+  </parent>
+
+  <dependencies>
+    <!-- Annotations -->
+    <dependency>
+      <groupId>com.google.errorprone</groupId>
+      <artifactId>error_prone_annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jetbrains</groupId>
+      <artifactId>annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apiguardian</groupId>
+      <artifactId>apiguardian-api</artifactId>
+    </dependency>
+
+    <!-- Testing -->
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-engine</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.junit.jupiter</groupId>
+      <artifactId>junit-jupiter-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Decoder.java b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Decoder.java
new file mode 100644
index 0000000..d2f2403
--- /dev/null
+++ b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Decoder.java
@@ -0,0 +1,652 @@
+package eu.mulk.jgvariant.core;
+
+import static java.nio.ByteOrder.LITTLE_ENDIAN;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.RecordComponent;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import org.apiguardian.api.API;
+import org.apiguardian.api.API.Status;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Type class for decodable types.
+ *
+ * <p>Use the {@code of*} family of constructor methods to acquire a suitable {@link Decoder} for
+ * the type you wish to decode.
+ *
+ * <p><strong>Example</strong>
+ *
+ * <p>To parse a GVariant of type {@code "a(si)"}, which is an array of pairs of {@link String} and
+ * {@code int}, you can use the following code:
+ *
+ * <pre>{@code
+ * record ExampleRecord(String s, int i) {}
+ *
+ * var decoder =
+ *   Decoder.ofArray(
+ *     Decoder.ofStructure(
+ *       ExampleRecord.class,
+ *       Decoder.ofString(UTF_8),
+ *       Decoder.ofInt().withByteOrder(LITTLE_ENDIAN)));
+ *
+ * byte[] bytes = ...;
+ * List<ExampleRecord> example = decoder.decode(ByteBuffer.wrap(bytes));
+ * }</pre>
+ *
+ * @param <T> the type that the {@link Decoder} can decode.
+ */
+@SuppressWarnings("java:S1610")
+@API(status = Status.EXPERIMENTAL)
+public abstract class Decoder<T> {
+
+  private Decoder() {}
+
+  /**
+   * Decodes a {@link ByteBuffer} holding a serialized GVariant into a value of type {@code T}.
+   *
+   * <p><strong>Note:</strong> Due to the way the GVariant serialization format works, it is
+   * important that the start and end boundaries of the passed byte slice correspond to the actual
+   * start and end of the serialized value. The format does generally not allow for the dynamic
+   * discovery of the end of the data structure.
+   *
+   * @param byteSlice a byte slice holding a serialized GVariant.
+   * @return the deserialized value.
+   * @throws java.nio.BufferUnderflowException if the byte buffer is shorter than the requested
+   *     data.
+   * @throws IllegalArgumentException if the serialized GVariant is ill-formed
+   */
+  public abstract T decode(ByteBuffer byteSlice);
+
+  abstract byte alignment();
+
+  @Nullable
+  abstract Integer fixedSize();
+
+  final boolean hasFixedSize() {
+    return fixedSize() != null;
+  }
+
+  /**
+   * Switches the input {@link ByteBuffer} to a given {@link ByteOrder} before reading from it.
+   *
+   * @param byteOrder the byte order to use.
+   * @return a new, decorated {@link Decoder}.
+   */
+  public Decoder<T> withByteOrder(ByteOrder byteOrder) {
+    var delegate = this;
+
+    return new Decoder<>() {
+      @Override
+      public byte alignment() {
+        return delegate.alignment();
+      }
+
+      @Override
+      public @Nullable Integer fixedSize() {
+        return delegate.fixedSize();
+      }
+
+      @Override
+      public T decode(ByteBuffer byteSlice) {
+        byteSlice.order(byteOrder);
+        return delegate.decode(byteSlice);
+      }
+    };
+  }
+
+  /**
+   * Creates a {@link Decoder} for an {@code Array} type.
+   *
+   * @param elementDecoder a {@link Decoder} for the elements of the array.
+   * @param <U> the element type.
+   * @return a new {@link Decoder}.
+   */
+  public static <U> Decoder<List<U>> ofArray(Decoder<U> elementDecoder) {
+    return new ArrayDecoder<>(elementDecoder);
+  }
+
+  /**
+   * Creates a {@link Decoder} for a {@code Maybe} type.
+   *
+   * @param elementDecoder a {@link Decoder} for the contained element.
+   * @param <U> the element type.
+   * @return a new {@link Decoder}.
+   */
+  public static <U> Decoder<Optional<U>> ofMaybe(Decoder<U> elementDecoder) {
+    return new MaybeDecoder<>(elementDecoder);
+  }
+
+  /**
+   * Creates a {@link Decoder} for a {@code Structure} type, decoding into a {@link Record}.
+   *
+   * @param recordType the {@link Record} type that represents the components of the structure.
+   * @param componentDecoders a {@link Decoder} for each component of the structure.
+   * @param <U> the {@link Record} type that represents the components of the structure.
+   * @return a new {@link Decoder}.
+   */
+  public static <U extends Record> Decoder<U> ofStructure(
+      Class<U> recordType, Decoder<?>... componentDecoders) {
+    return new StructureDecoder<>(recordType, componentDecoders);
+  }
+
+  /**
+   * Creates a {@link Decoder} for a {@code Structure} type, decoding into a {@link List}.
+   *
+   * <p>Prefer {@link #ofStructure(Class, Decoder[])} if possible, which is both more type-safe and
+   * more convenient.
+   *
+   * @param componentDecoders a {@link Decoder} for each component of the structure.
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<Object[]> ofStructure(Decoder<?>... componentDecoders) {
+    return new TupleDecoder(componentDecoders);
+  }
+
+  /**
+   * Creates a {@link Decoder} for the {@link Variant} type.
+   *
+   * <p>The contained {@link Object} can be of one of the following types:
+   *
+   * <ul>
+   *   <li>{@link Boolean}
+   *   <li>{@link Byte}
+   *   <li>{@link Short}
+   *   <li>{@link Integer}
+   *   <li>{@link Long}
+   *   <li>{@link String}
+   *   <li>{@link Optional} (a GVariant {@code Maybe} type)
+   *   <li>{@link List} (a GVariant array)
+   *   <li>{@code Object[]} (a GVariant structure)
+   *   <li>{@link Variant} (a nested variant)
+   * </ul>
+   *
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<Variant> ofVariant() {
+    return new VariantDecoder();
+  }
+
+  /**
+   * Creates a {@link Decoder} for the {@code boolean} type.
+   *
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<Boolean> ofBoolean() {
+    return new BooleanDecoder();
+  }
+
+  /**
+   * Creates a {@link Decoder} for the 8-bit {@code byte} type.
+   *
+   * <p><strong>Note:</strong> It is often useful to apply {@link #withByteOrder(ByteOrder)} to the
+   * result of this method.
+   *
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<Byte> ofByte() {
+    return new ByteDecoder();
+  }
+
+  /**
+   * Creates a {@link Decoder} for the 16-bit {@code short} type.
+   *
+   * <p><strong>Note:</strong> It is often useful to apply {@link #withByteOrder(ByteOrder)} to the
+   * result of this method.
+   *
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<Short> ofShort() {
+    return new ShortDecoder();
+  }
+
+  /**
+   * Creates a {@link Decoder} for the 32-bit {@code int} type.
+   *
+   * <p><strong>Note:</strong> It is often useful to apply {@link #withByteOrder(ByteOrder)} to the
+   * result of this method.
+   *
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<Integer> ofInt() {
+    return new IntegerDecoder();
+  }
+
+  /**
+   * Creates a {@link Decoder} for the 64-bit {@code long} type.
+   *
+   * <p><strong>Note:</strong> It is often useful to apply {@link #withByteOrder(ByteOrder)} to the
+   * result of this method.
+   *
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<Long> ofLong() {
+    return new LongDecoder();
+  }
+
+  /**
+   * Creates a {@link Decoder} for the {@code double} type.
+   *
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<Double> ofDouble() {
+    return new DoubleDecoder();
+  }
+
+  /**
+   * Creates a {@link Decoder} for the {@link String} type.
+   *
+   * <p><strong>Note:</strong> While GVariant does not prescribe any particular encoding, {@link
+   * java.nio.charset.StandardCharsets#UTF_8} is the most common choice.
+   *
+   * @param charset the {@link Charset} the string is encoded in.
+   * @return a new {@link Decoder}.
+   */
+  public static Decoder<String> ofString(Charset charset) {
+    return new StringDecoder(charset);
+  }
+
+  private static int align(int offset, byte alignment) {
+    return offset % alignment == 0 ? offset : offset + alignment - (offset % alignment);
+  }
+
+  private static int getIntN(ByteBuffer byteSlice) {
+    var intBytes = new byte[4];
+    byteSlice.get(intBytes, 0, Math.min(4, byteSlice.limit()));
+    return ByteBuffer.wrap(intBytes).order(LITTLE_ENDIAN).getInt();
+  }
+
+  @SuppressWarnings("java:S3358")
+  private static int byteCount(int n) {
+    return n < (1 << 8) ? 1 : n < (1 << 16) ? 2 : 4;
+  }
+
+  private static class ArrayDecoder<U> extends Decoder<List<U>> {
+
+    private final Decoder<U> elementDecoder;
+
+    ArrayDecoder(Decoder<U> elementDecoder) {
+      this.elementDecoder = elementDecoder;
+    }
+
+    @Override
+    public byte alignment() {
+      return elementDecoder.alignment();
+    }
+
+    @Override
+    @Nullable
+    Integer fixedSize() {
+      return null;
+    }
+
+    @Override
+    public List<U> decode(ByteBuffer byteSlice) {
+      List<U> elements;
+
+      var elementSize = elementDecoder.fixedSize();
+      if (elementSize != null) {
+        // A simple C-style array.
+        elements = new ArrayList<>(byteSlice.limit() / elementSize);
+        for (int i = 0; i < byteSlice.limit(); i += elementSize) {
+          var element = elementDecoder.decode(byteSlice.slice(i, elementSize));
+          elements.add(element);
+        }
+      } else {
+        // An array with aligned elements and a vector of framing offsets in the end.
+        int framingOffsetSize = byteCount(byteSlice.limit());
+        int lastFramingOffset =
+            getIntN(byteSlice.slice(byteSlice.limit() - framingOffsetSize, framingOffsetSize));
+        int elementCount = (byteSlice.limit() - lastFramingOffset) / framingOffsetSize;
+
+        elements = new ArrayList<>(elementCount);
+        int position = 0;
+        for (int i = 0; i < elementCount; i++) {
+          int framingOffset =
+              getIntN(
+                  byteSlice.slice(lastFramingOffset + i * framingOffsetSize, framingOffsetSize));
+          elements.add(elementDecoder.decode(byteSlice.slice(position, framingOffset - position)));
+          position = align(framingOffset, alignment());
+        }
+      }
+
+      return elements;
+    }
+  }
+
+  private static class MaybeDecoder<U> extends Decoder<Optional<U>> {
+
+    private final Decoder<U> elementDecoder;
+
+    MaybeDecoder(Decoder<U> elementDecoder) {
+      this.elementDecoder = elementDecoder;
+    }
+
+    @Override
+    public byte alignment() {
+      return elementDecoder.alignment();
+    }
+
+    @Override
+    @Nullable
+    Integer fixedSize() {
+      return null;
+    }
+
+    @Override
+    public Optional<U> decode(ByteBuffer byteSlice) {
+      if (!byteSlice.hasRemaining()) {
+        return Optional.empty();
+      } else {
+        if (!elementDecoder.hasFixedSize()) {
+          // Remove trailing zero byte.
+          byteSlice.limit(byteSlice.limit() - 1);
+        }
+
+        return Optional.of(elementDecoder.decode(byteSlice));
+      }
+    }
+  }
+
+  private static class StructureDecoder<U extends Record> extends Decoder<U> {
+
+    private final Class<U> recordType;
+    private final TupleDecoder tupleDecoder;
+
+    StructureDecoder(Class<U> recordType, Decoder<?>... componentDecoders) {
+      var recordComponents = recordType.getRecordComponents();
+      if (componentDecoders.length != recordComponents.length) {
+        throw new IllegalArgumentException(
+            "number of decoders (%d) does not match number of structure components (%d)"
+                .formatted(componentDecoders.length, recordComponents.length));
+      }
+
+      this.recordType = recordType;
+      this.tupleDecoder = new TupleDecoder(componentDecoders);
+    }
+
+    @Override
+    public byte alignment() {
+      return tupleDecoder.alignment();
+    }
+
+    @Override
+    public Integer fixedSize() {
+      return tupleDecoder.fixedSize();
+    }
+
+    @Override
+    public U decode(ByteBuffer byteSlice) {
+      Object[] recordConstructorArguments = tupleDecoder.decode(byteSlice);
+
+      try {
+        var recordComponentTypes =
+            Arrays.stream(recordType.getRecordComponents())
+                .map(RecordComponent::getType)
+                .toArray(Class<?>[]::new);
+        var recordConstructor = recordType.getDeclaredConstructor(recordComponentTypes);
+        return recordConstructor.newInstance(recordConstructorArguments);
+      } catch (NoSuchMethodException
+          | InstantiationException
+          | IllegalAccessException
+          | InvocationTargetException e) {
+        throw new IllegalStateException(e);
+      }
+    }
+  }
+
+  private static class TupleDecoder extends Decoder<Object[]> {
+
+    private final Decoder<?>[] componentDecoders;
+
+    TupleDecoder(Decoder<?>... componentDecoders) {
+      this.componentDecoders = componentDecoders;
+    }
+
+    @Override
+    public byte alignment() {
+      return (byte) Arrays.stream(componentDecoders).mapToInt(Decoder::alignment).max().orElse(1);
+    }
+
+    @Override
+    public Integer fixedSize() {
+      int position = 0;
+      for (var componentDecoder : componentDecoders) {
+        var fixedComponentSize = componentDecoder.fixedSize();
+        if (fixedComponentSize == null) {
+          return null;
+        }
+
+        position = align(position, componentDecoder.alignment());
+        position += fixedComponentSize;
+      }
+
+      if (position == 0) {
+        return 1;
+      }
+
+      return align(position, alignment());
+    }
+
+    @Override
+    public Object[] decode(ByteBuffer byteSlice) {
+      int framingOffsetSize = byteCount(byteSlice.limit());
+
+      var objects = new Object[componentDecoders.length];
+
+      int position = 0;
+      int framingOffsetIndex = 0;
+      int componentIndex = 0;
+      for (var componentDecoder : componentDecoders) {
+        position = align(position, componentDecoder.alignment());
+
+        var fixedComponentSize = componentDecoder.fixedSize();
+        if (fixedComponentSize != null) {
+          objects[componentIndex] =
+              componentDecoder.decode(byteSlice.slice(position, fixedComponentSize));
+          position += fixedComponentSize;
+        } else {
+          if (componentIndex == componentDecoders.length - 1) {
+            // The last component never has a framing offset.
+            int endPosition = byteSlice.limit() - framingOffsetIndex * framingOffsetSize;
+            objects[componentIndex] =
+                componentDecoder.decode(byteSlice.slice(position, endPosition - position));
+            position = endPosition;
+          } else {
+            int framingOffset =
+                getIntN(
+                    byteSlice.slice(
+                        byteSlice.limit() - (1 + framingOffsetIndex) * framingOffsetSize,
+                        framingOffsetSize));
+            objects[componentIndex] =
+                componentDecoder.decode(byteSlice.slice(position, framingOffset - position));
+            position = framingOffset;
+            ++framingOffsetIndex;
+          }
+        }
+
+        ++componentIndex;
+      }
+
+      return objects;
+    }
+  }
+
+  private static class VariantDecoder extends Decoder<Variant> {
+
+    @Override
+    public byte alignment() {
+      return 8;
+    }
+
+    @Override
+    @Nullable
+    Integer fixedSize() {
+      return null;
+    }
+
+    @Override
+    public Variant decode(ByteBuffer byteSlice) {
+      for (int i = byteSlice.limit() - 1; i >= 0; --i) {
+        if (byteSlice.get(i) != 0) {
+          continue;
+        }
+
+        var dataBytes = byteSlice.slice(0, i);
+        var signatureBytes = byteSlice.slice(i + 1, byteSlice.limit() - (i + 1));
+
+        Signature signature;
+        try {
+          signature = Signature.parse(signatureBytes);
+        } catch (ParseException e) {
+          throw new IllegalArgumentException(e);
+        }
+
+        return new Variant(signature, signature.decoder().decode(dataBytes));
+      }
+
+      throw new IllegalArgumentException("variant signature not found");
+    }
+  }
+
+  private static class BooleanDecoder extends Decoder<Boolean> {
+
+    @Override
+    public byte alignment() {
+      return 1;
+    }
+
+    @Override
+    public Integer fixedSize() {
+      return 1;
+    }
+
+    @Override
+    public Boolean decode(ByteBuffer byteSlice) {
+      return byteSlice.get() != 0;
+    }
+  }
+
+  private static class ByteDecoder extends Decoder<Byte> {
+
+    @Override
+    public byte alignment() {
+      return 1;
+    }
+
+    @Override
+    public Integer fixedSize() {
+      return 1;
+    }
+
+    @Override
+    public Byte decode(ByteBuffer byteSlice) {
+      return byteSlice.get();
+    }
+  }
+
+  private static class ShortDecoder extends Decoder<Short> {
+
+    @Override
+    public byte alignment() {
+      return 2;
+    }
+
+    @Override
+    public Integer fixedSize() {
+      return 2;
+    }
+
+    @Override
+    public Short decode(ByteBuffer byteSlice) {
+      return byteSlice.getShort();
+    }
+  }
+
+  private static class IntegerDecoder extends Decoder<Integer> {
+
+    @Override
+    public byte alignment() {
+      return 4;
+    }
+
+    @Override
+    public Integer fixedSize() {
+      return 4;
+    }
+
+    @Override
+    public Integer decode(ByteBuffer byteSlice) {
+      return byteSlice.getInt();
+    }
+  }
+
+  private static class LongDecoder extends Decoder<Long> {
+
+    @Override
+    public byte alignment() {
+      return 8;
+    }
+
+    @Override
+    public Integer fixedSize() {
+      return 8;
+    }
+
+    @Override
+    public Long decode(ByteBuffer byteSlice) {
+      return byteSlice.getLong();
+    }
+  }
+
+  private static class DoubleDecoder extends Decoder<Double> {
+
+    @Override
+    public byte alignment() {
+      return 8;
+    }
+
+    @Override
+    public Integer fixedSize() {
+      return 8;
+    }
+
+    @Override
+    public Double decode(ByteBuffer byteSlice) {
+      return byteSlice.getDouble();
+    }
+  }
+
+  private static class StringDecoder extends Decoder<String> {
+
+    private final Charset charset;
+
+    public StringDecoder(Charset charset) {
+      this.charset = charset;
+    }
+
+    @Override
+    public byte alignment() {
+      return 1;
+    }
+
+    @Override
+    @Nullable
+    Integer fixedSize() {
+      return null;
+    }
+
+    @Override
+    public String decode(ByteBuffer byteSlice) {
+      byteSlice.limit(byteSlice.limit() - 1);
+      return charset.decode(byteSlice).toString();
+    }
+  }
+}
diff --git a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Signature.java b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Signature.java
new file mode 100644
index 0000000..d9de5f1
--- /dev/null
+++ b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Signature.java
@@ -0,0 +1,116 @@
+package eu.mulk.jgvariant.core;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import org.apiguardian.api.API;
+import org.apiguardian.api.API.Status;
+
+/**
+ * A GVariant signature string.
+ *
+ * <p>Describes a type in the GVariant type system. The type can be arbitrarily complex.
+ *
+ * <p><strong>Examples</strong>
+ *
+ * <dl>
+ *   <dt>{@code "i"}
+ *   <dd>a single 32-bit integer
+ *   <dt>{@code "ai"}
+ *   <dd>an array of 32-bit integers
+ *   <dt>{@code "(bbb(sai))"}
+ *   <dd>a record consisting of three booleans and a nested record, which consists of a string and
+ *       an array of 32-bit integers
+ * </dl>
+ */
+@API(status = Status.STABLE)
+public final class Signature {
+
+  private final String signatureString;
+  private final Decoder<?> decoder;
+
+  Signature(ByteBuffer signatureBytes) throws ParseException {
+    this.decoder = parseSignature(signatureBytes);
+
+    signatureBytes.rewind();
+    this.signatureString = StandardCharsets.US_ASCII.decode(signatureBytes).toString();
+  }
+
+  static Signature parse(ByteBuffer signatureBytes) throws ParseException {
+    return new Signature(signatureBytes);
+  }
+
+  static Signature parse(String signatureString) throws ParseException {
+    var signatureBytes = ByteBuffer.wrap(signatureString.getBytes(StandardCharsets.US_ASCII));
+    return parse(signatureBytes);
+  }
+
+  /**
+   * Returns a {@link Decoder} that can decode values conforming to this signature.
+   *
+   * @return a {@link Decoder} for this signature
+   */
+  @SuppressWarnings("unchecked")
+  Decoder<Object> decoder() {
+    return (Decoder<Object>) decoder;
+  }
+
+  /**
+   * Returns the signature formatted as a GVariant signature string.
+   *
+   * @return a GVariant signature string.
+   */
+  @Override
+  public String toString() {
+    return signatureString;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return (o instanceof Signature signature)
+        && Objects.equals(signatureString, signature.signatureString);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(signatureString);
+  }
+
+  private static Decoder<?> parseSignature(ByteBuffer signature) throws ParseException {
+    char c = (char) signature.get();
+    return switch (c) {
+      case 'b' -> Decoder.ofBoolean();
+      case 'y' -> Decoder.ofByte();
+      case 'n', 'q' -> Decoder.ofShort();
+      case 'i', 'u' -> Decoder.ofInt();
+      case 'x', 't' -> Decoder.ofLong();
+      case 'd' -> Decoder.ofDouble();
+      case 's', 'o', 'g' -> Decoder.ofString(StandardCharsets.UTF_8);
+      case 'v' -> Decoder.ofVariant();
+      case 'm' -> Decoder.ofMaybe(parseSignature(signature));
+      case 'a' -> Decoder.ofArray(parseSignature(signature));
+      case '(', '{' -> Decoder.ofStructure(parseTupleTypes(signature).toArray(new Decoder<?>[0]));
+      default -> throw new ParseException(
+          String.format("encountered unknown signature byte '%c'", c), signature.position());
+    };
+  }
+
+  private static List<Decoder<?>> parseTupleTypes(ByteBuffer signature) throws ParseException {
+    List<Decoder<?>> decoders = new ArrayList<>();
+
+    while (true) {
+      char c = (char) signature.get(signature.position());
+      if (c == ')' || c == '}') {
+        signature.get();
+        break;
+      }
+
+      decoders.add(parseSignature(signature));
+    }
+
+    return decoders;
+  }
+}
diff --git a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Variant.java b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Variant.java
new file mode 100644
index 0000000..d1c1049
--- /dev/null
+++ b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/Variant.java
@@ -0,0 +1,30 @@
+package eu.mulk.jgvariant.core;
+
+import org.apiguardian.api.API;
+import org.apiguardian.api.API.Status;
+
+/**
+ * A dynamically typed GVariant value carrying a {@link Signature} describing its type.
+ *
+ * <p>{@link #value()} can be of one of the following types:
+ *
+ * <ul>
+ *   <li>{@link Boolean}
+ *   <li>{@link Byte}
+ *   <li>{@link Short}
+ *   <li>{@link Integer}
+ *   <li>{@link Long}
+ *   <li>{@link String}
+ *   <li>{@link java.util.Optional} (a GVariant {@code Maybe} type)
+ *   <li>{@link java.util.List} (a GVariant array)
+ *   <li>{@code Object[]} (a GVariant structure)
+ *   <li>{@link Variant} (a nested variant)
+ * </ul>
+ *
+ * @param signature the signature describing the type of the value.
+ * @param value the value itself; one of {@link Boolean}, {@link Byte}, {@link Short}, {@link
+ *     Integer}, {@link Long}, {@link String}, {@link java.util.Optional}, {@link java.util.List},
+ *     {@code Object[]}, {@link Variant}.
+ */
+@API(status = Status.EXPERIMENTAL)
+public record Variant(Signature signature, Object value) {}
diff --git a/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/package-info.java b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/package-info.java
new file mode 100644
index 0000000..1754096
--- /dev/null
+++ b/jgvariant-core/src/main/java/eu/mulk/jgvariant/core/package-info.java
@@ -0,0 +1,27 @@
+/**
+ * Provides {@link eu.mulk.jgvariant.core.Decoder}, the foundational class for <a
+ * href="https://docs.gtk.org/glib/struct.Variant.html">GVariant</a> parsing.
+ *
+ * <p>Instances of {@link eu.mulk.jgvariant.core.Decoder} read a given value type from a {@link
+ * java.nio.ByteBuffer}. The class also contains factory methods to create those instances.
+ *
+ * <p><strong>Example</strong>
+ *
+ * <p>To parse a GVariant of type {@code "a(si)"}, which is an array of pairs of {@link
+ * java.lang.String} and {@code int}, you can use the following code:
+ *
+ * <pre>{@code
+ * record ExampleRecord(String s, int i) {}
+ *
+ * var decoder =
+ *   Decoder.ofArray(
+ *     Decoder.ofStructure(
+ *       ExampleRecord.class,
+ *       Decoder.ofString(UTF_8),
+ *       Decoder.ofInt().withByteOrder(LITTLE_ENDIAN)));
+ *
+ * byte[] bytes = ...;
+ * List<ExampleRecord> example = decoder.decode(ByteBuffer.wrap(bytes));
+ * }</pre>
+ */
+package eu.mulk.jgvariant.core;
diff --git a/jgvariant-core/src/main/java/module-info.java b/jgvariant-core/src/main/java/module-info.java
new file mode 100644
index 0000000..a1830f6
--- /dev/null
+++ b/jgvariant-core/src/main/java/module-info.java
@@ -0,0 +1,79 @@
+/**
+ * Provides a parser for the <a href="https://docs.gtk.org/glib/struct.Variant.html">GVariant</a>
+ * serialization format.
+ *
+ * <ul>
+ *   <li><a href="#sect-overview">Overview</a>
+ *   <li><a href="#sect-installation">Installation</a>
+ * </ul>
+ *
+ * <h2 id="sect-overview">Overview</h2>
+ *
+ * <p>The {@link eu.mulk.jgvariant.core} package contains the {@link eu.mulk.jgvariant.core.Decoder}
+ * type, which contains classes to parse and represent serialized <a
+ * href="https://docs.gtk.org/glib/struct.Variant.html">GVariant</a> values.
+ *
+ * <h2 id="sect-installation">Installation</h2>
+ *
+ * <ul>
+ *   <li><a href="#sect-installation-maven">Usage with Maven</a>
+ *   <li><a href="#sect-installation-gradle">Usage with Gradle</a>
+ * </ul>
+ *
+ * <h3 id="sect-installation-maven">Usage with Maven</h3>
+ *
+ * <pre>{@code
+ * <project>
+ *   ...
+ *
+ *   <dependencyManagement>
+ *     ...
+ *
+ *     <dependencies>
+ *       <dependency>
+ *         <groupId>eu.mulk.jgvariant</groupId>
+ *         <artifactId>jgvariant-bom</artifactId>
+ *         <version>0.1.4</version>
+ *         <type>pom</type>
+ *         <scope>import</scope>
+ *       </dependency>
+ *     </dependencies>
+ *
+ *     ...
+ *   </dependencyManagement>
+ *
+ *   <dependencies>
+ *     ...
+ *
+ *     <dependency>
+ *       <groupId>eu.mulk.jgvariant</groupId>
+ *       <artifactId>jgvariant-core</artifactId>
+ *     </dependency>
+ *
+ *     ...
+ *   </dependencies>
+ *
+ *   ...
+ * </project>
+ * }</pre>
+ *
+ * <h3 id="sect-installation-gradle">Usage with Gradle</h3>
+ *
+ * <pre>{@code
+ * dependencies {
+ *   ...
+ *
+ *   implementation(platform("eu.mulk.jgvariant:jgvariant-bom:0.1.4")
+ *   implementation("eu.mulk.jgvariant:jgvariant-core")
+ *
+ *   ...
+ * }
+ * }</pre>
+ */
+module eu.mulk.jgvariant.core {
+  requires com.google.errorprone.annotations;
+  requires org.jetbrains.annotations;
+  requires org.apiguardian.api;
+
+  exports eu.mulk.jgvariant.core;
+}
diff --git a/jgvariant-core/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java b/jgvariant-core/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java
new file mode 100644
index 0000000..5cf1a1c
--- /dev/null
+++ b/jgvariant-core/src/test/java/eu/mulk/jgvariant/core/DecoderTest.java
@@ -0,0 +1,437 @@
+package eu.mulk.jgvariant.core;
+
+import static java.nio.ByteOrder.BIG_ENDIAN;
+import static java.nio.ByteOrder.LITTLE_ENDIAN;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.nio.ByteBuffer;
+import java.text.ParseException;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests based on the examples given in <a
+ * href="https://people.gnome.org/~desrt/gvariant-serialisation.pdf">~desrt/gvariant-serialisation.pdf</a>.
+ */
+class DecoderTest {
+
+  @Test
+  void testString() {
+    var data = new byte[] {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x00};
+    var decoder = Decoder.ofString(UTF_8);
+    assertEquals("hello world", decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testMaybe() {
+    var data =
+        new byte[] {0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x00, 0x00};
+    var decoder = Decoder.ofMaybe(Decoder.ofString(UTF_8));
+    assertEquals(Optional.of("hello world"), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testBooleanArray() {
+    var data = new byte[] {0x01, 0x00, 0x00, 0x01, 0x01};
+    var decoder = Decoder.ofArray(Decoder.ofBoolean());
+    assertEquals(List.of(true, false, false, true, true), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testStructure() {
+    var data =
+        new byte[] {
+          0x66, 0x6F, 0x6F, 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, 0x04
+        };
+
+    record TestRecord(String s, int i) {}
+
+    var decoder = Decoder.ofStructure(TestRecord.class, Decoder.ofString(UTF_8), Decoder.ofInt());
+    assertEquals(new TestRecord("foo", -1), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testComplexStructureArray() {
+    var data =
+        new byte[] {
+          0x68,
+          0x69,
+          0x00,
+          0x00,
+          (byte) 0xfe,
+          (byte) 0xff,
+          (byte) 0xff,
+          (byte) 0xff,
+          0x03,
+          0x00,
+          0x00,
+          0x00,
+          0x62,
+          0x79,
+          0x65,
+          0x00,
+          (byte) 0xff,
+          (byte) 0xff,
+          (byte) 0xff,
+          (byte) 0xff,
+          0x04,
+          0x09,
+          0x15
+        };
+
+    record TestRecord(String s, int i) {}
+
+    var decoder =
+        Decoder.ofArray(
+            Decoder.ofStructure(
+                TestRecord.class,
+                Decoder.ofString(UTF_8),
+                Decoder.ofInt().withByteOrder(LITTLE_ENDIAN)));
+    assertEquals(
+        List.of(new TestRecord("hi", -2), new TestRecord("bye", -1)),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testStringArray() {
+    var data =
+        new byte[] {
+          0x69, 0x00, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E,
+          0x67, 0x73, 0x3F, 0x00, 0x02, 0x06, 0x0a, 0x13
+        };
+    var decoder = Decoder.ofArray(Decoder.ofString(UTF_8));
+    assertEquals(List.of("i", "can", "has", "strings?"), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testNestedStructure() {
+    var data =
+        new byte[] {
+          0x69, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
+          0x73, 0x3F, 0x00, 0x04, 0x0d, 0x05
+        };
+
+    record TestChild(byte b, String s) {}
+    record TestParent(TestChild tc, List<String> as) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestParent.class,
+            Decoder.ofStructure(TestChild.class, Decoder.ofByte(), Decoder.ofString(UTF_8)),
+            Decoder.ofArray(Decoder.ofString(UTF_8)));
+
+    assertEquals(
+        new TestParent(new TestChild((byte) 0x69, "can"), List.of("has", "strings?")),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testNestedStructureVariant() {
+    var data =
+        new byte[] {
+          0x69, 0x63, 0x61, 0x6E, 0x00, 0x68, 0x61, 0x73, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
+          0x73, 0x3F, 0x00, 0x04, 0x0d, 0x05, 0x00, 0x28, 0x28, 0x79, 0x73, 0x29, 0x61, 0x73, 0x29
+        };
+
+    var decoder = Decoder.ofVariant();
+    var variant = decoder.decode(ByteBuffer.wrap(data));
+    var result = (Object[]) variant.value();
+
+    assertAll(
+        () -> assertEquals(Signature.parse("((ys)as)"), variant.signature()),
+        () -> assertEquals(2, result.length),
+        () -> assertArrayEquals(new Object[] {(byte) 0x69, "can"}, (Object[]) result[0]),
+        () -> assertEquals(List.of("has", "strings?"), result[1]));
+  }
+
+  @Test
+  void testSimpleStructure() {
+    var data = new byte[] {0x60, 0x70};
+
+    record TestRecord(byte b1, byte b2) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestRecord.class,
+            Decoder.ofByte().withByteOrder(LITTLE_ENDIAN),
+            Decoder.ofByte().withByteOrder(LITTLE_ENDIAN));
+
+    assertEquals(new TestRecord((byte) 0x60, (byte) 0x70), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testPaddedStructureRight() {
+    var data = new byte[] {0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00};
+
+    record TestRecord(int b1, byte b2) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestRecord.class,
+            Decoder.ofInt().withByteOrder(LITTLE_ENDIAN),
+            Decoder.ofByte().withByteOrder(LITTLE_ENDIAN));
+
+    assertEquals(new TestRecord(0x60, (byte) 0x70), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testPaddedStructureLeft() {
+    var data = new byte[] {0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00};
+
+    record TestRecord(byte b1, int b2) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestRecord.class,
+            Decoder.ofByte().withByteOrder(LITTLE_ENDIAN),
+            Decoder.ofInt().withByteOrder(LITTLE_ENDIAN));
+
+    assertEquals(new TestRecord((byte) 0x60, 0x70), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testSimpleStructureArray() {
+    var data =
+        new byte[] {
+          0x60,
+          0x00,
+          0x00,
+          0x00,
+          0x70,
+          0x00,
+          0x00,
+          0x00,
+          (byte) 0x88,
+          0x02,
+          0x00,
+          0x00,
+          (byte) 0xF7,
+          0x00,
+          0x00,
+          0x00
+        };
+
+    record TestRecord(int b1, byte b2) {}
+
+    var decoder =
+        Decoder.ofArray(
+            Decoder.ofStructure(
+                TestRecord.class,
+                Decoder.ofInt().withByteOrder(LITTLE_ENDIAN),
+                Decoder.ofByte().withByteOrder(LITTLE_ENDIAN)));
+
+    assertEquals(
+        List.of(new TestRecord(96, (byte) 0x70), new TestRecord(648, (byte) 0xf7)),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testByteArray() {
+    var data = new byte[] {0x04, 0x05, 0x06, 0x07};
+
+    var decoder = Decoder.ofArray(Decoder.ofByte());
+
+    assertEquals(
+        List.of((byte) 0x04, (byte) 0x05, (byte) 0x06, (byte) 0x07),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testIntegerArray() {
+    var data = new byte[] {0x04, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00};
+
+    var decoder = Decoder.ofArray(Decoder.ofInt().withByteOrder(LITTLE_ENDIAN));
+
+    assertEquals(List.of(4, 258), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testDictionaryEntry() {
+    var data =
+        new byte[] {0x61, 0x20, 0x6B, 0x65, 0x79, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x06};
+
+    record TestEntry(String key, int value) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestEntry.class, Decoder.ofString(UTF_8), Decoder.ofInt().withByteOrder(LITTLE_ENDIAN));
+    assertEquals(new TestEntry("a key", 514), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testPaddedPrimitives() {
+    var data =
+        new byte[] {
+          0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+          0x00, 0x40, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+        };
+
+    record TestRecord(short s, long l, double d) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestRecord.class,
+            Decoder.ofShort().withByteOrder(BIG_ENDIAN),
+            Decoder.ofLong().withByteOrder(LITTLE_ENDIAN),
+            Decoder.ofDouble());
+    assertEquals(new TestRecord((short) 1, 2, 3.25), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testEmbeddedMaybe() {
+    var data = new byte[] {0x01, 0x01};
+
+    record TestRecord(Optional<Byte> set, Optional<Byte> unset) {}
+
+    var decoder =
+        Decoder.ofStructure(
+            TestRecord.class, Decoder.ofMaybe(Decoder.ofByte()), Decoder.ofMaybe(Decoder.ofByte()));
+    assertEquals(
+        new TestRecord(Optional.of((byte) 1), Optional.empty()),
+        decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testRecordComponentMismatch() {
+    record TestRecord(Optional<Byte> set) {}
+
+    var maybeDecoder = Decoder.ofMaybe(Decoder.ofByte());
+    assertThrows(
+        IllegalArgumentException.class,
+        () -> Decoder.ofStructure(TestRecord.class, maybeDecoder, maybeDecoder));
+  }
+
+  @Test
+  void testTrivialRecord() {
+    var data = new byte[] {0x00};
+
+    record TestRecord() {}
+
+    var decoder = Decoder.ofStructure(TestRecord.class);
+    assertEquals(new TestRecord(), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testTwoElementTrivialRecordArray() {
+    var data = new byte[] {0x00, 0x00};
+
+    record TestRecord() {}
+
+    var decoder = Decoder.ofArray(Decoder.ofStructure(TestRecord.class));
+    assertEquals(
+        List.of(new TestRecord(), new TestRecord()), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testSingletonTrivialRecordArray() {
+    var data = new byte[] {0x00};
+
+    record TestRecord() {}
+
+    var decoder = Decoder.ofArray(Decoder.ofStructure(TestRecord.class));
+    assertEquals(List.of(new TestRecord()), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testEmptyTrivialRecordArray() {
+    var data = new byte[] {};
+
+    record TestRecord() {}
+
+    var decoder = Decoder.ofArray(Decoder.ofStructure(TestRecord.class));
+    assertEquals(List.of(), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testVariantArray() {
+    var data = new byte[] {};
+
+    record TestRecord() {}
+
+    var decoder = Decoder.ofArray(Decoder.ofStructure(TestRecord.class));
+    assertEquals(List.of(), decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testInvalidVariantSignature() {
+    var data = new byte[] {0x00, 0x00, 0x2E};
+
+    var decoder = Decoder.ofVariant();
+    assertThrows(IllegalArgumentException.class, () -> decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testMissingVariantSignature() {
+    var data = new byte[] {0x01};
+
+    var decoder = Decoder.ofVariant();
+    assertThrows(IllegalArgumentException.class, () -> decoder.decode(ByteBuffer.wrap(data)));
+  }
+
+  @Test
+  void testSimpleVariantRecord() throws ParseException {
+    // signature: "(bynqiuxtdsogvmiai)"
+    var data =
+        new byte[] {
+          0x01, // b
+          0x02, // y
+          0x00, 0x03, // n
+          0x00, 0x04, // q
+          0x00, 0x00, // (padding)
+          0x00, 0x00, 0x00, 0x05, // i
+          0x00, 0x00, 0x00, 0x06, // u
+          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, // x
+          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, // t
+          0x40, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d
+          0x68, 0x69, 0x00, // s
+          0x68, 0x69, 0x00, // o
+          0x68, 0x69, 0x00, // g
+          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (padding)
+          0x00, 0x00, 0x00, 0x09, 0x00, 0x69, // v
+          0x00, 0x00, // (padding)
+          0x00, 0x00, 0x00, 0x0a, // mi
+          0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, // ai
+          68, 62, 49, 46, 43, // framing offsets
+          0x00, 0x28, 0x62, 0x79, 0x6E, 0x71, 0x69, 0x75, 0x78, 0x74, 0x64, 0x73, 0x6F, 0x67, 0x76,
+          0x6D, 0x69, 0x61, 0x69, 0x29
+        };
+
+    var decoder = Decoder.ofVariant();
+    assertArrayEquals(
+        new Object[] {
+          true,
+          (byte) 2,
+          (short) 3,
+          (short) 4,
+          (int) 5,
+          (int) 6,
+          (long) 7,
+          (long) 8,
+          (double) 3.25,
+          "hi",
+          "hi",
+          "hi",
+          new Variant(Signature.parse("i"), 9),
+          Optional.of(10),
+          List.of(11, 12)
+        },
+        (Object[]) decoder.decode(ByteBuffer.wrap(data)).value());
+  }
+
+  @Test
+  void testSignatureString() throws ParseException {
+    var data =
+        new byte[] {
+          0x28, 0x62, 0x79, 0x6E, 0x71, 0x69, 0x75, 0x78, 0x74, 0x64, 0x73, 0x6F, 0x67, 0x76, 0x6D,
+          0x69, 0x61, 0x69, 0x29
+        };
+
+    var signature = Signature.parse(ByteBuffer.wrap(data));
+    assertEquals("(bynqiuxtdsogvmiai)", signature.toString());
+  }
+}
