/*
 * 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.karaf.tooling;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.stream.Collectors;
import java.util.zip.ZipFile;

import org.apache.karaf.profile.assembly.Builder;
import org.apache.karaf.tooling.utils.IoUtils;
import org.apache.karaf.tooling.utils.MavenUtil;
import org.apache.karaf.tooling.utils.MojoSupport;
import org.apache.karaf.tooling.utils.ReactorMavenResolver;
import org.apache.karaf.tools.utils.model.KarafPropertyEdits;
import org.apache.karaf.tools.utils.model.io.stax.KarafPropertyInstructionsModelStaxReader;
import org.apache.karaf.util.Version;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.repository.WorkspaceReader;
import org.osgi.framework.Constants;
import org.osgi.framework.launch.FrameworkFactory;

/**
 * Creates a customized Karaf distribution by installing features and setting up
 * configuration files.
 *
 * <p>The plugin gets features from feature.xml files and KAR
 * archives declared as dependencies or as files configured with the
 * [startup|boot|installed]Respositories parameters. It picks up other files, such as config files,
 * from ${project.build.directory}/classes. Thus, a file in src/main/resources/etc
 * will be copied by the resource plugin to ${project.build.directory}/classes/etc,
 * and then added to the assembly by this goal.
 */
@Mojo(name = "assembly", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true)
public class AssemblyMojo extends MojoSupport {

    /**
     * Base directory used to overwrite resources in generated assembly after the build (resource directory).
     */
    @Parameter(defaultValue = "${project.basedir}/src/main/resources/assembly")
    protected File sourceDirectory;

    /**
     * Base directory used to copy the resources during the build (working directory).
     */
    @Parameter(defaultValue = "${project.build.directory}/assembly")
    protected File workDirectory;

    /**
     * Optional location for custom features processing XML configuration
     * (<code>etc/org.apache.karaf.features.cfg</code>)
     */
    @Parameter
    protected File featuresProcessing;

    /*
     * There are three builder stages related to maven dependency scopes:
     *  - Stage.Startup : scope=compile
     *  - Stage.Boot : scope=runtime
     *  - Stage.Installed : scope=provided
     * There's special category not related to stage - Blacklisted
     *
     * There are five kinds of artifacts/dependencies that may go into any of the above stages/categories/scopes:
     *  - kars: maven artifacts with "kar" type
     *  - repositories: maven artifacts with "features" classifier
     *  - features: Karaf feature names (name[/version])
     *  - bundles: maven artifacts with "jar" or "bundle" type
     *  - profiles: directories with Karaf 4 profiles
     * (Not all artifacts/dependencies may be connected with every stage/category/scope.)
     *
     * Blacklisting:
     *  - kars: there are no blacklisted kars
     *  - repositories: won't be processed at all (also affects transitive repositories)
     *  - features: will be removed from JAXB model of features XML after loading
     *  - bundles: will be removed from features of JAXB model after loading
     *  - profiles: will be removed
     *
     * Stage.Startup:
     *  - bundles: will be put to etc/startup.properties
     *  - features: their bundles will be put to etc/startup.properties
     *  - repositories: will be used to resolve startup bundles/feature before adding them to etc/startup.properties
     *  - kars: unpacked to assembly, detected features XML repositories added as Stage.Startup repositories
     *
     * Stage.Boot:
     *  - bundles: special etc/<UUID>.xml features XML file will be created with <UUID> feature.
     *      etc/org.apacha.karaf.features.cfg will have this features XML file in featuresRepositories property and
     *      the feature itself in featuresBoot property
     *  - features: will be added to etc/org.apacha.karaf.features.cfg file, featuresBoot property
     *      also features from Stage.Startup will be used here.
     *  - repositories: will be added to etc/org.apacha.karaf.features.cfg file, featuresRepositories property
     *      also repositories from Stage.Startup will be used here.
     *  - kars: unpacked to assembly, detected features XML repositories added as Stage.Boot repositories
     *
     * Stage.Installed:
     *  - bundles: will be copied to system/
     *  - features: their bundles and config files will be copied to system/
     *  - repositories: will be used to find Stage.Installed features
     *      also repositories from Stage.Boot will be searched for Stage.Installed features
     *  - kars: unpacked to assembly, detected features XML repositories added as Stage.Installed repositories
     */

    /**
     * For given stage (startup, boot, install) if there are no stage-specific features and profiles, all features
     * from stage-specific repositories will be used.
     */
    @Parameter(defaultValue = "true")
    protected boolean installAllFeaturesByDefault = true;

