JCLOUDS-562: Decode object names with spaces, added test cases and updated test names.
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToSwiftObject.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToSwiftObject.java
index aabf63c..8fe00c7 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToSwiftObject.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToSwiftObject.java
@@ -24,6 +24,7 @@
 import org.jclouds.openstack.swift.v1.domain.SwiftObject.Builder;
 
 import com.google.common.base.Function;
+import com.google.common.io.ByteSource;
 
 public class ToSwiftObject implements Function<StorageMetadata, SwiftObject> {
 
@@ -44,10 +45,8 @@
       return to.build();
    }
 
-   private static final byte[] NO_CONTENT = new byte[] {};
-
    private static Payload payload(long bytes, String contentType) {
-      Payload payload = Payloads.newByteArrayPayload(NO_CONTENT);
+      Payload payload = Payloads.newByteSourcePayload(ByteSource.empty());
       payload.getContentMetadata().setContentLength(bytes);
       payload.getContentMetadata().setContentType(contentType);
       return payload;
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
index 0b58e8b..cf03265 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
@@ -16,7 +16,8 @@
  */
 package org.jclouds.openstack.swift.v1.functions;
 
-import java.net.URI;
+import static org.jclouds.http.Uris.uriBuilder;
+
 import java.util.Date;
 import java.util.List;
 
@@ -35,6 +36,7 @@
 
 import com.google.common.base.Function;
 import com.google.common.collect.Lists;
+import com.google.common.io.ByteSource;
 
 public class ParseObjectListFromResponse implements Function<HttpResponse, ObjectList>,
       InvocationContext<ParseObjectListFromResponse> {
@@ -75,7 +77,7 @@
       @Override
       public SwiftObject apply(InternalObject input) {
          return SwiftObject.builder()
-               .uri(URI.create(String.format("%s%s", containerUri, input.name)))
+               .uri(uriBuilder(containerUri).clearQuery().appendPath(input.name).build())
                .name(input.name)
                .etag(input.hash)
                .payload(payload(input.bytes, input.content_type))
@@ -95,10 +97,8 @@
       return this;
    }
 
-   private static final byte[] NO_CONTENT = new byte[] {};
-
    private static Payload payload(long bytes, String contentType) {
-      Payload payload = Payloads.newByteArrayPayload(NO_CONTENT);
+      Payload payload = Payloads.newByteSourcePayload(ByteSource.empty());
       payload.getContentMetadata().setContentLength(bytes);
       payload.getContentMetadata().setContentType(contentType);
       return payload;
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
index fb53927..dc2b6cc 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
@@ -36,14 +36,26 @@
 import com.google.common.collect.ImmutableMap;
 
 /**
- * @author Adrian Cole
- * @author Jeremy Daggett
+ * Provides live tests for the {@link ContainerApi}.
  */
 @Test(groups = "live", testName = "ContainerApiLiveTest")
 public class ContainerApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
 
    private String name = getClass().getSimpleName();
 
+   public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
+      final String nameWithSpaces = "container # ! special";
+
+      for (String regionId : regions) {
+         assertTrue(api.getContainerApiForRegion(regionId).create(nameWithSpaces));
+         Container container = api.getContainerApiForRegion(regionId).get(nameWithSpaces);
+         assertNotNull(container);
+         assertEquals(container.getName(), nameWithSpaces);
+
+         assertTrue(api.getContainerApiForRegion(regionId).deleteIfEmpty(nameWithSpaces));
+      }
+   }
+
    public void testList() throws Exception {
       for (String regionId : regions) {
          ContainerApi containerApi = api.getContainerApiForRegion(regionId);
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
index a6bb7cd..20707c7 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
@@ -189,6 +189,23 @@
       }
    }
 
+   public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
+
+      try {
+         SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+         assertTrue(api.getContainerApiForRegion("DFW").create("container # ! special"));
+
+         assertEquals(server.getRequestCount(), 2);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container%20%23%20%21%20special");
+      } finally {
+         server.shutdown();
+      }
+   }
+
    public void testAlreadyCreated() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
@@ -233,7 +250,7 @@
       }
    }
 
-   public void updateMetadata() throws Exception {
+   public void testUpdateMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(containerResponse()
@@ -257,7 +274,7 @@
       }
    }
 
-   public void deleteMetadata() throws Exception {
+   public void testDeleteMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(containerResponse()));
@@ -279,7 +296,7 @@
       }
    }
 
