Utility code to sort lists with versions
Support for Error.TWO_VERSIONS in analyze
diff --git a/data/expected/repo1-analysis-19700101-000000.html b/data/expected/repo1-analysis-19700101-000000.html
index 9d9dd24..fee3d23 100644
--- a/data/expected/repo1-analysis-19700101-000000.html
+++ b/data/expected/repo1-analysis-19700101-000000.html
@@ -20,7 +20,7 @@
   <body>
     <h1>Analysis of ${repo} (1970.01.01 00:00:00)</h1>
     <p>Found 6 POM files</p>
-    <p>Found 25 problems</p>
+    <p>Found 26 problems</p>
     <h2>Table of Contents</h2>
     <ul class='toc'>
       <li>
@@ -48,10 +48,13 @@
         <a href='#toc8'>Path Problems (1)</a>
       </li>
       <li>
-        <a href='#toc9'>Multiple Nested JARs (1)</a>
+        <a href='#toc9'>Artifacts With Several Versions (1)</a>
       </li>
       <li>
-        <a href='#toc10'>Missing Sources (3)</a>
+        <a href='#toc10'>Multiple Nested JARs (1)</a>
+      </li>
+      <li>
+        <a href='#toc11'>Missing Sources (3)</a>
       </li>
       <li>
         <a href='#poms'>6 POMs in the repository</a>
@@ -310,13 +313,19 @@
       <span class='file'>${repo}/junit/test/different-version/1.0/different-version-1.0.pom</span> but was 
       <span class='file'>${repo}/junit/test/different-versions/1.0/different-versions-1.0.pom</span>
     </div>
-    <h2 id='toc9'>Multiple Nested JARs</h2>
+    <h2 id='toc9'>Artifacts With Several Versions</h2>
+    <p>1 time</p>
+    <div class='problem'>
+      <div class='ignoreKey'>TwoVersionsProblem E0001 org.eclipse.orbit:orbit.org.apache.lucene 1.9.1 2.9.1</div>
+      <span class='message'>The artifact org.eclipse.orbit:orbit.org.apache.lucene exists with several versions: 1.9.1 2.9.1</span>
+    </div>
+    <h2 id='toc10'>Multiple Nested JARs</h2>
     <p>1 time</p>
     <div class='problem'>
       <div class='ignoreKey'>MultipleNestedJarsProblem W0004 org/eclipse/birt/org.eclipse.birt.report.data.oda.jdbc.dbprofile/3.7.0.v20110603/org.eclipse.birt.report.data.oda.jdbc.dbprofile-3.7.0.v20110603.jar .,src</div>
       <span class='message'>Found multiple nested JARs in .../m2repo/org/eclipse/birt/org.eclipse.birt.report.data.oda.jdbc.dbprofile/3.7.0.v20110603/org.eclipse.birt.report.data.oda.jdbc.dbprofile-3.7.0.v20110603.jar</span>
     </div>
-    <h2 id='toc10'>Missing Sources</h2>
+    <h2 id='toc11'>Missing Sources</h2>
     <p>3 times</p>
     <div class='problem'>
       <p>Missing sources for 3 artifacts</p>
diff --git a/data/input/repo1/.mt4e/logs/dependencyManagement.xml b/data/input/repo1/.mt4e/logs/dependencyManagement.xml
new file mode 100644
index 0000000..5bfe22f
--- /dev/null
+++ b/data/input/repo1/.mt4e/logs/dependencyManagement.xml
@@ -0,0 +1,3 @@
+<mt4e-log command='dependencyManagement'>
+<error code='E0001' artifact='org.eclipse.orbit:orbit.org.apache.lucene:1.9.1' shortKey='org.eclipse.orbit:orbit.org.apache.lucene' version1='1.9.1' version2='2.9.1'>The repository contains (at least) two versions of org.eclipse.orbit:orbit.org.apache.lucene: 1.9.1 and 2.9.1. Omitting both.</error>
+</mt4e-log>
\ No newline at end of file
diff --git a/src/main/groovy/m4e/AnalyzeCmd.groovy b/src/main/groovy/m4e/AnalyzeCmd.groovy
index dbfebc5..38987db 100644
--- a/src/main/groovy/m4e/AnalyzeCmd.groovy
+++ b/src/main/groovy/m4e/AnalyzeCmd.groovy
@@ -193,6 +193,10 @@
         def problem
         
         switch( e ) {
+        case Error.TWO_VERSIONS:
+            problem = TwoVersionsProblem.create( node )
+            break
+            
         case Error.MISSING_MANIFEST:
             problem = MissingManifest.create( node )
             break
@@ -708,6 +712,23 @@
     }
 }
 