    /**
     * An environment identifier that may be used to select different variant of PID configuration file, e.g.,
     * <code>org.ops4j.pax.url.mvn.cfg#docker</code>.
     */
    @Parameter
    private String environment;

    /**
     * Default start level for bundles in features that don't specify it.
     */
    @Parameter
    protected int defaultStartLevel = 30;

    /**
     * List of additional allowed protocols on bundles location URI
     */
    @Parameter
    private List<String> extraProtocols;

    /**
     * List of compile-scope features XML files to be used in startup stage (etc/startup.properties)
     */
    @Parameter
    private List<String> startupRepositories;
    /**
     * List of runtime-scope features XML files to be used in boot stage (etc/org.apache.karaf.features.cfg)
     */
    @Parameter
    private List<String> bootRepositories;
    /**
     * List of provided-scope features XML files to be used in install stage
     */
    @Parameter
    private List<String> installedRepositories;
    /**
     * List of blacklisted repository URIs. Blacklisted URI may use globs and version ranges. See
     * {@link org.apache.karaf.features.LocationPattern}.
     */
    @Parameter
    private List<String> blacklistedRepositories;

    /**
     * List of features from compile-scope features XML files and KARs to be installed into system repo
     * and listed in etc/startup.properties.
     */
    @Parameter
    private List<String> startupFeatures;
    /**
     * List of features from runtime-scope features XML files and KARs to be installed into system repo
     * and listed in featuresBoot property in etc/org.apache.karaf.features.cfg
     */
    @Parameter
    private List<String> bootFeatures;
    /**
     * List of features from provided-scope features XML files and KARs to be installed into system repo
     * and not mentioned elsewhere.
     */
    @Parameter
    private List<String> installedFeatures;
    /**
     * <p>List of feature blacklisting clauses. Each clause is in one of the formats ({@link org.apache.karaf.features.FeaturePattern}):<ul>
     *     <li><code>feature-name</code></li>
     *     <li><code>feature-name;range=version-or-range</code></li>
     *     <li><code>feature-name/version-or-range</code></li>
     * </ul></p>
     */
    @Parameter
    private List<String> blacklistedFeatures;

    /**
     * List of compile-scope bundles added to etc/startup.properties
     */
    @Parameter
    private List<String> startupBundles;
    /**
     * List of runtime-scope bundles wrapped in special feature added to featuresBoot property
     * in etc/org.apache.karaf.features.cfg
     */
    @Parameter
    private List<String> bootBundles;
    /**
     * List of provided-scope bundles added to system repo
     */
    @Parameter
    private List<String> installedBundles;
    /**
     * List of blacklisted bundle URIs. Blacklisted URI may use globs and version ranges. See
     * {@link org.apache.karaf.features.LocationPattern}.
     */
    @Parameter
    private List<String> blacklistedBundles;

    /**
     * List of profile URIs to use
     */
    @Parameter
    private List<String> profilesUris;

    /**
     * List of profiles names to load from configured <code>profilesUris</code> and use as startup profiles.
     */
    @Parameter
    private List<String> startupProfiles;
    /**
     * List of profiles names to load from configured <code>profilesUris</code> and use as boot profiles.
     */
    @Parameter
    private List<String> bootProfiles;
    /**
     * List of profiles names to load from configured <code>profilesUris</code> and use as installed profiles.
     */
    @Parameter
    private List<String> installedProfiles;
    /**
     * List of blacklisted profile names (possibly using <code>*</code> glob)
     */
    @Parameter
    private List<String> blacklistedProfiles;

    /**
     * When assembly custom distribution, we can include generated and added profiles in the distribution itself,
     * in <code>${karaf.etc}/profiles</code> directory.
     */
    @Parameter(defaultValue = "false")
    private boolean writeProfiles;

    /**
     * When assembly custom distribution, we can also generate an XML/XSLT report with the summary of bundles.
     * This parameter specifies target directory, to which <code>bundle-report.xml</code> and <code>bundle-report-full.xml</code>
     * (along with XSLT stylesheet) will be written.
     */
    @Parameter
    private String generateConsistencyReport;

    /**
     * When generating consistency report, we can specify project name. By default it's "Apache Karaf"
     */
    @Parameter(defaultValue = "Apache Karaf")
    private String consistencyReportProjectName;