-   public void deleteIfEmpty() throws Exception {
+   public void testDeleteIfEmpty() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(204)));
@@ -298,7 +315,7 @@
       }
    }
 
-   public void alreadyDeleted() throws Exception {
+   public void testAlreadyDeleted() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
@@ -318,7 +335,7 @@
    }
 
    @Test(expectedExceptions = IllegalStateException.class)
-   public void deleteWhenNotEmpty() throws Exception {
+   public void testDeleteWhenNotEmpty() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(409)));
@@ -339,7 +356,7 @@
 
    private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
 
-   public static MockResponse containerResponse() {
+   static MockResponse containerResponse() {
       return new MockResponse()
             .addHeader(CONTAINER_OBJECT_COUNT, "42")
             .addHeader(CONTAINER_BYTES_USED, "323479");
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
index cc55a0c..446abbf 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
@@ -49,14 +49,32 @@
 
 /**
  * Provides live tests for the {@link ObjectApi}.
- * 
  */
 @Test(groups = "live", testName = "ObjectApiLiveTest", singleThreaded = true)
 public class ObjectApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
    
    private String name = getClass().getSimpleName();
    private String containerName = getClass().getSimpleName() + "Container";
-   
+   static final Payload PAYLOAD = newByteSourcePayload(ByteSource.wrap("swifty".getBytes()));
+
+   public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
+      final String containerName = "container # ! special";
+      final String objectName = "object # ! special";
+
+      for (String regionId : regions) {
+         assertNotNull(api.getContainerApiForRegion(regionId).create(containerName));
+         assertNotNull(api.getObjectApiForRegionAndContainer(regionId, containerName).put(objectName, PAYLOAD));
+
+         SwiftObject object = api.getObjectApiForRegionAndContainer(regionId, containerName).get(objectName);
+         assertEquals(object.getName(), objectName);
+         checkObject(object);
+         assertEquals(toStringAndClose(object.getPayload().openStream()), "swifty");
+
+         api.getObjectApiForRegionAndContainer(regionId, containerName).delete(objectName);
+         api.getContainerApiForRegion(regionId).deleteIfEmpty(containerName);
+      }
+   }
+
    public void testCopyObject() throws Exception {
       for (String regionId : regions) {
          // source
@@ -69,9 +87,6 @@
          String destinationObject = "copy.txt";
          String destinationPath = "/" + destinationContainer + "/" + destinationObject;
          
-         String stringPayload = "Hello World";
-         Payload data = newByteSourcePayload(ByteSource.wrap(stringPayload.getBytes()));
-         
          ContainerApi containerApi = api.getContainerApiForRegion(regionId);
          
          // create source and destination dirs
@@ -83,12 +98,12 @@
          ObjectApi destApi = api.getObjectApiForRegionAndContainer(regionId, destinationContainer);
          
          // Create source object 
-         assertNotNull(srcApi.put(sourceObjectName, data));
+         assertNotNull(srcApi.put(sourceObjectName, PAYLOAD));
          SwiftObject sourceObject = srcApi.get(sourceObjectName);
          checkObject(sourceObject);
 
          // Create the destination object
-         assertNotNull(destApi.put(destinationObject, data));
+         assertNotNull(destApi.put(destinationObject, PAYLOAD));
          SwiftObject object = destApi.get(destinationObject);
          checkObject(object);
 
@@ -98,7 +113,7 @@
          
          // now get a real SwiftObject
          SwiftObject destSwiftObject = destApi.get(destinationObject);
-         assertEquals(Strings2.toString(destSwiftObject.getPayload()), stringPayload);
+         assertEquals(Strings2.toString(destSwiftObject.getPayload()), "swifty");
          
          // test exception thrown on bad source name
          try {
@@ -144,7 +159,7 @@
          SwiftObject object = api.getObjectApiForRegionAndContainer(regionId, containerName).get(name);
          assertEquals(object.getName(), name);
          checkObject(object);
-         assertEquals(toStringAndClose(object.getPayload().openStream()), "");
+         assertEquals(toStringAndClose(object.getPayload().openStream()), "swifty");
       }
    }
 
@@ -223,8 +238,7 @@
       super.setup();
       for (String regionId : regions) {
          api.getContainerApiForRegion(regionId).create(containerName);
-         api.getObjectApiForRegionAndContainer(regionId, containerName)
-            .put(name, newByteSourcePayload(ByteSource.wrap("swifty".getBytes())));
+         api.getObjectApiForRegionAndContainer(regionId, containerName).put(name, PAYLOAD);
       }
    }
 
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
index b762919..348700e 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
@@ -30,6 +30,7 @@
 import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_READ;
 import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_METADATA_PREFIX;
 import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_REMOVE_METADATA_PREFIX;
+import static org.jclouds.util.Strings2.toStringAndClose;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
@@ -49,10 +50,8 @@
 import org.jclouds.openstack.swift.v1.domain.ObjectList;
 import org.jclouds.openstack.swift.v1.domain.SwiftObject;
 import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
-import org.jclouds.openstack.swift.v1.options.PutOptions;
 import org.jclouds.openstack.swift.v1.reference.SwiftHeaders;
 import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
-import org.jclouds.util.Strings2;
 import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
@@ -64,14 +63,13 @@
 
 /**
  * Provides mock tests for the {@link ObjectApi}.
- * 
- * @author Adrian Cole
- * @author Jeremy Daggett
  */
 @Test(groups = "unit", testName = "ObjectApiMockTest")
 public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    SimpleDateFormatDateService dates = new SimpleDateFormatDateService();
 
+   static final Payload PAYLOAD = newByteSourcePayload(ByteSource.wrap("swifty".getBytes()));
+
    protected ImmutableList<SwiftObject> parsedObjectsForUrl(String baseUri) {
       baseUri += "v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer";
       return ImmutableList.of(
@@ -86,7 +84,13 @@
                   .uri(URI.create(baseUri + "/test_obj_2"))
                   .etag("b039efe731ad111bc1b0ef221c3849d0")
                   .payload(payload(64l, "application/octet-stream"))
-                  .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build());
+                  .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build(),
+            SwiftObject.builder()
+                  .name("test obj 3")
+                  .uri(URI.create(baseUri + "/test%20obj%203"))
+                  .etag("0b2e80bd0744d9ebb20484149a57c82e")
+                  .payload(payload(14, "application/octet-stream"))
+                  .lastModified(dates.iso8601DateParse("2014-05-20T05:26:32.612278")).build());
    }
 
    public void testList() throws Exception {
@@ -151,7 +155,7 @@
       }
    }
 
