diff --git a/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java b/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
index 116ec26..9dea9bc 100644
--- a/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
+++ b/src/main/java/org/apache/sling/feature/io/json/FeatureJSONReader.java
@@ -19,23 +19,14 @@
 import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
-import java.util.function.BiConsumer;
 
 import javax.json.Json;
 import javax.json.JsonObject;
 import javax.json.stream.JsonParsingException;
 
-import org.apache.felix.utils.resource.CapabilityImpl;
-import org.apache.felix.utils.resource.RequirementImpl;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
 
 /**
  * This class offers a method to read a {@code Feature} using a {@code Reader} instance.
@@ -104,9 +95,9 @@
         this.readFrameworkProperties(map, feature.getFrameworkProperties());
         this.readConfigurations(map, feature.getConfigurations());
 
-        this.readCapabilities(map);
-        this.readRequirements(map);
-        this.readIncludes(map);
+        this.readCapabilities(map, feature.getCapabilities());
+        this.readRequirements(map, feature.getRequirements());
+        feature.setInclude(this.readInclude(map));
 
         this.readExtensions(map,
                 JSONConstants.FEATURE_KNOWN_PROPERTIES,
@@ -124,197 +115,6 @@
             throw new IOException("Unsupported model version: " + modelVersion);
         }
     }
-
-    private void readIncludes(final Map<String, Object> map) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_INCLUDE)) {
-            final Object includeObj = map.get(JSONConstants.FEATURE_INCLUDE);
-            checkType(JSONConstants.FEATURE_INCLUDE, includeObj, Map.class, String.class);
-
-            @SuppressWarnings("unchecked")
-            final Include include;
-            if ( includeObj instanceof String ) {
-                final ArtifactId id = ArtifactId.parse(includeObj.toString());
-                include = new Include(id);
-            } else {
-                @SuppressWarnings("unchecked")
-                final Map<String, Object> obj = (Map<String, Object>) includeObj;
-                if ( !obj.containsKey(JSONConstants.ARTIFACT_ID) ) {
-                    throw new IOException(exceptionPrefix + " include is missing required artifact id");
-                }
-                checkType("Include " + JSONConstants.ARTIFACT_ID, obj.get(JSONConstants.ARTIFACT_ID), String.class);
-                final ArtifactId id = ArtifactId.parse(obj.get(JSONConstants.ARTIFACT_ID).toString());
-                include = new Include(id);
-
-                if ( obj.containsKey(JSONConstants.INCLUDE_REMOVALS) ) {
-                    checkType("Include removals", obj.get(JSONConstants.INCLUDE_REMOVALS), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> removalObj = (Map<String, Object>) obj.get(JSONConstants.INCLUDE_REMOVALS);
-                    if ( removalObj.containsKey(JSONConstants.FEATURE_BUNDLES) ) {
-                        checkType("Include removal bundles", removalObj.get(JSONConstants.FEATURE_BUNDLES), List.class);
-                        @SuppressWarnings("unchecked")
-                        final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_BUNDLES);
-                        for(final Object val : list) {
-                            checkType("Include removal bundles", val, String.class);
-                            if ( val.toString().startsWith("#")) {
-                                continue;
-                            }
-                            include.getBundleRemovals().add(ArtifactId.parse(val.toString()));
-                        }
-                    }
-                    if ( removalObj.containsKey(JSONConstants.FEATURE_CONFIGURATIONS) ) {
-                        checkType("Include removal configuration", removalObj.get(JSONConstants.FEATURE_CONFIGURATIONS), List.class);
-                        @SuppressWarnings("unchecked")
-                        final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_CONFIGURATIONS);
-                        for(final Object val : list) {
-                            checkType("Include removal configuration", val, String.class);
-                            include.getConfigurationRemovals().add(val.toString());
-                        }
-                    }
-                    if ( removalObj.containsKey(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES) ) {
-                        checkType("Include removal framework properties", removalObj.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES), List.class);
-                        @SuppressWarnings("unchecked")
-                        final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES);
-                        for(final Object val : list) {
-                            checkType("Include removal framework properties", val, String.class);
-                            include.getFrameworkPropertiesRemovals().add(val.toString());
-                        }
-                    }
-                    if ( removalObj.containsKey(JSONConstants.INCLUDE_EXTENSION_REMOVALS) ) {
-                        checkType("Include removal extensions", removalObj.get(JSONConstants.INCLUDE_EXTENSION_REMOVALS), List.class);
-                        @SuppressWarnings("unchecked")
-                        final List<Object> list = (List<Object>)removalObj.get(JSONConstants.INCLUDE_EXTENSION_REMOVALS);
-                        for(final Object val : list) {
-                            checkType("Include removal extension", val, String.class, Map.class);
-                            if ( val instanceof String ) {
-                                if ( val.toString().startsWith("#")) {
-                                    continue;
-                                }
-                                include.getExtensionRemovals().add(val.toString());
-                            } else {
-                                @SuppressWarnings("unchecked")
-                                final Map<String, Object> removalMap = (Map<String, Object>)val;
-                                final Object nameObj = removalMap.get("name");
-                                checkType("Include removal extension", nameObj, String.class);
-                                if ( removalMap.containsKey("artifacts") ) {
-                                    checkType("Include removal extension artifacts", removalMap.get("artifacts"), List.class);
-                                    @SuppressWarnings("unchecked")
-                                    final List<Object> artifactList = (List<Object>)removalMap.get("artifacts");
-                                    final List<ArtifactId> ids = new ArrayList<>();
-                                    for(final Object aid : artifactList) {
-                                        checkType("Include removal extension artifact", aid, String.class);
-                                        ids.add(ArtifactId.parse(aid.toString()));
-                                    }
-                                    include.getArtifactExtensionRemovals().put(nameObj.toString(), ids);
-                                } else {
-                                    include.getExtensionRemovals().add(nameObj.toString());
-                                }
-                            }
-                        }
-                    }
-
-                }
-            }
-            feature.setInclude(include);
-        }
-    }
-
-    private void readRequirements(Map<String, Object> map) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_REQUIREMENTS)) {
-            final Object reqObj = map.get(JSONConstants.FEATURE_REQUIREMENTS);
-            checkType(JSONConstants.FEATURE_REQUIREMENTS, reqObj, List.class);
-
-            @SuppressWarnings("unchecked")
-            final List<Object> requirements = (List<Object>)reqObj;
-            for(final Object req : requirements) {
-                checkType("Requirement", req, Map.class);
-                @SuppressWarnings("unchecked")
-                final Map<String, Object> obj = (Map<String, Object>) req;
-
-                if ( !obj.containsKey(JSONConstants.REQCAP_NAMESPACE) ) {
-                    throw new IOException(this.exceptionPrefix + "Namespace is missing for requirement");
-                }
-                checkType("Requirement namespace", obj.get(JSONConstants.REQCAP_NAMESPACE), String.class);
-
-                Map<String, Object> attrMap = new HashMap<>();
-                if ( obj.containsKey(JSONConstants.REQCAP_ATTRIBUTES) ) {
-                    checkType("Requirement attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES);
-                    attrs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalAttribute(key, value, attrMap::put)));
-                }
-
-                Map<String, String> dirMap = new HashMap<>();
-                if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) {
-                    checkType("Requirement directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> dirs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_DIRECTIVES);
-                    dirs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalDirective(key, value, dirMap::put)));
-                }
-
-                final Requirement r = new RequirementImpl(null, obj.get(JSONConstants.REQCAP_NAMESPACE).toString(), dirMap, attrMap);
-                feature.getRequirements().add(r);
-            }
-        }
-    }
-
-    private void readCapabilities(Map<String, Object> map) throws IOException {
-        if ( map.containsKey(JSONConstants.FEATURE_CAPABILITIES)) {
-            final Object capObj = map.get(JSONConstants.FEATURE_CAPABILITIES);
-            checkType(JSONConstants.FEATURE_CAPABILITIES, capObj, List.class);
-
-            @SuppressWarnings("unchecked")
-            final List<Object> capabilities = (List<Object>)capObj;
-            for(final Object cap : capabilities) {
-                checkType("Capability", cap, Map.class);
-                @SuppressWarnings("unchecked")
-                final Map<String, Object> obj = (Map<String, Object>) cap;
-
-                if ( !obj.containsKey(JSONConstants.REQCAP_NAMESPACE) ) {
-                    throw new IOException(this.exceptionPrefix + "Namespace is missing for capability");
-                }
-                checkType("Capability namespace", obj.get(JSONConstants.REQCAP_NAMESPACE), String.class);
-
-                Map<String, Object> attrMap = new HashMap<>();
-                if ( obj.containsKey(JSONConstants.REQCAP_ATTRIBUTES) ) {
-                    checkType("Capability attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES);
-                    attrs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalAttribute(key, value, attrMap::put)));
-                }
-
-                Map<String, String> dirMap = new HashMap<>();
-                if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) {
-                    checkType("Capability directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class);
-                    @SuppressWarnings("unchecked")
-                    final Map<String, Object> dirs = (Map<String, Object>) obj.get(JSONConstants.REQCAP_DIRECTIVES);
-                    dirs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalDirective(key, value, dirMap::put)));
-                }
-
-                final Capability c = new CapabilityImpl(null, obj.get(JSONConstants.REQCAP_NAMESPACE).toString(), dirMap, attrMap);
-                feature.getCapabilities().add(c);
-            }
-        }
-    }
-
-    @FunctionalInterface
-    private interface BiConsumer_WithExceptions<T, V, E extends Exception> {
-        void accept(T t, V u) throws E;
-    }
-
-    private static <T, V, E extends Exception> BiConsumer<T, V> rethrowBiConsumer(BiConsumer_WithExceptions<T, V, E> biConsumer) {
-        return (t, u) -> {
-            try {
-                biConsumer.accept(t, u);
-            } catch (Exception exception) {
-                throwAsUnchecked(exception);
-            }
-        };
-    }
-
-    @SuppressWarnings ("unchecked")
-    private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E {
-        throw (E) exception;
-    }
 }
 
 
diff --git a/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java b/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
index 163a164..a7cd9a1 100644
--- a/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
+++ b/src/main/java/org/apache/sling/feature/io/json/FeatureJSONWriter.java
@@ -18,19 +18,12 @@
 
 import java.io.IOException;
 import java.io.Writer;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
 
 import javax.json.stream.JsonGenerator;
 
-import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.Configurations;
 import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
 
 /**
  * Simple JSON writer for a feature
@@ -51,116 +44,6 @@
         w.writeFeature(writer, feature);
     }
 
-    private void writeProperty(final JsonGenerator generator, final String key, final String value) {
-        if ( value != null ) {
-            generator.write(key, value);
-        }
-    }
-
-    private <T> void writeList(final JsonGenerator generator, final String name, final Collection<T> values) {
-        if (!values.isEmpty()) {
-            generator.writeStartArray(name);
-            for (T value : values) {
-                generator.write(value.toString());
-            }
-            generator.writeEnd();
-        }
-    }
-
-    private void writeInclude(final JsonGenerator generator, final Include inc) {
-        if (inc == null) {
-            return;
-        }
-
-        if ( inc.getArtifactExtensionRemovals().isEmpty()
-             && inc.getBundleRemovals().isEmpty()
-             && inc.getConfigurationRemovals().isEmpty()
-             && inc.getFrameworkPropertiesRemovals().isEmpty() ) {
-
-            generator.write(JSONConstants.FEATURE_INCLUDE, inc.getId().toMvnId());
-        } else {
-            generator.writeStartObject(JSONConstants.FEATURE_INCLUDE);
-            writeProperty(generator, JSONConstants.ARTIFACT_ID, inc.getId().toMvnId());
-
-            generator.writeStartObject(JSONConstants.INCLUDE_REMOVALS);
-
-            if ( !inc.getArtifactExtensionRemovals().isEmpty()
-                 || inc.getExtensionRemovals().isEmpty() ) {
-                generator.writeStartArray(JSONConstants.INCLUDE_EXTENSION_REMOVALS);
-
-                for(final String id : inc.getExtensionRemovals()) {
-                    generator.write(id);
-                }
-                for(final Map.Entry<String, List<ArtifactId>> entry : inc.getArtifactExtensionRemovals().entrySet()) {
-                    generator.writeStartObject();
-
-                    writeList(generator, entry.getKey(), entry.getValue());
-
-                    generator.writeEnd();
-                }
-
-                generator.writeEnd();
-            }
-            writeList(generator, JSONConstants.FEATURE_CONFIGURATIONS, inc.getConfigurationRemovals());
-            writeList(generator, JSONConstants.FEATURE_BUNDLES, inc.getBundleRemovals());
-            writeList(generator, JSONConstants.FEATURE_FRAMEWORK_PROPERTIES, inc.getFrameworkPropertiesRemovals());
-
-            generator.writeEnd().writeEnd();
-        }
-    }
-
-    private void writeRequirements(final JsonGenerator generator, final List<Requirement> requirements) {
-        if (requirements.isEmpty()) {
-            return;
-        }
-
-        generator.writeStartArray(JSONConstants.FEATURE_REQUIREMENTS);
-
-        for(final Requirement req : requirements) {
-            generator.writeStartObject();
-            writeProperty(generator, JSONConstants.REQCAP_NAMESPACE, req.getNamespace());
-            if ( !req.getAttributes().isEmpty() ) {
-                generator.writeStartObject(JSONConstants.REQCAP_ATTRIBUTES);
-                req.getAttributes().forEach((key, value) -> ManifestUtils.marshalAttribute(key, value, generator::write));
-                generator.writeEnd();
-            }
-            if ( !req.getDirectives().isEmpty() ) {
-                generator.writeStartObject(JSONConstants.REQCAP_DIRECTIVES);
-                req.getDirectives().forEach((key, value) -> ManifestUtils.marshalDirective(key, value, generator::write));
-                generator.writeEnd();
-            }
-            generator.writeEnd();
-        }
-
-        generator.writeEnd();
-    }
-
-    private void writeCapabilities(final JsonGenerator generator, final List<Capability> capabilities) {
-        if (capabilities.isEmpty()) {
-            return;
-        }
-
-        generator.writeStartArray(JSONConstants.FEATURE_CAPABILITIES);
-
-        for(final Capability cap : capabilities) {
-            generator.writeStartObject();
-            writeProperty(generator, JSONConstants.REQCAP_NAMESPACE, cap.getNamespace());
-            if ( !cap.getAttributes().isEmpty() ) {
-                generator.writeStartObject(JSONConstants.REQCAP_ATTRIBUTES);
-                cap.getAttributes().forEach((key, value) -> ManifestUtils.marshalAttribute(key, value, generator::write));
-                generator.writeEnd();
-            }
-            if ( !cap.getDirectives().isEmpty() ) {
-                generator.writeStartObject(JSONConstants.REQCAP_DIRECTIVES);
-                cap.getDirectives().forEach((key, value) -> ManifestUtils.marshalDirective(key, value, generator::write));
-                generator.writeEnd();
-            }
-            generator.writeEnd();
-        }
-
-        generator.writeEnd();
-    }
-
     private void writeFeature(final Writer writer, final Feature feature)
     throws IOException {
         JsonGenerator generator = newGenerator(writer);
diff --git a/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java b/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java
index 4602f2c..90b5668 100644
--- a/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java
+++ b/src/main/java/org/apache/sling/feature/io/json/JSONReaderBase.java
@@ -20,6 +20,8 @@
 import org.apache.felix.configurator.impl.json.JSONUtil;
 import org.apache.felix.configurator.impl.json.TypeConverter;
 import org.apache.felix.configurator.impl.model.Config;
+import org.apache.felix.utils.resource.CapabilityImpl;
+import org.apache.felix.utils.resource.RequirementImpl;
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Bundles;
@@ -28,7 +30,10 @@
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Extensions;
+import org.apache.sling.feature.Include;
 import org.apache.sling.feature.KeyValueMap;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
 
 import java.io.IOException;
 import java.io.Reader;
@@ -44,6 +49,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.function.BiConsumer;
 import java.util.Set;
 
 import javax.json.Json;
@@ -489,4 +495,195 @@
             throw new IOException(this.exceptionPrefix + "Key " + key + " is not one of the allowed types " + Arrays.toString(types) + " : " + val.getClass());
         }
     }
+
+    protected Include readInclude(final Map<String, Object> map) throws IOException {
+        if ( map.containsKey(JSONConstants.FEATURE_INCLUDE)) {
+            final Object includeObj = map.get(JSONConstants.FEATURE_INCLUDE);
+            checkType(JSONConstants.FEATURE_INCLUDE, includeObj, Map.class, String.class);
+
+            final Include include;
+            if ( includeObj instanceof String ) {
+                final ArtifactId id = ArtifactId.parse(includeObj.toString());
+                include = new Include(id);
+            } else {
+                @SuppressWarnings("unchecked")
+                final Map<String, Object> obj = (Map<String, Object>) includeObj;
+                if ( !obj.containsKey(JSONConstants.ARTIFACT_ID) ) {
+                    throw new IOException(exceptionPrefix + " include is missing required artifact id");
+                }
+                checkType("Include " + JSONConstants.ARTIFACT_ID, obj.get(JSONConstants.ARTIFACT_ID), String.class);
+                final ArtifactId id = ArtifactId.parse(obj.get(JSONConstants.ARTIFACT_ID).toString());
+                include = new Include(id);
+
+                if ( obj.containsKey(JSONConstants.INCLUDE_REMOVALS) ) {
+                    checkType("Include removals", obj.get(JSONConstants.INCLUDE_REMOVALS), Map.class);
+                    @SuppressWarnings("unchecked")
+                    final Map<String, Object> removalObj = (Map<String, Object>) obj.get(JSONConstants.INCLUDE_REMOVALS);
+                    if ( removalObj.containsKey(JSONConstants.FEATURE_BUNDLES) ) {
+                        checkType("Include removal bundles", removalObj.get(JSONConstants.FEATURE_BUNDLES), List.class);
+                        @SuppressWarnings("unchecked")
+                        final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_BUNDLES);
+                        for(final Object val : list) {
+                            checkType("Include removal bundles", val, String.class);
+                            if ( val.toString().startsWith("#")) {
+                                continue;
+                            }
+                            include.getBundleRemovals().add(ArtifactId.parse(val.toString()));
+                        }
+                    }
+                    if ( removalObj.containsKey(JSONConstants.FEATURE_CONFIGURATIONS) ) {
+                        checkType("Include removal configuration", removalObj.get(JSONConstants.FEATURE_CONFIGURATIONS), List.class);
+                        @SuppressWarnings("unchecked")
+                        final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_CONFIGURATIONS);
+                        for(final Object val : list) {
+                            checkType("Include removal configuration", val, String.class);
+                            include.getConfigurationRemovals().add(val.toString());
+                        }
+                    }
+                    if ( removalObj.containsKey(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES) ) {
+                        checkType("Include removal framework properties", removalObj.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES), List.class);
+                        @SuppressWarnings("unchecked")
+                        final List<Object> list = (List<Object>)removalObj.get(JSONConstants.FEATURE_FRAMEWORK_PROPERTIES);
+                        for(final Object val : list) {
+                            checkType("Include removal framework properties", val, String.class);
+                            include.getFrameworkPropertiesRemovals().add(val.toString());
+                        }
+                    }
+                    if ( removalObj.containsKey(JSONConstants.INCLUDE_EXTENSION_REMOVALS) ) {
+                        checkType("Include removal extensions", removalObj.get(JSONConstants.INCLUDE_EXTENSION_REMOVALS), List.class);
+                        @SuppressWarnings("unchecked")
+                        final List<Object> list = (List<Object>)removalObj.get(JSONConstants.INCLUDE_EXTENSION_REMOVALS);
+                        for(final Object val : list) {
+                            checkType("Include removal extension", val, String.class, Map.class);
+                            if ( val instanceof String ) {
+                                if ( val.toString().startsWith("#")) {
+                                    continue;
+                                }
+                                include.getExtensionRemovals().add(val.toString());
+                            } else {
+                                @SuppressWarnings("unchecked")
+                                final Map<String, Object> removalMap = (Map<String, Object>)val;
+                                final Object nameObj = removalMap.get("name");
+                                checkType("Include removal extension", nameObj, String.class);
+                                if ( removalMap.containsKey("artifacts") ) {
+                                    checkType("Include removal extension artifacts", removalMap.get("artifacts"), List.class);
+                                    @SuppressWarnings("unchecked")
+                                    final List<Object> artifactList = (List<Object>)removalMap.get("artifacts");
+                                    final List<ArtifactId> ids = new ArrayList<>();
+                                    for(final Object aid : artifactList) {
+                                        checkType("Include removal extension artifact", aid, String.class);
+                                        ids.add(ArtifactId.parse(aid.toString()));
+                                    }
+                                    include.getArtifactExtensionRemovals().put(nameObj.toString(), ids);
+                                } else {
+                                    include.getExtensionRemovals().add(nameObj.toString());
+                                }
+                            }
+                        }
+                    }
+
+                }
+            }
+            return include;
+        }
+        return null;
+    }
+
+    protected void readRequirements(Map<String, Object> map, final List<Requirement> container) throws IOException {
+        if ( map.containsKey(JSONConstants.FEATURE_REQUIREMENTS)) {
+            final Object reqObj = map.get(JSONConstants.FEATURE_REQUIREMENTS);
+            checkType(JSONConstants.FEATURE_REQUIREMENTS, reqObj, List.class);
+
+            @SuppressWarnings("unchecked")
+            final List<Object> requirements = (List<Object>)reqObj;
+            for(final Object req : requirements) {
+                checkType("Requirement", req, Map.class);
+                @SuppressWarnings("unchecked")
+                final Map<String, Object> obj = (Map<String, Object>) req;
+
+                if ( !obj.containsKey(JSONConstants.REQCAP_NAMESPACE) ) {
+                    throw new IOException(this.exceptionPrefix + "Namespace is missing for requirement");
+                }
+                checkType("Requirement namespace", obj.get(JSONConstants.REQCAP_NAMESPACE), String.class);
+
+                Map<String, Object> attrMap = new HashMap<>();
+                if ( obj.containsKey(JSONConstants.REQCAP_ATTRIBUTES) ) {
+                    checkType("Requirement attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class);
+                    @SuppressWarnings("unchecked")
+                    final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES);
+                    attrs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalAttribute(key, value, attrMap::put)));
+                }
+
+                Map<String, String> dirMap = new HashMap<>();
+                if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) {
+                    checkType("Requirement directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class);
+                    @SuppressWarnings("unchecked")
+                    final Map<String, Object> dirs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_DIRECTIVES);
+                    dirs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalDirective(key, value, dirMap::put)));
+                }
+
+                final Requirement r = new RequirementImpl(null, obj.get(JSONConstants.REQCAP_NAMESPACE).toString(), dirMap, attrMap);
+                container.add(r);
+            }
+        }
+    }
+
+    protected void readCapabilities(Map<String, Object> map, final List<Capability> container) throws IOException {
+        if ( map.containsKey(JSONConstants.FEATURE_CAPABILITIES)) {
+            final Object capObj = map.get(JSONConstants.FEATURE_CAPABILITIES);
+            checkType(JSONConstants.FEATURE_CAPABILITIES, capObj, List.class);
+
+            @SuppressWarnings("unchecked")
+            final List<Object> capabilities = (List<Object>)capObj;
+            for(final Object cap : capabilities) {
+                checkType("Capability", cap, Map.class);
+                @SuppressWarnings("unchecked")
+                final Map<String, Object> obj = (Map<String, Object>) cap;
+
+                if ( !obj.containsKey(JSONConstants.REQCAP_NAMESPACE) ) {
+                    throw new IOException(this.exceptionPrefix + "Namespace is missing for capability");
+                }
+                checkType("Capability namespace", obj.get(JSONConstants.REQCAP_NAMESPACE), String.class);
+
+                Map<String, Object> attrMap = new HashMap<>();
+                if ( obj.containsKey(JSONConstants.REQCAP_ATTRIBUTES) ) {
+                    checkType("Capability attributes", obj.get(JSONConstants.REQCAP_ATTRIBUTES), Map.class);
+                    @SuppressWarnings("unchecked")
+                    final Map<String, Object> attrs = (Map<String, Object>)obj.get(JSONConstants.REQCAP_ATTRIBUTES);
+                    attrs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalAttribute(key, value, attrMap::put)));
+                }
+
+                Map<String, String> dirMap = new HashMap<>();
+                if ( obj.containsKey(JSONConstants.REQCAP_DIRECTIVES) ) {
+                    checkType("Capability directives", obj.get(JSONConstants.REQCAP_DIRECTIVES), Map.class);
+                    @SuppressWarnings("unchecked")
+                    final Map<String, Object> dirs = (Map<String, Object>) obj.get(JSONConstants.REQCAP_DIRECTIVES);
+                    dirs.forEach(rethrowBiConsumer((key, value) -> ManifestUtils.unmarshalDirective(key, value, dirMap::put)));
+                }
+
+                final Capability c = new CapabilityImpl(null, obj.get(JSONConstants.REQCAP_NAMESPACE).toString(), dirMap, attrMap);
+                container.add(c);
+            }
+        }
+    }
+
+    @FunctionalInterface
+    private interface BiConsumer_WithExceptions<T, V, E extends Exception> {
+        void accept(T t, V u) throws E;
+    }
+
+    private static <T, V, E extends Exception> BiConsumer<T, V> rethrowBiConsumer(BiConsumer_WithExceptions<T, V, E> biConsumer) {
+        return (t, u) -> {
+            try {
+                biConsumer.accept(t, u);
+            } catch (Exception exception) {
+                throwAsUnchecked(exception);
+            }
+        };
+    }
+
+    @SuppressWarnings ("unchecked")
+    private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E {
+        throw (E) exception;
+    }
 }
diff --git a/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java b/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java
index 3533e68..23fb2df 100644
--- a/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java
+++ b/src/main/java/org/apache/sling/feature/io/json/JSONWriterBase.java
@@ -19,8 +19,8 @@
 import java.io.StringReader;
 import java.io.Writer;
 import java.lang.reflect.Array;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
 
@@ -30,12 +30,16 @@
 import javax.json.stream.JsonGeneratorFactory;
 
 import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Bundles;
 import org.apache.sling.feature.Configuration;
 import org.apache.sling.feature.Configurations;
 import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Include;
 import org.apache.sling.feature.KeyValueMap;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
 
 /**
  * Common functionality for writing JSON
@@ -109,14 +113,13 @@
 
             generator.writeStartObject(key);
 
-            final Enumeration<String> e = cfg.getProperties().keys();
-            while ( e.hasMoreElements() ) {
-                final String name = e.nextElement();
+            for(final Map.Entry<String, Object> prop : cfg.getProperties().entrySet()) {
+                final String name = prop.getKey();
                 if ( Configuration.PROP_ARTIFACT_ID.equals(name) ) {
                     continue;
                 }
 
-                final Object val = cfg.getProperties().get(name);
+                final Object val = prop.getValue();
 
                 String typePostFix = null;
                 final Object typeCheck;
@@ -256,4 +259,114 @@
             }
         }
     }
+
+    protected void writeProperty(final JsonGenerator generator, final String key, final String value) {
+        if ( value != null ) {
+            generator.write(key, value);
+        }
+    }
+
+    protected <T> void writeList(final JsonGenerator generator, final String name, final Collection<T> values) {
+        if (!values.isEmpty()) {
+            generator.writeStartArray(name);
+            for (T value : values) {
+                generator.write(value.toString());
+            }
+            generator.writeEnd();
+        }
+    }
+
+    protected void writeInclude(final JsonGenerator generator, final Include inc) {
+        if (inc == null) {
+            return;
+        }
+
+        if ( inc.getArtifactExtensionRemovals().isEmpty()
+             && inc.getBundleRemovals().isEmpty()
+             && inc.getConfigurationRemovals().isEmpty()
+             && inc.getFrameworkPropertiesRemovals().isEmpty() ) {
+
+            generator.write(JSONConstants.FEATURE_INCLUDE, inc.getId().toMvnId());
+        } else {
+            generator.writeStartObject(JSONConstants.FEATURE_INCLUDE);
+            writeProperty(generator, JSONConstants.ARTIFACT_ID, inc.getId().toMvnId());
+
+            generator.writeStartObject(JSONConstants.INCLUDE_REMOVALS);
+
+            if ( !inc.getArtifactExtensionRemovals().isEmpty()
+                 || inc.getExtensionRemovals().isEmpty() ) {
+                generator.writeStartArray(JSONConstants.INCLUDE_EXTENSION_REMOVALS);
+
+                for(final String id : inc.getExtensionRemovals()) {
+                    generator.write(id);
+                }
+                for(final Map.Entry<String, List<ArtifactId>> entry : inc.getArtifactExtensionRemovals().entrySet()) {
+                    generator.writeStartObject();
+
+                    writeList(generator, entry.getKey(), entry.getValue());
+
+                    generator.writeEnd();
+                }
+
+                generator.writeEnd();
+            }
+            writeList(generator, JSONConstants.FEATURE_CONFIGURATIONS, inc.getConfigurationRemovals());
+            writeList(generator, JSONConstants.FEATURE_BUNDLES, inc.getBundleRemovals());
+            writeList(generator, JSONConstants.FEATURE_FRAMEWORK_PROPERTIES, inc.getFrameworkPropertiesRemovals());
+
+            generator.writeEnd().writeEnd();
+        }
+    }
+
+    protected void writeRequirements(final JsonGenerator generator, final List<Requirement> requirements) {
+        if (requirements.isEmpty()) {
+            return;
+        }
+
+        generator.writeStartArray(JSONConstants.FEATURE_REQUIREMENTS);
+
+        for(final Requirement req : requirements) {
+            generator.writeStartObject();
+            writeProperty(generator, JSONConstants.REQCAP_NAMESPACE, req.getNamespace());
+            if ( !req.getAttributes().isEmpty() ) {
+                generator.writeStartObject(JSONConstants.REQCAP_ATTRIBUTES);
+                req.getAttributes().forEach((key, value) -> ManifestUtils.marshalAttribute(key, value, generator::write));
+                generator.writeEnd();
+            }
+            if ( !req.getDirectives().isEmpty() ) {
+                generator.writeStartObject(JSONConstants.REQCAP_DIRECTIVES);
+                req.getDirectives().forEach((key, value) -> ManifestUtils.marshalDirective(key, value, generator::write));
+                generator.writeEnd();
+            }
+            generator.writeEnd();
+        }
+
+        generator.writeEnd();
+    }
+
+    protected void writeCapabilities(final JsonGenerator generator, final List<Capability> capabilities) {
+        if (capabilities.isEmpty()) {
+            return;
+        }
+
+        generator.writeStartArray(JSONConstants.FEATURE_CAPABILITIES);
+
+        for(final Capability cap : capabilities) {
+            generator.writeStartObject();
+            writeProperty(generator, JSONConstants.REQCAP_NAMESPACE, cap.getNamespace());
+            if ( !cap.getAttributes().isEmpty() ) {
+                generator.writeStartObject(JSONConstants.REQCAP_ATTRIBUTES);
+                cap.getAttributes().forEach((key, value) -> ManifestUtils.marshalAttribute(key, value, generator::write));
+                generator.writeEnd();
+            }
+            if ( !cap.getDirectives().isEmpty() ) {
+                generator.writeStartObject(JSONConstants.REQCAP_DIRECTIVES);
+                cap.getDirectives().forEach((key, value) -> ManifestUtils.marshalDirective(key, value, generator::write));
+                generator.writeEnd();
+            }
+            generator.writeEnd();
+        }
+
+        generator.writeEnd();
+    }
 }