    /**
     * When generating consistency report, we can specify project version. By default it's "${project.version}"
     */
    @Parameter(defaultValue = "${project.version}")
    private String consistencyReportProjectVersion;

    /*
     * KARs are not configured using Maven plugin configuration, but rather detected from dependencies.
     * All KARs are just unzipped into the assembly being constructed, but additionally KAR's embedded
     * features XML repositories are added to relevant stage.
     */

    private List<String> startupKars = new ArrayList<>();
    private List<String> bootKars = new ArrayList<>();
    private List<String> installedKars = new ArrayList<>();

    /**
     * TODOCUMENT
     */
    @Parameter
    private Builder.BlacklistPolicy blacklistPolicy = Builder.BlacklistPolicy.Discard;

    /**
     * Ignore the dependency attribute (dependency="[true|false]") on bundles, effectively forcing their
     * installation.
     */
    @Parameter(defaultValue = "false")
    protected boolean ignoreDependencyFlag;

    /**
     * <p>Additional libraries to add into assembled distribution. Libraries are specified using
     * <code>name[;url:=&lt;url&gt;][;type:=&lt;type&gt;][;export:=true|false][;delegate:=true|false]</code>
     * syntax. If there's no <code>url</code> header directive, <code>name</code> is used as URI. Otherwise
     * <code>name</code> is used as target file name to use.
     *
     * <p><code>type</code> may be:<ul>
     *     <li>endorsed - library will be added to <code>${karaf.home}/lib/endorsed</code></li>
     *     <li>extension - library will be added to <code>${karaf.home}/lib/ext</code></li>
     *     <li>boot - library will be added to <code>${karaf.home}/lib/boot</code></li>
     *     <li>by default, library is put directly into <code>${karaf.home}/lib</code> - these libraries will
     *     be used in default classloader for OSGi framework which will load {@link FrameworkFactory} implementation.</li>
     * </ul>
     *
     * <p><code>export</code> flag determines whether packages from <code>Export-Package</code> manifest
     * header of the library will be added to <code>org.osgi.framework.system.packages.extra</code> property in
     * <code>${karaf.etc}/config.properties</code>.
     *
     * <p><code>delegate</code> flag determines whether packages from <code>Export-Pavkage</code> manifest
     * header of the library will be added to <code>org.osgi.framework.bootdelegation</code> property in
     * <code>${karaf.etc}/config.properties</code>.
     */
    @Parameter
    protected List<String> libraries;

    /**
     * Use <code>reference:file:gr/oup/Id/artifactId/version/artifactId-version-classifier.type</code> style
     * urls in <code>etc/startup.properties</code>.
     */
    // see:
    //  - org.apache.felix.framework.cache.BundleArchive.createRevisionFromLocation()
    //  - org.apache.karaf.main.Main.installAndStartBundles()
    @Parameter(defaultValue = "false")
    protected boolean useReferenceUrls;

    /**
     * Include project build output directory in the assembly. This allows (filtered or unfiltered) Maven
     * resources directories to be used to provide additional resources in the assembly.
     */
    @Parameter(defaultValue = "true")
    protected boolean includeBuildOutputDirectory;

    /**
     * Karaf version changes the way some configuration files are prepared (to adjust to given Karaf version
     * requirements).
     */
    @Parameter
    protected Builder.KarafVersion karafVersion = Builder.KarafVersion.v4x;

    /**
     * Specify the version of Java SE to be assumed for osgi.ee. The value will be used in
     * <code>etc/config.properties</code> file, in <code>java.specification.version</code> placeholder used in
     * several properties:<ul>
     *     <li><code>org.osgi.framework.system.packages</code></li>
     *     <li><code>org.osgi.framework.system.capabilities</code></li>
     * </ul>
     * <p>Valid values are: 1.6, 1.7, 1.8, 9
     */
    @Parameter(defaultValue = "1.8")
    protected String javase;

    /**
     * Specify which framework to use
     * (one of framework, framework-logback, static-framework, static-framework-logback, custom).
     */
    @Parameter
    protected String framework;

