diff --git a/maven-plugins/maven-assembly-plugin/.cvsignore b/maven-plugins/maven-assembly-plugin/.cvsignore
new file mode 100644
index 0000000000..cce9515ca7
--- /dev/null
+++ b/maven-plugins/maven-assembly-plugin/.cvsignore
@@ -0,0 +1,8 @@
+target
+*~
+*.log
+.classpath
+.project
+*.ipr
+*.iws
+*.iml
diff --git a/maven-plugins/maven-assembly-plugin/build.sh b/maven-plugins/maven-assembly-plugin/build.sh
new file mode 100755
index 0000000000..d493f20343
--- /dev/null
+++ b/maven-plugins/maven-assembly-plugin/build.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+#
+# WORKAROUND FOR http://jira.codehaus.org/browse/MNG-214
+#
+
+
+REPO=$HOME/repository-new
+
+cp pom.xml pom.xml.backup
+cat pom.xml.backup | sed 's#maven-plugin##' >pom.xml
+
+m2 clean:clean plugin:descriptor package
+cp target/maven-assembly-plugin-1.0-SNAPSHOT.jar $REPO/org/apache/maven/plugins/maven-assembly-plugin/1.0-SNAPSHOT
+
+mv pom.xml.backup pom.xml
+cp pom.xml $REPO/org/apache/maven/plugins/maven-assembly-plugin/1.0-SNAPSHOT/maven-assembly-plugin-1.0-SNAPSHOT.pom
+
diff --git a/maven-plugins/maven-assembly-plugin/pom.xml b/maven-plugins/maven-assembly-plugin/pom.xml
new file mode 100755
index 0000000000..a4cd9e2293
--- /dev/null
+++ b/maven-plugins/maven-assembly-plugin/pom.xml
@@ -0,0 +1,47 @@
+
+
+ maven-plugin-parent
+ org.apache.maven.plugins
+ 2.0-SNAPSHOT
+
+ 4.0.0
+ maven-assembly-plugin
+ maven-plugin
+ Maven Assembly Plugin
+ 1.0-SNAPSHOT
+
+
+ org.apache.maven
+ maven-artifact
+ 2.0-SNAPSHOT
+
+
+ plexus
+ plexus-archiver
+ 1.0-alpha-1
+
+
+
+
+
+ maven-modello-plugin
+ 1.0-alpha-1
+
+ src/main/mdo/descriptor.mdo
+ 1.0.0
+
+
+
+ xpp3-reader
+
+
+ xpp3-writer
+
+
+ java
+
+
+
+
+
+
diff --git a/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/AssembleMojo.java b/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/AssembleMojo.java
new file mode 100755
index 0000000000..b3ad3e72a6
--- /dev/null
+++ b/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/AssembleMojo.java
@@ -0,0 +1,391 @@
+package org.apache.maven.plugin.assembly;
+
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.plugin.AbstractPlugin;
+import org.apache.maven.plugin.PluginExecutionException;
+import org.apache.maven.plugins.assembly.model.Assembly;
+import org.apache.maven.plugins.assembly.model.DependencySet;
+import org.apache.maven.plugins.assembly.model.FileSet;
+import org.apache.maven.plugins.assembly.model.io.xpp3.AssemblyXpp3Reader;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.tar.TarArchiver;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.util.IOUtil;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author Brett Porter
+ * @version $Id$
+ * @goal assembly
+ * @requiresDependencyResolution test
+ * @description assemble an application bundle or distribution
+ * @parameter name="basedir" type="String" required="true" validator="" expression="#basedir" description=""
+ * @parameter name="outputDirectory" type="java.io.File" required="true" validator="" expression="#project.build.directory" description=""
+ * @parameter name="descriptor" type="java.io.File" required="false" validator="" expression="#maven.assembly.descriptor" description=""
+ * @parameter name="finalName" type="String" required="true" validator="" expression="#project.build.finalName" description=""
+ * @parameter name="descriptorId" type="String" required="false" validator="" expression="#maven.assembly.descriptorId" description=""
+ * @parameter name="dependencies" type="java.util.Set" required="false" validator="" expression="#project.artifacts" description=""
+ */
+public class AssemblyMojo
+ extends AbstractPlugin
+{
+ private static final String[] EMPTY_STRING_ARRAY = {};
+
+ private String basedir;
+
+ /**
+ * @todo use java.io.File
+ */
+ private String outputDirectory;
+
+ private File descriptor;
+
+ private String descriptorId;
+
+ private String finalName;
+
+ private Set dependencies;
+
+ public void execute()
+ throws PluginExecutionException
+ {
+ try
+ {
+ doExecute();
+ }
+ catch ( Exception e )
+ {
+ // TODO: don't catch exception
+ throw new PluginExecutionException( "Error creating assembly", e );
+ }
+ }
+
+ private void doExecute()
+ throws Exception
+ {
+ Reader r = null;
+
+ if ( descriptor != null )
+ {
+ r = new FileReader( descriptor );
+ }
+ else if ( descriptorId != null )
+ {
+ InputStream resourceAsStream = getClass().getResourceAsStream( "/assemblies/" + descriptorId + ".xml" );
+ if ( resourceAsStream == null )
+ {
+ // TODO: better exception
+ throw new Exception( "Descriptor with ID '" + descriptorId + "' not found" );
+ }
+ r = new InputStreamReader( resourceAsStream );
+ }
+ else
+ {
+ // TODO: better exception
+ throw new Exception( "You must specify descriptor or descriptorId" );
+ }
+
+ try
+ {
+ AssemblyXpp3Reader reader = new AssemblyXpp3Reader();
+ Assembly assembly = reader.read( r );
+
+ // TODO: include dependencies marked for distribution under certain formats
+ // TODO: how, might we plug this into an installer, such as NSIS?
+ // TODO: allow file mode specifications?
+
+ String fullName = finalName + "-" + assembly.getId();
+
+ for ( Iterator i = assembly.getFormats().iterator(); i.hasNext(); )
+ {
+ String format = (String) i.next();
+
+ String filename = fullName + "." + format;
+
+ // TODO: use component roles? Can we do that in a mojo?
+ Archiver archiver = createArchiver( format );
+
+ processFileSets( archiver, assembly.getFileSets() );
+ processDependencySets( archiver, assembly.getDependencySets() );
+
+ archiver.setDestFile( new File( outputDirectory, filename ) );
+ archiver.createArchive();
+ }
+ }
+ finally
+ {
+ IOUtil.close( r );
+ }
+ }
+
+ private void processDependencySets( Archiver archiver, List dependencySets )
+ throws ArchiverException
+ {
+ for ( Iterator i = dependencySets.iterator(); i.hasNext(); )
+ {
+ DependencySet depedencySet = (DependencySet) i.next();
+ String output = depedencySet.getOutputDirectory();
+ output = getOutputDirectory( output );
+
+ AndArtifactFilter filter = new AndArtifactFilter();
+ filter.add( new ScopeArtifactFilter( depedencySet.getScope() ) );
+ if ( !depedencySet.getIncludes().isEmpty() )
+ {
+ filter.add( new IncludesArtifactFilter( depedencySet.getIncludes() ) );
+ }
+ if ( !depedencySet.getExcludes().isEmpty() )
+ {
+ filter.add( new ExcludesArtifactFilter( depedencySet.getExcludes() ) );
+ }
+
+ // TODO: includes and excludes
+ for ( Iterator j = dependencies.iterator(); j.hasNext(); )
+ {
+ Artifact artifact = (Artifact) j.next();
+
+ if ( filter.include( artifact ) )
+ {
+ archiver.addFile( artifact.getFile(), output + artifact.getFile().getName() );
+ }
+ }
+ }
+ }
+
+ private String getOutputDirectory( String output )
+ {
+ if ( output == null )
+ {
+ output = "";
+ }
+ if ( !output.endsWith( "/" ) && !output.endsWith( "\\" ) )
+ {
+ // TODO: shouldn't archiver do this?
+ output += '/';
+ }
+
+ if ( output.startsWith( "/" ) )
+ {
+ output = finalName + output;
+ }
+ else
+ {
+ output = finalName + "/" + output;
+ }
+ return output;
+ }
+
+ private Archiver createArchiver( String format )
+ throws ArchiverException
+ {
+ Archiver archiver;
+ if ( format.startsWith( "tar" ) )
+ {
+ TarArchiver tarArchiver = new TarArchiver();
+ archiver = tarArchiver;
+ int index = format.indexOf( '.' );
+ if ( index >= 0 )
+ {
+ // TODO: this needs a cleanup in plexus archiver - use a real typesafe enum
+ TarArchiver.TarCompressionMethod tarCompressionMethod = new TarArchiver.TarCompressionMethod();
+ // TODO: this should accept gz and bz2 as well so we can skip over the switch
+ String compression = format.substring( index + 1 );
+ if ( compression.equals( "gz" ) )
+ {
+ tarCompressionMethod.setValue( "gzip" );
+ }
+ else if ( compression.equals( "bz2" ) )
+ {
+ tarCompressionMethod.setValue( "bzip2" );
+ }
+ else
+ {
+ // TODO: better handling
+ throw new IllegalArgumentException( "Unknown compression format: " + compression );
+ }
+ tarArchiver.setCompression( tarCompressionMethod );
+ }
+ }
+ else if ( format.startsWith( "zip" ) )
+ {
+ archiver = new ZipArchiver();
+ }
+ else if ( format.startsWith( "jar" ) )
+ {
+ // TODO: use MavenArchiver for manifest?
+ archiver = new JarArchiver();
+ }
+ else
+ {
+ // TODO: better handling
+ throw new IllegalArgumentException( "Unknown format: " + format );
+ }
+ return archiver;
+ }
+
+ private void processFileSets( Archiver archiver, java.util.List fileSets )
+ throws ArchiverException
+ {
+ for ( Iterator i = fileSets.iterator(); i.hasNext(); )
+ {
+ FileSet fileSet = (FileSet) i.next();
+ String directory = fileSet.getDirectory();
+ String output = fileSet.getOutputDirectory();
+ if ( directory == null )
+ {
+ directory = basedir;
+ if ( output == null )
+ {
+ output = "";
+ }
+ }
+ else
+ {
+ if ( output == null )
+ {
+ output = directory;
+ }
+ }
+ output = getOutputDirectory( output );
+
+ String[] includes = (String[]) fileSet.getIncludes().toArray( EMPTY_STRING_ARRAY );
+ if ( includes.length == 0 )
+ {
+ includes = null;
+ }
+
+ List excludesList = fileSet.getExcludes();
+ excludesList.addAll( getDefaultExcludes() );
+ String[] excludes = (String[]) excludesList.toArray( EMPTY_STRING_ARRAY );
+
+ // TODO: default excludes should be in the archiver?
+ archiver.addDirectory( new File( directory ), output, includes, excludes );
+ }
+ }
+
+ public List getDefaultExcludes()
+ {
+ List defaultExcludes = new ArrayList();
+ defaultExcludes.add( "**/*~" );
+ defaultExcludes.add( "**/#*#" );
+ defaultExcludes.add( "**/.#*" );
+ defaultExcludes.add( "**/%*%" );
+ defaultExcludes.add( "**/._*" );
+
+ // CVS
+ defaultExcludes.add( "**/CVS" );
+ defaultExcludes.add( "**/CVS/**" );
+ defaultExcludes.add( "**/.cvsignore" );
+
+ // SCCS
+ defaultExcludes.add( "**/SCCS" );
+ defaultExcludes.add( "**/SCCS/**" );
+
+ // Visual SourceSafe
+ defaultExcludes.add( "**/vssver.scc" );
+
+ // Subversion
+ defaultExcludes.add( "**/.svn" );
+ defaultExcludes.add( "**/.svn/**" );
+
+ // Mac
+ defaultExcludes.add( "**/.DS_Store" );
+
+ return defaultExcludes;
+ }
+
+ // TODO: move to maven-artifact - generally useful
+ private static class AndArtifactFilter
+ implements ArtifactFilter
+ {
+ private final List filters = new ArrayList();
+
+ public boolean include( Artifact artifact )
+ {
+ boolean include = true;
+ for ( Iterator i = filters.iterator(); i.hasNext() && include; )
+ {
+ ArtifactFilter filter = (ArtifactFilter) i.next();
+ if ( !filter.include( artifact ) )
+ {
+ include = false;
+ }
+ }
+ return include;
+ }
+
+ public void add( ArtifactFilter artifactFilter )
+ {
+ filters.add( artifactFilter );
+ }
+ }
+
+ private static class IncludesArtifactFilter
+ implements ArtifactFilter
+ {
+ private final List patterns;
+
+ public IncludesArtifactFilter( List patterns )
+ {
+ this.patterns = patterns;
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ String id = artifact.getGroupId() + ":" + artifact.getArtifactId();
+
+ boolean matched = false;
+ for ( Iterator i = patterns.iterator(); i.hasNext() & !matched; )
+ {
+ // TODO: what about wildcards? Just specifying groups? versions?
+ if ( id.equals( i.next() ) )
+ {
+ matched = true;
+ }
+ }
+ return matched;
+ }
+ }
+
+ private static class ExcludesArtifactFilter
+ extends IncludesArtifactFilter
+ {
+ public ExcludesArtifactFilter( List patterns )
+ {
+ super( patterns );
+ }
+
+ public boolean include( Artifact artifact )
+ {
+ return !super.include( artifact );
+ }
+ }
+}
diff --git a/maven-plugins/maven-assembly-plugin/src/main/mdo/descriptor.mdo b/maven-plugins/maven-assembly-plugin/src/main/mdo/descriptor.mdo
new file mode 100644
index 0000000000..2378350ac0
--- /dev/null
+++ b/maven-plugins/maven-assembly-plugin/src/main/mdo/descriptor.mdo
@@ -0,0 +1,119 @@
+
+ assembly
+ Assembly
+
+
+
+ package
+ org.apache.maven.plugins.assembly.model
+
+
+
+
+ Assembly
+ Describes the assembly layout and packaging.
+ 1.0.0
+
+
+ id
+ 1.0.0
+ true
+ String
+
+
+ formats
+ 1.0.0
+ true
+
+ String
+ *
+
+
+
+ fileSets
+ 1.0.0
+
+ FileSet
+ *
+
+
+
+ dependencySets
+ 1.0.0
+
+ DependencySet
+ *
+
+
+
+
+
+ FileSet
+ 1.0.0
+
+
+ directory
+ 1.0.0
+ String
+ true
+
+
+ outputDirectory
+ 1.0.0
+ String
+
+
+ includes
+ 1.0.0
+
+ String
+ *
+
+
+
+ excludes
+ 1.0.0
+
+ String
+ *
+
+
+
+
+
+ DependencySet
+ 1.0.0
+
+
+ outputDirectory
+ 1.0.0
+ String
+
+
+ scope
+ 1.0.0
+ String
+ runtime
+ true
+
+
+ includes
+ 1.0.0
+
+ String
+ *
+
+
+
+ excludes
+ 1.0.0
+
+ String
+ *
+
+
+
+
+
+
+
diff --git a/maven-plugins/maven-assembly-plugin/src/main/resources/assemblies/bin.xml b/maven-plugins/maven-assembly-plugin/src/main/resources/assemblies/bin.xml
new file mode 100755
index 0000000000..e2650b4fe1
--- /dev/null
+++ b/maven-plugins/maven-assembly-plugin/src/main/resources/assemblies/bin.xml
@@ -0,0 +1,26 @@
+
+ bin
+
+ tar.gz
+ tar.bz2
+ zip
+
+
+
+
+ README*
+ LICENSE*
+ NOTICE*
+
+
+
+
+
+ target
+
+
+ *.jar
+
+
+
+
diff --git a/maven-plugins/maven-assembly-plugin/src/main/resources/assemblies/src.xml b/maven-plugins/maven-assembly-plugin/src/main/resources/assemblies/src.xml
new file mode 100755
index 0000000000..ee1a0d62f0
--- /dev/null
+++ b/maven-plugins/maven-assembly-plugin/src/main/resources/assemblies/src.xml
@@ -0,0 +1,22 @@
+
+ src
+
+ tar.gz
+ tar.bz2
+ zip
+
+
+
+
+ README*
+ LICENSE*
+ NOTICE*
+ pom.xml
+
+
+
+
+ src
+
+
+