Index: src/main/java/org/apache/maven/plugin/dependency/SortMojo.java
===================================================================
--- src/main/java/org/apache/maven/plugin/dependency/SortMojo.java	(revision 0)
+++ src/main/java/org/apache/maven/plugin/dependency/SortMojo.java	(revision 0)
@@ -0,0 +1,462 @@
+package org.apache.maven.plugin.dependency;
+
+/*
+ * 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.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+
+
+/**
+ * This goal sorts dependencies in alphabetical order.  It can also remove
+ * duplicate dependency definitions.
+ * 
+ * @goal sort
+ */
+public class SortMojo
+    extends AbstractMojo
+{
+    // fields -----------------------------------------------------------------
+
+    /**
+     * The current project
+     * 
+     * @parameter expression="${project}"
+     * @required
+     * @readonly
+     */
+    private MavenProject project;
+
+
+    /**
+     * Output file to write the sorted dependencies
+     * @parameter expression="${mdep.sort.outputFile}"
+     */
+    private File outputFile;
+            
+    /**
+     * Flag to use for scriptable output
+     * 
+     * @parameter expression="${mdep.sort.sortDepMng}" default-value="false"
+     */
+    private boolean sortDepMng;
+    
+    /**
+     * Sort the dependencies in ascending or descending alphabetical order.
+     * 
+     * @parameter expression="${mdep.sort.ascending}" default-value="true"
+     */
+    private boolean ascending;
+    
+    /**
+     * Whether to group the dependencies by scope
+     * 
+     * @parameter expression="${mdep.sort.groupByScope}" default-value="false"
+     */
+    private boolean groupByScope;
+    
+    /**
+     * Whether to remove duplicate dependency definitions
+     * 
+     * @parameter expression="${mdep.sort.removeDuplicates}" default-value="true"
+     */
+    private boolean removeDeplicates;
+    
+    
+    // Mojo methods -----------------------------------------------------------
+
+    /*
+     * @see org.apache.maven.plugin.Mojo#execute()
+     */
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        List dependencies = null;
+        if (sortDepMng)
+        {
+            dependencies = project.getDependencyManagement().getDependencies();
+        }
+        else
+        {
+            dependencies = project.getDependencies();
+        }
+        
+        if (this.removeDeplicates)
+        {
+           removeDuplicates(dependencies);
+        }
+        
+        if (groupByScope) 
+        {
+            List [] dependencyLists = groupByScope(dependencies);
+            for ( int i = 0; i < dependencyLists.length; ++i )
+            {
+                this.sortDependencies(dependencyLists[i]);
+            }
+            
+            getLog().info( "Writing sorted dependencies to: " + this.outputFile );
+
+            for ( int i = 0; i < dependencyLists.length; ++i )
+            {
+                this.writeDependencyXML(dependencyLists[i]);
+            }
+
+        }
+        else 
+        {
+            this.sortDependencies(dependencies);
+            getLog().info( "The sorted list of dependencies: " );
+            this.writeDependencyXML(dependencies);
+        }
+        
+    }
+
+    // private methods --------------------------------------------------------
+
+    /**
+     * Sorts dependencies in place.
+     */
+    private void sortDependencies(List dependencies)
+    {        
+        quicksort( dependencies, 0, dependencies.size() - 1 , ascending);
+    }
+    
+    private List [] groupByScope(List dependencies)
+    {
+        List[] dependencyLists = { new ArrayList(), new ArrayList(),
+                new ArrayList(), new ArrayList(), new ArrayList() };
+        Iterator iter = dependencies.iterator();
+        while(iter.hasNext())
+        {
+            Dependency dependency = (Dependency)iter.next();
+            if ( dependency.getScope() == null || dependency.getScope().equals("compile") )
+            {
+                dependencyLists[0].add(dependency);
+            }
+            else if ( dependency.getScope().equals("provided") )
+            {
+                dependencyLists[1].add(dependency);
+            }
+            else if ( dependency.getScope().equals("runtime") )
+            {
+                dependencyLists[2].add(dependency);
+            }
+            else if ( dependency.getScope().equals("test") )
+            {
+                dependencyLists[3].add(dependency);
+            }
+            else if ( dependency.getScope().equals("system") )
+            {
+                dependencyLists[4].add(dependency);
+            }
+        }
+        return dependencyLists;
+    }
+
+    private void removeDuplicates(List dependencies)
+    {
+        int i = 0;
+        while( i < dependencies.size() )
+        {
+            if ( contains( dependencies, (Dependency)dependencies.get(i), i + 1 ) )
+            {
+                dependencies.remove( i );
+            }
+            else 
+            {
+                ++i;
+            }
+        }
+    }
+    
+    private boolean contains(List dependencies, Dependency dependency, int index)
+    {
+        for( int i = index; i < dependencies.size(); ++i)
+        {
+            Dependency dependency2 = (Dependency)dependencies.get(i);
+            if (compare(dependency, dependency2) == 0)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private void swap( List list, int i, int j ) 
+    {
+        Object tmp = list.get(i);
+        list.set(i, list.get(j));
+        list.set(j, tmp);
+    }
+    
+    /**
+     * Quicksort a list of dependencies.
+     * @param list - the list to sort
+     * @param left - left end of the list
+     * @param right - right end of the list
+     * @param ascending - Sort ascending or descending
+     */
+    private void quicksort(List list, int left, int right, boolean ascending) 
+    {
+        int i, last;
+
+        if (left >= right) { // do nothing if array size < 2
+            return;
+        }
+        swap(list, left, (left + right) / 2);
+        last = left;
+        for (i = left + 1; i <= right; i++) 
+        {
+            Dependency dep1 = (Dependency)list.get(i);
+            Dependency dep2 = (Dependency)list.get(left);
+            if (ascending && compare(dep1, dep2) < 0) 
+            {
+                swap(list, ++last, i);
+            } 
+            else if (!ascending && compare(dep1, dep2) > 0) 
+            {
+                swap(list, ++last, i);
+            }
+        }
+        swap(list, left, last);
+        quicksort(list, left, last - 1, ascending);
+        quicksort(list, last + 1, right, ascending);
+    }
+
+
+    /**
+     * Compare two dependencies.  Follows the conventions of java.lang.Comparable.
+     * Two dependencies are considered equal if the groupId, artifactId, version, scope,
+     * and type are all the same.
+     * @param dep1
+     * @param dep2
+     * @return
+     */
+    private int compare(Dependency dep1, Dependency dep2) 
+    {
+        if (dep1.equals(dep2))
+        {
+            return 0;
+        }
+        
+        int result = dep1.getGroupId().compareTo(dep2.getGroupId());
+        
+        if (result != 0) return result;
+
+        result = dep1.getArtifactId().compareTo(dep2.getArtifactId());
+
+        if (result != 0) return result;
+        
+        if (dep1.getVersion() == null) 
+        {
+            if (dep2.getVersion() == null) 
+            {
+                result = 0;
+            }
+            else
+            {
+                result = -1;
+            }
+        }
+        else
+        {
+            if (dep2.getVersion() == null)
+            {
+                result = 1;
+            }
+            else 
+            {
+                result = dep1.getVersion().compareTo(dep2.getVersion());
+            }
+        }
+
+        if (result != 0) return result;
+        
+        if (dep1.getScope() == null) 
+        {
+            if (dep2.getScope() == null) 
+            {
+                result = 0;
+            }
+            else
+            {
+                result = -1;
+            }
+        }
+        else
+        {
+            result = dep1.getScope().compareTo(dep2.getScope());
+        }
+        
+        if (result != 0) return result;
+
+        if (dep1.getClassifier() == null) 
+        {
+            if (dep2.getClassifier() == null) 
+            {
+                result = 0;
+            }
+            else
+            {
+                result = -1;
+            }
+        }
+        else
+        {
+            if (dep2.getClassifier() == null) 
+            {
+                result = 1;
+            }
+            else
+            {
+                result = dep1.getClassifier().compareTo(dep2.getClassifier());
+            }
+        }
+            
+        if (result != 0) return result;
+        
+        if (dep1.getType() == null) {
+            if (dep2.getType() == null) 
+            {
+                result = 0;
+            }
+            else
+            {
+                result = -1;
+            }
+        }
+        else
+        {
+            if (dep2.getType() == null)
+            {
+                result = 1;
+            }
+            else
+            {
+                result = dep1.getType().compareTo(dep2.getType());
+            }
+        }
+        
+        return result;
+    }
+    
+    private void writeDependencyXML( List dependencies )
+    {
+        if ( !dependencies.isEmpty() )
+        {
+            StringWriter out = new StringWriter();
+            PrettyPrintXMLWriter writer = new PrettyPrintXMLWriter( out );
+
+            Iterator iter = dependencies.iterator();
+            while ( iter.hasNext() )
+            {
+                Dependency dependency = (Dependency) iter.next();
+
+                writer.startElement( "dependency" );
+                writer.startElement( "groupId" );
+                writer.writeText( dependency.getGroupId() );
+                writer.endElement();
+                writer.startElement( "artifactId" );
+                writer.writeText( dependency.getArtifactId() );
+                writer.endElement();
+                writer.startElement( "version" );
+                writer.writeText( dependency.getVersion());
+                writer.endElement();
+
+                if ( dependency.getScope() != null )
+                {
+                    writer.startElement( "scope" );
+                    writer.writeText( dependency.getScope() );
+                    writer.endElement();
+                }
+                
+                if ( dependency.getClassifier() != null )
+                {
+                    writer.startElement( "classifier" );
+                    writer.writeText( dependency.getClassifier() );
+                    writer.endElement();
+                }
+                
+                if ( dependency.getType() != null && (! dependency.getType().equals("jar")))
+                {
+                    writer.startElement( "type" );
+                    writer.writeText( dependency.getType() );
+                    writer.endElement();
+                }
+                
+                List exclusions = dependency.getExclusions();
+                if ( exclusions != null && (exclusions.size() > 0) )
+                {
+                    writer.startElement( "exclusions" );
+                    Iterator exclIter = exclusions.iterator();
+                    while(exclIter.hasNext())
+                    {
+                        Exclusion exclusion = (Exclusion)exclIter.next();
+                        writer.startElement( "exclusion" );
+                        writer.startElement("groupId");
+                        writer.writeText( exclusion.getGroupId() );
+                        writer.endElement();
+                        writer.startElement("artifactId");
+                        writer.writeText( exclusion.getArtifactId() );
+                        writer.endElement();
+                        writer.endElement();
+                    }
+                    writer.endElement();
+                }
+                writer.endElement();
+                
+            }
+
+            if ( this.outputFile == null )
+            {
+                getLog().info( "\n" + out.getBuffer() );
+            }
+            else 
+            {
+                if ( ! outputFile.getParentFile().exists() )
+                {
+                    outputFile.getParentFile().mkdirs();
+                }
+                try 
+                {
+                    FileWriter fos = new FileWriter( this.outputFile );
+                    fos.write( "\n" + out.getBuffer() );
+                }
+                catch ( IOException ioe )
+                {
+                    getLog().error( ioe );
+                }
+            }
+        }
+    }
+    
+}

Property changes on: src/main/java/org/apache/maven/plugin/dependency/SortMojo.java
___________________________________________________________________
Name: svn:executable
   + *


