diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesIOFactory.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesIOFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..d06c783da45dae716266a3318389e341ed4dd0ec
--- /dev/null
+++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesIOFactory.java
@@ -0,0 +1,30 @@
+package de.evoal.core.api.properties.io;
+
+import de.evoal.core.api.cdi.BeanFactory;
+import de.evoal.core.api.properties.PropertiesSpecification;
+import de.evoal.core.api.utils.EvoalIOException;
+
+import java.io.File;
+
+/**
+ * Factory class for creating instances of {@code PropertiesReader} and {@code PropertiesWriter}.
+ */
+public final class PropertiesIOFactory {
+    private PropertiesIOFactory() {}
+
+    public static PropertiesReader reader(final File filename, final PropertiesSpecification specification) throws EvoalIOException {
+        final String [] parts = filename.toString().split("\\.");
+        final String extension = parts[parts.length - 1];
+        final String name = extension + "-reader";
+
+        return BeanFactory.create(name, PropertiesReader.class).init(filename, specification);
+    }
+
+    public static PropertiesWriter writer(final File filename, final PropertiesSpecification specification) throws EvoalIOException {
+        final String [] parts = filename.toString().split("\\.");
+        final String extension = parts[parts.length - 1];
+        final String name = extension + "-writer";
+
+        return BeanFactory.create(name, PropertiesWriter.class).init(filename, specification);
+    }
+}
diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesReader.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesReader.java
index ad7873ea3a37772fc914e68faff415ee9636b6a7..6dacc2d02ab1eb3a185e6e652b53ed279c279058 100644
--- a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesReader.java
+++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesReader.java
@@ -1,145 +1,24 @@
 package de.evoal.core.api.properties.io;
 
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.JsonToken;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import de.evoal.core.api.properties.Properties;
 import de.evoal.core.api.properties.PropertiesSpecification;
-import de.evoal.core.api.properties.PropertySpecification;
-import de.evoal.core.api.utils.Requirements;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
+import de.evoal.core.api.utils.EvoalIOException;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
 