-   public void testReplace() throws Exception {
+   public void testCreate() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse()
@@ -161,8 +165,8 @@
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          assertEquals(
-               api.getObjectApiForRegionAndContainer("DFW", "myContainer").put("myObject",
-                     newByteSourcePayload(ByteSource.wrap("swifty".getBytes())), metadata(metadata)), "d9f5eb4bba4e2f2f046e54611bc8196b");
+               api.getObjectApiForRegionAndContainer("DFW", "myContainer").put("myObject", PAYLOAD,
+                     metadata(metadata)), "d9f5eb4bba4e2f2f046e54611bc8196b");
 
          assertEquals(server.getRequestCount(), 2);
          assertAuthentication(server);
@@ -178,7 +182,32 @@
       }
    }
 
-   public void testReplace408Retry() throws Exception {
+   public void testCreateWithSpacesAndSpecialCharacters() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201).addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b")));
+
+      final String containerName = "container # ! special";
+      final String objectName = "object # ! special";
+
+      try {
+         SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+         assertEquals(
+               api.getObjectApiForRegionAndContainer("DFW", containerName).put(objectName, PAYLOAD,
+                     metadata(metadata)), "d9f5eb4bba4e2f2f046e54611bc8196b");
+
+         assertEquals(server.getRequestCount(), 2);
+         assertAuthentication(server);
+         RecordedRequest replace = server.takeRequest();
+         assertRequest(replace, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container%20%23%20%21%20special/object%20%23%20%21%20special");
+
+         assertEquals(new String(replace.getBody()), "swifty");
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   public void testCreateWith408Retry() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(408))); // 1
@@ -196,8 +225,8 @@
 
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift", overrides);
          assertEquals(
-               api.getObjectApiForRegionAndContainer("DFW", "myContainer").put("myObject",
-                     new ByteSourcePayload(ByteSource.wrap("swifty".getBytes())), PutOptions.Builder.metadata(metadata)), "d9f5eb4bba4e2f2f046e54611bc8196b");
+               api.getObjectApiForRegionAndContainer("DFW", "myContainer").put("myObject", PAYLOAD,
+                     metadata(metadata)), "d9f5eb4bba4e2f2f046e54611bc8196b");
 
          assertEquals(server.getRequestCount(), 5);
          assertAuthentication(server);
