[WAGON-569] Inconsistent encoding behavior for repository URLs with spaces
diff --git a/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java b/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java
index 9d3630b..09ff0ef 100755
--- a/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java
+++ b/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/AbstractHttpClientWagon.java
@@ -665,9 +665,19 @@
      */
     private String buildUrl( Resource resource )
     {
-        return EncodingUtil.encodeURLToString( getRepository().getUrl(), resource.getName() );
+        return buildUrl( resource.getName() );
     }
 
+    /**
+     * Builds a complete URL string from the repository URL and the relative path of the resource passed.
+     *
+     * @param resourceName the resourcerelative path
+     * @return the complete URL
+     */
+    private String buildUrl( String resourceName )
+    {
+        return EncodingUtil.encodeURLToString( getRepository().getUrl(), resourceName );
+    }
 
     private void put( Resource resource, File source, HttpEntity httpEntity, String url )
         throws TransferFailedException, AuthorizationException, ResourceDoesNotExistException
@@ -804,8 +814,7 @@
     private boolean resourceExists( int wait, String resourceName )
         throws TransferFailedException, AuthorizationException
     {
-        String repositoryUrl = getRepository().getUrl();
-        String url = repositoryUrl + ( repositoryUrl.endsWith( "/" ) ? "" : "/" ) + resourceName;
+        String url = buildUrl( resourceName );
         HttpHead headMethod = new HttpHead( url );
         try
         {
@@ -1082,8 +1091,7 @@
     {
         Resource resource = inputData.getResource();
 
-        String repositoryUrl = getRepository().getUrl();
-        String url = repositoryUrl + ( repositoryUrl.endsWith( "/" ) ? "" : "/" ) + resource.getName();
+        String url = buildUrl( resource );
         HttpGet getMethod = new HttpGet( url );
         long timestamp = resource.getLastModified();
         if ( timestamp > 0 )
diff --git a/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/EncodingUtil.java b/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/EncodingUtil.java
index 1794288..67f5e5f 100644
--- a/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/EncodingUtil.java
+++ b/wagon-providers/wagon-http-shared/src/main/java/org/apache/maven/wagon/shared/http/EncodingUtil.java
@@ -24,6 +24,8 @@
 import java.net.URISyntaxException;
 import java.net.URL;
 
+import org.apache.http.client.utils.URLEncodedUtils;
+
 /**
  * Encoding utility.
  *
@@ -38,7 +40,9 @@
      * @return Parsed/encoded {@link URI} that represents the string form URL passed in.
      * @throws MalformedURLException
      * @throws URISyntaxException
+     * @deprecated to be removed with 4.0.0
      */
+    @Deprecated
     public static URI encodeURL( String url )
         throws MalformedURLException, URISyntaxException
     {
@@ -61,7 +65,9 @@
      * @param url Raw/decoded string form of a URL to parse/encode.
      * @return Parsed/encoded URI (as string) that represents the
      * @throws IllegalArgumentException in case the URL string is invalid.
+     * @deprecated To be remvoed with 4.0.0
      */
+    @Deprecated
     public static String encodeURLToString( String url )
     {
         try
@@ -75,31 +81,43 @@
     }
 
     /**
-     * Parses and returns an encoded version of the given URL string alongside the given paths.
+     * Parses and returns an encoded version of the given URL string alongside the given path.
      *
-     * @param baseUrl Base URL to use when constructing the final URL, ie: scheme://authority/initial.path.
-     * @param paths   Additional path(s) to append at the end of the base path.
-     * @return Composed URL (base + paths) already encoded, separating the individual path components by "/".
+     * @param baseUrl Base URL to use when constructing the final URL. This has to be a valid URL already.
+     * @param path Additional unencoded path to append at the end of the base path.
+     * @return Composed URL (base + path) already encoded, separating the individual path segments by "/".
      * @since TODO
      */
-    public static String encodeURLToString( String baseUrl, String... paths )
+    public static String encodeURLToString( String baseUrl, String path )
+    {
+        String[] pathSegments = path == null ? new String[0] : path.split( "/" );
+
+        return encodeURLToString( baseUrl, pathSegments );
+    }
+
+    /**
+     * Parses and returns an encoded version of the given URL string alongside the given path segments.
+     *
+     * @param baseUrl Base URL to use when constructing the final URL. This has to be a valid URL already.
+     * @param pathSegments Additional unencoded path segments to append at the end of the base path.
+     * @return Composed URL (base + path) already encoded, separating the individual path segments by "/".
+     * @since TODO
+     */
+    public static String encodeURLToString( String baseUrl, String... pathSegments )
     {
         StringBuilder url = new StringBuilder( baseUrl );
 
-        String[] parts = paths == null ? //
-            new String[0] : //
-            paths.length == 1 ? paths[0].split( "/" ) : paths;
+        String[] segments = pathSegments == null ? new String[0] : pathSegments;
 
-        for ( String part : parts )
+        String path = URLEncodedUtils.formatSegments( segments );
+
+        if ( url.toString().endsWith( "/" ) && !path.isEmpty() )
         {
-            if ( !url.toString().endsWith( "/" ) )
-            {
-                url.append( '/' );
-            }
-
-            url.append( part );
+            url.deleteCharAt( url.length() - 1 );
         }
 
-        return encodeURLToString( url.toString() );
+        url.append( path );
+
+        return url.toString();
     }
 }
diff --git a/wagon-providers/wagon-http-shared/src/test/java/org/apache/maven/wagon/shared/http/EncodingUtilTest.java b/wagon-providers/wagon-http-shared/src/test/java/org/apache/maven/wagon/shared/http/EncodingUtilTest.java
index f20f35f..4ec549c 100644
--- a/wagon-providers/wagon-http-shared/src/test/java/org/apache/maven/wagon/shared/http/EncodingUtilTest.java
+++ b/wagon-providers/wagon-http-shared/src/test/java/org/apache/maven/wagon/shared/http/EncodingUtilTest.java
@@ -46,8 +46,73 @@
     public void testEncodeURLWithSpacesInBothBaseAndPath()
         throws URISyntaxException, MalformedURLException
     {
-        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1/with a", "path with spaces" );
+        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1/with%20a", "path with spaces" );
 
         assertEquals( "file://host:1/with%20a/path%20with%20spaces", encodedURL );
     }
+
+    public void testEncodeURLWithSlashes1()
+        throws URISyntaxException, MalformedURLException
+    {
+        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1/basePath", "a", "b", "c" );
+
+        assertEquals( "file://host:1/basePath/a/b/c", encodedURL );
+
+        encodedURL = EncodingUtil.encodeURLToString( "file://host:1/basePath", "a/b/c" );
+
+        assertEquals( "file://host:1/basePath/a/b/c", encodedURL );
+    }
+
+    public void testEncodeURLWithSlashes2()
+        throws URISyntaxException, MalformedURLException
+    {
+        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1/basePath/", "a", "b", "c" );
+
+        assertEquals( "file://host:1/basePath/a/b/c", encodedURL );
+
+        encodedURL = EncodingUtil.encodeURLToString( "file://host:1/basePath/", "a/b/c" );
+
+        assertEquals( "file://host:1/basePath/a/b/c", encodedURL );
+    }
+
+    public void testEncodeURLWithSlashes3()
+            throws URISyntaxException, MalformedURLException
+    {
+        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1/basePath/", new String[0] );
+
+        assertEquals( "file://host:1/basePath/", encodedURL );
+    }
+
+    public void testEncodeURLWithSlashes4()
+        throws URISyntaxException, MalformedURLException
+    {
+        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1/basePath", new String[0] );
+
+        assertEquals( "file://host:1/basePath", encodedURL );
+    }
+
+    public void testEncodeURLWithSlashes5()
+        throws URISyntaxException, MalformedURLException
+    {
+        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1/basePath",
+                                                            "a/1", "b/1", "c/1" );
+
+        assertEquals( "file://host:1/basePath/a%2F1/b%2F1/c%2F1", encodedURL );
+    }
+
+    public void testEncodeURLWithSlashes6()
+        throws URISyntaxException, MalformedURLException
+    {
+        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1/", new String[0] );
+
+        assertEquals( "file://host:1/", encodedURL );
+    }
+
+    public void testEncodeURLWithSlashes7()
+        throws URISyntaxException, MalformedURLException
+    {
+        String encodedURL = EncodingUtil.encodeURLToString( "file://host:1", new String[0] );
+
+        assertEquals( "file://host:1", encodedURL );
+    }
 }