-@Slf4j
-public class PropertiesReader implements AutoCloseable, Iterator<Properties> {
-
-    private final JsonParser jsonParser;
-
-    private final Set<String> properties;
-
-    private final PropertiesSpecification specification;
-
-    public PropertiesReader(final File inputFile, final PropertiesSpecification specification) throws IOException {
-        log.info("Creating properties reader for {}.", specification);
-        this.specification = specification;
-
-        properties = specification.getProperties()
-                                  .stream()
-                                  .map(PropertySpecification::name)
-                                  .collect(Collectors.toSet());
-
-        final ObjectMapper mapper = new ObjectMapper();
-        jsonParser = mapper.createParser(inputFile);
-        jsonParser.nextToken();
-        assertStartArray();
-    }
-
-    private Properties readProperties() throws IOException {
-        assertStartArray();
-
-        final Map<String, Object> entries = new TreeMap<>();
-        while(!JsonToken.END_ARRAY.equals(jsonParser.currentToken())) {
-            Requirements.requireEqual(jsonParser.currentToken(), JsonToken.START_OBJECT);
-
-            String name = null;
-            Object value = null;
-
-            while(!JsonToken.END_OBJECT.equals(jsonParser.currentToken())) {
-                final String fieldName = jsonParser.nextFieldName();
-
-                if("name".equals(fieldName)) {
-                    name = jsonParser.nextTextValue();
-                } else if("value".equals(fieldName)) {
-                    final JsonToken token = jsonParser.nextValue();
-
-                    if(token == JsonToken.VALUE_NUMBER_FLOAT) {
-                        value = jsonParser.getDoubleValue();
-                    } else if(token == JsonToken.VALUE_STRING) {
-                        value = jsonParser.getValueAsString();
-                    } else if(token == JsonToken.VALUE_FALSE) {
-                        value = false;
-                    } else if(token == JsonToken.VALUE_TRUE) {
-                        value = true;
-                    } else if(token == JsonToken.VALUE_NUMBER_INT) {
-                        value = jsonParser.getValueAsInt();
-                    } else {
-                        throw new RuntimeException("Unsupported token type " + token);
-                    }
-                }
-            }
-            assertEndObject();
-
-            entries.put(name, value);
-        }
-
-        assertEndArray();
-
-        try {
-            final PropertiesSpecification spec =
-                    PropertiesSpecification.builder()
-                                           .add(entries.keySet()
-                                                       .stream()
-                                                       .filter(properties::contains)
-                                                       .map(specification::find)
-                                                       .map(PropertySpecification::type)
-                                               )
-                                           .build();
-
-            return new Properties(spec).putAll(entries);
-        } catch(final NullPointerException e) {
-            log.error("Failed to read properties file entry {} for specification {}.", entries, specification);
-
-            entries.keySet()
-                    .stream()
-                    .filter(k -> !properties.contains(k))
-                    .forEach(n -> System.err.println("There is no properties specification for " + n));
-            throw e;
-        }
-    }
-
-    private void assertEndArray() throws IOException {
-        Requirements.requireEqual(jsonParser.currentToken(), JsonToken.END_ARRAY);
-        jsonParser.nextToken();
-    }
-
-
-    private void assertEndObject() throws IOException {
-        Requirements.requireEqual(jsonParser.currentToken(), JsonToken.END_OBJECT);
-        jsonParser.nextToken();
-    }
-
-
-    private void assertStartArray() throws IOException {
-        Requirements.requireEqual(jsonParser.currentToken(), JsonToken.START_ARRAY);
-        jsonParser.nextToken();
-    }
-
-    private void assertStartObject() throws IOException {
-        Requirements.requireEqual(jsonParser.currentToken(), JsonToken.START_OBJECT);
-        jsonParser.nextToken();
-    }
-
-    @Override
-    public void close() throws Exception {
-        jsonParser.close();
-    }
-
-    @Override
-    public boolean hasNext() {
-        return !JsonToken.END_ARRAY.equals(jsonParser.currentToken());
-    }
-
-    @Override
-    @SneakyThrows(IOException.class)
-    public Properties next() {
-        return readProperties();
-    }
+/**
+ * Base interface for reading properties from disk.
+ */
+public interface PropertiesReader extends AutoCloseable, Iterator<Properties> {
+    /**
+     * The reader's initialisation method. Receives the file to read and the
+     *   specification to use.
+     *
+     * @param input The input file.
+     * @param specification The input specification.
+     *
+     * @return The instance itself.
+     */
+    public PropertiesReader init(final File input, final PropertiesSpecification specification) throws EvoalIOException;
 }
diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesWriter.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesWriter.java
index 21b887eb713caf858d176e88bd96431350f0de84..7503d2b29dd37c4f6a0996265dfcaa3ddd2f22cc 100644
--- a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesWriter.java
+++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/io/PropertiesWriter.java
@@ -1,53 +1,30 @@
 package de.evoal.core.api.properties.io;
 
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import de.evoal.core.api.properties.Properties;
-import de.evoal.core.api.properties.PropertySpecification;
-import lombok.SneakyThrows;
+import de.evoal.core.api.properties.PropertiesSpecification;
+import de.evoal.core.api.utils.EvoalIOException;
+import lombok.NonNull;
 
 import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
 
-public class PropertiesWriter implements AutoCloseable {
-    private final FileOutputStream outputStream;
-    private final JsonGenerator jsonGenerator;
-
-    public PropertiesWriter(final File outputFile) throws IOException {
-        outputStream = new FileOutputStream(outputFile);
-
-        final ObjectMapper mapper = new ObjectMapper();
-        jsonGenerator = mapper.createGenerator(outputStream);
-        jsonGenerator.writeStartArray();
-    }
-
-    @SneakyThrows(IOException.class)
-    public void addProperties(final Properties properties) {
-        jsonGenerator.writeStartArray();
-        for(final PropertySpecification spec : properties.getSpecification().getProperties()) {
-            jsonGenerator.writeStartObject();
-            jsonGenerator.writeStringField("name", spec.name());
-
-            final Object value = properties.get(spec);
-            if(value instanceof Double || value instanceof Float) {
-                jsonGenerator.writeNumberField("value", ((Number)properties.get(spec)).doubleValue());
-            } else if(value instanceof Integer) {
-                jsonGenerator.writeNumberField("value", ((Number)properties.get(spec)).longValue());
-            } else if(value instanceof Boolean) {
-                jsonGenerator.writeBooleanField("value", (Boolean)properties.get(spec));
-            } else if(value instanceof String) {
-                jsonGenerator.writeStringField("value", (String)properties.get(spec));
-            }
-            jsonGenerator.writeEndObject();
-        }
-        jsonGenerator.writeEndArray();
-    }
-
-    @Override
-    public void close() throws Exception {
-        jsonGenerator.writeEndArray();
-        jsonGenerator.close();
-        outputStream.close();
-    }
+/**
+ * Base interface for properties writers. A properties writer's task is to serialize a sequence of properties.
+ */
+public interface PropertiesWriter extends AutoCloseable {
+    /**
+     * Writes a new properties instance to the repository.
+     *
+     * @param properties The properties to write.
+     * @throws EvoalIOException An exception to signal some problem while serialising the data.
+     */
+    public void add(final @NonNull Properties properties) throws EvoalIOException;
+
+    /**
+     * Inits the writer with the specification information.
+     *
+     * @param specification The properties specification of the properties to write.
+     *
+     * @return The instance itself.
+     */
+    public PropertiesWriter init(final File outputFile, final PropertiesSpecification specification) throws EvoalIOException;
 }
diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/stream/FileBasedPropertiesStreamSupplier.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/stream/FileBasedPropertiesStreamSupplier.java
index a008a8c504926275f401f008ba0aaeb70ef7bcc7..c5dcee1ac0ffb351b92452d6a2b4cdf41d61cddb 100644
--- a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/stream/FileBasedPropertiesStreamSupplier.java
+++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/properties/stream/FileBasedPropertiesStreamSupplier.java
@@ -1,6 +1,7 @@
 package de.evoal.core.api.properties.stream;
 
 import de.evoal.core.api.properties.PropertiesSpecification;
+import de.evoal.core.api.properties.io.PropertiesIOFactory;
 import de.evoal.core.api.properties.io.PropertiesReader;
 import lombok.extern.slf4j.Slf4j;
 
@@ -22,7 +23,7 @@ public class FileBasedPropertiesStreamSupplier extends PropertiesBasedProperties
         super(Collections.emptyList());
         log.info("Creating properties stream for {}.", filename);
 
-        try(final PropertiesReader reader = new PropertiesReader(filename, specification)) {
+        try(final PropertiesReader reader = PropertiesIOFactory.reader(filename, specification)) {
             while(reader.hasNext()) {
                 properties.add(reader.next());
             }
diff --git a/src/core/de.evoal.core/src/main/java/de/evoal/core/api/utils/EvoalIOException.java b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/utils/EvoalIOException.java
new file mode 100644
index 0000000000000000000000000000000000000000..ad6b34f34c5f3ac7196af3bf43449f2690841a20
--- /dev/null
+++ b/src/core/de.evoal.core/src/main/java/de/evoal/core/api/utils/EvoalIOException.java
@@ -0,0 +1,11 @@
+package de.evoal.core.api.utils;
+
+public class EvoalIOException extends EvoalException {
+    public EvoalIOException(final String message) {
+        super(message);
+    }
+
+    public EvoalIOException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/src/core/de.evoal.core/src/main/java/module-info.java b/src/core/de.evoal.core/src/main/java/module-info.java
index 43401de0c3edfc1d2b4cda3962de1e3a840be4e2..dabb7fc35be0c62c80a59a16b10635f1c7b1ed6b 100644
--- a/src/core/de.evoal.core/src/main/java/module-info.java
+++ b/src/core/de.evoal.core/src/main/java/module-info.java
@@ -95,4 +95,5 @@ module de.evoal.core {
     opens de.evoal.core.api.ea.constraints.calculation to weld.core.impl;
     opens de.evoal.core.api.properties.info to weld.core.impl;
     opens de.evoal.core.api.ea.constraints.strategies to weld.core.impl;
+    opens de.evoal.core.main.properties to weld.core.impl;
 }
diff --git a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/internal/StatementExecutor.java b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/internal/StatementExecutor.java
index 47ed93c6e35d76dcd6b36da213670c06883a4c87..c179923809912ff9da75d968e81e4c78787f259a 100644
--- a/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/internal/StatementExecutor.java
+++ b/src/core/de.evoal.generator.main/src/main/java/de/evoal/generator/main/internal/StatementExecutor.java
@@ -2,7 +2,9 @@ package de.evoal.generator.main.internal;
 
 import de.evoal.core.api.properties.Properties;
 import de.evoal.core.api.properties.PropertiesSpecification;
+import de.evoal.core.api.properties.io.PropertiesIOFactory;
 import de.evoal.core.api.properties.io.PropertiesWriter;
+import de.evoal.core.api.utils.EvoalIOException;
 import de.evoal.generator.api.GeneratorFunction;
 import de.evoal.languages.model.generator.*;
 import de.evoal.languages.model.generator.util.GeneratorSwitch;
@@ -156,9 +158,18 @@ public class StatementExecutor extends GeneratorSwitch<Object> {
 
         new File(filename).getParentFile().mkdirs();
 
-        try(final PropertiesWriter writer = new PropertiesWriter(new File(filename))) {
+        PropertiesSpecification.Builder resultSpec = PropertiesSpecification.builder();
+        stream.peek(p -> resultSpec.add(p.getSpecification()));
+
+        try(final PropertiesWriter writer = PropertiesIOFactory.writer(new File(filename), resultSpec.build())) {
             stream.limit(count)
-                  .forEach(writer::addProperties);
+                  .forEach(p -> {
+                      try {
+                          writer.add(p);
+                      } catch (final EvoalIOException e) {
+                          log.error("Failed to writer properties.", e);
+                      }
+                  });
         } catch (final Exception e) {
             log.error("Failed to write properties to file '{}'.", filename);
         }