@@ -215,7 +244,7 @@
    }
 
    /** upper-cases first char, and lower-cases rest!! **/
-   public void testHeadKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
+   public void testGetWithoutKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(objectResponse()
@@ -234,7 +263,7 @@
          }
          assertEquals(object.getPayload().getContentMetadata().getContentLength(), new Long(4));
          assertEquals(object.getPayload().getContentMetadata().getContentType(), "text/plain; charset=UTF-8");
-         assertEquals(Strings2.toStringAndClose(object.getPayload().openStream()), "");
+         assertEquals(toStringAndClose(object.getPayload().openStream()), "");
 
          assertEquals(server.getRequestCount(), 2);
          assertAuthentication(server);
@@ -244,7 +273,7 @@
       }
    }
 
-   public void get() throws Exception {
+   public void testGet() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(objectResponse()
@@ -264,7 +293,7 @@
          assertEquals(object.getPayload().getContentMetadata().getContentLength(), new Long(4));
          assertEquals(object.getPayload().getContentMetadata().getContentType(), "text/plain; charset=UTF-8");
          // note MWS doesn't process Range header at the moment
-         assertEquals(Strings2.toStringAndClose(object.getPayload().openStream()), "ABCD");
+         assertEquals(toStringAndClose(object.getPayload().openStream()), "ABCD");
 
          assertEquals(server.getRequestCount(), 2);
          assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
@@ -278,7 +307,7 @@
    }
 
    @Test(expectedExceptions = HttpResponseException.class, timeOut = 20000)
-   public void testReplaceTimeout() throws Exception {
+   public void testCreateWithTimeout() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       // Typically we would enqueue a response for the put. However, in this case, test the timeout by not providing one.
@@ -292,7 +321,7 @@
 
          final SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift", overrides);
          
-         api.getObjectApiForRegionAndContainer("DFW", "myContainer").put("myObject", new ByteSourcePayload(ByteSource.wrap("swifty".getBytes())), PutOptions.Builder.metadata(metadata));
+         api.getObjectApiForRegionAndContainer("DFW", "myContainer").put("myObject", new ByteSourcePayload(ByteSource.wrap("swifty".getBytes())), metadata(metadata));
 
          fail("testReplaceTimeout test should have failed with an HttpResponseException.");
       } finally {
@@ -300,7 +329,7 @@
       }
    }
 
-   public void updateMetadata() throws Exception {
+   public void testUpdateMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(objectResponse()
@@ -351,7 +380,7 @@
       }
    }
 
-   public void deleteMetadata() throws Exception {
+   public void testDeleteMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(objectResponse()));
@@ -373,7 +402,7 @@
       }
    }
 
-   public void delete() throws Exception {
+   public void testDelete() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(204)));
@@ -392,7 +421,7 @@
       }
    }
 
-   public void alreadyDeleted() throws Exception {
+   public void testAlreadyDeleted() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
@@ -411,7 +440,7 @@
       }
    }
    
-   public void copyObject() throws Exception {
+   public void testCopyObject() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)
@@ -433,7 +462,7 @@
    }
    
    @Test(expectedExceptions = CopyObjectException.class)
-   public void copyObjectFail() throws InterruptedException, IOException {
+   public void testCopyObjectFail() throws InterruptedException, IOException {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)
@@ -450,7 +479,7 @@
    
    private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
 
-   public static MockResponse objectResponse() {
+   static MockResponse objectResponse() {
       return new MockResponse()
             .addHeader("Last-Modified", "Fri, 12 Jun 2010 13:40:18 GMT")
             .addHeader("ETag", "8a964ee2a5e88be344f36c22562a6486")
@@ -460,10 +489,8 @@
             .addHeader("Content-Length", "4").addHeader("Content-Type", "text/plain; charset=UTF-8");
    }
 
-   private static final byte[] NO_CONTENT = new byte[] {};
-
-   private static Payload payload(long bytes, String contentType) {
-      Payload payload = newByteSourcePayload(ByteSource.wrap(NO_CONTENT));
+   static Payload payload(long bytes, String contentType) {
+      Payload payload = newByteSourcePayload(ByteSource.empty());
       payload.getContentMetadata().setContentLength(bytes);
       payload.getContentMetadata().setContentType(contentType);
       return payload;
diff --git a/openstack-swift/src/test/resources/object_list.json b/openstack-swift/src/test/resources/object_list.json
index 9cac144..afe8c77 100644
--- a/openstack-swift/src/test/resources/object_list.json
+++ b/openstack-swift/src/test/resources/object_list.json
@@ -12,5 +12,12 @@
         "bytes": 64,
         "content_type": "application/octet-stream",
         "last_modified": "2009-02-03T05:26:32.612278"
+    },
+    {
+        "name": "test obj 3",
+        "hash": "0b2e80bd0744d9ebb20484149a57c82e",
+        "bytes": 123,
+        "content_type": "application/octet-stream",
+        "last_modified": "2014-05-20T05:26:32.612278"
     }
 ]
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiMockTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiMockTest.java
index 3e07de5..f90204e 100644
--- a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiMockTest.java
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiMockTest.java
@@ -280,6 +280,26 @@
       }
    }
 
