diff --git a/pom.xml b/pom.xml
index 6096e09..bfe02ac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -124,6 +124,11 @@
maven-plugin-annotations
provided
+
+ org.yaml
+ snakeyaml
+ 2.3
+
diff --git a/src/main/java/org/codehaus/mojo/properties/managers/YmlPropertiesManager.java b/src/main/java/org/codehaus/mojo/properties/managers/YmlPropertiesManager.java
new file mode 100644
index 0000000..23182b6
--- /dev/null
+++ b/src/main/java/org/codehaus/mojo/properties/managers/YmlPropertiesManager.java
@@ -0,0 +1,108 @@
+package org.codehaus.mojo.properties.managers;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.yaml.snakeyaml.Yaml;
+
+/**
+ * Properties manager using YAML as backand.
+ */
+@Named
+@Singleton
+public class YmlPropertiesManager implements PropertiesManager {
+
+ private static final String SUPPORTED_EXTENSION_YML = "yml";
+ private static final String SUPPORTED_EXTENSION_YAML = "yaml";
+
+ @Override
+ public boolean isExtensionSupport(final String extension) {
+ return SUPPORTED_EXTENSION_YML.equals(extension) || SUPPORTED_EXTENSION_YAML.equals(extension);
+ }
+
+ @Override
+ public Properties load(final InputStream in) throws IOException {
+ final Properties properties = new Properties();
+ final Map map = flattenYamlToMap("", new Yaml().load(in));
+ properties.putAll(map);
+ return properties;
+ }
+
+ public Map flattenYamlToMap(String parentKey, final Map yamlMap) {
+ if (parentKey != null && !parentKey.trim().isEmpty()) {
+ parentKey = parentKey.trim() + ".";
+ }
+ final Map result = new HashMap<>();
+
+ for (final Map.Entry entry : yamlMap.entrySet()) {
+ final String key = String.format("%s%s", parentKey, entry.getKey().trim());
+ final Object value = entry.getValue();
+ if (value instanceof Map) {
+ final Map stringObjectMap = flattenYamlToMap(key, (Map) value);
+ result.putAll(stringObjectMap);
+ } else if (value instanceof Collection) {
+ final Object[] values = ((Collection>) value).toArray();
+ for (int i = 0; i < values.length; i++) {
+ if (values[i] instanceof Map) {
+ result.putAll(flattenYamlToMap(
+ String.format("%s%s[%d]", parentKey, entry.getKey(), i), (Map) values[i]));
+ } else {
+ result.put(String.format("%s%s[%d]", parentKey, entry.getKey(), i), String.valueOf(values[i]));
+ }
+ }
+ } else {
+ result.put(key, value);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void save(final Properties properties, final OutputStream out, String comments) throws IOException {
+
+ final OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out, StandardCharsets.ISO_8859_1);
+
+ try (PrintWriter pw = new PrintWriter(outputStreamWriter);
+ StringWriter sw = new StringWriter()) {
+ properties.store(sw, comments);
+ comments = '#' + comments;
+
+ final List lines = new ArrayList<>();
+ try (BufferedReader r = new BufferedReader(new StringReader(sw.toString()))) {
+ String line;
+ while ((line = r.readLine()) != null) {
+ if (!line.startsWith("#") || line.equals(comments)) {
+ lines.add(line);
+ }
+ }
+ }
+
+ Collections.sort(lines);
+ for (final String l : lines) {
+ pw.println(l);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s [extension=%s]", getClass().getSimpleName(), SUPPORTED_EXTENSION_YML);
+ }
+}
diff --git a/src/test/java/org/codehaus/mojo/properties/managers/YmlPropertiesManagerTest.java b/src/test/java/org/codehaus/mojo/properties/managers/YmlPropertiesManagerTest.java
new file mode 100644
index 0000000..e0d4eb2
--- /dev/null
+++ b/src/test/java/org/codehaus/mojo/properties/managers/YmlPropertiesManagerTest.java
@@ -0,0 +1,55 @@
+package org.codehaus.mojo.properties.managers;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class YmlPropertiesManagerTest {
+
+ private static final String NL = System.lineSeparator();
+
+ private final YmlPropertiesManager manager = new YmlPropertiesManager();
+
+ @Test
+ public void testLoad() throws IOException {
+
+ // given
+ final String props = "# comments" + NL + NL + "key1:" + NL + " key2: value1" + NL + "key3: value2" + NL
+ + "key4: " + NL + " - A" + NL + " - B" + NL + " - C" + NL;
+
+ final ByteArrayInputStream inputStream = new ByteArrayInputStream(props.getBytes());
+
+ // when
+ final Properties properties = manager.load(inputStream);
+
+ // then
+ assertEquals(5, properties.size());
+ assertEquals("value1", properties.getProperty("key1.key2"));
+ assertEquals("value2", properties.getProperty("key3"));
+ assertEquals("A", properties.getProperty("key4[0]"));
+ }
+
+ @Test
+ public void testSave() throws IOException {
+
+ // given
+ final Properties properties = new Properties();
+ properties.setProperty("key1", "value1");
+ properties.setProperty("key2", "value2");
+
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ // when
+ manager.save(properties, outputStream, "Test comments");
+
+ // then
+ final String expected = "#Test comments" + NL + "key1=value1" + NL + "key2=value2" + NL;
+
+ assertEquals(expected, outputStream.toString());
+ }
+}