package org.apache.maven.plugin.resources.remote;

/*
 * 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.
 */

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.io.output.DeferredFileOutputStream;
import org.apache.maven.ProjectDependenciesResolver;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.internal.ProjectArtifactFactory;
import org.apache.maven.model.Model;
import org.apache.maven.model.Organization;
import org.apache.maven.model.Resource;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.resources.remote.io.xpp3.RemoteResourcesBundleXpp3Reader;
import org.apache.maven.plugin.resources.remote.io.xpp3.SupplementalDataModelXpp3Reader;
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.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter;
import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter;
import org.apache.maven.shared.artifact.filter.collection.ProjectTransitivityFilter;
import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
import org.apache.maven.shared.filtering.MavenFileFilter;
import org.apache.maven.shared.filtering.MavenFileFilterRequest;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.log.LogChute;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.codehaus.plexus.resource.ResourceManager;
import org.codehaus.plexus.resource.loader.FileResourceLoader;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * <p>
 * Pull down resourceBundles containing remote resources and process the resources contained inside. When that is done,
 * the resources are injected into the current (in-memory) Maven project, making them available to the process-resources
 * phase.
 * </p>
 * <p>
 * Resources that end in ".vm" are treated as Velocity templates. For those, the ".vm" is stripped off for the final
 * artifact name and it's fed through Velocity to have properties expanded, conditions processed, etc...
 * </p>
 * Resources that don't end in ".vm" are copied "as is".
 */