    /**
     * Specify an XML file that instructs this goal to apply edits to
     * one or more standard Karaf property files.
     * The contents of this file are documented in detail on
     * <a href="karaf-property-instructions-model.html">this page</a>.
     * This allows you to
     * customize these files without making copies in your resources
     * directories. Here's a simple example:
     * <pre>
     * {@literal
      <property-edits xmlns="http://karaf.apache.org/tools/property-edits/1.0.0">
         <edits>
          <edit>
            <file>config.properties</file>
            <operation>put</operation>
            <key>karaf.framework</key>
            <value>equinox</value>
          </edit>
          <edit>
            <file>config.properties</file>
            <operation>extend</operation>
            <key>org.osgi.framework.system.capabilities</key>
            <value>my-magic-capability</value>
          </edit>
          <edit>
            <file>config.properties</file>
            <operation prepend='true'>extend</operation>
            <key>some-other-list</key>
            <value>my-value-goes-first</value>
            </edit>
         </edits>
      </property-edits>
    }
     </pre>
     */
    @Parameter(defaultValue = "${project.basedir}/src/main/karaf/assembly-property-edits.xml")
    protected String propertyFileEdits;

    /**
     * Glob specifying which configuration PIDs in the selected boot features
     * should be extracted to <code>${karaf.etc}</code> directory. By default all PIDs are extracted.
     */
    @Parameter
    protected List<String> pidsToExtract = Collections.singletonList("*");

    /**
     * Specify a set of translated urls to use instead of downloading the artifacts
     * from their original locations.  The given set will be extended with already
     * built artifacts from the maven project.
     */
    @Parameter
    protected Map<String, String> translatedUrls;

    /**
     * Specify a list of additional properties that should be added to <code>${karaf.etc}/config.properties</code>
     */
    @Parameter
    protected Map<String, String> config;

    /**
     * Specify a list of additional properties that should be added to <code>${karaf.etc}/system.properties</code>
     */
    @Parameter
    protected Map<String, String> system;

