[MSHARED-811] Improve handling of Metadata
diff --git a/src/it/maven-artifact-deployer-plugin/src/main/java/org/apache/maven/plugin/artifact/deployer/ArtifactDeployerMojo.java b/src/it/maven-artifact-deployer-plugin/src/main/java/org/apache/maven/plugin/artifact/deployer/ArtifactDeployerMojo.java
index 039f6f8..2e40e67 100644
--- a/src/it/maven-artifact-deployer-plugin/src/main/java/org/apache/maven/plugin/artifact/deployer/ArtifactDeployerMojo.java
+++ b/src/it/maven-artifact-deployer-plugin/src/main/java/org/apache/maven/plugin/artifact/deployer/ArtifactDeployerMojo.java
@@ -21,6 +21,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.channels.UnsupportedAddressTypeException;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -31,6 +32,9 @@
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.metadata.AbstractArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataStoreException;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -42,6 +46,7 @@
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployer;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
+import org.apache.maven.shared.transfer.metadata.ArtifactMetadata;
 import org.apache.maven.shared.transfer.repository.RepositoryManager;
 
 /**
@@ -113,6 +118,15 @@
             artifactWithClassifier.setRepository( session.getProjectBuildingRequest().getLocalRepository() );
 
             Collection<Artifact> mavenArtifacts = Arrays.<Artifact>asList( artifact, artifactWithClassifier );
+            
+            for ( Artifact a : mavenArtifacts )
+            {
+                File camVfile = File.createTempFile( "test-deploy", ".camV", artifactsDirectory );
+                a.addMetadata( new CustomArtifactMetadata( a, camVfile, true ) );
+                
+                File camGfile = File.createTempFile( "test-deploy", ".camG", artifactsDirectory );
+                a.addMetadata( new CustomArtifactMetadata( a, camGfile, false ) );
+            }
 
             deployer.deploy( session.getProjectBuildingRequest(), mavenArtifacts );
         }
@@ -126,4 +140,77 @@
         }
     }
 
+    private class CustomArtifactMetadata extends AbstractArtifactMetadata implements ArtifactMetadata
+    {
+        private final File file;
+
+        private final boolean storedInArtifactVersionDirectory;
+        
+        protected CustomArtifactMetadata( Artifact artifact, File file, boolean storedInArtifactVersionDirectory ) 
+        {
+            super( artifact );   
+            this.file = file;
+            this.storedInArtifactVersionDirectory = storedInArtifactVersionDirectory;
+        }
+        
+        @Override
+        public File getFile() 
+        {
+            return file;
+        }
+        
+        @Override
+        public String getRemoteFilename()
+        {
+            return artifact.getArtifactId() + '-' + artifact.getVersion() + getDotExtension();
+        }
+        
+        @Override
+        public String getLocalFilename( ArtifactRepository repository )
+        {
+            return artifact.getArtifactId() + '-' + artifact.getVersion() + getDotExtension();
+        }
+        
+        @Override
+        public void storeInLocalRepository( ArtifactRepository localRepository, ArtifactRepository remoteRepository )
+            throws RepositoryMetadataStoreException
+        {
+            throw new UnsupportedOperationException("ArtifactDeployerMojo.CustomArtifactMetadata.storeInLocalRepository(ArtifactRepository, ArtifactRepository)");   
+        }
+        
+        @Override
+        public boolean storedInArtifactVersionDirectory()
+        {
+            return storedInArtifactVersionDirectory;
+        }
+        
+        @Override
+        public void merge( org.apache.maven.artifact.metadata.ArtifactMetadata metadata )
+        {
+            throw new UnsupportedOperationException("ArtifactDeployerMojo.CustomArtifactMetadata.merge(ArtifactMetadata)");
+        }
+
+        @Override
+        public void merge( org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata )
+        {
+            throw new UnsupportedOperationException("ArtifactDeployerMojo.CustomArtifactMetadata.merge(ArtifactMetadata)");
+        }
+        
+        @Override
+        public String getBaseVersion()
+        {
+            return artifact.getBaseVersion();
+        }
+
+        @Override
+        public Object getKey()
+        {
+            return artifact.getId() + getDotExtension();
+        }
+        
+        private String getDotExtension() 
+        {
+            return file.getName().substring( file.getName().lastIndexOf( '.' ) );
+        }
+    }
 }
diff --git a/src/it/maven-artifact-deployer-plugin/src/test/java/org/apache/maven/plugin/artifact/deployer/ArtifactDeployerTest.java b/src/it/maven-artifact-deployer-plugin/src/test/java/org/apache/maven/plugin/artifact/deployer/ArtifactDeployerTest.java
index 6fcb201..6a9ebd0 100644
--- a/src/it/maven-artifact-deployer-plugin/src/test/java/org/apache/maven/plugin/artifact/deployer/ArtifactDeployerTest.java
+++ b/src/it/maven-artifact-deployer-plugin/src/test/java/org/apache/maven/plugin/artifact/deployer/ArtifactDeployerTest.java
@@ -70,6 +70,7 @@
                 .withCliOption( "-DmvnVersion=" + mavenRuntime.getMavenVersion() ) // Might be superfluous
                 .withCliOption( "-B" )
                 .withCliOption( "-V" )
+                .withCliOption( "-e" )
                 .execute( "clean", "verify" );
         //@formatter:on
 
@@ -92,6 +93,8 @@
         File baseDirectoy = new File( localRepo, "ARTIFACT-DEPLOYER-GROUPID-" + mvnVersion + "/ARTIFACTID/VERSION/" );
 
         checkForArtifactFile( baseDirectoy );
+        checkForArtifactGroupMetaFile( baseDirectoy );
+        checkForArtifactVersionMetaFile( baseDirectoy );
         checkForArtifactClassifierFile( baseDirectoy );
 
         assertTrue( new File( localRepo, "ARTIFACT-DEPLOYER-GROUPID-" + mvnVersion
@@ -117,4 +120,22 @@
         assertTrue( "artifactFile md5 not found.", new File( artifactFile.getAbsolutePath() + ".md5" ).exists() );
         assertTrue( "artifactFile sha1 not found.", new File( artifactFile.getAbsolutePath() + ".sha1" ).exists() );
     }
+    
+    private void checkForArtifactGroupMetaFile( File baseDirectoy )
+    {
+        File localFile = new File( baseDirectoy.getParentFile(), "ARTIFACTID-VERSION-local.camG" );
+        File baseFile = new File( baseDirectoy.getParentFile(), "ARTIFACTID-VERSION.camG" );
+        assertTrue( "localFile '" + localFile.getAbsolutePath() + "'", localFile.exists() );
+        assertTrue( "artifactFile md5 not found.", new File( baseFile.getAbsolutePath() + ".md5" ).exists() );
+        assertTrue( "artifactFile sha1 not found.", new File( baseFile.getAbsolutePath() + ".sha1" ).exists() );
+    }
+    
+    private void checkForArtifactVersionMetaFile( File baseDirectoy )
+    {
+        File localFile = new File( baseDirectoy, "ARTIFACTID-VERSION-local.camV" );
+        File baseFile = new File( baseDirectoy, "ARTIFACTID-VERSION.camV" );
+        assertTrue( "localFile '" + localFile.getAbsolutePath() + "'", localFile.exists() );
+        assertTrue( "artifactFile md5 not found.", new File( baseFile.getAbsolutePath() + ".md5" ).exists() );
+        assertTrue( "artifactFile sha1 not found.", new File( baseFile.getAbsolutePath() + ".sha1" ).exists() );
+    }
 }
\ No newline at end of file
diff --git a/src/it/maven-artifact-installer-plugin/src/main/java/org/apache/maven/plugin/artifact/installer/ArtifactInstallerMojo.java b/src/it/maven-artifact-installer-plugin/src/main/java/org/apache/maven/plugin/artifact/installer/ArtifactInstallerMojo.java
index 2a0bf73..f9f1496 100644
--- a/src/it/maven-artifact-installer-plugin/src/main/java/org/apache/maven/plugin/artifact/installer/ArtifactInstallerMojo.java
+++ b/src/it/maven-artifact-installer-plugin/src/main/java/org/apache/maven/plugin/artifact/installer/ArtifactInstallerMojo.java
@@ -31,6 +31,9 @@
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.metadata.AbstractArtifactMetadata;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadataStoreException;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -42,6 +45,7 @@
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstaller;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.transfer.metadata.ArtifactMetadata;
 import org.apache.maven.shared.transfer.repository.RepositoryManager;
 
 /**
@@ -111,6 +115,15 @@
             artifactWithClassifier.setFile( tmpFileClassifier );
 
             Collection<Artifact> mavenArtifacts = Arrays.<Artifact>asList( artifact, artifactWithClassifier );
+            
+            for ( Artifact a : mavenArtifacts )
+            {
+                File camVfile = File.createTempFile( "test-install", ".camV", artifactsDirectory );
+                a.addMetadata( new CustomArtifactMetadata( a, camVfile, true ) );
+                
+                File camGfile = File.createTempFile( "test-install", ".camG", artifactsDirectory );
+                a.addMetadata( new CustomArtifactMetadata( a, camGfile, false ) );
+            }
 
             installer.install( session.getProjectBuildingRequest(), mavenArtifacts );
         }
@@ -125,4 +138,77 @@
 
     }
 
+    private class CustomArtifactMetadata extends AbstractArtifactMetadata implements ArtifactMetadata
+    {
+        private final File file;
+
+        private final boolean storedInArtifactVersionDirectory;
+        
+        protected CustomArtifactMetadata( Artifact artifact, File file, boolean storedInArtifactVersionDirectory ) 
+        {
+            super( artifact );   
+            this.file = file;
+            this.storedInArtifactVersionDirectory = storedInArtifactVersionDirectory;
+        }
+        
+        @Override
+        public File getFile() 
+        {
+            return file;
+        }
+        
+        @Override
+        public String getRemoteFilename()
+        {
+            return artifact.getArtifactId() + '-' + artifact.getVersion() + getDotExtension();
+        }
+        
+        @Override
+        public String getLocalFilename( ArtifactRepository repository )
+        {
+            return artifact.getArtifactId() + '-' + artifact.getVersion() + getDotExtension();
+        }
+        
+        @Override
+        public void storeInLocalRepository( ArtifactRepository localRepository, ArtifactRepository remoteRepository )
+            throws RepositoryMetadataStoreException
+        {
+            throw new UnsupportedOperationException("ArtifactDeployerMojo.CustomArtifactMetadata.storeInLocalRepository(ArtifactRepository, ArtifactRepository)");   
+        }
+        
+        @Override
+        public boolean storedInArtifactVersionDirectory()
+        {
+            return storedInArtifactVersionDirectory;
+        }
+        
+        @Override
+        public void merge( org.apache.maven.artifact.metadata.ArtifactMetadata metadata )
+        {
+            throw new UnsupportedOperationException("ArtifactDeployerMojo.CustomArtifactMetadata.merge(ArtifactMetadata)");
+        }
+
+        @Override
+        public void merge( org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata )
+        {
+            throw new UnsupportedOperationException("ArtifactDeployerMojo.CustomArtifactMetadata.merge(ArtifactMetadata)");
+        }
+        
+        @Override
+        public String getBaseVersion()
+        {
+            return artifact.getBaseVersion();
+        }
+
+        @Override
+        public Object getKey()
+        {
+            return artifact.getId() + getDotExtension();
+        }
+        
+        private String getDotExtension() 
+        {
+            return file.getName().substring( file.getName().lastIndexOf( '.' ) );
+        }
+    }
 }
diff --git a/src/it/maven-artifact-installer-plugin/src/test/java/org/apache/maven/plugin/artifact/installer/ArtifactInstallerTest.java b/src/it/maven-artifact-installer-plugin/src/test/java/org/apache/maven/plugin/artifact/installer/ArtifactInstallerTest.java
index a48c51c..7d6a0c3 100644
--- a/src/it/maven-artifact-installer-plugin/src/test/java/org/apache/maven/plugin/artifact/installer/ArtifactInstallerTest.java
+++ b/src/it/maven-artifact-installer-plugin/src/test/java/org/apache/maven/plugin/artifact/installer/ArtifactInstallerTest.java
@@ -95,6 +95,8 @@
         // We don't have a pom file.
         checkForNonExistingPomFile( baseDirectoy );
         checkForArtifact( baseDirectoy );
+        checkForArtifactGroupMetaFile( baseDirectoy );
+        checkForArtifactVersionMetaFile( baseDirectoy );
         checkForArtifactClassifier( baseDirectoy );
     }
 
@@ -116,6 +118,20 @@
         assertFalse( "artifactFile md5 not found.", new File( artifactFile.getAbsolutePath() + ".md5" ).exists() );
         assertFalse( "artifactFile sha1 not found.", new File( artifactFile.getAbsolutePath() + ".sha1" ).exists() );
     }
+    
+    private void checkForArtifactGroupMetaFile( File baseDirectoy )
+    {
+        File localFile = new File( baseDirectoy.getParentFile(), "ARTIFACTID-VERSION-local.camG" );
+        File baseFile = new File( baseDirectoy.getParentFile(), "ARTIFACTID-VERSION.camG" );
+        assertTrue( "localFile '" + localFile.getAbsolutePath() + "'", localFile.exists() );
+    }
+    
+    private void checkForArtifactVersionMetaFile( File baseDirectoy )
+    {
+        File localFile = new File( baseDirectoy, "ARTIFACTID-VERSION-local.camV" );
+        File baseFile = new File( baseDirectoy, "ARTIFACTID-VERSION.camV" );
+        assertTrue( "localFile '" + localFile.getAbsolutePath() + "'", localFile.exists() );
+    }
 
     private void checkForNonExistingPomFile( File baseDirectoy )
     {
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven30ArtifactDeployer.java b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven30ArtifactDeployer.java
index 64d9249..83cc6a2 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven30ArtifactDeployer.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven30ArtifactDeployer.java
@@ -29,6 +29,7 @@
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployer;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
+import org.apache.maven.shared.transfer.metadata.internal.Maven30MetadataBridge;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.sonatype.aether.RepositorySystem;
@@ -109,9 +110,12 @@
                 {
                     // eaten, handled by repo system
                 }
-                else
+                else if ( metadata instanceof org.apache.maven.shared.transfer.metadata.ArtifactMetadata )
                 {
-                    // request.addMetadata( new MetadataBridge( metadata ) );
+                    org.apache.maven.shared.transfer.metadata.ArtifactMetadata transferMedata =
+                                    ( org.apache.maven.shared.transfer.metadata.ArtifactMetadata ) metadata;
+                    
+                    request.addMetadata( new Maven30MetadataBridge( metadata ).setFile( transferMedata.getFile() ) );
                 }
             }
         }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven31ArtifactDeployer.java b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven31ArtifactDeployer.java
index 82dbf8f..71594de 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven31ArtifactDeployer.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven31ArtifactDeployer.java
@@ -29,6 +29,7 @@
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployer;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
+import org.apache.maven.shared.transfer.metadata.internal.Maven31MetadataBridge;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.eclipse.aether.RepositorySystem;
@@ -109,9 +110,12 @@
                 {
                     // eaten, handled by repo system
                 }
-                else
+                else if ( metadata instanceof org.apache.maven.shared.transfer.metadata.ArtifactMetadata )
                 {
-                    // request.addMetadata( new MetadataBridge( metadata ) );
+                    org.apache.maven.shared.transfer.metadata.ArtifactMetadata transferMetadata = 
+                                    (org.apache.maven.shared.transfer.metadata.ArtifactMetadata) metadata;
+                    
+                    request.addMetadata( new Maven31MetadataBridge( metadata ).setFile( transferMetadata.getFile() ) );
                 }
             }
         }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstaller.java b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstaller.java
index 013568c..260beec 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstaller.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstaller.java
@@ -29,6 +29,7 @@
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstaller;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.transfer.metadata.internal.Maven30MetadataBridge;
 import org.apache.maven.shared.transfer.repository.RepositoryManager;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
@@ -89,9 +90,12 @@
                 {
                     // eaten, handled by repo system
                 }
-                else
+                else if ( metadata instanceof org.apache.maven.shared.transfer.metadata.ArtifactMetadata )
                 {
-                    // request.addMetadata( new MetadataBridge( metadata ) );
+                    org.apache.maven.shared.transfer.metadata.ArtifactMetadata transferMedata =
+                                    ( org.apache.maven.shared.transfer.metadata.ArtifactMetadata ) metadata;
+                    
+                    request.addMetadata( new Maven30MetadataBridge( metadata ).setFile( transferMedata.getFile() ) );
                 }
             }
         }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven31ArtifactInstaller.java b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven31ArtifactInstaller.java
index 236c0cf..d922b97 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven31ArtifactInstaller.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven31ArtifactInstaller.java
@@ -29,6 +29,7 @@
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstaller;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.transfer.metadata.internal.Maven31MetadataBridge;
 import org.apache.maven.shared.transfer.repository.RepositoryManager;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
@@ -89,9 +90,12 @@
                 {
                     // eaten, handled by repo system
                 }
-                else
+                else if ( metadata instanceof org.apache.maven.shared.transfer.metadata.ArtifactMetadata )
                 {
-                    // request.addMetadata( new MetadataBridge( metadata ) );
+                    org.apache.maven.shared.transfer.metadata.ArtifactMetadata transferMetadata = 
+                                    (org.apache.maven.shared.transfer.metadata.ArtifactMetadata) metadata;
+                    
+                    request.addMetadata( new Maven31MetadataBridge( metadata ).setFile( transferMetadata.getFile() ) );
                 }
             }
         }
diff --git a/src/main/java/org/apache/maven/shared/transfer/metadata/ArtifactMetadata.java b/src/main/java/org/apache/maven/shared/transfer/metadata/ArtifactMetadata.java
new file mode 100644
index 0000000..e77d6fd
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/transfer/metadata/ArtifactMetadata.java
@@ -0,0 +1,33 @@
+package org.apache.maven.shared.transfer.metadata;
+
+/*
+ * 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;
+
+/**
+ * Original ArtifactMetada with File reference
+ * 
+ * @author Robert Scholte
+ *
+ */
+public interface ArtifactMetadata extends org.apache.maven.repository.legacy.metadata.ArtifactMetadata
+{
+    File getFile();
+}
diff --git a/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven30MetadataBridge.java b/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven30MetadataBridge.java
new file mode 100644
index 0000000..fde00a8
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven30MetadataBridge.java
@@ -0,0 +1,107 @@
+package org.apache.maven.shared.transfer.metadata.internal;
+
+/*
+ * 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 org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
+import org.sonatype.aether.metadata.Metadata;
+
+/**
+ * A MetadataBridge for Maven 3.0
+ * 
+ * @author Robert Scholte
+ *
+ */
+public class Maven30MetadataBridge implements Metadata
+{
+    private ArtifactMetadata metadata;
+    
+    private File file;
+
+    public Maven30MetadataBridge( ArtifactMetadata metadata )
+    {
+        this.metadata = metadata;
+    }
+
+    @Override
+    public String getGroupId()
+    {
+        return emptify( metadata.getGroupId() );
+    }
+
+    @Override
+    public String getArtifactId()
+    {
+        return metadata.storedInGroupDirectory() ? "" : emptify( metadata.getArtifactId() );
+    }
+
+    @Override
+    public String getVersion()
+    {
+        return metadata.storedInArtifactVersionDirectory() ? emptify( metadata.getBaseVersion() ) : "";
+    }
+
+    @Override
+    public String getType()
+    {
+        return metadata.getRemoteFilename();
+    }
+
+    private String emptify( String string )
+    {
+        return ( string != null ) ? string : "";
+    }
+
+    @Override
+    public File getFile()
+    {
+        return file;
+    }
+    
+    @Override
+    public Maven30MetadataBridge setFile( File file )
+    {
+        this.file = file;
+        return this;
+    }
+
+    @Override
+    public Nature getNature()
+    {
+        if ( metadata instanceof RepositoryMetadata )
+        {
+            switch ( ( (RepositoryMetadata) metadata ).getNature() )
+            {
+                case RepositoryMetadata.RELEASE_OR_SNAPSHOT:
+                    return Nature.RELEASE_OR_SNAPSHOT;
+                case RepositoryMetadata.SNAPSHOT:
+                    return Nature.SNAPSHOT;
+                default:
+                    return Nature.RELEASE;
+            }
+        }
+        else
+        {
+            return Nature.RELEASE;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven31MetadataBridge.java b/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven31MetadataBridge.java
new file mode 100644
index 0000000..b33d96e
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven31MetadataBridge.java
@@ -0,0 +1,106 @@
+package org.apache.maven.shared.transfer.metadata.internal;
+
+/*
+ * 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.util.Map;
+
+import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
+import org.eclipse.aether.metadata.AbstractMetadata;
+import org.eclipse.aether.metadata.Metadata;
+
+/**
+ * A MetadataBridge for Maven 3.1 
+ * @author Robert Scholte
+ */
+public class Maven31MetadataBridge extends AbstractMetadata implements Metadata
+{
+    private ArtifactMetadata metadata;
+    
+    private File file;
+    
+    public Maven31MetadataBridge( ArtifactMetadata metadata )
+    {
+        this.metadata = metadata;
+    }
+
+    @Override
+    public String getGroupId()
+    {
+        return emptify( metadata.getGroupId() );
+    }
+
+    @Override
+    public String getArtifactId()
+    {
+        return metadata.storedInGroupDirectory() ? "" : emptify( metadata.getArtifactId() );
+    }
+
+    @Override
+    public String getVersion()
+    {
+        return metadata.storedInArtifactVersionDirectory() ? emptify( metadata.getBaseVersion() ) : "";
+    }
+
+    @Override
+    public String getType()
+    {
+        return metadata.getRemoteFilename();
+    }
+
+    private String emptify( String string )
+    {
+        return ( string != null ) ? string : "";
+    }
+
+    @Override
+    public File getFile()
+    {
+        return file;
+    }
+    
+    @Override
+    public Nature getNature()
+    {
+        if ( metadata instanceof RepositoryMetadata )
+        {
+            switch ( ( (RepositoryMetadata) metadata ).getNature() )
+            {
+                case RepositoryMetadata.RELEASE_OR_SNAPSHOT:
+                    return Nature.RELEASE_OR_SNAPSHOT;
+                case RepositoryMetadata.SNAPSHOT:
+                    return Nature.SNAPSHOT;
+                default:
+                    return Nature.RELEASE;
+            }
+        }
+        else
+        {
+            return Nature.RELEASE;
+        }
+    }
+
+    @Override
+    public Map<String, String> getProperties()
+    {
+        return copyProperties( null );
+    }
+}