// NOTE: Removed the following in favor of maven-artifact-resolver library, for MRRESOURCES-41
// If I leave this intact, interdependent projects within the reactor that haven't been built
// (remember, this runs in the generate-resources phase) will cause the build to fail.
//
// @requiresDependencyResolution test
@Mojo( name = "process", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, threadSafe = true )
public class ProcessRemoteResourcesMojo
    extends AbstractMojo
    implements LogChute
{

    private static final String TEMPLATE_SUFFIX = ".vm";

    /**
     * <p>
     * In cases where a local resource overrides one from a remote resource bundle, that resource should be filtered if
     * the resource set specifies it. In those cases, this parameter defines the list of delimiters for filterable
     * expressions. These delimiters are specified in the form 'beginToken*endToken'. If no '*' is given, the delimiter
     * is assumed to be the same for start and end.
     * </p>
     * <p>
     * So, the default filtering delimiters might be specified as:
     * </p>
     * 
     * <pre>
     * &lt;delimiters&gt;
     *   &lt;delimiter&gt;${*}&lt;/delimiter&gt;
     *   &lt;delimiter&gt;@&lt;/delimiter&gt;
     * &lt;/delimiters&gt;
     * </pre>
     * Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can).
     *
     * @since 1.1
     */
    @Parameter
    protected List<String> filterDelimiters;

    /**
     * @since 1.1
     */
    @Parameter( defaultValue = "true" )
    protected boolean useDefaultFilterDelimiters;

    /**
     * If true, only generate resources in the directory of the root project in a multimodule build.
     * Dependencies from all modules will be aggregated before resource-generation takes place.
     *
     * @since 1.1
     */
    @Parameter( defaultValue = "false" )
    protected boolean runOnlyAtExecutionRoot;

    /**
     * Used for calculation of execution-root for {@link ProcessRemoteResourcesMojo#runOnlyAtExecutionRoot}.
     */
    @Parameter( defaultValue = "${basedir}", readonly = true, required = true )
    protected File basedir;

    /**
     * The character encoding scheme to be applied when filtering resources.
     */
    @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
    protected String encoding;

    /**
     * The local repository taken from Maven's runtime. Typically <code>$HOME/.m2/repository</code>.
     */
    @Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
    private ArtifactRepository localRepository;

    /**
     * List of Remote Repositories used by the resolver.
     */
    @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true )
    private List<ArtifactRepository> remoteArtifactRepositories;

    /**
     * The current Maven project.
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    private MavenProject project;

    /**
     * The directory where processed resources will be placed for packaging.
     */
    @Parameter( defaultValue = "${project.build.directory}/maven-shared-archive-resources" )
    private File outputDirectory;

    /**
     * The directory containing extra information appended to the generated resources.
     */
    @Parameter( defaultValue = "${basedir}/src/main/appended-resources" )
    private File appendedResourcesDirectory;

    /**
     * Supplemental model data. Useful when processing
     * artifacts with incomplete POM metadata.
     * <p/>
     * By default, this Mojo looks for supplemental model data in the file
     * "<code>${appendedResourcesDirectory}/supplemental-models.xml</code>".
     *
     * @since 1.0-alpha-5
     */
    @Parameter
    private String[] supplementalModels;

    /**
     * List of artifacts that are added to the search path when looking
     * for supplementalModels, expressed with <code>groupId:artifactId:version[:type[:classifier]]</code> format.
     *
     * @since 1.1
     */
    @Parameter
    private List<String> supplementalModelArtifacts;

    /**
     * Map of artifacts to supplemental project object models.
     */
    private Map<String, Model> supplementModels;

    /**
     * Merges supplemental data model with artifact metadata. Useful when processing artifacts with
     * incomplete POM metadata.
     */
    private ModelInheritanceAssembler inheritanceAssembler = new ModelInheritanceAssembler();

    /**
     * The resource bundles that will be retrieved and processed,
     * expressed with <code>groupId:artifactId:version[:type[:classifier]]</code> format.
     */
    @Parameter( required = true )
    private List<String> resourceBundles;

    /**
     * Skip remote-resource processing
     *
     * @since 1.0-alpha-5
     */
    @Parameter( property = "remoteresources.skip", defaultValue = "false" )
    private boolean skip;

    /**
     * Attaches the resources to the main build of the project as a resource directory.
     *
     * @since 1.5
     */
    @Parameter( defaultValue = "true", property = "attachToMain" )
    private boolean attachToMain;

    /**
     * Attaches the resources to the test build of the project as a resource directory.
     *
     * @since 1.5
     */
    @Parameter( defaultValue = "true", property = "attachToTest" )
    private boolean attachToTest;

    /**
     * Additional properties to be passed to Velocity.
     * <p/>
     * Several properties are automatically added:<ul>
     * <li><code>project</code> - the current MavenProject </li>
     * <li><code>projects</code> - the list of dependency projects</li>
     * <li><code>projectsSortedByOrganization</code> - the list of dependency projects sorted by organization</li>
     * <li><code>projectTimespan</code> - the timespan of the current project (requires inceptionYear in pom)</li>
     * <li><code>locator</code> - the ResourceManager that can be used to retrieve additional resources</li>
     * </ul>
     * See <a
     * href="https://maven.apache.org/ref/current/maven-project/apidocs/org/apache/maven/project/MavenProject.html"> the
     * javadoc for MavenProject</a> for information about the properties on the MavenProject.
     */
    @Parameter
    private Map<String, Object> properties = new HashMap<>();

    /**
     * Whether to include properties defined in the project when filtering resources.
     *
     * @since 1.2
     */
    @Parameter( defaultValue = "false" )
    protected boolean includeProjectProperties = false;

    /**
     * When the result of velocity transformation fits in memory, it is compared with the actual contents on disk
     * to eliminate unnecessary destination file overwrite. This improves build times since further build steps
     * typically rely on the modification date.
     *
     * @since 1.6
     */
    @Parameter( defaultValue = "5242880" )
    protected int velocityFilterInMemoryThreshold = 5 * 1024 * 1024;

    /**
     * The list of resources defined for the project.
     */
    @Parameter( defaultValue = "${project.resources}", readonly = true, required = true )
    private List<Resource> resources;

    /**
     * Repository system, needed to create Artifact and Repository objects.
     */
    @Component
    protected RepositorySystem repositorySystem;

    /**
     * Artifact Resolver, needed to resolve and download the {@code resourceBundles}.
     */
    @Component
    private ArtifactResolver artifactResolver;

    /**
     * Filtering support, for local resources that override those in the remote bundle.
     */
    @Component
    private MavenFileFilter fileFilter;

    /**
     * Project artifact factory, needed to create artifacts for the project dependencies.
     */
    @Component
    private ProjectArtifactFactory projectArtifactFactory;

    /**
     * The Maven session.
     */
    @Parameter( defaultValue = "${session}", readonly = true, required = true )
    private MavenSession mavenSession;

    /**
     * ProjectBuilder, needed to create projects from the artifacts.
     */
    @Component( role = ProjectBuilder.class )
    private ProjectBuilder projectBuilder;

    /**
     */
    @Component
    private ResourceManager locator;

    /**
     * Scope to include. An Empty string indicates all scopes (default is "runtime").
     *
     * @since 1.0
     */
    @Parameter( property = "includeScope", defaultValue = "runtime" )
    protected String includeScope;

    /**
     * Scope to exclude. An Empty string indicates no scopes (default).
     *
     * @since 1.0
     */
    @Parameter( property = "excludeScope", defaultValue = "" )
    protected String excludeScope;

    /**
     * When resolving project dependencies, specify the scopes to include.
     * The default is the same as "includeScope" if there are no exclude scopes set.
     * Otherwise, it defaults to "test" to grab all the dependencies so the
     * exclude filters can filter out what is not needed.
     * 
     * @since 1.5
     */
    @Parameter
    private String[] resolveScopes;

    /**
     * Comma separated list of Artifact names too exclude.
     *
     * @since 1.0
     */
    @Parameter( property = "excludeArtifactIds", defaultValue = "" )
    protected String excludeArtifactIds;

    /**
     * Comma separated list of Artifact names to include.
     *
     * @since 1.0
     */
    @Parameter( property = "includeArtifactIds", defaultValue = "" )
    protected String includeArtifactIds;

    /**
     * Comma separated list of GroupId Names to exclude.
     *
     * @since 1.0
     */
    @Parameter( property = "excludeGroupIds", defaultValue = "" )
    protected String excludeGroupIds;

    /**
     * Comma separated list of GroupIds to include.
     *
     * @since 1.0
     */
    @Parameter( property = "includeGroupIds", defaultValue = "" )
    protected String includeGroupIds;

    /**
     * If we should exclude transitive dependencies
     *
     * @since 1.0
     */
    @Parameter( property = "excludeTransitive", defaultValue = "false" )
    protected boolean excludeTransitive;

    /**
     * Timestamp for reproducible output archive entries, either formatted as ISO 8601
     * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
     * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
     */
    @Parameter( defaultValue = "${project.build.outputTimestamp}" )
    private String outputTimestamp;

    /**
     */
    @Component( hint = "default" )
    protected ProjectDependenciesResolver dependencyResolver;

    private VelocityEngine velocity;

    @Override
    @SuppressWarnings( "unchecked" )
    public void execute()
        throws MojoExecutionException
    {
        if ( skip )
        {
            getLog().info( "Skipping remote resources execution." );
            return;
        }

        if ( StringUtils.isEmpty( encoding ) )
        {
            getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
                               + ", i.e. build is platform dependent!" );
        }

        if ( runOnlyAtExecutionRoot && !project.isExecutionRoot() )
        {
            getLog().info( "Skipping remote-resource generation in this project because it's not the Execution Root" );
            return;
        }

        if ( resolveScopes == null )
        {
            resolveScopes =
                new String[] { StringUtils.isEmpty( excludeScope ) ? this.includeScope : Artifact.SCOPE_TEST };
        }

        if ( supplementalModels == null )
        {
            File sups = new File( appendedResourcesDirectory, "supplemental-models.xml" );
            if ( sups.exists() )
            {
                try
                {
                    supplementalModels = new String[] { sups.toURI().toURL().toString() };
                }
                catch ( MalformedURLException e )
                {
                    // ignore
                    getLog().debug( "URL issue with supplemental-models.xml: " + e.toString() );
                }
            }
        }

        configureLocator();

        if ( includeProjectProperties )
        {
            final Properties projectProperties = project.getProperties();
            for ( Object key : projectProperties.keySet() )
            {
                properties.put( key.toString(), projectProperties.get( key ).toString() );
            }
        }

        ClassLoader origLoader = Thread.currentThread().getContextClassLoader();
        try
        {
            validate();

            List<File> resourceBundleArtifacts = downloadBundles( resourceBundles );
            supplementModels = loadSupplements( supplementalModels );

            ClassLoader classLoader = initalizeClassloader( resourceBundleArtifacts );

            Thread.currentThread().setContextClassLoader( classLoader );

            velocity = new VelocityEngine();
            velocity.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, this );
            velocity.setProperty( "resource.loader", "classpath" );
            velocity.setProperty( "classpath.resource.loader.class", ClasspathResourceLoader.class.getName() );
            velocity.init();

            VelocityContext context = buildVelocityContext( properties );

            processResourceBundles( classLoader, context );

            if ( outputDirectory.exists() )
            {
                // ----------------------------------------------------------------------------
                // Push our newly generated resources directory into the MavenProject so that
                // these resources can be picked up by the process-resources phase.
                // ----------------------------------------------------------------------------
                Resource resource = new Resource();
                resource.setDirectory( outputDirectory.getAbsolutePath() );
                // MRRESOURCES-61 handle main and test resources separately
                if ( attachToMain )
                {
                    project.getResources().add( resource );
                }
                if ( attachToTest )
                {
                    project.getTestResources().add( resource );
                }

                // ----------------------------------------------------------------------------
                // Write out archiver dot file
                // ----------------------------------------------------------------------------
                try
                {
                    File dotFile = new File( project.getBuild().getDirectory(), ".plxarc" );
                    FileUtils.mkdir( dotFile.getParentFile().getAbsolutePath() );
                    FileUtils.fileWrite( dotFile.getAbsolutePath(), outputDirectory.getName() );
                }
                catch ( IOException e )
                {
                    throw new MojoExecutionException( "Error creating dot file for archiving instructions.", e );
                }
            }
        }
        finally
        {
            Thread.currentThread().setContextClassLoader( origLoader );
        }
    }

    private void configureLocator()
        throws MojoExecutionException
    {
        if ( supplementalModelArtifacts != null && !supplementalModelArtifacts.isEmpty() )
        {
            List<File> artifacts = downloadBundles( supplementalModelArtifacts );

            for ( File artifact : artifacts )
            {
                if ( artifact.isDirectory() )
                {
                    locator.addSearchPath( FileResourceLoader.ID, artifact.getAbsolutePath() );
                }
                else
                {
                    try
                    {
                        locator.addSearchPath( "jar", "jar:" + artifact.toURI().toURL().toExternalForm() );
                    }
                    catch ( MalformedURLException e )
                    {
                        throw new MojoExecutionException( "Could not use jar " + artifact.getAbsolutePath(), e );
                    }
                }
            }

        }

        locator.addSearchPath( FileResourceLoader.ID, project.getFile().getParentFile().getAbsolutePath() );
        if ( appendedResourcesDirectory != null )
        {
            locator.addSearchPath( FileResourceLoader.ID, appendedResourcesDirectory.getAbsolutePath() );
        }
        locator.addSearchPath( "url", "" );
        locator.setOutputDirectory( new File( project.getBuild().getDirectory() ) );
    }

    @SuppressWarnings( "unchecked" )
    protected List<MavenProject> getProjects()
    {
        List<MavenProject> projects = new ArrayList<>();

        // add filters in well known order, least specific to most specific
        FilterArtifacts filter = new FilterArtifacts();

        Set<Artifact> artifacts = resolveProjectArtifacts();
        if ( this.excludeTransitive )
        {
            Set<Artifact> depArtifacts;
            if ( runOnlyAtExecutionRoot )
            {
                depArtifacts = aggregateProjectDependencyArtifacts();
            }
            else
            {
                depArtifacts = project.getDependencyArtifacts();
            }
            filter.addFilter( new ProjectTransitivityFilter( depArtifacts, true ) );
        }

        filter.addFilter( new ScopeFilter( this.includeScope, this.excludeScope ) );
        filter.addFilter( new GroupIdFilter( this.includeGroupIds, this.excludeGroupIds ) );
        filter.addFilter( new ArtifactIdFilter( this.includeArtifactIds, this.excludeArtifactIds ) );

        // perform filtering
        try
        {
            artifacts = filter.filter( artifacts );
        }
        catch ( ArtifactFilterException e )
        {
            throw new IllegalStateException( e.getMessage(), e );
        }

        for ( Artifact artifact : artifacts )
        {
            List<ArtifactRepository> remoteRepo = remoteArtifactRepositories;
            if ( artifact.isSnapshot() )
            {
                VersionRange rng = VersionRange.createFromVersion( artifact.getBaseVersion() );
                artifact = new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), rng,
                                                artifact.getScope(), artifact.getType(), artifact.getClassifier(),
                                                artifact.getArtifactHandler(), artifact.isOptional() );
            }

            getLog().debug( "Building project for " + artifact );
            MavenProject p;
            try
            {
                ProjectBuildingRequest req = new DefaultProjectBuildingRequest()
                        .setLocalRepository( localRepository )
                        .setRemoteRepositories( remoteRepo );
                ProjectBuildingResult res = projectBuilder.build( artifact, req );
                p = res.getProject();
            }
            catch ( ProjectBuildingException e )
            {
                getLog().warn( "Invalid project model for artifact [" + artifact.getArtifactId() + ":"
                                   + artifact.getGroupId() + ":" + artifact.getVersion() + "]. "
                                   + "It will be ignored by the remote resources Mojo." );
                continue;
            }

            String supplementKey =
                generateSupplementMapKey( p.getModel().getGroupId(), p.getModel().getArtifactId() );

            if ( supplementModels.containsKey( supplementKey ) )
            {
                Model mergedModel = mergeModels( p.getModel(), supplementModels.get( supplementKey ) );
                MavenProject mergedProject = new MavenProject( mergedModel );
                projects.add( mergedProject );
                mergedProject.setArtifact( artifact );
                mergedProject.setVersion( artifact.getVersion() );
                getLog().debug( "Adding project with groupId [" + mergedProject.getGroupId() + "] (supplemented)" );
            }
            else
            {
                projects.add( p );
                getLog().debug( "Adding project with groupId [" + p.getGroupId() + "]" );
            }
        }
        Collections.sort( projects, new ProjectComparator() );
        return projects;
    }

    private Set<Artifact> resolveProjectArtifacts()
    {
        try
        {
            if ( runOnlyAtExecutionRoot )
            {
                List<MavenProject> projects = mavenSession.getProjects();
                return dependencyResolver.resolve( projects, Arrays.asList( resolveScopes ), mavenSession );
            }
            else
            {
                return dependencyResolver.resolve( project, Arrays.asList( resolveScopes ), mavenSession );
            }
        }
        catch ( ArtifactResolutionException e )
        {
            throw new IllegalStateException( "Failed to resolve dependencies for one or more projects in the reactor. "
                + "Reason: " + e.getMessage(), e );
        }
        catch ( ArtifactNotFoundException e )
        {
            throw new IllegalStateException( "Failed to resolve dependencies for one or more projects in the reactor. "
                + "Reason: " + e.getMessage(), e );
        }
    }

    @SuppressWarnings( "unchecked" )
    private Set<Artifact> aggregateProjectDependencyArtifacts()
    {
        Set<Artifact> artifacts = new LinkedHashSet<>();

        List<MavenProject> projects = mavenSession.getProjects();
        for ( MavenProject p : projects )
        {
            if ( p.getDependencyArtifacts() == null )
            {
                try
                {
                    Set<Artifact> depArtifacts = projectArtifactFactory.createArtifacts( p );

                    if ( depArtifacts != null && !depArtifacts.isEmpty() )
                    {
                        for ( Artifact artifact : depArtifacts )
                        {
                            if ( artifact.getVersion() == null && artifact.getVersionRange() != null )
                            {
                                // Version is required for equality comparison between artifacts,
                                // but it is not needed for our purposes of filtering out
                                // transitive dependencies (which requires only groupId/artifactId).
                                // Therefore set an arbitrary version if missing.
                                artifact.setResolvedVersion( Artifact.LATEST_VERSION );
                            }
                            artifacts.add( artifact );
                        }
                    }
                }
                catch ( InvalidDependencyVersionException e )
                {
                    throw new IllegalStateException( "Failed to create dependency artifacts for: " + p.getId()
                        + ". Reason: " + e.getMessage(), e );
                }
            }
        }

        return artifacts;
    }

    protected Map<Organization, List<MavenProject>> getProjectsSortedByOrganization( List<MavenProject> projects )
    {
        Map<Organization, List<MavenProject>> organizations =
            new TreeMap<>( new OrganizationComparator() );
        List<MavenProject> unknownOrganization = new ArrayList<>();

        for ( MavenProject p : projects )
        {
            if ( p.getOrganization() != null && StringUtils.isNotEmpty( p.getOrganization().getName() ) )
            {
                List<MavenProject> sortedProjects = organizations.get( p.getOrganization() );
                if ( sortedProjects == null )
                {
                    sortedProjects = new ArrayList<>();
                }
                sortedProjects.add( p );

                organizations.put( p.getOrganization(), sortedProjects );
            }
            else
            {
                unknownOrganization.add( p );
            }
        }
        if ( !unknownOrganization.isEmpty() )
        {
            Organization unknownOrg = new Organization();
            unknownOrg.setName( "an unknown organization" );
            organizations.put( unknownOrg, unknownOrganization );
        }

        return organizations;
    }

    protected boolean copyResourceIfExists( File file, String relFileName, VelocityContext context )
        throws IOException, MojoExecutionException
    {
        for ( Resource resource : resources )
        {
            File resourceDirectory = new File( resource.getDirectory() );

            if ( !resourceDirectory.exists() )
            {
                continue;
            }

            // TODO - really should use the resource includes/excludes and name mapping
            File source = new File( resourceDirectory, relFileName );
            File templateSource = new File( resourceDirectory, relFileName + TEMPLATE_SUFFIX );

            if ( !source.exists() && templateSource.exists() )
            {
                source = templateSource;
            }

            if ( source.exists() && !source.equals( file ) )
            {
                if ( source == templateSource )
                {
                    try ( DeferredFileOutputStream os = 
                                    new DeferredFileOutputStream( velocityFilterInMemoryThreshold, file ) )
                    {
                        try ( Reader reader = getReader( source ); Writer writer = getWriter( os ) )
                        {
                            velocity.evaluate( context, writer, "", reader );
                        }
                        catch ( ParseErrorException | MethodInvocationException | ResourceNotFoundException e )
                        {
                            throw new MojoExecutionException( "Error rendering velocity resource: " + source, e );
                        }
                        fileWriteIfDiffers( os );
                    }
                }
                else if ( resource.isFiltering() )
                {

                    MavenFileFilterRequest req = setupRequest( resource, source, file );

                    try
                    {
                        fileFilter.copyFile( req );
                    }
                    catch ( MavenFilteringException e )
                    {
                        throw new MojoExecutionException( "Error filtering resource: " + source, e );
                    }
                }
                else
                {
                    FileUtils.copyFile( source, file );
                }

                // exclude the original (so eclipse doesn't complain about duplicate resources)
                resource.addExclude( relFileName );

                return true;
            }

        }
        return false;
    }

    private Reader getReader( File source ) throws IOException
    {
        if ( encoding != null )
        {
            return new InputStreamReader( new FileInputStream( source ), encoding );
        }
        else
        {
            return ReaderFactory.newPlatformReader( source );
        }
    }
    
    private Writer getWriter( OutputStream os ) throws IOException
    {
        if ( encoding != null )
        {
            return new OutputStreamWriter( os, encoding );
        }
        else
        {
            return WriterFactory.newPlatformWriter( os );
        }
    }

    /**
     * If the transformation result fits in memory and the destination file already exists
     * then both are compared.
     * <p>If destination file is byte-by-byte equal, then it is not overwritten.
     * This improves subsequent compilation times since upstream plugins property see that
     * the resource was not modified.
     * <p>Note: the method should be called after {@link org.apache.commons.io.output.DeferredFileOutputStream#close}
     *
     * @param outStream Deferred stream
     * @throws IOException
     */
    private void fileWriteIfDiffers( DeferredFileOutputStream outStream )
        throws IOException
    {
        File file = outStream.getFile();
        if ( outStream.isThresholdExceeded() )
        {
            getLog().info( "File " + file + " was overwritten due to content limit threshold "
                    + outStream.getThreshold() + " reached" );
            return;
        }
        boolean needOverwrite = true;

        if ( file.exists() )
        {
            try ( InputStream is = new FileInputStream( file ) )
            {
                final InputStream newContents = new ByteArrayInputStream( outStream.getData() );
                needOverwrite = !IOUtil.contentEquals( is, newContents );
                if ( getLog().isDebugEnabled() )
                {
                    getLog().debug( "File " + file + " contents "
                                        + ( needOverwrite ? "differs" : "does not differ" ) );
                }
            }
        }

        if ( !needOverwrite )
        {
            getLog().debug( "File " + file + " is up to date" );
            return;
        }
        getLog().debug( "Writing " + file );
        
        try ( OutputStream os = new FileOutputStream( file ) )
        {
            outStream.writeTo( os );
        }
    }

    private MavenFileFilterRequest setupRequest( Resource resource, File source, File file )
    {
        MavenFileFilterRequest req = new MavenFileFilterRequest();
        req.setFrom( source );
        req.setTo( file );
        req.setFiltering( resource.isFiltering() );

        req.setMavenProject( project );
        req.setMavenSession( mavenSession );
        req.setInjectProjectBuildFilters( true );

        if ( encoding != null )
        {
            req.setEncoding( encoding );
        }

        if ( filterDelimiters != null && !filterDelimiters.isEmpty() )
        {
            LinkedHashSet<String> delims = new LinkedHashSet<>();
            if ( useDefaultFilterDelimiters )
            {
                delims.addAll( req.getDelimiters() );
            }

            for ( String delim : filterDelimiters )
            {
                if ( delim == null )
                {
                    delims.add( "${*}" );
                }
                else
                {
                    delims.add( delim );
                }
            }

            req.setDelimiters( delims );
        }

        return req;
    }

    protected void validate()
        throws MojoExecutionException
    {
        int bundleCount = 1;

        for ( String artifactDescriptor : resourceBundles )
        {
            // groupId:artifactId:version, groupId:artifactId:version:type
            // or groupId:artifactId:version:type:classifier
            String[] s = StringUtils.split( artifactDescriptor, ":" );

            if ( s.length < 3 || s.length > 5 )
            {
                String position;

                if ( bundleCount == 1 )
                {
                    position = "1st";
                }
                else if ( bundleCount == 2 )
                {
                    position = "2nd";
                }
                else if ( bundleCount == 3 )
                {
                    position = "3rd";
                }
                else
                {
                    position = bundleCount + "th";
                }

                throw new MojoExecutionException( "The " + position
                    + " resource bundle configured must specify a groupId, artifactId, "
                    + " version and, optionally, type and classifier for a remote resource bundle. "
                    + "Must be of the form <resourceBundle>groupId:artifactId:version</resourceBundle>, "
                    + "<resourceBundle>groupId:artifactId:version:type</resourceBundle> or "
                    + "<resourceBundle>groupId:artifactId:version:type:classifier</resourceBundle>" );
            }

            bundleCount++;
        }

    }

    private static final String KEY_PROJECTS = "projects";
    private static final String KEY_PROJECTS_ORGS = "projectsSortedByOrganization";

    protected VelocityContext buildVelocityContext( Map<String, Object> properties )
        throws MojoExecutionException
    {
        // the following properties are expensive to calculate, so we provide them lazily
        VelocityContext context = new VelocityContext( properties )
        {
            @Override
            public Object internalGet( String key )
            {
                Object result = super.internalGet( key );
                if ( result == null && key != null && key.startsWith( KEY_PROJECTS ) && containsKey( key ) )
                {
                    // calculate and put projects* properties
                    List<MavenProject> projects = getProjects();
                    put( KEY_PROJECTS, projects );
                    put( KEY_PROJECTS_ORGS, getProjectsSortedByOrganization( projects ) );
                    return super.internalGet( key );
                }
                return result;
            }
        };
        // to have a consistent getKeys()/containsKey() behaviour, keys must be present from the start
        context.put( KEY_PROJECTS, null );
        context.put( KEY_PROJECTS_ORGS, null );
        // the following properties are cheap to calculate, so we provide them eagerly

        // Reproducible Builds: try to use reproducible output timestamp 
        MavenArchiver archiver = new MavenArchiver();
        Date outputDate = archiver.parseOutputTimestamp( outputTimestamp );

        String inceptionYear = project.getInceptionYear();
        String year = new SimpleDateFormat( "yyyy" ).format( ( outputDate == null ) ? new Date() : outputDate );

        if ( StringUtils.isEmpty( inceptionYear ) )
        {
            if ( getLog().isDebugEnabled() )
            {
                getLog().debug( "inceptionYear not specified, defaulting to " + year );
            }

            inceptionYear = year;
        }
        context.put( "project", project );
        context.put( "presentYear", year );
        context.put( "locator", locator );

        if ( inceptionYear.equals( year ) )
        {
            context.put( "projectTimespan", year );
        }
        else
        {
            context.put( "projectTimespan", inceptionYear + "-" + year );
        }
        return context;
    }

    private List<File> downloadBundles( List<String> bundles )
        throws MojoExecutionException
    {
        List<File> bundleArtifacts = new ArrayList<>();

        for ( String artifactDescriptor : bundles )
        {
            getLog().info( "Preparing remote bundle " + artifactDescriptor );
            // groupId:artifactId:version[:type[:classifier]]
            String[] s = artifactDescriptor.split( ":" );

            File artifactFile = null;
            // check if the artifact is part of the reactor
            if ( mavenSession != null )
            {
                List<MavenProject> list = mavenSession.getProjects();
                for ( MavenProject p : list )
                {
                    if ( s[0].equals( p.getGroupId() ) && s[1].equals( p.getArtifactId() )
                        && s[2].equals( p.getVersion() ) )
                    {
                        if ( s.length >= 4 && "test-jar".equals( s[3] ) )
                        {
                            artifactFile = new File( p.getBuild().getTestOutputDirectory() );
                        }
                        else
                        {
                            artifactFile = new File( p.getBuild().getOutputDirectory() );
                        }
                    }
                }
            }
            if ( artifactFile == null || !artifactFile.exists() )
            {
                String type = ( s.length >= 4 ? s[3] : "jar" );
                String classifier = ( s.length == 5 ? s[4] : null );
                Artifact artifact = repositorySystem.createArtifactWithClassifier( s[0], s[1], s[2], type, classifier );

                try
                {
                    ArtifactResult result = artifactResolver.resolveArtifact(
                            mavenSession.getProjectBuildingRequest(), artifact );
                    artifactFile = result.getArtifact().getFile();
                }
                catch ( ArtifactResolverException e )
                {
                    throw new MojoExecutionException( "Error processing remote resources", e );
                }

            }
            bundleArtifacts.add( artifactFile );
        }

        return bundleArtifacts;
    }

    private ClassLoader initalizeClassloader( List<File> artifacts )
        throws MojoExecutionException
    {
        RemoteResourcesClassLoader cl = new RemoteResourcesClassLoader( null );
        try
        {
            for ( File artifact : artifacts )
            {
                cl.addURL( artifact.toURI().toURL() );
            }
            return cl;
        }
        catch ( MalformedURLException e )
        {
            throw new MojoExecutionException( "Unable to configure resources classloader: " + e.getMessage(), e );
        }
    }

    protected void processResourceBundles( ClassLoader classLoader, VelocityContext context )
        throws MojoExecutionException
    {
        List<Map.Entry<String, RemoteResourcesBundle>> remoteResources =
            new ArrayList<>();
        int bundleCount = 0;
        int resourceCount = 0;

        // list remote resources form bundles
        try
        {
            RemoteResourcesBundleXpp3Reader bundleReader = new RemoteResourcesBundleXpp3Reader();

            for ( Enumeration<URL> e =
                classLoader.getResources( BundleRemoteResourcesMojo.RESOURCES_MANIFEST ); e.hasMoreElements(); )
            {
                URL url = e.nextElement();
                bundleCount++;
                getLog().debug( "processResourceBundle on bundle#" + bundleCount + " " + url );

                RemoteResourcesBundle bundle;
                
                try ( InputStream in = url.openStream() )
                {
                    bundle = bundleReader.read( in );
                }

                int n = 0;
                for ( String bundleResource : bundle.getRemoteResources() )
                {
                    n++;
                    resourceCount++;
                    getLog().debug( "bundle#" + bundleCount + " resource#" + n + " " + bundleResource );
                    remoteResources.add( new AbstractMap.SimpleEntry<>( bundleResource,
                                                                                                     bundle ) );
                }
            }
        }
        catch ( IOException ioe )
        {
            throw new MojoExecutionException( "Error finding remote resources manifests", ioe );
        }
        catch ( XmlPullParserException xppe )
        {
            throw new MojoExecutionException( "Error parsing remote resource bundle descriptor.", xppe );
        }

        getLog().info( "Copying " + resourceCount + " resource" + ( ( resourceCount > 1 ) ? "s" : "" ) + " from "
            + bundleCount + " bundle" + ( ( bundleCount > 1 ) ? "s" : "" ) + "." );

        String velocityResource = null;
        try
        {

            for ( Map.Entry<String, RemoteResourcesBundle> entry : remoteResources )
            {
                String bundleResource = entry.getKey();
                RemoteResourcesBundle bundle = entry.getValue();

                String projectResource = bundleResource;

                boolean doVelocity = false;
                if ( projectResource.endsWith( TEMPLATE_SUFFIX ) )
                {
                    projectResource = projectResource.substring( 0, projectResource.length() - 3 );
                    velocityResource = bundleResource;
                    doVelocity = true;
                }

                // Don't overwrite resource that are already being provided.

                File f = new File( outputDirectory, projectResource );

                FileUtils.mkdir( f.getParentFile().getAbsolutePath() );

                if ( !copyResourceIfExists( f, projectResource, context ) )
                {
                    if ( doVelocity )
                    {
                        try ( DeferredFileOutputStream os =
                                        new DeferredFileOutputStream( velocityFilterInMemoryThreshold, f ) )
                        {
                            try ( Writer writer = bundle.getSourceEncoding() == null ? new OutputStreamWriter( os )
                                            : new OutputStreamWriter( os, bundle.getSourceEncoding() ) )
                            {
                                if ( bundle.getSourceEncoding() == null )
                                {
                                    // TODO: Is this correct? Shouldn't we behave like the rest of maven and fail
                                    // down to JVM default instead ISO-8859-1 ?
                                    velocity.mergeTemplate( bundleResource, "ISO-8859-1", context, writer );
                                }
                                else
                                {
                                    velocity.mergeTemplate( bundleResource, bundle.getSourceEncoding(), context,
                                                            writer );
                                }
                            }
                            fileWriteIfDiffers( os );
                        }
                    }
                    else
                    {
                        URL resUrl = classLoader.getResource( bundleResource );
                        if ( resUrl != null )
                        {
                            FileUtils.copyURLToFile( resUrl, f );
                        }
                    }

                    File appendedResourceFile = new File( appendedResourcesDirectory, projectResource );
                    File appendedVmResourceFile = new File( appendedResourcesDirectory, projectResource + ".vm" );

                    if ( appendedResourceFile.exists() )
                    {
                        getLog().info( "Copying appended resource: " + projectResource );
                        try ( InputStream in = new FileInputStream( appendedResourceFile );
                              OutputStream out = new FileOutputStream( f, true ) )
                        {
                            IOUtil.copy( in, out );
                        }
                        
                    }
                    else if ( appendedVmResourceFile.exists() )
                    {
                        getLog().info( "Filtering appended resource: " + projectResource + ".vm" );
                        

                        try ( Reader reader = new FileReader( appendedVmResourceFile ); 
                              Writer writer = getWriter( bundle, f ) )
                        {
                            Velocity.init();
                            Velocity.evaluate( context, writer, "remote-resources", reader );
                        }
                    }
                }
            }
        }
        catch ( IOException ioe )
        {
            throw new MojoExecutionException( "Error reading remote resource", ioe );
        }
        catch ( VelocityException e )
        {
            throw new MojoExecutionException( "Error rendering Velocity resource '" + velocityResource + "'", e );
        }
    }

    private Writer getWriter( RemoteResourcesBundle bundle, File f )
        throws IOException, UnsupportedEncodingException, FileNotFoundException
    {
        Writer writer;
        if ( bundle.getSourceEncoding() == null )
        {
            writer = new PrintWriter( new FileWriter( f, true ) );
        }
        else
        {
            writer = new PrintWriter( new OutputStreamWriter( new FileOutputStream( f, true ),
                                                              bundle.getSourceEncoding() ) );
        }
        return writer;
    }

    protected Model getSupplement( Xpp3Dom supplementModelXml )
        throws MojoExecutionException
    {
        MavenXpp3Reader modelReader = new MavenXpp3Reader();
        Model model = null;

        try
        {
            model = modelReader.read( new StringReader( supplementModelXml.toString() ) );
            String groupId = model.getGroupId();
            String artifactId = model.getArtifactId();

            if ( groupId == null || groupId.trim().equals( "" ) )
            {
                throw new MojoExecutionException( "Supplemental project XML "
                    + "requires that a <groupId> element be present." );
            }

            if ( artifactId == null || artifactId.trim().equals( "" ) )
            {
                throw new MojoExecutionException( "Supplemental project XML "
                    + "requires that a <artifactId> element be present." );
            }
        }
        catch ( IOException e )
        {
            getLog().warn( "Unable to read supplemental XML: " + e.getMessage(), e );
        }
        catch ( XmlPullParserException e )
        {
            getLog().warn( "Unable to parse supplemental XML: " + e.getMessage(), e );
        }

        return model;
    }

    protected Model mergeModels( Model parent, Model child )
    {
        inheritanceAssembler.assembleModelInheritance( child, parent );
        return child;
    }

    private static String generateSupplementMapKey( String groupId, String artifactId )
    {
        return groupId.trim() + ":" + artifactId.trim();
    }

    private Map<String, Model> loadSupplements( String models[] )
        throws MojoExecutionException
    {
        if ( models == null )
        {
            getLog().debug( "Supplemental data models won't be loaded.  " + "No models specified." );
            return Collections.emptyMap();
        }

        List<Supplement> supplements = new ArrayList<>();
        for ( String set : models )
        {
            getLog().debug( "Preparing ruleset: " + set );
            try
            {
                File f = locator.getResourceAsFile( set, getLocationTemp( set ) );

                if ( null == f || !f.exists() )
                {
                    throw new MojoExecutionException( "Cold not resolve " + set );
                }
                if ( !f.canRead() )
                {
                    throw new MojoExecutionException( "Supplemental data models won't be loaded. " + "File "
                        + f.getAbsolutePath() + " cannot be read, check permissions on the file." );
                }

                getLog().debug( "Loading supplemental models from " + f.getAbsolutePath() );

                SupplementalDataModelXpp3Reader reader = new SupplementalDataModelXpp3Reader();
                SupplementalDataModel supplementalModel = reader.read( new FileReader( f ) );
                supplements.addAll( supplementalModel.getSupplement() );
            }
            catch ( Exception e )
            {
                String msg = "Error loading supplemental data models: " + e.getMessage();
                getLog().error( msg, e );
                throw new MojoExecutionException( msg, e );
            }
        }

        getLog().debug( "Loading supplements complete." );

        Map<String, Model> supplementMap = new HashMap<>();
        for ( Supplement sd : supplements )
        {
            Xpp3Dom dom = (Xpp3Dom) sd.getProject();

            Model m = getSupplement( dom );
            supplementMap.put( generateSupplementMapKey( m.getGroupId(), m.getArtifactId() ), m );
        }

        return supplementMap;
    }

    /**
     * Convenience method to get the location of the specified file name.
     *
     * @param name the name of the file whose location is to be resolved
     * @return a String that contains the absolute file name of the file
     */
    private String getLocationTemp( String name )
    {
        String loc = name;
        if ( loc.indexOf( '/' ) != -1 )
        {
            loc = loc.substring( loc.lastIndexOf( '/' ) + 1 );
        }
        if ( loc.indexOf( '\\' ) != -1 )
        {
            loc = loc.substring( loc.lastIndexOf( '\\' ) + 1 );
        }
        getLog().debug( "Before: " + name + " After: " + loc );
        return loc;
    }

    class OrganizationComparator
        implements Comparator<Organization>
    {
        @Override
        public int compare( Organization org1, Organization org2 )
        {
            int i = compareStrings( org1.getName(), org2.getName() );
            if ( i == 0 )
            {
                i = compareStrings( org1.getUrl(), org2.getUrl() );
            }
            return i;
        }

        public boolean equals( Organization o1, Organization o2 )
        {
            return compare( o1, o2 ) == 0;
        }

        private int compareStrings( String s1, String s2 )
        {
            if ( s1 == null && s2 == null )
            {
                return 0;
            }
            else if ( s1 == null && s2 != null )
            {
                return 1;
            }
            else if ( s1 != null && s2 == null )
            {
                return -1;
            }

            return s1.compareToIgnoreCase( s2 );
        }
    }

    class ProjectComparator
        implements Comparator<MavenProject>
    {
        @Override
        public int compare( MavenProject p1, MavenProject p2 )
        {
            return p1.getArtifact().compareTo( p2.getArtifact() );
        }

        public boolean equals( MavenProject p1, MavenProject p2 )
        {
            return p1.getArtifact().equals( p2.getArtifact() );
        }
    }

    /* LogChute methods */
    @Override
    public void init( RuntimeServices rs )
        throws Exception
    {
    }

    @Override
    public void log( int level, String message )
    {
        switch ( level )
        {
            case LogChute.WARN_ID:
                getLog().warn( message );
                break;
            case LogChute.INFO_ID:
                // velocity info messages are too verbose, just consider them as debug messages...
                getLog().debug( message );
                break;
            case LogChute.DEBUG_ID:
                getLog().debug( message );
                break;
            case LogChute.ERROR_ID:
                getLog().error( message );
                break;
            default:
                getLog().debug( message );
                break;
        }
    }

    @Override
    public void log( int level, String message, Throwable t )
    {
        switch ( level )
        {
            case LogChute.WARN_ID:
                getLog().warn( message, t );
                break;
            case LogChute.INFO_ID:
                // velocity info messages are too verbose, just consider them as debug messages...
                getLog().debug( message, t );
                break;
            case LogChute.DEBUG_ID:
                getLog().debug( message, t );
                break;
            case LogChute.ERROR_ID:
                getLog().error( message, t );
                break;
            default:
                getLog().debug( message, t );
                break;
        }
    }

    @Override
    public boolean isLevelEnabled( int level )
    {
        return false;
    }

}