    @Component(role = WorkspaceReader.class, hint = "reactor")
    protected WorkspaceReader reactor;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        try {
            setNullListsToEmpty();
            setNullMapsToEmpty();

            doExecute();
        } catch (MojoExecutionException | MojoFailureException e) {
            throw e;
        } catch (Exception e) {
            throw new MojoExecutionException("Unable to build assembly", e);
        }
    }

    /**
     * Main processing method. Most of the work involves configuring and invoking {@link Builder a profile builder}.
     */
    protected void doExecute() throws Exception {
        if (!startupProfiles.isEmpty() || !bootProfiles.isEmpty() || !installedProfiles.isEmpty()) {
            if (profilesUris.size() == 0) {
                throw new IllegalArgumentException("profilesUris option must be specified");
            }
        }

        Builder builder = Builder.newInstance();

        // Set up miscellaneous options
        builder.extraProtocols(extraProtocols);
        builder.offline(mavenSession.isOffline());
        builder.localRepository(localRepo.getBasedir());
        builder.resolverWrapper((resolver) -> new ReactorMavenResolver(reactor, resolver));
        builder.javase(javase);
        builder.karafVersion(karafVersion);
        builder.useReferenceUrls(useReferenceUrls);
        builder.defaultAddAll(installAllFeaturesByDefault);
        builder.ignoreDependencyFlag(ignoreDependencyFlag);
        builder.propertyEdits(configurePropertyEdits());
        builder.translatedUrls(configureTranslatedUrls());
        builder.pidsToExtract(pidsToExtract);
        builder.writeProfiles(writeProfiles);
        builder.generateConsistencyReport(generateConsistencyReport);
        builder.setConsistencyReportProjectName(consistencyReportProjectName);
        builder.setConsistencyReportProjectVersion(consistencyReportProjectVersion);
        builder.environment(environment);
        builder.defaultStartLevel(defaultStartLevel);
        if (featuresProcessing != null) {
            builder.setFeaturesProcessing(featuresProcessing.toPath());
        }

        // Set up remote repositories from Maven build, to be used by pax-url-aether resolver
        String remoteRepositories = MavenUtil.remoteRepositoryList(project.getRemoteProjectRepositories());
        getLog().info("Using repositories:");
        for (String r : remoteRepositories.split(",")) {
            getLog().info("   " + r);
        }
        builder.mavenRepositories(remoteRepositories);

        // Set up config and system properties
        config.forEach(builder::config);
        system.forEach(builder::system);

        // Set up blacklisted items
        builder.blacklistBundles(blacklistedBundles);
        builder.blacklistFeatures(blacklistedFeatures);
        builder.blacklistProfiles(blacklistedProfiles);
        builder.blacklistRepositories(blacklistedRepositories);
        builder.blacklistPolicy(blacklistPolicy);

        // Creating system directory
        configureWorkDirectory();
        getLog().info("Creating work directory: " + workDirectory);
        builder.homeDirectory(workDirectory.toPath());

        // Loading KARs and features repositories
        getLog().info("Loading direct KAR and features XML dependencies");
        processDirectMavenDependencies();

        // Set up profiles and libraries
        profilesUris.forEach(builder::profilesUris);
        libraries.forEach(builder::libraries);

        // Startup stage
        detectStartupKarsAndFeatures(builder);
        builder.defaultStage(Builder.Stage.Startup)
               .kars(toArray(startupKars))
               .repositories(startupFeatures.isEmpty() && startupProfiles.isEmpty() && installAllFeaturesByDefault, toArray(startupRepositories))
               .features(toArray(startupFeatures))
               .bundles(toArray(startupBundles))
               .profiles(toArray(startupProfiles));

        // Installed stage
        builder.defaultStage(Builder.Stage.Installed)
                .kars(toArray(installedKars))
                .repositories(installedFeatures.isEmpty() && installedProfiles.isEmpty() && installAllFeaturesByDefault, toArray(installedRepositories))
                .features(toArray(installedFeatures))
                .bundles(toArray(installedBundles))
                .profiles(toArray(installedProfiles));

        // Boot stage
        builder.defaultStage(Builder.Stage.Boot)
                .kars(toArray(bootKars))
                .repositories(bootFeatures.isEmpty() && bootProfiles.isEmpty() && installAllFeaturesByDefault, toArray(bootRepositories))
                .features(toArray(bootFeatures))
                .bundles(toArray(bootBundles))
                .profiles(toArray(bootProfiles));

        // Generate the assembly
        builder.generateAssembly();

        // Include project classes content if not specified otherwise
        if (includeBuildOutputDirectory)
            IoUtils.copyDirectory(new File(project.getBuild().getOutputDirectory()), workDirectory);

        // Overwrite assembly dir contents with source directory (not filtered) when directory exists
        if (sourceDirectory.exists())
            IoUtils.copyDirectory(sourceDirectory, workDirectory);

        // Chmod the bin/* scripts
        File[] files = new File(workDirectory, "bin").listFiles();
        if (files != null) {
            for (File file : files) {
                if (!file.getName().endsWith(".bat")) {
                    try {
                        Files.setPosixFilePermissions(file.toPath(), PosixFilePermissions.fromString("rwxr-xr-x"));
                    } catch (Throwable ignore) {
                        // we tried our best, perhaps the OS does not support POSIX file perms.
                    }
                }
            }
        }
    }

    private void configureWorkDirectory() {
        IoUtils.deleteRecursive(workDirectory);
        workDirectory.mkdirs();
        new File(workDirectory, "etc").mkdirs();
        new File(workDirectory, "system").mkdirs();
    }

    /**
     * <p>Turns direct maven dependencies into startup/boot/installed artifacts.</p>
     * <p>{@link MavenProject#getDependencyArtifacts()} is deprecated, but we don't want (?) transitive
     * dependencies given by {@link MavenProject#getArtifacts()}.</p>
     */
    @SuppressWarnings("deprecation")
    private void processDirectMavenDependencies() {
        for (Artifact artifact : project.getDependencyArtifacts()) {
            Builder.Stage stage = Builder.Stage.fromMavenScope(artifact.getScope());
            if (stage == null) {
                continue;
            }
            String uri = artifactToMvn(artifact);
            switch (getType(artifact)) {
                case "kar":
                    addUris(stage, uri, startupKars, bootKars, installedKars);
                    break;
                case "features":
                    addUris(stage, uri, startupRepositories, bootRepositories, installedRepositories);
                    break;
                case "bundle":
                    addUris(stage, uri, startupBundles, bootBundles, installedBundles);
                    break;
            }
        }
    }

    private void addUris(Builder.Stage stage, String uri, List<String> startup, List<String> boot, List<String> installed) {
        switch (stage) {
            case Startup:
                startup.add(uri);
                break;
            case Boot:
                boot.add(uri);
                break;
            case Installed:
                installed.add(uri);
                break;
        }
    }

    /**
     * <p>Custom distribution is created from at least one <em>startup KAR</em> and one <em>startup</em>
     * feature. Such startup KAR + feature is called <em>framework</em>.</p>
     *
     * <p>We can specify one of 5 <em>frameworks</em>:<ul>
     *     <li>framework: <code>mvn:org.apache.karaf.features/framework/VERSION/kar</code> and <code>framework</code> feature</li>
     *     <li>framework-logback: <code>mvn:org.apache.karaf.features/framework/VERSION/kar</code> and <code>framework-logback</code> feature</li>
     *     <li>static-framework: <code>mvn:org.apache.karaf.features/static/VERSION/kar</code> and <code>static-framework</code> feature</li>
     *     <li>static-framework-logback: <code>mvn:org.apache.karaf.features/static/VERSION/kar</code> and <code>static-framework-logback</code> feature</li>
     *     <li>custom: both startup KAR and startup feature has to be specified explicitly</li>
     * </ul></p>
     * @param builder
     */
    private void detectStartupKarsAndFeatures(Builder builder) {
        boolean hasStandardKarafFrameworkKar = false;
        boolean hasCustomFrameworkKar = false;
        for (Iterator<String> iterator = startupKars.iterator(); iterator.hasNext(); ) {
            String kar = iterator.next();
            if (kar.startsWith("mvn:org.apache.karaf.features/framework/")
                    || kar.startsWith("mvn:org.apache.karaf.features/static/")) {
                hasStandardKarafFrameworkKar = true;
                iterator.remove();
                if (framework == null) {
                    framework = kar.startsWith("mvn:org.apache.karaf.features/framework/")
                            ? "framework" : "static-framework";
                }
                getLog().info("   Standard startup Karaf KAR found: " + kar);
                builder.kars(Builder.Stage.Startup, false, kar);
                break;
            }
        }

        if (!hasStandardKarafFrameworkKar) {
            if ("custom".equals(framework)) {
                // we didn't detect standard Karaf KAR (framework or static), so we expect at least one
                // other KAR dependency with compile scope and at least one startup feature
                if (startupKars.isEmpty()) {
                    throw new IllegalArgumentException("Custom KAR was declared, but there's no Maven dependency with type=kar and scope=compile." +
                            " Please specify at least one KAR for custom assembly.");
                }
                if (startupFeatures.isEmpty()) {
                    throw new IllegalArgumentException("Custom KAR was declared, but there's no startup feature declared." +
                            " Please specify at least one startup feature defined in features XML repository inside custom startup KAR or startup repository.");
                }
                hasCustomFrameworkKar = true;
                for (String startupKar : startupKars) {
                    getLog().info("   Custom startup KAR found: " + startupKar);
                }
            } else if (framework == null) {
                throw new IllegalArgumentException("Can't determine framework to use (framework, framework-logback, static-framework, static-framework-logback, custom)." +
                        " Please specify valid \"framework\" option or add Maven dependency with \"kar\" type and \"compile\" scope for one of standard Karaf KARs.");
            } else {
                String realKarafVersion = Version.karafVersion();
                String kar;
                switch (framework) {
                    case "framework":
                    case "framework-logback":
                        kar = "mvn:org.apache.karaf.features/framework/" + realKarafVersion + "/kar";
                        break;
                    case "static-framework":
                    case "static-framework-logback":
                        kar = "mvn:org.apache.karaf.features/static/" + realKarafVersion + "/kar";
                        break;
                    default:
                        throw new IllegalArgumentException("Unsupported framework: " + framework);
                }
                getLog().info("   Standard startup KAR implied from framework (" + framework + "): " + kar);
                builder.kars(Builder.Stage.Startup, false, kar);
            }
        }

        if (hasStandardKarafFrameworkKar && !startupFeatures.contains(framework)) {
            getLog().info("   Feature " + framework + " will be added as a startup feature");
            builder.features(Builder.Stage.Startup, framework);
        }
    }

    private KarafPropertyEdits configurePropertyEdits() throws IOException, XMLStreamException {
        KarafPropertyEdits edits = null;
        if (propertyFileEdits != null) {
            File file = new File(propertyFileEdits);
            if (file.exists()) {
                try (InputStream editsStream = new FileInputStream(propertyFileEdits)) {
                    KarafPropertyInstructionsModelStaxReader kipmsr = new KarafPropertyInstructionsModelStaxReader();
                    edits = kipmsr.read(editsStream, true);
                }
            }
        }
        return edits;
    }

    private Map<String,String> configureTranslatedUrls() {
        Map<String, String> urls = new HashMap<>();
        List<Artifact> artifacts = new ArrayList<>(project.getAttachedArtifacts());
        artifacts.add(project.getArtifact());
        for (Artifact artifact : artifacts) {
            if (artifact.getFile() != null && artifact.getFile().exists()) {
                String mvnUrl = artifactToMvn(artifact);
                urls.put(mvnUrl, artifact.getFile().toURI().toString());
            }
        }
        urls.putAll(translatedUrls);
        return urls;
    }

    private String getType(Artifact artifact) {
        // Identify kars
        if ("kar".equals(artifact.getType())) {
            return "kar";
        }
        if ("zip".equals(artifact.getType())) {
            try (ZipFile zip = new ZipFile(artifact.getFile())) {
                if (zip.getEntry("META-INF/KARAF.MF") != null) {
                    return "kar";
                }
            } catch (IOException e) {
                // Ignore
            }
        }
        // Identify features
        if ("features".equals(artifact.getClassifier())) {
            return "features";
        }
        if ("xml".equals(artifact.getType())) {
            try (InputStream is = new FileInputStream(artifact.getFile())) {
                XMLInputFactory xif = XMLInputFactory.newFactory();
                xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
                XMLStreamReader r = xif.createXMLStreamReader(is);
                r.nextTag();
                QName name = r.getName();
                if (name.getLocalPart().equals("features")
                        && (name.getNamespaceURI().isEmpty()
                                || name.getNamespaceURI().startsWith("http://karaf.apache.org/xmlns/features/"))) {
                    return "features";
                }

            } catch (Exception e) {
                // Ignore
            }
        }
        // Identify bundles
        if ("bundle".equals(artifact.getType())) {
            return "bundle";
        }
        if ("jar".equals(artifact.getType())) {
            try (JarFile jar = new JarFile(artifact.getFile())) {
                Manifest manifest = jar.getManifest();
                if (manifest != null
                        && manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME) != null) {
                    return "bundle";
                }
            } catch (Exception e) {
                // Ignore
            }
        }
        return "unknown";
    }

    private String artifactToMvn(Artifact artifact) {
        String uri;

        String groupId = artifact.getGroupId();
        String artifactId = artifact.getArtifactId();
        String version = artifact.getBaseVersion();
        String type = artifact.getArtifactHandler().getExtension();
        String classifier = artifact.getClassifier();

        if (MavenUtil.isEmpty(classifier)) {
            if ("jar".equals(type)) {
                uri = String.format("mvn:%s/%s/%s", groupId, artifactId, version);
            } else {
                uri = String.format("mvn:%s/%s/%s/%s", groupId, artifactId, version, type);
            }
        } else {
            uri = String.format("mvn:%s/%s/%s/%s/%s", groupId, artifactId, version, type, classifier);
        }
        return uri;
    }

    private String[] toArray(List<String> strings) {
        return strings.toArray(new String[strings.size()]);
    }

    private void setNullListsToEmpty() {
        startupRepositories = nonNullList(startupRepositories);
        bootRepositories = nonNullList(bootRepositories);
        installedRepositories = nonNullList(installedRepositories);
        blacklistedRepositories = nonNullList(blacklistedRepositories);
        extraProtocols = nonNullList(extraProtocols);
        startupBundles = nonNullList(startupBundles);
        bootBundles = nonNullList(bootBundles);
        installedBundles = nonNullList(installedBundles);
        blacklistedBundles = nonNullList(blacklistedBundles);
        startupFeatures = nonNullList(startupFeatures);
        bootFeatures = nonNullList(bootFeatures);
        installedFeatures = nonNullList(installedFeatures);
        blacklistedFeatures = nonNullList(blacklistedFeatures);
        startupProfiles = nonNullList(startupProfiles);
        bootProfiles = nonNullList(bootProfiles);
        installedProfiles = nonNullList(installedProfiles);
        blacklistedProfiles = nonNullList(blacklistedProfiles);
        libraries = nonNullList(libraries);
        profilesUris = nonNullList(profilesUris);
    }

    private void setNullMapsToEmpty() {
        config = nonNullMap(config);
        system = nonNullMap(system);
        translatedUrls = nonNullMap(translatedUrls);
    }

    private List<String> nonNullList(List<String> list) {
        final List<String> nonNullList = list == null ? new ArrayList<>() : list;
        return nonNullList.stream().filter(Objects::nonNull).collect(Collectors.toList());
    }

    private Map<String, String> nonNullMap(Map<String, String> map) {
        return map == null ? new LinkedHashMap<>() : map;
    }

}