+class TwoVersionsProblem extends CommandProblem {
+    
+    static TwoVersionsProblem create( node ) {
+        
+        String shortKey = node.'@shortKey'
+        String version1 = node.'@version1'
+        String version2 = node.'@version2'
+        String key = "${node.'@code'} ${shortKey} ${version1} ${version2}"
+        
+        String message = "The artifact ${shortKey} exists with several versions: ${version1} ${version2}"
+        
+        def result = new TwoVersionsProblem( key: key, message: message )
+        
+        return result
+    }
+}
+
 class MissingManifest extends CommandProblem {
     
     String jar
@@ -1114,6 +1135,7 @@
     ProblemVersionRange( 'Dependencies With Version Ranges', 'Dependencies should not use version ranges.' ),
     ProblemSnaphotVersion( 'Snapshot Versions', 'Release Repositories should not contain SNAPSHOTs' ),
     PathProblem( 'Path Problems', 'These POMs are not where they should be' ),
+    TwoVersionsProblem( 'Artifacts With Several Versions' ),
     MultipleNestedJarsProblem( 'Multiple Nested JARs' ),
     MissingSources( 'Missing Sources' )
     
diff --git a/src/main/groovy/m4e/DependencyManagementCmd.groovy b/src/main/groovy/m4e/DependencyManagementCmd.groovy
index 16fc992..660224c 100644
--- a/src/main/groovy/m4e/DependencyManagementCmd.groovy
+++ b/src/main/groovy/m4e/DependencyManagementCmd.groovy
@@ -13,6 +13,7 @@
 import groovy.xml.MarkupBuilder;
 import java.io.File;
 import java.text.SimpleDateFormat;
+import m4e.maven.VersionUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -38,6 +39,8 @@
         if( !repo.exists() ) {
             throw new UserError( "Directory ${repo} doesn't exist" )
         }
+        
+        prepareErrorLog( repo, 'dependencyManagement' )
 
         if( args.size() <= 2 ) {
             throw new UserError( 'Missing groupId:artifactId:version of the POM to create' )
@@ -91,13 +94,16 @@
     }
 
     void twoVersionsError( Pom pom, String oldVersion ) {
+        
+        def versions = VersionUtils.sort( [ pom.version(), oldVersion ] )
+        
         def xml = [
             artifact: pom.key(),
             shortKey: pom.shortKey(),
-            version1: pom.version(),
-            version2: oldVersion,
+            version1: versions[0],
+            version2: versions[1],
         ]
-        error( Error.TWO_VERSIONS, "The repository contains (at least) two versions of ${pom.shortKey()}: ${pom.version()} and ${oldVersion}. Omitting both.", xml )
+        error( Error.TWO_VERSIONS, "The repository contains (at least) two versions of ${pom.shortKey()}: ${versions[0]} and ${versions[1]}. Omitting both.", xml )
     }
 
     void createPom() {
diff --git a/src/main/groovy/m4e/maven/VersionUtils.groovy b/src/main/groovy/m4e/maven/VersionUtils.groovy
new file mode 100644
index 0000000..2e83db7
--- /dev/null
+++ b/src/main/groovy/m4e/maven/VersionUtils.groovy
@@ -0,0 +1,14 @@
+package m4e.maven
+
+class VersionUtils {
+
+    static List sort( List versions ) {
+        return versions.sort { a, b -> compare( a, b ) }
+    }
+    
+    static int compare( String version1, String version2 ) {
+        [ version1, version2 ]*.tokenize('.')*.collect { it.isInteger() ? new Integer( it ) : it }.with { u, v ->
+            [ u,v ].transpose().findResult{ x,y-> x<=>y ?: null } ?: u.size() <=> v.size()
+        }
+    }
+}
diff --git a/src/test/groovy/m4e/maven/VersionUtilsTest.groovy b/src/test/groovy/m4e/maven/VersionUtilsTest.groovy
new file mode 100644
index 0000000..11ab19f
--- /dev/null
+++ b/src/test/groovy/m4e/maven/VersionUtilsTest.groovy
@@ -0,0 +1,39 @@
+package m4e.maven;
+
+import static org.junit.Assert.*;
+import org.junit.Test;
+
+class VersionUtilsTest {
+
+    @Test
+    public void testSort() throws Exception {
+        def l = [ '1.0', '10.0' ]
+        l.permutations().each {
+            assert '[1.0, 10.0]' == VersionUtils.sort( it ).toString()
+        }
+    }
+    
+    @Test
+    public void testSort_2() throws Exception {
+        def l = [ '1.10', '10.0' ]
+        l.permutations().each {
+            assert '[1.10, 10.0]' == VersionUtils.sort( it ).toString()
+        }
+    }
+    
+    @Test
+    public void testSort_3() throws Exception {
+        def l = [ '2.0', '1.5', '1.10', '10.0', '1.17.1' ]
+        l.permutations().each {
+            assert '[1.5, 1.10, 1.17.1, 2.0, 10.0]' == VersionUtils.sort( it ).toString()
+        }
+    }
+    
+    @Test
+    public void testSort_4() throws Exception {
+        def l = [ '1.a2', '1.b1', '1.a10' ]
+        l.permutations().each {
+            assert '[1.a10, 1.a2, 1.b1]' == VersionUtils.sort( it ).toString()
+        }
+    }
+}