You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2018/04/27 09:51:37 UTC

[sling-org-apache-sling-feature] 17/22: Move the process package from the feature api module to the support one.

This is an automated email from the ASF dual-hosted git repository.

davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature.git

commit 77d89a31442d2bc72650d8dcfab25422cbacc107
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Wed Apr 11 16:51:50 2018 +0100

    Move the process package from the feature api module to the support one.
    
    Also move the associated tests.
---
 .../sling/feature/process/ApplicationBuilder.java  | 177 ------------
 .../sling/feature/process/BuilderContext.java      |  67 -----
 .../apache/sling/feature/process/BuilderUtil.java  | 261 ------------------
 .../sling/feature/process/FeatureBuilder.java      | 182 -------------
 .../feature/process/FeatureExtensionHandler.java   |  55 ----
 .../sling/feature/process/FeatureProvider.java     |  30 --
 .../sling/feature/process/FeatureResolver.java     |  39 ---
 .../apache/sling/feature/process/package-info.java |  23 --
 .../sling/feature/process/BuilderUtilTest.java     | 153 -----------
 .../sling/feature/process/FeatureBuilderTest.java  | 302 ---------------------
 10 files changed, 1289 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java b/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
deleted file mode 100644
index 71fc8b0..0000000
--- a/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.process;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.FeatureResource;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Build an application based on features.
- */
-public class ApplicationBuilder {
-
-    /**
-     * Assemble an application based on the provided feature Ids.
-     *
-     * Upgrade features are only applied if the provided feature list
-     * contains the feature to be upgraded. Otherwise the upgrade feature
-     * is ignored.
-     *
-     * @param app The optional application to use as a base.
-     * @param context The builder context
-     * @param resolver The Feature Resolver to use
-     * @param featureIds The feature ids
-     * @return The application
-     * throws IllegalArgumentException If context or featureIds is {@code null}
-     * throws IllegalStateException If the provided ids are invalid, or the feature can't be provided
-     */
-    public static Application assemble(final Application app,
-            final BuilderContext context,
-            final FeatureResolver resolver,
-            final String... featureIds) {
-        if ( featureIds == null || context == null ) {
-            throw new IllegalArgumentException("Features and/or context must not be null");
-        }
-
-        final Feature[] features = new Feature[featureIds.length];
-        int index = 0;
-        for(final String id : featureIds) {
-            features[index] = context.getFeatureProvider().provide(ArtifactId.parse(id));
-            if ( features[index] == null ) {
-                throw new IllegalStateException("Unable to find included feature " + id);
-            }
-            index++;
-        }
-        return assemble(app, context, resolver, features);
-    }
-
-    /**
-     * Assemble an application based on the provided features.
-     *
-     * If the same feature is included more than once only the feature with
-     * the highest version is used. The others are ignored.
-     *
-     * @param app The optional application to use as a base.
-     * @param context The builder context
-     * @param resolver The Feature Resolver to use
-     * @param features The features
-     * @return The application
-     * throws IllegalArgumentException If context or featureIds is {@code null}
-     * throws IllegalStateException If a feature can't be provided
-     */
-    public static Application assemble(
-            Application app,
-            final BuilderContext context,
-            final FeatureResolver resolver, final Feature... features) {
-        if ( features == null || context == null ) {
-            throw new IllegalArgumentException("Features and/or context must not be null");
-        }
-
-        if ( app == null ) {
-            app = new Application();
-        }
-
-        // Remove duplicate features by selecting the one with the highest version
-        final List<Feature> featureList = new ArrayList<>();
-        for(final Feature f : features) {
-            Feature found = null;
-            for(final Feature s : featureList) {
-                if ( s.getId().isSame(f.getId()) ) {
-                    found = s;
-                    break;
-                }
-            }
-            boolean add = true;
-            // feature with different version found
-            if ( found != null ) {
-                if ( f.getId().getOSGiVersion().compareTo(found.getId().getOSGiVersion()) <= 0 ) {
-                    // higher version already included
-                    add = false;
-                } else {
-                    // remove lower version, higher version will be added
-                    featureList.remove(found);
-                }
-            }
-            if ( add ) {
-                featureList.add(f);
-            }
-        }
-
-        final List<Feature> sortedFeatures;
-        if (resolver != null) {
-            // order by dependency chain
-            final List<FeatureResource> sortedResources = resolver.orderResources(featureList);
-
-            sortedFeatures = new ArrayList<>();
-            for (final FeatureResource fr : sortedResources) {
-                Feature f = fr.getFeature();
-                if (!sortedFeatures.contains(f)) {
-                    sortedFeatures.add(f);
-                }
-            }
-        } else {
-            sortedFeatures = featureList;
-            Collections.sort(sortedFeatures);
-        }
-
-        // assemble
-        int featureStartOrder = 5; // begin with start order a little higher than 0
-        for(final Feature f : sortedFeatures) {
-            app.getFeatureIds().add(f.getId());
-            final Feature assembled = FeatureBuilder.assemble(f, context.clone(new FeatureProvider() {
-
-                @Override
-                public Feature provide(final ArtifactId id) {
-                    for(final Feature f : features) {
-                        if ( f.getId().equals(id) ) {
-                            return f;
-                        }
-                    }
-                    return context.getFeatureProvider().provide(id);
-                }
-            }));
-
-            int globalStartOrder = featureStartOrder;
-            for (Artifact a : assembled.getBundles()) {
-                int so = a.getStartOrder() + featureStartOrder;
-                if (so > globalStartOrder)
-                    globalStartOrder = so;
-                a.setStartOrder(so);
-            }
-            // Next feature will have a higher start order than the previous
-            featureStartOrder = globalStartOrder + 1;
-
-            merge(app, assembled);
-        }
-
-        return app;
-    }
-
-    private static void merge(final Application target, final Feature source) {
-        BuilderUtil.mergeBundles(target.getBundles(), source.getBundles(), BuilderUtil.ArtifactMerge.HIGHEST);
-        BuilderUtil.mergeConfigurations(target.getConfigurations(), source.getConfigurations());
-        BuilderUtil.mergeFrameworkProperties(target.getFrameworkProperties(), source.getFrameworkProperties());
-        BuilderUtil.mergeExtensions(target, source, BuilderUtil.ArtifactMerge.HIGHEST);
-    }
-}
diff --git a/src/main/java/org/apache/sling/feature/process/BuilderContext.java b/src/main/java/org/apache/sling/feature/process/BuilderContext.java
deleted file mode 100644
index 024076d..0000000
--- a/src/main/java/org/apache/sling/feature/process/BuilderContext.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.process;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Builder context holds services used by {@link ApplicationBuilder}
- * and {@link FeatureBuilder}.
- */
-public class BuilderContext {
-
-    private final FeatureProvider provider;
-
-    private final List<FeatureExtensionHandler> featureExtensionHandlers = new ArrayList<>();
-
-    /**
-     * Assemble the full feature by processing all includes.
-     *
-     * @param feature The feature to start
-     * @param provider A provider providing the included features
-     * @param extensionMergers Optional feature mergers
-     * @return The assembled feature.
-     * @throws IllegalArgumentException If feature or provider is {@code null}
-     * @throws IllegalStateException If an included feature can't be provided or merged.
-     */
-    public BuilderContext(final FeatureProvider provider) {
-        if ( provider == null ) {
-            throw new IllegalArgumentException("Provider must not be null");
-        }
-        this.provider = provider;
-    }
-
-    FeatureProvider getFeatureProvider() {
-        return this.provider;
-    }
-
-    List<FeatureExtensionHandler> getFeatureExtensionHandlers() {
-        return this.featureExtensionHandlers;
-    }
-
-    public BuilderContext add(final FeatureExtensionHandler handler) {
-        featureExtensionHandlers.add(handler);
-        return this;
-    }
-
-    BuilderContext clone(final FeatureProvider featureProvider) {
-        final BuilderContext ctx = new BuilderContext(featureProvider);
-        ctx.featureExtensionHandlers.addAll(featureExtensionHandlers);
-        return ctx;
-    }
-}
diff --git a/src/main/java/org/apache/sling/feature/process/BuilderUtil.java b/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
deleted file mode 100644
index 90da88e..0000000
--- a/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.process;
-
-import java.io.StringReader;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
-
-import org.apache.sling.feature.Application;
-import org.apache.sling.feature.Artifact;
-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.Feature;
-import org.apache.sling.feature.KeyValueMap;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-/**
- * Utility methods for the builders
- */
-class BuilderUtil {
-
-    public enum ArtifactMerge {
-        LATEST,
-        HIGHEST
-    };
-
-    // bundles
-    static void mergeBundles(final Bundles target,
-            final Bundles source,
-            final ArtifactMerge artifactMergeAlg) {
-        for(final Map.Entry<Integer, List<Artifact>> entry : source.getBundlesByStartOrder().entrySet()) {
-            for(final Artifact a : entry.getValue()) {
-                // version handling - use provided algorithm
-                boolean replace = true;
-                if ( artifactMergeAlg == ArtifactMerge.HIGHEST ) {
-                    final Artifact existing = target.getSame(a.getId());
-                    if ( existing != null && existing.getId().getOSGiVersion().compareTo(a.getId().getOSGiVersion()) > 0 ) {
-                        replace = false;
-                    }
-                }
-                if ( replace ) {
-                    target.removeSame(a.getId());
-                    target.add(a);
-                }
-            }
-        }
-    }
-
-    // configurations - merge / override
-    static void mergeConfigurations(final Configurations target, final Configurations source) {
-        for(final Configuration cfg : source) {
-            boolean found = false;
-            for(final Configuration current : target) {
-                if ( current.compareTo(cfg) == 0 ) {
-                    found = true;
-                    // merge / override properties
-                    final Enumeration<String> i = cfg.getProperties().keys();
-                    while ( i.hasMoreElements() ) {
-                        final String key = i.nextElement();
-                        current.getProperties().put(key, cfg.getProperties().get(key));
-                    }
-                    break;
-                }
-            }
-            if ( !found ) {
-                target.add(cfg);
-            }
-        }
-    }
-
-    // framework properties (add/merge)
-    static void mergeFrameworkProperties(final KeyValueMap target, final KeyValueMap source) {
-        target.putAll(source);
-    }
-
-    // requirements (add)
-    static void mergeRequirements(final List<Requirement> target, final List<Requirement> source) {
-        for(final Requirement req : source) {
-            if ( !target.contains(req) ) {
-                target.add(req);
-            }
-        }
-    }
-
-    // capabilities (add)
-    static void mergeCapabilities(final List<Capability> target, final List<Capability> source) {
-        for(final Capability cap : source) {
-            if ( !target.contains(cap) ) {
-                target.add(cap);
-            }
-        }
-    }
-
-    // default merge for extensions
-    static void mergeExtensions(final Extension target,
-            final Extension source,
-            final ArtifactMerge artifactMergeAlg) {
-        switch ( target.getType() ) {
-            case TEXT : // simply append
-                        target.setText(target.getText() + "\n" + source.getText());
-                        break;
-            case JSON : final JsonStructure struct1;
-                        try ( final StringReader reader = new StringReader(target.getJSON()) ) {
-                            struct1 = Json.createReader(reader).read();
-                        }
-                        final JsonStructure struct2;
-                        try ( final StringReader reader = new StringReader(source.getJSON()) ) {
-                            struct2 = Json.createReader(reader).read();
-                        }
-
-                        if ( struct1.getValueType() != struct2.getValueType() ) {
-                            throw new IllegalStateException("Found different JSON types for extension " + target.getName()
-                                + " : " + struct1.getValueType() + " and " + struct2.getValueType());
-                        }
-                        if ( struct1.getValueType() == ValueType.ARRAY ) {
-                            // array is append
-                            final JsonArray a1 = (JsonArray)struct1;
-                            final JsonArray a2 = (JsonArray)struct2;
-                            for(final JsonValue val : a2) {
-                                a1.add(val);
-                            }
-                        } else {
-                            // object is merge
-                            merge((JsonObject)struct1, (JsonObject)struct2);
-                        }
-                        break;
-
-            case ARTIFACTS : for(final Artifact a : source.getArtifacts()) {
-                                 // use artifactMergeAlg
-                                 boolean add = true;
-                                 for(final Artifact targetArtifact : target.getArtifacts()) {
-                                     if ( targetArtifact.getId().isSame(a.getId()) ) {
-                                         if ( artifactMergeAlg == ArtifactMerge.HIGHEST ) {
-                                             if ( targetArtifact.getId().getOSGiVersion().compareTo(a.getId().getOSGiVersion()) > 0 ) {
-                                                 add = false;
-                                             } else {
-                                                 target.getArtifacts().remove(targetArtifact);
-                                             }
-                                         } else { // latest
-
-                                             target.getArtifacts().remove(targetArtifact);
-                                         }
-                                         break;
-                                     }
-                                 }
-
-                                 if ( add ) {
-                                     target.getArtifacts().add(a);
-                                 }
-
-                             }
-                             break;
-        }
-    }
-
-    // extensions (add/merge)
-    static void mergeExtensions(final Feature target,
-            final Feature source,
-            final ArtifactMerge artifactMergeAlg,
-            final BuilderContext context) {
-        for(final Extension ext : source.getExtensions()) {
-            boolean found = false;
-            for(final Extension current : target.getExtensions()) {
-                if ( current.getName().equals(ext.getName()) ) {
-                    found = true;
-                    if ( current.getType() != ext.getType() ) {
-                        throw new IllegalStateException("Found different types for extension " + current.getName()
-                        + " : " + current.getType() + " and " + ext.getType());
-                    }
-                    boolean handled = false;
-                    for(final FeatureExtensionHandler fem : context.getFeatureExtensionHandlers()) {
-                        if ( fem.canMerge(current.getName()) ) {
-                            fem.merge(target, source, current.getName());
-                            handled = true;
-                            break;
-                        }
-                    }
-                    if ( !handled ) {
-                        // default merge
-                        mergeExtensions(current, ext, artifactMergeAlg);
-                    }
-                }
-            }
-            if ( !found ) {
-                target.getExtensions().add(ext);
-            }
-        }
-    }
-
-    static void mergeExtensions(final Application target,
-            final Feature source,
-            final ArtifactMerge artifactMergeAlg) {
-        for(final Extension ext : source.getExtensions()) {
-            boolean found = false;
-            for(final Extension current : target.getExtensions()) {
-                if ( current.getName().equals(ext.getName()) ) {
-                    found = true;
-                    if ( current.getType() != ext.getType() ) {
-                        throw new IllegalStateException("Found different types for extension " + current.getName()
-                        + " : " + current.getType() + " and " + ext.getType());
-                    }
-                    // default merge
-                    mergeExtensions(current, ext, artifactMergeAlg);
-                }
-            }
-            if ( !found ) {
-                target.getExtensions().add(ext);
-            }
-        }
-    }
-
-    private static void merge(final JsonObject obj1, final JsonObject obj2) {
-        for(final Map.Entry<String, JsonValue> entry : obj2.entrySet()) {
-            if ( !obj1.containsKey(entry.getKey()) ) {
-                obj1.put(entry.getKey(), entry.getValue());
-            } else {
-                final JsonValue oldValue = obj1.get(entry.getKey());
-                if ( oldValue.getValueType() != entry.getValue().getValueType() ) {
-                    // new type wins
-                    obj1.put(entry.getKey(), entry.getValue());
-                } else if ( oldValue.getValueType() == ValueType.ARRAY ) {
-                    final JsonArray a1 = (JsonArray)oldValue;
-                    final JsonArray a2 = (JsonArray)entry.getValue();
-                    for(final JsonValue val : a2) {
-                        a1.add(val);
-                    }
-
-                } else if ( oldValue.getValueType() == ValueType.OBJECT ) {
-                    merge((JsonObject)oldValue, (JsonObject)entry.getValue());
-                } else {
-                    obj1.put(entry.getKey(), entry.getValue());
-                }
-            }
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/feature/process/FeatureBuilder.java b/src/main/java/org/apache/sling/feature/process/FeatureBuilder.java
deleted file mode 100644
index 6d57dc6..0000000
--- a/src/main/java/org/apache/sling/feature/process/FeatureBuilder.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.process;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-
-public class FeatureBuilder {
-
-    /**
-     * Assemble the full feature by processing all includes.
-     *
-     * @param feature The feature to start
-     * @param context The builder context
-     * @return The assembled feature.
-     * @throws IllegalArgumentException If feature or context is {@code null}
-     * @throws IllegalStateException If an included feature can't be provided or merged.
-     */
-    public static Feature assemble(final Feature feature,
-            final BuilderContext context) {
-        if ( feature == null || context == null ) {
-            throw new IllegalArgumentException("Feature and/or context must not be null");
-        }
-        return internalAssemble(new ArrayList<>(), feature, context);
-    }
-
-    private static Feature internalAssemble(final List<String> processedFeatures,
-            final Feature feature,
-            final BuilderContext context) {
-        if ( feature.isAssembled() ) {
-            return feature;
-        }
-        if ( processedFeatures.contains(feature.getId().toMvnId()) ) {
-            throw new IllegalStateException("Recursive inclusion of " + feature.getId().toMvnId() + " via " + processedFeatures);
-        }
-        processedFeatures.add(feature.getId().toMvnId());
-
-        // we copy the feature as we set the assembled flag on the result
-        final Feature result = feature.copy();
-
-        if ( !result.getIncludes().isEmpty() ) {
-
-            final List<Include> includes = new ArrayList<>(result.getIncludes());
-
-            // clear everything in the result, will be added in the process
-            result.getBundles().clear();
-            result.getFrameworkProperties().clear();
-            result.getConfigurations().clear();
-            result.getRequirements().clear();
-            result.getCapabilities().clear();
-            result.getIncludes().clear();
-            result.getExtensions().clear();
-
-            for(final Include i : includes) {
-                final Feature f = context.getFeatureProvider().provide(i.getId());
-                if ( f == null ) {
-                    throw new IllegalStateException("Unable to find included feature " + i.getId());
-                }
-                final Feature af = internalAssemble(processedFeatures, f, context);
-
-                // process include instructions
-                include(af, i);
-
-                // and now merge
-                merge(result, af, context);
-            }
-            merge(result, feature, context);
-        }
-        processedFeatures.remove(feature.getId().toMvnId());
-
-        result.setAssembled(true);
-        return result;
-    }
-
-    private static void merge(final Feature target,
-            final Feature source,
-            final BuilderContext context) {
-        BuilderUtil.mergeBundles(target.getBundles(), source.getBundles(), BuilderUtil.ArtifactMerge.LATEST);
-        BuilderUtil.mergeConfigurations(target.getConfigurations(), source.getConfigurations());
-        BuilderUtil.mergeFrameworkProperties(target.getFrameworkProperties(), source.getFrameworkProperties());
-        BuilderUtil.mergeRequirements(target.getRequirements(), source.getRequirements());
-        BuilderUtil.mergeCapabilities(target.getCapabilities(), source.getCapabilities());
-        BuilderUtil.mergeExtensions(target,
-                source,
-                BuilderUtil.ArtifactMerge.LATEST,
-                context);
-    }
-
-    private static void include(final Feature base, final Include i) {
-        // process removals
-        // bundles
-        for(final ArtifactId a : i.getBundleRemovals()) {
-            base.getBundles().removeExact(a);
-            final Iterator<Configuration> iter = base.getConfigurations().iterator();
-            while ( iter.hasNext() ) {
-                final Configuration cfg = iter.next();
-                final String bundleId = (String)cfg.getProperties().get(Configuration.PROP_ARTIFACT);
-                if ( a.toMvnId().equals(bundleId) ) {
-                    iter.remove();
-                }
-            }
-        }
-        // configurations
-        for(final String c : i.getConfigurationRemovals()) {
-            final int attrPos = c.indexOf('@');
-            final String val = (attrPos == -1 ? c : c.substring(0, attrPos));
-            final String attr = (attrPos == -1 ? null : c.substring(attrPos + 1));
-
-            final int sepPos = val.indexOf('~');
-            Configuration found = null;
-            if ( sepPos == -1 ) {
-                found = base.getConfigurations().getConfiguration(val);
-
-            } else {
-                final String factoryPid = val.substring(0, sepPos);
-                final String name = val.substring(sepPos + 1);
-
-                found = base.getConfigurations().getFactoryConfiguration(factoryPid, name);
-            }
-            if ( found != null ) {
-                if ( attr == null ) {
-                    base.getConfigurations().remove(found);
-                } else {
-                    found.getProperties().remove(attr);
-                }
-            }
-        }
-
-        // framework properties
-        for(final String p : i.getFrameworkPropertiesRemovals()) {
-            base.getFrameworkProperties().remove(p);
-        }
-
-        // extensions
-        for(final String name : i.getExtensionRemovals()) {
-            for(final Extension ext : base.getExtensions()) {
-                if ( ext.getName().equals(name) ) {
-                    base.getExtensions().remove(ext);
-                    break;
-                }
-            }
-        }
-        for(final Map.Entry<String, List<ArtifactId>> entry : i.getArtifactExtensionRemovals().entrySet()) {
-            for(final Extension ext : base.getExtensions()) {
-                if ( ext.getName().equals(entry.getKey()) ) {
-                    for(final ArtifactId id : entry.getValue() ) {
-                        for(final Artifact a : ext.getArtifacts()) {
-                            if ( a.getId().equals(id) ) {
-                                ext.getArtifacts().remove(a);
-                                break;
-                            }
-                        }
-                    }
-                    break;
-                }
-            }
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/feature/process/FeatureExtensionHandler.java b/src/main/java/org/apache/sling/feature/process/FeatureExtensionHandler.java
deleted file mode 100644
index c2a9460..0000000
--- a/src/main/java/org/apache/sling/feature/process/FeatureExtensionHandler.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.process;
-
-import org.apache.sling.feature.Feature;
-
-/**
- * A feature extension handler can merge a feature of a particular type
- * and also post process the final assembled feature.
- */
-public interface FeatureExtensionHandler {
-
-    /**
-     * Checks whether this merger can merge extensions with that name
-     * @param extensionName The extension name
-     * @return {@code true} if merger can handle this
-     */
-    boolean canMerge(String extensionName);
-
-    /**
-     * Merge the source extension into the target extension.
-     *
-     * The caller of this method already ensured that both
-     * extensions share the same name and type and that
-     * {@link #canMerge(String)} returned {@code true}.
-     *
-     * @param target The target feature
-     * @param source The source feature
-     * @param extensionName The extension name
-     * @throws IllegalStateException If the extensions can't be merged
-     */
-    void merge(Feature target, Feature source, String extensionName);
-
-    /**
-     * Post process the feature with respect to the extension
-     * @param feature The feature
-     * @param extensionName The extension name
-     * @throws IllegalStateException If post processing failed
-     */
-    void postProcess(Feature feature, String extensionName);
-}
diff --git a/src/main/java/org/apache/sling/feature/process/FeatureProvider.java b/src/main/java/org/apache/sling/feature/process/FeatureProvider.java
deleted file mode 100644
index 8d3c35a..0000000
--- a/src/main/java/org/apache/sling/feature/process/FeatureProvider.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.process;
-
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Feature;
-
-public interface FeatureProvider {
-
-    /**
-     * Provide the feature with the given id.
-     * @param id The feature id
-     * @return The feature or {@code null}
-     */
-    Feature provide(ArtifactId id);
-}
diff --git a/src/main/java/org/apache/sling/feature/process/FeatureResolver.java b/src/main/java/org/apache/sling/feature/process/FeatureResolver.java
deleted file mode 100644
index 5fbba7c..0000000
--- a/src/main/java/org/apache/sling/feature/process/FeatureResolver.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with this
- * work for additional information regarding copyright ownership. The ASF
- * licenses this file to You under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.sling.feature.process;
-
-import java.util.List;
-
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.FeatureResource;
-
-/**
- * A resolver that can perform operations on the feature model.
- */
-public interface FeatureResolver extends AutoCloseable {
-    /**
-     * Order the resources in list of features by their dependency chain.
-     * Each feature and its components are resolved. Then all the resources
-     * in the feature are ordered so that each resource is placed before
-     * the requiring feature/resources in the result.
-     *
-     * @param features
-     *            The features to order.
-     * @return The ordered resources from the features.
-     */
-    List<FeatureResource> orderResources(List<Feature> features);
-}
diff --git a/src/main/java/org/apache/sling/feature/process/package-info.java b/src/main/java/org/apache/sling/feature/process/package-info.java
deleted file mode 100644
index f6d563a..0000000
--- a/src/main/java/org/apache/sling/feature/process/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-@org.osgi.annotation.versioning.Version("1.0.0")
-package org.apache.sling.feature.process;
-
-
diff --git a/src/test/java/org/apache/sling/feature/process/BuilderUtilTest.java b/src/test/java/org/apache/sling/feature/process/BuilderUtilTest.java
deleted file mode 100644
index 42ce069..0000000
--- a/src/test/java/org/apache/sling/feature/process/BuilderUtilTest.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.process;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.BundlesTest;
-import org.apache.sling.feature.process.BuilderUtil.ArtifactMerge;
-import org.junit.Test;
-
-public class BuilderUtilTest {
-
-    private List<Map.Entry<Integer, Artifact>> getBundles(final Bundles f) {
-        final List<Map.Entry<Integer, Artifact>> result = new ArrayList<>();
-        for(final Map.Entry<Integer, List<Artifact>> entry : f.getBundlesByStartOrder().entrySet()) {
-            for(final Artifact artifact : entry.getValue()) {
-                result.add(new Map.Entry<Integer, Artifact>() {
-
-                    @Override
-                    public Integer getKey() {
-                        return entry.getKey();
-                    }
-
-                    @Override
-                    public Artifact getValue() {
-                        return artifact;
-                    }
-
-                    @Override
-                    public Artifact setValue(Artifact value) {
-                        return null;
-                    }
-                });
-            }
-        }
-
-        return result;
-    }
-
-    private void assertContains(final List<Map.Entry<Integer, Artifact>> bundles,
-            final int level, final ArtifactId id) {
-        for(final Map.Entry<Integer, Artifact> entry : bundles) {
-            if ( entry.getKey().intValue() == level
-                 && entry.getValue().getId().equals(id) ) {
-                return;
-            }
-        }
-        fail(id.toMvnId());
-    }
-
-    @Test public void testMergeBundlesWithAlgHighest() {
-        final Bundles target = new Bundles();
-
-        target.add(BundlesTest.createBundle("g/a/1.0", 1));
-        target.add(BundlesTest.createBundle("g/b/2.0", 2));
-        target.add(BundlesTest.createBundle("g/c/2.5", 3));
-
-        final Bundles source = new Bundles();
-        source.add(BundlesTest.createBundle("g/a/1.1", 1));
-        source.add(BundlesTest.createBundle("g/b/1.9", 2));
-        source.add(BundlesTest.createBundle("g/c/2.5", 3));
-
-        BuilderUtil.mergeBundles(target, source, ArtifactMerge.HIGHEST);
-
-        final List<Map.Entry<Integer, Artifact>> result = getBundles(target);
-        assertEquals(3, result.size());
-        assertContains(result, 1, ArtifactId.parse("g/a/1.1"));
-        assertContains(result, 2, ArtifactId.parse("g/b/2.0"));
-        assertContains(result, 3, ArtifactId.parse("g/c/2.5"));
-    }
-
-    @Test public void testMergeBundlesWithAlgLatest() {
-        final Bundles target = new Bundles();
-
-        target.add(BundlesTest.createBundle("g/a/1.0", 1));
-        target.add(BundlesTest.createBundle("g/b/2.0", 2));
-        target.add(BundlesTest.createBundle("g/c/2.5", 3));
-
-        final Bundles source = new Bundles();
-        source.add(BundlesTest.createBundle("g/a/1.1", 1));
-        source.add(BundlesTest.createBundle("g/b/1.9", 2));
-        source.add(BundlesTest.createBundle("g/c/2.5", 3));
-
-        BuilderUtil.mergeBundles(target, source, ArtifactMerge.LATEST);
-
-        final List<Map.Entry<Integer, Artifact>> result = getBundles(target);
-        assertEquals(3, result.size());
-        assertContains(result, 1, ArtifactId.parse("g/a/1.1"));
-        assertContains(result, 2, ArtifactId.parse("g/b/1.9"));
-        assertContains(result, 3, ArtifactId.parse("g/c/2.5"));
-    }
-
-    @Test public void testMergeBundlesDifferentStartlevel() {
-        final Bundles target = new Bundles();
-
-        target.add(BundlesTest.createBundle("g/a/1.0", 1));
-
-        final Bundles source = new Bundles();
-        source.add(BundlesTest.createBundle("g/a/1.1", 2));
-
-        BuilderUtil.mergeBundles(target, source, ArtifactMerge.LATEST);
-
-        final List<Map.Entry<Integer, Artifact>> result = getBundles(target);
-        assertEquals(1, result.size());
-        assertContains(result, 2, ArtifactId.parse("g/a/1.1"));
-    }
-
-    @Test public void testMergeBundles() {
-        final Bundles target = new Bundles();
-
-        target.add(BundlesTest.createBundle("g/a/1.0", 1));
-        target.add(BundlesTest.createBundle("g/b/2.0", 2));
-        target.add(BundlesTest.createBundle("g/c/2.5", 3));
-
-        final Bundles source = new Bundles();
-        source.add(BundlesTest.createBundle("g/d/1.1", 1));
-        source.add(BundlesTest.createBundle("g/e/1.9", 2));
-        source.add(BundlesTest.createBundle("g/f/2.5", 3));
-
-        BuilderUtil.mergeBundles(target, source, ArtifactMerge.LATEST);
-
-        final List<Map.Entry<Integer, Artifact>> result = getBundles(target);
-        assertEquals(6, result.size());
-        assertContains(result, 1, ArtifactId.parse("g/a/1.0"));
-        assertContains(result, 2, ArtifactId.parse("g/b/2.0"));
-        assertContains(result, 3, ArtifactId.parse("g/c/2.5"));
-        assertContains(result, 1, ArtifactId.parse("g/d/1.1"));
-        assertContains(result, 2, ArtifactId.parse("g/e/1.9"));
-        assertContains(result, 3, ArtifactId.parse("g/f/2.5"));
-    }
-}
diff --git a/src/test/java/org/apache/sling/feature/process/FeatureBuilderTest.java b/src/test/java/org/apache/sling/feature/process/FeatureBuilderTest.java
deleted file mode 100644
index ca27cf5..0000000
--- a/src/test/java/org/apache/sling/feature/process/FeatureBuilderTest.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.feature.process;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.sling.feature.Artifact;
-import org.apache.sling.feature.ArtifactId;
-import org.apache.sling.feature.BundlesTest;
-import org.apache.sling.feature.Configuration;
-import org.apache.sling.feature.Extension;
-import org.apache.sling.feature.Feature;
-import org.apache.sling.feature.Include;
-import org.apache.sling.feature.OSGiCapability;
-import org.apache.sling.feature.OSGiRequirement;
-import org.junit.Test;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Requirement;
-
-public class FeatureBuilderTest {
-
-    private static final Map<String, Feature> FEATURES = new HashMap<>();
-
-    static {
-        final Feature f1 = new Feature(ArtifactId.parse("g/a/1"));
-
-        f1.getFrameworkProperties().put("foo", "2");
-        f1.getFrameworkProperties().put("bar", "X");
-
-        f1.getBundles().add(BundlesTest.createBundle("org.apache.sling/foo-bar/4.5.6", 3));
-        f1.getBundles().add(BundlesTest.createBundle("group/testnewversion_low/2", 5));
-        f1.getBundles().add(BundlesTest.createBundle("group/testnewversion_high/2", 5));
-        f1.getBundles().add(BundlesTest.createBundle("group/testnewstartlevel/1", 5));
-        f1.getBundles().add(BundlesTest.createBundle("group/testnewstartlevelandversion/1", 5));
-
-        final Configuration c1 = new Configuration("org.apache.sling.foo");
-        c1.getProperties().put("prop", "value");
-        f1.getConfigurations().add(c1);
-
-        FEATURES.put(f1.getId().toMvnId(), f1);
-    }
-
-    private final FeatureProvider provider = new FeatureProvider() {
-
-        @Override
-        public Feature provide(final ArtifactId id) {
-            return FEATURES.get(id.getGroupId() + ":" + id.getArtifactId() + ":" + id.getVersion());
-        }
-    };
-
-    private List<Map.Entry<Integer, Artifact>> getBundles(final Feature f) {
-        final List<Map.Entry<Integer, Artifact>> result = new ArrayList<>();
-        for(final Map.Entry<Integer, List<Artifact>> entry : f.getBundles().getBundlesByStartOrder().entrySet()) {
-            for(final Artifact artifact : entry.getValue()) {
-                result.add(new Map.Entry<Integer, Artifact>() {
-
-                    @Override
-                    public Integer getKey() {
-                        return entry.getKey();
-                    }
-
-                    @Override
-                    public Artifact getValue() {
-                        return artifact;
-                    }
-
-                    @Override
-                    public Artifact setValue(Artifact value) {
-                        return null;
-                    }
-                });
-            }
-        }
-
-        return result;
-    }
-
-    private void equals(final Feature expected, final Feature actuals) {
-        assertFalse(expected.isAssembled());
-        assertTrue(actuals.isAssembled());
-
-        assertEquals(expected.getId(), actuals.getId());
-        assertEquals(expected.getTitle(), actuals.getTitle());
-        assertEquals(expected.getDescription(), actuals.getDescription());
-        assertEquals(expected.getVendor(), actuals.getVendor());
-        assertEquals(expected.getLicense(), actuals.getLicense());
-
-        // bundles
-        final List<Map.Entry<Integer, Artifact>> expectedBundles = getBundles(expected);
-        final List<Map.Entry<Integer, Artifact>> actualsBundles = getBundles(actuals);
-        assertEquals(expectedBundles.size(), actualsBundles.size());
-        for(final Map.Entry<Integer, Artifact> entry : expectedBundles) {
-            boolean found = false;
-            for(final Map.Entry<Integer, Artifact> inner : actualsBundles) {
-                if ( inner.getValue().getId().equals(entry.getValue().getId()) ) {
-                    found = true;
-                    assertEquals("Startlevel of bundle " + entry.getValue(), entry.getKey(), inner.getKey());
-                    assertEquals("Metadata of bundle " + entry.getValue(), entry.getValue().getMetadata(), inner.getValue().getMetadata());
-                    break;
-                }
-            }
-            assertTrue("Bundle " + entry.getValue() + " in level " + entry.getKey(), found);
-        }
-
-        // configurations
-        assertEquals(expected.getConfigurations().size(), actuals.getConfigurations().size());
-        for(final Configuration cfg : expected.getConfigurations()) {
-            final Configuration found = (cfg.isFactoryConfiguration() ? actuals.getConfigurations().getFactoryConfiguration(cfg.getFactoryPid(), cfg.getName())
-                                                                      : actuals.getConfigurations().getConfiguration(cfg.getPid()));
-            assertNotNull("Configuration " + cfg, found);
-            assertEquals("Configuration " + cfg, cfg.getProperties(), found.getProperties());
-        }
-
-        // frameworkProperties
-        assertEquals(expected.getFrameworkProperties(), actuals.getFrameworkProperties());
-
-        // requirements
-        assertEquals(expected.getRequirements().size(), actuals.getRequirements().size());
-        for(final Requirement r : expected.getRequirements()) {
-            boolean found = false;
-            for(final Requirement i : actuals.getRequirements()) {
-                if ( r.equals(i) ) {
-                    found = true;
-                    break;
-                }
-            }
-            assertTrue(found);
-        }
-
-        // capabilities
-        assertEquals(expected.getCapabilities().size(), actuals.getCapabilities().size());
-        for(final Capability r : expected.getCapabilities()) {
-            boolean found = false;
-            for(final Capability i : actuals.getCapabilities()) {
-                if ( r.equals(i) ) {
-                    found = true;
-                    break;
-                }
-            }
-            assertTrue(found);
-        }
-
-        // extensions
-        assertEquals(expected.getExtensions().size(), actuals.getExtensions().size());
-        for(final Extension ext : expected.getExtensions()) {
-            final Extension inner = actuals.getExtensions().getByName(ext.getName());
-            assertNotNull(inner);
-            assertEquals(ext.getType(), inner.getType());
-            switch ( ext.getType()) {
-                case JSON : assertEquals(ext.getJSON(), inner.getJSON());
-                            break;
-                case TEXT : assertEquals(ext.getText(), inner.getText());
-                            break;
-                case ARTIFACTS : assertEquals(ext.getArtifacts().size(), inner.getArtifacts().size());
-                                 for(final Artifact art : ext.getArtifacts()) {
-                                     boolean found = false;
-                                     for(final Artifact i : inner.getArtifacts()) {
-                                         if ( art.getId().equals(i.getId()) ) {
-                                             found = true;
-                                             assertEquals(art.getMetadata(), i.getMetadata());
-                                             break;
-                                         }
-                                     }
-                                     assertTrue(found);
-                                 }
-            }
-        }
-
-        // includes should always be empty
-        assertTrue(actuals.getIncludes().isEmpty());
-    }
-
-    @Test public void testNoIncludesNoUpgrade() throws Exception {
-        final Feature base = new Feature(ArtifactId.parse("org.apache.sling/test-feature/1.1"));
-
-        final Requirement r1 = new OSGiRequirement("osgi.contract",
-                Collections.emptyMap(), Collections.singletonMap("filter", "(&(osgi.contract=JavaServlet)(version=3.1))"));
-        base.getRequirements().add(r1);
-
-        Map<String, Object> attrs = new HashMap<>();
-        attrs.put("osgi.implementation", "osgi.http");
-        attrs.put("version:Version", "1.1");
-        final Capability c1 = new OSGiCapability("osgi.implementation", attrs,
-                Collections.singletonMap("uses", "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"));
-        base.getCapabilities().add(c1);
-        final Capability c2 = new OSGiCapability("osgi.service",
-                Collections.singletonMap("objectClass:List<String>", "org.osgi.service.http.runtime.HttpServiceRuntime"),
-                Collections.singletonMap("uses", "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"));
-        base.getCapabilities().add(c2);
-
-        base.getFrameworkProperties().put("foo", "1");
-        base.getFrameworkProperties().put("brave", "something");
-        base.getFrameworkProperties().put("org.apache.felix.scr.directory", "launchpad/scr");
-
-        final Artifact a1 = new Artifact(ArtifactId.parse("org.apache.sling/oak-server/1.0.0"));
-        a1.getMetadata().put(Artifact.KEY_START_ORDER, "1");
-        a1.getMetadata().put("hash", "4632463464363646436");
-        base.getBundles().add(a1);
-        base.getBundles().add(BundlesTest.createBundle("org.apache.sling/application-bundle/2.0.0", 1));
-        base.getBundles().add(BundlesTest.createBundle("org.apache.sling/another-bundle/2.1.0", 1));
-        base.getBundles().add(BundlesTest.createBundle("org.apache.sling/foo-xyz/1.2.3", 2));
-
-        final Configuration co1 = new Configuration("my.pid");
-        co1.getProperties().put("foo", 5L);
-        co1.getProperties().put("bar", "test");
-        co1.getProperties().put("number", 7);
-        base.getConfigurations().add(co1);
-
-        final Configuration co2 = new Configuration("my.factory.pid", "name");
-        co2.getProperties().put("a.value", "yeah");
-        base.getConfigurations().add(co2);
-
-        assertFalse(base.isAssembled());
-
-        final Feature assembled = FeatureBuilder.assemble(base, new BuilderContext(provider));
-
-        equals(base, assembled);
-    }
-
-    @Test public void testSingleInclude() throws Exception {
-        final Feature base = new Feature(ArtifactId.parse("org.apache.sling/test-feature/1.1"));
-        final Include i1 = new Include(ArtifactId.parse("g/a/1"));
-        base.getIncludes().add(i1);
-
-        final Requirement r1 = new OSGiRequirement("osgi.contract",
-                Collections.emptyMap(), Collections.singletonMap("filter", "(&(osgi.contract=JavaServlet)(version=3.1))"));
-        base.getRequirements().add(r1);
-
-        Map<String, Object> attrs = new HashMap<>();
-        attrs.put("osgi.implementation", "osgi.http");
-        attrs.put("version:Version", "1.1");
-        final Capability c1 = new OSGiCapability("osgi.implementation", attrs,
-                Collections.singletonMap("uses", "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"));
-        base.getCapabilities().add(c1);
-
-        base.getFrameworkProperties().put("foo", "1");
-        base.getFrameworkProperties().put("brave", "something");
-        base.getFrameworkProperties().put("org.apache.felix.scr.directory", "launchpad/scr");
-
-        final Artifact a1 = new Artifact(ArtifactId.parse("org.apache.sling/oak-server/1.0.0"));
-        a1.getMetadata().put(Artifact.KEY_START_ORDER, "1");
-        a1.getMetadata().put("hash", "4632463464363646436");
-        base.getBundles().add(a1);
-        base.getBundles().add(BundlesTest.createBundle("org.apache.sling/application-bundle/2.0.0", 1));
-        base.getBundles().add(BundlesTest.createBundle("org.apache.sling/another-bundle/2.1.0", 1));
-        base.getBundles().add(BundlesTest.createBundle("org.apache.sling/foo-xyz/1.2.3", 2));
-        base.getBundles().add(BundlesTest.createBundle("group/testnewversion_low/1", 5));
-        base.getBundles().add(BundlesTest.createBundle("group/testnewversion_high/5", 5));
-        base.getBundles().add(BundlesTest.createBundle("group/testnewstartlevel/1", 10));
-        base.getBundles().add(BundlesTest.createBundle("group/testnewstartlevelandversion/2", 10));
-
-        final Configuration co1 = new Configuration("my.pid");
-        co1.getProperties().put("foo", 5L);
-        co1.getProperties().put("bar", "test");
-        co1.getProperties().put("number", 7);
-        base.getConfigurations().add(co1);
-
-        final Configuration co2 = new Configuration("my.factory.pid", "name");
-        co2.getProperties().put("a.value", "yeah");
-        base.getConfigurations().add(co2);
-
-        assertFalse(base.isAssembled());
-
-        // create the expected result
-        final Feature result = base.copy();
-        result.getIncludes().remove(0);
-        result.getFrameworkProperties().put("bar", "X");
-        result.getBundles().add(BundlesTest.createBundle("org.apache.sling/foo-bar/4.5.6", 3));
-        final Configuration co3 = new Configuration("org.apache.sling.foo");
-        co3.getProperties().put("prop", "value");
-        result.getConfigurations().add(co3);
-
-        // assemble
-        final Feature assembled = FeatureBuilder.assemble(base, new BuilderContext(provider));
-
-        // and test
-        equals(result, assembled);
-    }
-}

-- 
To stop receiving notification emails like this one, please contact
davidb@apache.org.