+   public void testGetCDNContainerWithSpaces() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(enabledResponse().setResponseCode(201)));
+
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+
+         CDNContainer cdnContainer = api.getCDNApiForRegion("DFW").get("cdn-container with spaces");
+         assertCDNContainerNotNull(cdnContainer);
+         assertEquals(mockCDNContainerWithSpaces, cdnContainer);
+
+         assertEquals(server.getRequestCount(), 2);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/cdn-container%20with%20spaces");
+      } finally {
+         server.shutdown();
+      }
+   }
+
    public void testGetFail() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
@@ -424,6 +444,17 @@
          .iosUri(URI.create("http://ios-id-1.iosr.rackspace.com"))
          .build();
 
+   private static final CDNContainer mockCDNContainerWithSpaces = CDNContainer.builder()
+         .name("cdn-container with spaces")
+         .enabled(true)
+         .logRetention(false)
+         .ttl(777777)
+         .uri(URI.create("http://id-1.cdn.rackspace.com"))
+         .sslUri(URI.create("https://ssl-id-1.ssl.rackspace.com"))
+         .streamingUri(URI.create("http://streaming-id-1.stream.rackspace.com"))
+         .iosUri(URI.create("http://ios-id-1.iosr.rackspace.com"))
+         .build();
+
    private static MockResponse enabledResponse() {
       return new MockResponse()
             .addHeader(CDN_ENABLED, "true")
@@ -482,7 +513,7 @@
                .iosUri(URI.create("http://ios-id-3.iosr.rackspace.com"))
                .build(),
          CDNContainer.builder()
-               .name("cdn-container-4")
+               .name("cdn-container-4 with spaces")
                .enabled(true)
                .logRetention(true)
                .ttl(777777)
diff --git a/rackspace-cloudfiles/src/test/resources/cdn_container_list.json b/rackspace-cloudfiles/src/test/resources/cdn_container_list.json
index 4dce8db..5a36ca3 100644
--- a/rackspace-cloudfiles/src/test/resources/cdn_container_list.json
+++ b/rackspace-cloudfiles/src/test/resources/cdn_container_list.json
@@ -31,7 +31,7 @@
     },
     {
         "cdn_streaming_uri": "http://streaming-id-4.stream.rackspace.com",
-        "name": "cdn-container-4",
+        "name": "cdn-container-4 with spaces",
         "cdn_ios_uri": "http://ios-id-4.iosr.rackspace.com",
         "cdn_ssl_uri": "https://ssl-id-4.ssl.rackspace.com",
         "cdn_enabled": true,
diff --git a/rackspace-cloudfiles/src/test/resources/cdn_container_list_at.json b/rackspace-cloudfiles/src/test/resources/cdn_container_list_at.json
index f1fa9ee..b3ae802 100644
--- a/rackspace-cloudfiles/src/test/resources/cdn_container_list_at.json
+++ b/rackspace-cloudfiles/src/test/resources/cdn_container_list_at.json
@@ -11,7 +11,7 @@
     },
     {
         "cdn_streaming_uri": "http://streaming-id-4.stream.rackspace.com",
-        "name": "cdn-container-4",
+        "name": "cdn-container-4 with spaces",
         "cdn_ios_uri": "http://ios-id-4.iosr.rackspace.com",
         "cdn_ssl_uri": "https://ssl-id-4.ssl.rackspace.com",
         "cdn_enabled": true,