diff --git a/sandbox/tbennett/maven-archiver/pom.xml b/sandbox/tbennett/maven-archiver/pom.xml
deleted file mode 100644
index 300d915..0000000
--- a/sandbox/tbennett/maven-archiver/pom.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <artifactId>maven</artifactId>
-    <groupId>org.apache.maven</groupId>
-    <version>2.0-alpha-3</version>
-  </parent>
-  <artifactId>maven-archiver</artifactId>
-  <name>Maven Archiver</name>
-  <version>2.0-alpha-3</version>
-  <dependencies>
-    <dependency>
-      <groupId>plexus</groupId>
-      <artifactId>plexus-archiver</artifactId>
-      <version>1.0-alpha-1</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-artifact</artifactId>
-      <version>2.0-alpha-3</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-project</artifactId>
-      <version>2.0-alpha-3</version>
-    </dependency>
-  </dependencies>
-</project>
diff --git a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/ManifestConfiguration.java b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/ManifestConfiguration.java
deleted file mode 100644
index 7ff960c..0000000
--- a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/ManifestConfiguration.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.apache.maven.archiver;
-
-/*
- * 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.
- */
-
-/**
- * Capture common manifest configuration.
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @version $Id: ManifestConfiguration.java 209060 2005-07-04 11:59:42Z evenisse $
- * @todo is this general enough to be in Plexus Archiver?
- */
-public class ManifestConfiguration
-{
-    private String mainClass;
-
-    private String packageName;
-
-    /**
-     * @todo boolean instead
-     */
-    private String addClasspath;
-
-    /**
-     * @todo boolean instead
-     */
-    private String addExtensions;
-
-    /**
-     * This gets prefixed to all classpath entries.
-     */
-    private String classpathPrefix = "";
-
-    public String getMainClass()
-    {
-        return mainClass;
-    }
-
-    public boolean isAddClasspath()
-    {
-        return addClasspath != null ? Boolean.valueOf( addClasspath ).booleanValue() : false;
-    }
-
-    public boolean isAddExtensions()
-    {
-        return addExtensions != null ? Boolean.valueOf( addExtensions ).booleanValue() : false;
-    }
-
-    public String getPackageName()
-    {
-        return packageName;
-    }
-
-    public String getClasspathPrefix()
-    {
-        String cpp = classpathPrefix.replaceAll( "\\\\", "/" );
-
-        if ( cpp.length() != 0 && !cpp.endsWith("/") )
-        {
-            cpp += "/";
-        }
-        
-        return cpp;
-    }
-}
diff --git a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiveConfiguration.java b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiveConfiguration.java
deleted file mode 100644
index ec14472..0000000
--- a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiveConfiguration.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.apache.maven.archiver;
-
-/*
- * 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 java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Capture common archive configuration.
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @version $Id: MavenArchiveConfiguration.java 225504 2005-07-27 12:48:52Z brett $
- * @todo is this general enough to be in Plexus Archiver?
- */
-public class MavenArchiveConfiguration
-{
-    private boolean compress = true;
-
-    private boolean index;
-
-    private File manifestFile;
-
-    private ManifestConfiguration manifest;
-
-	private Map manifestEntries = new HashMap();
-
-    public boolean isCompress()
-    {
-        return compress;
-    }
-
-    public boolean isIndex()
-    {
-        return index;
-    }
-
-    public File getManifestFile()
-    {
-        return manifestFile;
-    }
-
-    public ManifestConfiguration getManifest()
-    {
-        if ( manifest == null )
-        {
-            manifest = new ManifestConfiguration();
-        }
-        return manifest;
-    }
-
-    public void setCompress( boolean compress )
-    {
-        this.compress = compress;
-    }
-
-    public void setIndex( boolean index )
-    {
-        this.index = index;
-    }
-
-    public void setManifestFile( File manifestFile )
-    {
-        this.manifestFile = manifestFile;
-    }
-
-    public void setManifest( ManifestConfiguration manifest )
-    {
-        this.manifest = manifest;
-    }
-
-	public void addManifestEntry(Object key, Object value) {
-		manifestEntries.put(key, value);
-	}
-
-	public void addManifestEntries(Map map) {
-		manifestEntries.putAll(map);
-	}
-
-	public boolean isManifestEntriesEmpty() {
-		return manifestEntries.isEmpty();
-	}
-
-	public Map getManifestEntries() {
-		return manifestEntries;
-	}
-}
diff --git a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiver.java b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiver.java
deleted file mode 100644
index 16192e3..0000000
--- a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiver.java
+++ /dev/null
@@ -1,317 +0,0 @@
-package org.apache.maven.archiver;
-
-/*
- * 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.DependencyResolutionRequiredException;
-import org.apache.maven.project.MavenProject;
-import org.codehaus.plexus.archiver.ArchiverException;
-import org.codehaus.plexus.archiver.jar.JarArchiver;
-import org.codehaus.plexus.archiver.jar.Manifest;
-import org.codehaus.plexus.archiver.jar.ManifestException;
-import org.codehaus.plexus.util.IOUtil;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-/**
- * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
- * @version $Revision: 225504 $ $Date: 2005-07-27 07:48:52 -0500 (Wed, 27 Jul 2005) $
- */
-public class MavenArchiver
-{
-    private JarArchiver archiver = new JarArchiver();
-
-    private File archiveFile;
-
-    /**
-     * Return a pre-configured manifest
-     *
-     * @todo Add user attributes list and user groups list
-     */
-    public Manifest getManifest( MavenProject project, ManifestConfiguration config )
-        throws ManifestException, DependencyResolutionRequiredException
-    {
-        // Added basic entries
-        Manifest m = new Manifest();
-        Manifest.Attribute buildAttr = new Manifest.Attribute( "Built-By", System.getProperty( "user.name" ) );
-        m.addConfiguredAttribute( buildAttr );
-        Manifest.Attribute createdAttr = new Manifest.Attribute( "Created-By", "Apache Maven" );
-        m.addConfiguredAttribute( createdAttr );
-
-        if ( config.getPackageName() != null )
-        {
-            Manifest.Attribute packageAttr = new Manifest.Attribute( "Package", config.getPackageName() );
-            m.addConfiguredAttribute( packageAttr );
-        }
-
-        Manifest.Attribute buildJdkAttr = new Manifest.Attribute( "Build-Jdk", System.getProperty( "java.version" ) );
-        m.addConfiguredAttribute( buildJdkAttr );
-
-        if ( config.isAddClasspath() )
-        {
-            StringBuffer classpath = new StringBuffer();
-            List artifacts = project.getRuntimeClasspathElements();
-            String classpathPrefix = config.getClasspathPrefix();
-
-            for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
-            {
-                File f = new File( (String) iter.next() );
-                if ( f.isFile() )
-                {
-                    if ( classpath.length() > 0 )
-                    {
-                        classpath.append( " " );
-                    }
-
-                    classpath.append( classpathPrefix );
-                    classpath.append( f.getName() );
-                }
-            }
-
-            if ( classpath.length() > 0 )
-            {
-                Manifest.Attribute classpathAttr = new Manifest.Attribute( "Class-Path", classpath.toString() );
-                m.addConfiguredAttribute( classpathAttr );
-            }
-        }
-
-        // Added supplementary entries
-        Manifest.Attribute extensionNameAttr = new Manifest.Attribute( "Extension-Name", project.getArtifactId() );
-        m.addConfiguredAttribute( extensionNameAttr );
-
-        if ( project.getDescription() != null )
-        {
-            Manifest.Attribute specificationTitleAttr = new Manifest.Attribute( "Specification-Title",
-                                                                                project.getDescription() );
-            m.addConfiguredAttribute( specificationTitleAttr );
-        }
-
-        if ( project.getOrganization() != null )
-        {
-            Manifest.Attribute specificationVendor = new Manifest.Attribute( "Specification-Vendor",
-                                                                             project.getOrganization().getName() );
-            m.addConfiguredAttribute( specificationVendor );
-            Manifest.Attribute implementationVendorAttr = new Manifest.Attribute( "Implementation-Vendor",
-                                                                                  project.getOrganization().getName() );
-            m.addConfiguredAttribute( implementationVendorAttr );
-        }
-
-        Manifest.Attribute implementationTitleAttr = new Manifest.Attribute( "Implementation-Title",
-                                                                             project.getArtifactId() );
-        m.addConfiguredAttribute( implementationTitleAttr );
-        Manifest.Attribute implementationVersionAttr = new Manifest.Attribute( "Implementation-Version",
-                                                                               project.getVersion() );
-        m.addConfiguredAttribute( implementationVersionAttr );
-
-        String mainClass = config.getMainClass();
-        if ( mainClass != null && !"".equals( mainClass ) )
-        {
-            Manifest.Attribute mainClassAttr = new Manifest.Attribute( "Main-Class", mainClass );
-            m.addConfiguredAttribute( mainClassAttr );
-        }
-
-        // Added extensions
-        if ( config.isAddExtensions() )
-        {
-            StringBuffer extensionsList = new StringBuffer();
-            Set artifacts = project.getArtifacts();
-
-            for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
-            {
-                Artifact artifact = (Artifact) iter.next();
-                // TODO: type of ejb should be added too?
-                if ( "jar".equals( artifact.getType() ) )
-                {
-                    if ( extensionsList.length() > 0 )
-                    {
-                        extensionsList.append( " " );
-                    }
-                    extensionsList.append( artifact.getArtifactId() );
-                }
-            }
-
-            if ( extensionsList.length() > 0 )
-            {
-                Manifest.Attribute extensionsListAttr = new Manifest.Attribute( "Extension-List",
-                                                                                extensionsList.toString() );
-                m.addConfiguredAttribute( extensionsListAttr );
-            }
-
-            for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
-            {
-                Artifact artifact = (Artifact) iter.next();
-                if ( "jar".equals( artifact.getType() ) )
-                {
-                    Manifest.Attribute archExtNameAttr = new Manifest.Attribute(
-                        artifact.getArtifactId() + "-Extension-Name", artifact.getArtifactId() );
-                    m.addConfiguredAttribute( archExtNameAttr );
-                    String name = artifact.getArtifactId() + "-Implementation-Version";
-                    Manifest.Attribute archImplVersionAttr = new Manifest.Attribute( name, artifact.getVersion() );
-                    m.addConfiguredAttribute( archImplVersionAttr );
-
-                    if ( artifact.getRepository() != null )
-                    {
-                        // TODO: is this correct
-                        name = artifact.getArtifactId() + "-Implementation-URL";
-                        String url = artifact.getRepository().getUrl() + "/" + artifact.toString();
-                        Manifest.Attribute archImplUrlAttr = new Manifest.Attribute( name, url );
-                        m.addConfiguredAttribute( archImplUrlAttr );
-                    }
-                }
-            }
-        }
-
-        return m;
-    }
-
-    public JarArchiver getArchiver()
-    {
-        return archiver;
-    }
-
-    public void setArchiver( JarArchiver archiver )
-    {
-        this.archiver = archiver;
-    }
-
-    public void setOutputFile( File outputFile )
-    {
-        archiveFile = outputFile;
-    }
-
-    public void createArchive( MavenProject project, MavenArchiveConfiguration archiveConfiguration )
-        throws ArchiverException, ManifestException, IOException, DependencyResolutionRequiredException
-    {
-        // ----------------------------------------------------------------------
-        // We want to add the metadata for the project to the JAR in two forms:
-        //
-        // The first form is that of the POM itself. Applications that wish to
-        // access the POM for an artifact using maven tools they can.
-        //
-        // The second form is that of a properties file containing the basic
-        // top-level POM elements so that applications that wish to access
-        // POM information without the use of maven tools can do so.
-        // ----------------------------------------------------------------------
-
-        String groupId = project.getGroupId();
-
-        String artifactId = project.getArtifactId();
-
-        File exportReadyPom = writeExportReadyPom( project );
-
-        archiver.addFile( exportReadyPom, "META-INF/maven/" + groupId + "/" + artifactId + "/pom.xml" );
-
-        // ----------------------------------------------------------------------
-        // Create pom.properties file
-        // ----------------------------------------------------------------------
-
-        Properties p = new Properties();
-
-        p.setProperty( "groupId", project.getGroupId() );
-
-        p.setProperty( "artifactId", project.getArtifactId() );
-
-        p.setProperty( "version", project.getVersion() );
-
-        File pomPropertiesFile = new File( project.getFile().getParentFile(), "pom.properties" );
-
-        OutputStream os = new FileOutputStream( pomPropertiesFile );
-
-        p.store( os, "Generated by Maven" );
-
-        os.close(); // stream is flushed but not closed by Properties.store()
-
-        archiver.addFile( pomPropertiesFile, "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties" );
-
-        // ----------------------------------------------------------------------
-        // Create the manifest
-        // ----------------------------------------------------------------------
-
-        File manifestFile = archiveConfiguration.getManifestFile();
-
-        if ( manifestFile != null )
-        {
-            archiver.setManifest( manifestFile );
-        }
-
-        Manifest manifest = getManifest( project, archiveConfiguration.getManifest() );
-
-		// any custom manifest entries in the archive configuration manifest?
-		if (!archiveConfiguration.isManifestEntriesEmpty()) {
-			Map entries = archiveConfiguration.getManifestEntries();
-			Set keys = entries.keySet();
-			for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
-				String key = (String) iter.next();
-				String value = (String) entries.get(key);
-				Manifest.Attribute attr = new Manifest.Attribute(key, value);
-				manifest.addConfiguredAttribute(attr);
-			}
-		}
-
-        // Configure the jar
-        archiver.addConfiguredManifest( manifest );
-
-        archiver.setCompress( archiveConfiguration.isCompress() );
-
-        archiver.setIndex( archiveConfiguration.isIndex() );
-
-        archiver.setDestFile( archiveFile );
-
-        // create archive
-        archiver.createArchive();
-
-        // Cleanup
-
-        pomPropertiesFile.delete();
-    }
-
-    private File writeExportReadyPom( MavenProject project )
-        throws IOException
-    {
-        String buildDirectory = project.getBuild().getDirectory();
-
-        File buildDirectoryFile = new File( buildDirectory );
-
-        buildDirectoryFile.mkdirs();
-
-        File fullPom = new File( buildDirectoryFile, "exported-pom.xml" );
-
-        FileWriter fWriter = null;
-
-        try
-        {
-            fWriter = new FileWriter( fullPom );
-
-            project.writeModel( fWriter );
-        }
-        finally
-        {
-            IOUtil.close( fWriter );
-        }
-
-        return fullPom;
-    }
-}
