http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java
new file mode 100644
index 0000000..932c134
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.domain;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Represents an Account in OpenStack Object Storage.
+ * 
+ * @see org.jclouds.openstack.swift.v1.features.AccountApi
+ */
+public class Account {
+
+   private final long containerCount;
+   private final long objectCount;
+   private final long bytesUsed;
+   private final Map<String, String> metadata;
+   private final Multimap<String, String> headers;
+
+   // parsed from headers, so ConstructorProperties here would be misleading
+   protected Account(long containerCount, long objectCount, long bytesUsed, 
Map<String, String> metadata,
+         Multimap<String, String> headers) {
+      this.containerCount = containerCount;
+      this.objectCount = objectCount;
+      this.bytesUsed = bytesUsed;
+      this.metadata = metadata == null ? ImmutableMap.<String, String> of() : 
metadata;
+      this.headers = headers == null ? ImmutableMultimap.<String, String> of() 
: headers;
+   }
+
+   /**
+    * @return The count of containers for this account.
+    */
+   public long getContainerCount() {
+      return containerCount;
+   }
+
+   /**
+    * @return The count of objects for this account.
+    */
+   public long getObjectCount() {
+      return objectCount;
+   }
+
+   /**
+    * @return The number of bytes used by this account.
+    */
+   public long getBytesUsed() {
+      return bytesUsed;
+   }
+
+   /**
+    * @return The {@link Optional&lt;String&gt;} temporary URL key for this 
account.
+    */
+   public Optional<String> getTemporaryUrlKey() {
+      return Optional.fromNullable(metadata.get("temp-url-key"));
+   }
+
+   /**
+    * <h3>NOTE</h3>
+    * In current swift implementations, headers keys are lower-cased. This 
means
+    * characters such as turkish will probably not work out well.
+    *
+    * @return a {@code Map<String, String>} containing the account metadata.
+    */
+   public Map<String, String> getMetadata() {
+      return metadata;
+   }
+
+   /**
+    * @return The HTTP headers for this account.
+    */
+   public Multimap<String, String> getHeaders() {
+      return headers;
+   }
+
+   @Override
+   public boolean equals(Object object) {
+      if (this == object) {
+         return true;
+      }
+      if (object instanceof Account) {
+         Account that = Account.class.cast(object);
+         return equal(getContainerCount(), that.getContainerCount())
+               && equal(getObjectCount(), that.getObjectCount())
+               && equal(getBytesUsed(), that.getBytesUsed())
+               && equal(getMetadata(), that.getMetadata());
+      } else {
+         return false;
+      }
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(getContainerCount(), getObjectCount(), 
getBytesUsed(), getMetadata());
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   protected ToStringHelper string() {
+      return toStringHelper(this)
+            .add("containerCount", getContainerCount())
+            .add("objectCount", getObjectCount())
+            .add("bytesUsed", getBytesUsed())
+            .add("metadata", getMetadata());
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public Builder toBuilder() {
+      return builder().fromAccount(this);
+   }
+
+   public static class Builder {
+      protected long containerCount;
+      protected long objectCount;
+      protected long bytesUsed;
+      protected Multimap<String, String> headers = ImmutableMultimap.of();
+      protected Map<String, String> metadata = ImmutableMap.of();
+
+      /**
+       * @param containerCount  the count of containers for this account.
+       *
+       * @see Account#getContainerCount()
+       */
+      public Builder containerCount(long containerCount) {
+         this.containerCount = containerCount;
+         return this;
+      }
+
+      /**
+       * @param objectCount  the count of objects for this account.
+       *
+       * @see Account#getObjectCount()
+       */
+      public Builder objectCount(long objectCount) {
+         this.objectCount = objectCount;
+         return this;
+      }
+
+      /**
+       * @param bytesUsed  the number of bytes used by this account.
+       *
+       * @see Account#getBytesUsed()
+       */
+      public Builder bytesUsed(long bytesUsed) {
+         this.bytesUsed = bytesUsed;
+         return this;
+      }
+
+      /**
+       * <h3>NOTE</h3>
+       * This method will lower-case all metadata keys due to a Swift 
implementation
+       * decision.
+       *
+       * @param metadata  the metadata for this account. 
+       *
+       * @see Account#getMetadata()
+       */
+      public Builder metadata(Map<String, String> metadata) {
+         ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, 
String> builder();
+         for (Entry<String, String> entry : checkNotNull(metadata, 
"metadata").entrySet()) {
+            builder.put(entry.getKey().toLowerCase(), entry.getValue());
+         }
+         this.metadata = builder.build();
+         return this;
+      }
+
+      /**
+       * @see Account#getHeaders()
+       */
+      public Builder headers(Multimap<String, String> headers) {
+        this.headers = headers;
+        return this;
+      }
+
+      public Account build() {
+         return new Account(containerCount, objectCount, bytesUsed, metadata, 
headers);
+      }
+
+      public Builder fromAccount(Account from) {
+         return containerCount(from.getContainerCount())
+               .objectCount(from.getObjectCount())
+               .bytesUsed(from.getBytesUsed())
+               .metadata(from.getMetadata())
+               .headers(from.getHeaders());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java
new file mode 100644
index 0000000..4f79044
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.domain;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Objects;
+
+/**
+ * Represents a response from a Bulk Delete request.
+ * 
+ * @see org.jclouds.openstack.swift.v1.features.BulkApi
+ */
+public class BulkDeleteResponse {
+   public static BulkDeleteResponse create(int deleted, int notFound, 
Map<String, String> errors) {
+      return new BulkDeleteResponse(deleted, notFound, errors);
+   }
+
+   private final int deleted;
+   private final int notFound;
+   private final Map<String, String> errors;
+
+   private BulkDeleteResponse(int deleted, int notFound, Map<String, String> 
errors) {
+      this.deleted = deleted;
+      this.notFound = notFound;
+      this.errors = checkNotNull(errors, "errors");
+   }
+
+   /** 
+    * @return The number of files deleted.
+    * */
+   public int getDeleted() {
+      return deleted;
+   }
+
+   /** 
+    * @return The number of files not found.
+    */
+   public int getNotFound() {
+      return notFound;
+   }
+
+   /** 
+    * @return a {@code Map<String, String>} containing each path that failed 
+    *         to be deleted and its corresponding error response.
+    */
+   public Map<String, String> getErrors() {
+      return errors;
+   }
+
+   @Override
+   public boolean equals(Object object) {
+      if (this == object) {
+         return true;
+      }
+      if (object instanceof BulkDeleteResponse) {
+         BulkDeleteResponse that = BulkDeleteResponse.class.cast(object);
+         return equal(getDeleted(), that.getDeleted())
+               && equal(getNotFound(), that.getNotFound())
+               && equal(getErrors(), that.getErrors());
+      } else {
+         return false;
+      }
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(getDeleted(), getNotFound(), getErrors());
+   }
+
+   protected ToStringHelper string() {
+      return toStringHelper(this)
+            .add("deleted", getDeleted())
+            .add("notFound", getNotFound())
+            .add("errors", getErrors());
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java
new file mode 100644
index 0000000..4a31ab7
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.domain;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.beans.ConstructorProperties;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Represents a Container in OpenStack Object Storage.
+ * 
+ * @see org.jclouds.openstack.swift.v1.features.ContainerApi
+ */
+public class Container implements Comparable<Container> {
+
+   private final String name;
+   private final long objectCount;
+   private final long bytesUsed;
+   private final Optional<Boolean> anybodyRead;
+   private final Map<String, String> metadata;
+   private final Multimap<String, String> headers;
+
+   @ConstructorProperties({ "name", "count", "bytes", "anybodyRead", 
"metadata", "headers"})
+   protected Container(String name, long objectCount, long bytesUsed, 
Optional<Boolean> anybodyRead,
+         Map<String, String> metadata, Multimap<String, String> headers) {
+      this.name = checkNotNull(name, "name");
+      this.objectCount = objectCount;
+      this.bytesUsed = bytesUsed;
+      this.anybodyRead = anybodyRead == null ? Optional.<Boolean> absent() : 
anybodyRead;
+      this.metadata = metadata == null ? ImmutableMap.<String, String> of() : 
metadata;
+      this.headers = headers == null ? ImmutableMultimap.<String, String> of() 
: headers;
+   }
+
+   /**
+    * @return The name of this container.
+    */
+   public String getName() {
+      return name;
+   }
+
+   /**
+    * @return The count of objects for this container.
+    */
+   public long getObjectCount() {
+      return objectCount;
+   }
+
+   /**
+    * @return The number of bytes used by this container.
+    */
+   public long getBytesUsed() {
+      return bytesUsed;
+   }
+
+   /**
+    * Absent except in {@link ContainerApi#get(String) Get Container} commands.
+    * 
+    * @return true  if this container is publicly readable, false otherwise.
+    * 
+    * @see 
org.jclouds.openstack.swift.v1.options.CreateContainerOptions#anybodyRead()
+    */
+   public Optional<Boolean> getAnybodyRead() {
+      return anybodyRead;
+   }
+
+   /**
+    * <h3>NOTE</h3>
+    * In current swift implementations, headers keys are lower-cased. This 
means
+    * characters such as turkish will probably not work out well.
+    * 
+    * @return a {@code Map<String, String>} containing this container's 
metadata.
+    */
+   public Map<String, String> getMetadata() {
+      return metadata;
+   }
+
+   /**
+    * @return The HTTP headers for this account.
+    */
+   public Multimap<String, String> getHeaders() {
+      return headers;
+   }
+
+   @Override
+   public boolean equals(Object object) {
+      if (this == object) {
+         return true;
+      }
+      if (object instanceof Container) {
+         final Container that = Container.class.cast(object);
+         return equal(getName(), that.getName())
+               && equal(getObjectCount(), that.getObjectCount())
+               && equal(getBytesUsed(), that.getBytesUsed())
+               && equal(getMetadata(), that.getMetadata());
+      } else {
+         return false;
+      }
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(getName(), getObjectCount(), getBytesUsed(), 
getAnybodyRead(), getMetadata());
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   protected ToStringHelper string() {
+      return toStringHelper(this).omitNullValues()
+            .add("name", getName())
+            .add("objectCount", getObjectCount())
+            .add("bytesUsed", getBytesUsed())
+            .add("anybodyRead", getAnybodyRead().orNull())
+            .add("metadata", getMetadata());
+   }
+
+   @Override
+   public int compareTo(Container that) {
+      if (that == null)
+         return 1;
+      if (this == that)
+         return 0;
+      return this.getName().compareTo(that.getName());
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public Builder toBuilder() {
+      return builder().fromContainer(this);
+   }
+
+   public static class Builder {
+      protected String name;
+      protected long objectCount;
+      protected long bytesUsed;
+      protected Optional<Boolean> anybodyRead = Optional.absent();
+      protected Map<String, String> metadata = ImmutableMap.of();
+      protected Multimap<String, String> headers = ImmutableMultimap.of();
+
+      /**
+       * @see Container#getName()
+       */
+      public Builder name(String name) {
+         this.name = checkNotNull(name, "name");
+         return this;
+      }
+
+      /**
+       * @see Container#getObjectCount()
+       */
+      public Builder objectCount(long objectCount) {
+         this.objectCount = objectCount;
+         return this;
+      }
+
+      /**
+       * @see Container#getBytesUsed()
+       */
+      public Builder bytesUsed(long bytesUsed) {
+         this.bytesUsed = bytesUsed;
+         return this;
+      }
+
+      /**
+       * @see Container#getAnybodyRead()
+       */
+      public Builder anybodyRead(Boolean anybodyRead) {
+         this.anybodyRead = Optional.fromNullable(anybodyRead);
+         return this;
+      }
+
+      /**
+       * <h3>NOTE</h3>
+       * This method will lower-case all metadata keys.
+       * 
+       * @see Container#getMetadata()
+       */
+      public Builder metadata(Map<String, String> metadata) {
+         ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, 
String> builder();
+         for (Entry<String, String> entry : checkNotNull(metadata, 
"metadata").entrySet()) {
+            builder.put(entry.getKey().toLowerCase(), entry.getValue());
+         }
+         this.metadata = builder.build();
+         return this;
+      }
+
+      /**
+       * @see Container#getHeaders()
+       */
+      public Builder headers(Multimap<String, String> headers) {
+         this.headers = headers;
+         return this;
+      }
+
+      public Container build() {
+         return new Container(name, objectCount, bytesUsed, anybodyRead, 
metadata, headers);
+      }
+
+      public Builder fromContainer(Container from) {
+         return name(from.getName())
+               .objectCount(from.getObjectCount())
+               .bytesUsed(from.getBytesUsed())
+               .anybodyRead(from.getAnybodyRead().orNull())
+               .metadata(from.getMetadata())
+               .headers(from.getHeaders());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java
new file mode 100644
index 0000000..7e06e0e
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.domain;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Objects;
+
+/**
+ * Represents a response from an Extract Archive request.
+ *
+ * @see org.jclouds.openstack.swift.v1.features.BulkApi
+ */
+public class ExtractArchiveResponse {
+   public static ExtractArchiveResponse create(int created, Map<String, 
String> errors) {
+      return new ExtractArchiveResponse(created, errors);
+   }
+
+   private final int created;
+   private final Map<String, String> errors;
+
+   private ExtractArchiveResponse(int created, Map<String, String> errors) {
+      this.created = created;
+      this.errors = checkNotNull(errors, "errors");
+   }
+
+   /** 
+    * @return The number of files created.
+    */
+   public int getCreated() {
+      return created;
+   }
+
+   /** 
+    * @return a {@code Map<String, String>} containing each path that failed 
+    *         to be created and its corresponding error response.
+    */
+   public Map<String, String> getErrors() {
+      return errors;
+   }
+
+   @Override
+   public boolean equals(Object object) {
+      if (this == object) {
+         return true;
+      }
+      if (object instanceof ExtractArchiveResponse) {
+         ExtractArchiveResponse that = 
ExtractArchiveResponse.class.cast(object);
+         return equal(getCreated(), that.getCreated())
+               && equal(getErrors(), that.getErrors());
+      } else {
+         return false;
+      }
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(getCreated(), getErrors());
+   }
+
+   protected ToStringHelper string() {
+      return toStringHelper(this)
+            .add("created", getCreated())
+            .add("errors", getErrors());
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
new file mode 100644
index 0000000..5bc3136
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import com.google.common.collect.ForwardingList;
+
+/**
+ * Represents a list of objects in a container.
+ * 
+ * @see Container 
+ * @see SwiftObject
+ * @see org.jclouds.openstack.swift.v1.features.ObjectApi#list()
+ */
+public class ObjectList extends ForwardingList<SwiftObject> {
+
+   public static ObjectList create(List<SwiftObject> objects, Container 
container) {
+      return new ObjectList(objects, container);
+   }
+
+   private final List<SwiftObject> objects;
+   private final Container container;
+
+   protected ObjectList(List<SwiftObject> objects, Container container) {
+      this.objects = checkNotNull(objects, "objects");
+      this.container = checkNotNull(container, "container");
+   }
+
+   /**
+    * @return the parent {@link Container} the objects reside in.
+    */
+   public Container getContainer() {
+      return container;
+   }
+
+   @Override
+   protected List<SwiftObject> delegate() {
+      return objects;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java
new file mode 100644
index 0000000..a5f064f
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.domain;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.inject.Named;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Objects;
+
+/**
+ * Represents a single segment of a multi-part upload.
+ * 
+ * @see org.jclouds.openstack.swift.v1.features.StaticLargeObjectApi
+ */
+public class Segment {
+
+   private final String path;
+   private final String etag;
+   @Named("size_bytes")
+   private final long sizeBytes;
+
+   private Segment(String path, String etag, long sizeBytes) {
+      this.path = checkNotNull(path, "path");
+      this.etag = checkNotNull(etag, "etag of %s", path);
+      this.sizeBytes = checkNotNull(sizeBytes, "sizeBytes of %s", path);
+   }
+
+   /**
+    * @return The container and object name in the format: {@code 
<container-name>/<object-name>}
+    */
+   public String getPath() {
+      return path;
+   }
+
+   /**
+    * @return The ETag of the content of the segment object.
+    */
+   public String getETag() {
+      return etag;
+   }
+
+   /**
+    * @return The size of the segment object.
+    */
+   public long getSizeBytes() {
+      return sizeBytes;
+   }
+
+   @Override
+   public boolean equals(Object object) {
+      if (this == object) {
+         return true;
+      }
+      if (object instanceof Segment) {
+         Segment that = Segment.class.cast(object);
+         return equal(getPath(), that.getPath())
+               && equal(getETag(), that.getETag())
+               && equal(getSizeBytes(), that.getSizeBytes());
+      } else {
+         return false;
+      }
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(getPath(), getETag(), getSizeBytes());
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   protected ToStringHelper string() {
+      return toStringHelper(this)
+            .add("path", getPath())
+            .add("etag", getETag())
+            .add("sizeBytes", getSizeBytes());
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public static class Builder {
+      protected String path;
+      protected String etag;
+      protected long sizeBytes;
+
+      /**
+       * @see Segment#getPath()
+       */
+      public Builder path(String path) {
+         this.path = path;
+         return this;
+      }
+
+      /**
+       * @see Segment#getEtag()
+       */
+      public Builder etag(String etag) {
+         this.etag = etag;
+         return this;
+      }
+
+      /**
+       * @see Segment#getSizeBytes()
+       */
+      public Builder sizeBytes(long sizeBytes) {
+         this.sizeBytes = sizeBytes;
+         return this;
+      }
+
+      public Segment build() {
+         return new Segment(path, etag, sizeBytes);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java
new file mode 100644
index 0000000..2184ff2
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java
@@ -0,0 +1,267 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.domain;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jclouds.io.Payload;
+
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Represents an object in OpenStack Object Storage.
+ * 
+ * 
+ * @see ObjectApi
+ */
+public class SwiftObject implements Comparable<SwiftObject> {
+
+   private final String name;
+   private final URI uri;
+   private final String etag;
+   private final Date lastModified;
+   private final Multimap<String, String> headers;
+   private final Map<String, String> metadata;
+   private final Payload payload;
+
+   protected SwiftObject(String name, URI uri, String etag, Date lastModified,
+         Multimap<String, String> headers, Map<String, String> metadata, 
Payload payload) {
+      this.name = checkNotNull(name, "name");
+      this.uri = checkNotNull(uri, "uri of %s", uri);
+      this.etag = checkNotNull(etag, "etag of %s", name).replace("\"", "");
+      this.lastModified = checkNotNull(lastModified, "lastModified of %s", 
name);
+      this.headers = headers == null ? ImmutableMultimap.<String, String> of() 
: checkNotNull(headers, "headers of %s", name);
+      this.metadata = metadata == null ? ImmutableMap.<String, String> of() : 
metadata;
+      this.payload = checkNotNull(payload, "payload of %s", name);
+   }
+
+   /**
+    * @return The name of this object.
+    */
+   public String getName() {
+      return name;
+   }
+
+   /**
+    * @return The {@link URI} for this object.
+    */
+   public URI getUri() {
+      return uri;
+   }
+
+   /**
+    * @return The ETag of the content of this object.
+    * @deprecated Please use {@link #getETag()} as this method will be removed 
in jclouds 1.8.
+    */
+   public String getEtag() {
+      return etag;
+   }
+
+   /**
+    * @return The ETag of the content of this object.
+    */
+   public String getETag() {
+      return etag;
+   }
+
+   /**
+    * @return The {@link Date} that this object was last modified.
+    */
+   public Date getLastModified() {
+      return lastModified;
+   }
+
+   /**
+    * @return The HTTP headers for this object.
+    */
+   public Multimap<String, String> getHeaders() {
+      return headers;
+   }
+
+   /**
+    * <h3>NOTE</h3>
+    * In current swift implementations, headers keys are lower-cased. This 
means
+    * characters such as turkish will probably not work out well.
+    * 
+    * @return a {@code Map<String, String>} containing this object's metadata. 
The map is empty
+    *         except in {@link ObjectApi#head(String) GetObjectMetadata} or
+    *         {@link ObjectApi#get(String) GetObject} commands.
+    */
+   public Map<String, String> getMetadata() {
+      return metadata;
+   }
+
+   /**
+    * <h3>NOTE</h3>
+    * The object will only have a {@link Payload#getInput()} when retrieved 
via the
+    * {@link ObjectApi#get(String) GetObject} command.
+    * 
+    * @return The {@link Payload} for this object.
+    */
+   public Payload getPayload() {
+      return payload;
+   }
+
+   @Override
+   public boolean equals(Object object) {
+      if (this == object) {
+         return true;
+      }
+      if (object instanceof SwiftObject) {
+         final SwiftObject that = SwiftObject.class.cast(object);
+         return equal(getName(), that.getName())
+               && equal(getUri(), that.getUri())
+               && equal(getETag(), that.getETag());
+      } else {
+         return false;
+      }
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(getName(), getUri(), getETag());
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   protected ToStringHelper string() {
+      return toStringHelper(this)
+            .add("name", getName())
+            .add("uri", getUri())
+            .add("etag", getETag())
+            .add("lastModified", getLastModified())
+            .add("metadata", getMetadata());
+   }
+
+   @Override
+   public int compareTo(SwiftObject that) {
+      if (that == null)
+         return 1;
+      if (this == that)
+         return 0;
+      return this.getName().compareTo(that.getName());
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public Builder toBuilder() {
+      return builder().fromObject(this);
+   }
+
+   public static class Builder {
+      protected String name;
+      protected URI uri;
+      protected String etag;
+      protected Date lastModified;
+      protected Payload payload;
+      protected Multimap<String, String> headers = ImmutableMultimap.of();
+      protected Map<String, String> metadata = ImmutableMap.of();
+
+      /**
+       * @see SwiftObject#getName()
+       */
+      public Builder name(String name) {
+         this.name = checkNotNull(name, "name");
+         return this;
+      }
+
+      /**
+       * @see SwiftObject#getUri()
+       */
+      public Builder uri(URI uri) {
+         this.uri = checkNotNull(uri, "uri");
+         return this;
+      }
+
+      /**
+       * @see SwiftObject#getETag()
+       */
+      public Builder etag(String etag) {
+         this.etag = etag;
+         return this;
+      }
+
+      /**
+       * @see SwiftObject#getLastModified()
+       */
+      public Builder lastModified(Date lastModified) {
+         this.lastModified = lastModified;
+         return this;
+      }
+
+      /**
+       * @see SwiftObject#getPayload()
+       */
+      public Builder payload(Payload payload) {
+         this.payload = payload;
+         return this;
+      }
+
+      /**
+       * @see SwiftObject#getHeaders()
+       */
+      public Builder headers(Multimap<String, String> headers) {
+         this.headers = headers;
+         return this;
+      }
+
+      /**
+       * Will lower-case all metadata keys due to a swift implementation
+       * decision.
+       * 
+       * @see SwiftObject#getMetadata()
+       */
+      public Builder metadata(Map<String, String> metadata) {
+         ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, 
String> builder();
+         for (Entry<String, String> entry : checkNotNull(metadata, 
"metadata").entrySet()) {
+            builder.put(entry.getKey().toLowerCase(), entry.getValue());
+         }
+         this.metadata = builder.build();
+         return this;
+      }
+
+      public SwiftObject build() {
+         return new SwiftObject(name, uri, etag, lastModified, headers, 
metadata, payload);
+      }
+
+      public Builder fromObject(SwiftObject from) {
+         return name(from.getName())
+               .uri(from.getUri())
+               .etag(from.getETag())
+               .lastModified(from.getLastModified())
+               .headers(from.getHeaders())
+               .metadata(from.getMetadata())
+               .payload(from.getPayload());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
new file mode 100644
index 0000000..c9d5b9d
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.features;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_TEMPORARY_URL_KEY;
+
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import 
org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindAccountMetadataToHeaders;
+import 
org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveAccountMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.domain.Account;
+import org.jclouds.openstack.swift.v1.functions.ParseAccountFromHeaders;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Provides access to the OpenStack Object Storage (Swift) Account API 
features.
+ *
+ * <p/>
+ * Account metadata prefixed with {@code X-Account-Meta-} will be converted
+ * appropriately using a binder/parser.
+ * <p/>
+ * This API is new to jclouds and hence is in Beta. That means we need people 
to use it and give us feedback. Based
+ * on that feedback, minor changes to the interfaces may happen. This code 
will replace
+ * org.jclouds.openstack.swift.SwiftClient in jclouds 2.0 and it is 
recommended you adopt it sooner than later.
+ *
+ *
+ * @see {@link Account}
+ */
+@Beta
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(APPLICATION_JSON)
+public interface AccountApi {
+
+   /**
+    * Gets the {@link Account}.
+    *
+    * @return The {@link Account} object.
+    */
+   @Named("account:get")
+   @HEAD
+   @ResponseParser(ParseAccountFromHeaders.class)
+   Account get();
+
+   /**
+    * Creates or updates the {@link Account} metadata.
+    *
+    * @param metadata  the metadata to create or update.
+    *
+    * @return {@code true} if the metadata was successfully created or updated,
+    *         {@code false} if not.
+    */
+   @Named("account:updateMetadata")
+   @POST
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean updateMetadata(@BinderParam(BindAccountMetadataToHeaders.class) 
Map<String, String> metadata);
+
+   /**
+    * Replaces the temporary URL key for the {@link Account}.
+    *
+    * @param temporaryUrlKey  the temporary URL key to update.
+    *
+    * @return {@code true} if the temporary URL key was successfully updated,
+    *         {@code false} if not.
+    */
+   @Named("account:updateTemporaryUrlKey")
+   @POST
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean updateTemporaryUrlKey(@HeaderParam(ACCOUNT_TEMPORARY_URL_KEY) 
String temporaryUrlKey);
+
+   /**
+    * Deletes metadata from the {@link Account}.
+    *
+    * @param metadata  the metadata to delete.
+    *
+    * @return {@code true} if the metadata was successfully deleted,
+    *         {@code false} if not.
+    */
+   @Named("account:deleteMetadata")
+   @POST
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean 
deleteMetadata(@BinderParam(BindRemoveAccountMetadataToHeaders.class) 
Map<String, String> metadata);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
new file mode 100644
index 0000000..b62322f
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.features;
+
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.net.UrlEscapers.urlFragmentEscaper;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.io.Payload;
+import org.jclouds.io.Payloads;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.swift.v1.binders.SetPayload;
+import org.jclouds.openstack.swift.v1.domain.BulkDeleteResponse;
+import org.jclouds.openstack.swift.v1.domain.ExtractArchiveResponse;
+import org.jclouds.rest.Binder;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Joiner;
+
+/**
+ * Provides access to the OpenStack Object Storage (Swift) Bulk API features.
+ * <p/>
+ * This API is new to jclouds and hence is in Beta. That means we need people 
to use it and give us feedback. Based
+ * on that feedback, minor changes to the interfaces may happen. This code 
will replace
+ * org.jclouds.openstack.swift.SwiftClient in jclouds 2.0 and it is 
recommended you adopt it sooner than later.
+ */
+@Beta
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(APPLICATION_JSON)
+public interface BulkApi {
+
+   /**
+    * Extracts a tar archive at the path specified as {@code path}.
+    *
+    * @param path
+    *           the path to extract under.
+    * @param payload
+    *           the {@link Payload payload} archive.
+    * @param format
+    *           one of {@code tar}, {@code tar.gz}, or {@code tar.bz2}
+    *
+    * @return {@link BulkDeleteResponse#getErrors()} are empty on success.
+    */
+   @Named("bulk:extractArchive")
+   @PUT
+   @Path("/{path}")
+   ExtractArchiveResponse extractArchive(@PathParam("path") String path,
+         @BinderParam(SetPayload.class) Payload payload, 
@QueryParam("extract-archive") String format);
+
+   /**
+    * Deletes multiple objects or containers, if present.
+    *
+    * @param paths
+    *           format of {@code container}, for an empty container, or
+    *           {@code container/object} for an object.
+    *
+    * @return {@link BulkDeleteResponse#getErrors()} are empty on success.
+    */
+   @Named("bulk:delete")
+   @DELETE
+   @QueryParams(keys = "bulk-delete")
+   BulkDeleteResponse bulkDelete(@BinderParam(UrlEncodeAndJoinOnNewline.class) 
Iterable<String> paths);
+
+   // NOTE: this cannot be tested on MWS and is also brittle, as it relies on
+   // sending a body on DELETE.
+   // https://bugs.launchpad.net/swift/+bug/1232787
+   static class UrlEncodeAndJoinOnNewline implements Binder {
+      @SuppressWarnings("unchecked")
+      @Override
+      public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+         String encodedAndNewlineDelimited = Joiner.on('\n').join(
+               transform(Iterable.class.cast(input), 
urlFragmentEscaper().asFunction()));
+         Payload payload = 
Payloads.newStringPayload(encodedAndNewlineDelimited);
+         payload.getContentMetadata().setContentType(TEXT_PLAIN);
+         return (R) request.toBuilder().payload(payload).build();
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
new file mode 100644
index 0000000..4cbac0d
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.features;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static 
org.jclouds.openstack.swift.v1.SwiftFallbacks.TrueOn404FalseOn409;
+
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import 
org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindContainerMetadataToHeaders;
+import 
org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveContainerMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.openstack.swift.v1.functions.FalseOnAccepted;
+import org.jclouds.openstack.swift.v1.functions.ParseContainerFromHeaders;
+import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.openstack.swift.v1.options.UpdateContainerOptions;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.FluentIterable;
+
+/**
+ * Provides access to the OpenStack Object Storage (Swift) Container API 
features.
+ * <p/>
+ * This API is new to jclouds and hence is in Beta. That means we need people 
to use it and give us feedback. Based
+ * on that feedback, minor changes to the interfaces may happen. This code 
will replace
+ * {@code org.jclouds.openstack.swift.SwiftClient} in jclouds 2.0 and it is 
recommended you adopt it sooner than later.
+ */
+@Beta
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(APPLICATION_JSON)
+public interface ContainerApi {
+
+   /**
+    * Lists up to 10,000 containers.
+    *
+    * <h3>NOTE</h3>
+    * This method returns a list of {@link Container} objects <b>without</b> 
metadata. To retrieve
+    * the {@link Container} metadata, use the {@link #get(String)} method.
+    * <p/>
+    *
+    * @return a list of {@link Container containers} ordered by name.
+    */
+   @Named("container:list")
+   @GET
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<Container> list();
+
+   /**
+    * Lists containers with the supplied {@link ListContainerOptions}.
+    *
+    * <h3>NOTE</h3>
+    * This method returns a list of {@link Container} objects <b>without</b> 
metadata. To retrieve
+    * the {@link Container} metadata, use the {@link #get(String)} method.
+    * <p/>
+    *
+    * @param options
+    *          the options to control the output list.
+    *
+    * @return a list of {@link Container containers} ordered by name.
+    */
+   @Named("container:list")
+   @GET
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<Container> list(ListContainerOptions options);
+
+   /**
+    * Creates a container, if not already present.
+    *
+    * @param containerName
+    *           corresponds to {@link Container#getName()}.
+    *
+    * @return {@code true} if the container was created, {@code false} if the 
container already existed.
+    */
+   @Named("container:create")
+   @PUT
+   @Path("/{containerName}")
+   @ResponseParser(FalseOnAccepted.class)
+   boolean create(@PathParam("containerName") String containerName);
+
+   /**
+    * Creates a container, if not already present.
+    *
+    * @param containerName
+    *           corresponds to {@link Container#getName()}.
+    * @param options
+    *           the options to use when creating the container.
+    *
+    * @return {@code true} if the container was created, {@code false} if the 
container already existed.
+    */
+   @Named("container:create")
+   @PUT
+   @Path("/{containerName}")
+   @ResponseParser(FalseOnAccepted.class)
+   boolean create(@PathParam("containerName") String containerName, 
CreateContainerOptions options);
+
+   /**
+    * Gets the {@link Container}.
+    *
+    * @param containerName
+    *           corresponds to {@link Container#getName()}.
+    *
+    * @return the {@link Container}, or {@code null} if not found.
+    */
+   @Named("container:get")
+   @HEAD
+   @Path("/{containerName}")
+   @ResponseParser(ParseContainerFromHeaders.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Container get(@PathParam("containerName") String containerName);
+
+   /**
+    * Updates the {@link Container}.
+    *
+    * @param containerName
+    *           the container name corresponding to {@link 
Container#getName()}.
+    * @param options
+    *           the container options to update.
+    *
+    * @return {@code true} if the container metadata was successfully created 
or updated,
+    *         {@code false} if not.
+    */
+   @Named("container:update")
+   @POST
+   @Path("/{containerName}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean update(@PathParam("containerName") String containerName, 
UpdateContainerOptions options);
+
+   /**
+    * Creates or updates the {@link Container} metadata.
+    *
+    * @param containerName
+    *           the container name corresponding to {@link 
Container#getName()}.
+    * @param metadata
+    *           the container metadata to create or update.
+    *
+    * @return {@code true} if the container metadata was successfully created 
or updated,
+    *         {@code false} if not.
+    */
+   @Named("container:updateMetadata")
+   @POST
+   @Path("/{containerName}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean updateMetadata(@PathParam("containerName") String containerName,
+         @BinderParam(BindContainerMetadataToHeaders.class) Map<String, 
String> metadata);
+
+   /**
+    * Deletes {@link Container} metadata.
+    *
+    * @param containerName
+    *           corresponds to {@link Container#getName()}.
+    * @param metadata
+    *           the container metadata to delete.
+    *
+    * @return {@code true} if the container metadata was successfully deleted,
+    *         {@code false} if not.
+    */
+   @Named("container:deleteMetadata")
+   @POST
+   @Path("/{containerName}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean deleteMetadata(@PathParam("containerName") String containerName,
+         @BinderParam(BindRemoveContainerMetadataToHeaders.class) Map<String, 
String> metadata);
+
+   /**
+    * Deletes a {@link Container}, if empty.
+    *
+    * @param containerName
+    *           corresponds to {@link Container#getName()}.
+    *
+    * @return {@code true} if the container was deleted or not present.
+    *
+    * @throws IllegalStateException if the container was not empty.
+    */
+   @Named("container:deleteIfEmpty")
+   @DELETE
+   @Path("/{containerName}")
+   @Fallback(TrueOn404FalseOn409.class)
+   boolean deleteIfEmpty(@PathParam("containerName") String containerName) 
throws IllegalStateException;
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
new file mode 100644
index 0000000..4d4d603
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.features;
+
+import static com.google.common.net.HttpHeaders.EXPECT;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_COPY_FROM;
+
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
+import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnContainerNotFound;
+import org.jclouds.http.options.GetOptions;
+import org.jclouds.io.Payload;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import 
org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
+import 
org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveObjectMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.binders.SetPayload;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject;
+import org.jclouds.openstack.swift.v1.functions.ETagHeader;
+import org.jclouds.openstack.swift.v1.functions.ParseObjectFromResponse;
+import org.jclouds.openstack.swift.v1.functions.ParseObjectListFromResponse;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.openstack.swift.v1.options.PutOptions;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Headers;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Provides access to the OpenStack Object Storage (Swift) Object API features.
+ * <p/>
+ * This API is new to jclouds and hence is in Beta. That means we need people 
to use it and give us feedback. Based
+ * on that feedback, minor changes to the interfaces may happen. This code 
will replace
+ * org.jclouds.openstack.swift.SwiftClient in jclouds 2.0 and it is 
recommended you adopt it sooner than later.
+ */
+@Beta
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(APPLICATION_JSON)
+public interface ObjectApi {
+
+   /**
+    * Lists up to 10,000 objects.
+    *
+    * @return an {@link ObjectList} of {@link SwiftObject} ordered by name or 
{@code null}.
+    */
+   @Named("object:list")
+   @GET
+   @ResponseParser(ParseObjectListFromResponse.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   ObjectList list();
+
+   /**
+    * Lists up to 10,000 objects. To control a large list of containers beyond
+    * 10,000 objects, use the {@code marker} and {@code endMarker} parameters 
in the
+    * {@link ListContainerOptions} class.
+    *
+    * @param options
+    *           the {@link ListContainerOptions} for controlling the returned 
list.
+    *
+    * @return an {@link ObjectList} of {@link SwiftObject} ordered by name or 
{@code null}.
+    */
+   @Named("object:list")
+   @GET
+   @ResponseParser(ParseObjectListFromResponse.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   ObjectList list(ListContainerOptions options);
+
+   /**
+    * Creates or updates a {@link SwiftObject}.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    * @param payload
+    *           corresponds to {@link SwiftObject#getPayload()}.
+    *
+    * @return {@link SwiftObject#getETag()} of the object.
+    */
+   @Named("object:put")
+   @PUT
+   @Path("/{objectName}")
+   @Headers(keys = EXPECT, values = "100-continue")
+   @ResponseParser(ETagHeader.class)
+   String put(@PathParam("objectName") String objectName, 
@BinderParam(SetPayload.class) Payload payload);
+
+   /**
+    * Creates or updates a {@link SwiftObject}.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    * @param payload
+    *           corresponds to {@link SwiftObject#getPayload()}.
+    * @param options
+    *           {@link PutOptions options} to control creating the {@link 
SwiftObject}.
+    *
+    * @return {@link SwiftObject#getETag()} of the object.
+    */
+   @Named("object:put")
+   @PUT
+   @Path("/{objectName}")
+   @Headers(keys = EXPECT, values = "100-continue")
+   @ResponseParser(ETagHeader.class)
+   String put(@PathParam("objectName") String objectName, 
@BinderParam(SetPayload.class) Payload payload,
+         PutOptions options);
+
+   /**
+    * Gets the {@link SwiftObject} metadata without its {@link 
Payload#openStream() body}.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    *
+    * @return the {@link SwiftObject} or {@code null}, if not found.
+    */
+   @Named("object:getWithoutBody")
+   @HEAD
+   @Path("/{objectName}")
+   @ResponseParser(ParseObjectFromResponse.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   SwiftObject getWithoutBody(@PathParam("objectName") String objectName);
+
+   /**
+    * Gets the {@link SwiftObject} including its {@link Payload#openStream() 
body}.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    *
+    * @return the {@link SwiftObject} or {@code null}, if not found.
+    */
+   @Named("object:get")
+   @GET
+   @Path("/{objectName}")
+   @ResponseParser(ParseObjectFromResponse.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   SwiftObject get(@PathParam("objectName") String objectName);
+
+   /**
+    * Gets the {@link SwiftObject} including its {@link Payload#openStream() 
body}.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    * @param options
+    *           options to control the download.
+    *
+    * @return the {@link SwiftObject} or {@code null}, if not found.
+    */
+   @Named("object:get")
+   @GET
+   @Path("/{objectName}")
+   @ResponseParser(ParseObjectFromResponse.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   SwiftObject get(@PathParam("objectName") String objectName, GetOptions 
options);
+
+   /**
+    * Creates or updates the metadata for a {@link SwiftObject}.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    * @param metadata
+    *           the metadata to create or update.
+    *
+    * @return {@code true} if the metadata was successfully created or updated,
+    *         {@code false} if not.
+    */
+   @Named("object:updateMetadata")
+   @POST
+   @Path("/{objectName}")
+   @Produces("")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean updateMetadata(@PathParam("objectName") String objectName,
+         @BinderParam(BindObjectMetadataToHeaders.class) Map<String, String> 
metadata);
+
+   /**
+    * Deletes the metadata from a {@link SwiftObject}.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    * @param metadata
+    *           corresponds to {@link SwiftObject#getMetadata()}.
+    *
+    * @return {@code true} if the metadata was successfully deleted,
+    *         {@code false} if not.
+    */
+   @Named("object:deleteMetadata")
+   @POST
+   @Path("/{objectName}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean deleteMetadata(@PathParam("objectName") String objectName,
+         @BinderParam(BindRemoveObjectMetadataToHeaders.class) Map<String, 
String> metadata);
+
+   /**
+    * Deletes an object, if present.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    */
+   @Named("object:delete")
+   @DELETE
+   @Path("/{objectName}")
+   @Fallback(VoidOnNotFoundOr404.class)
+   void delete(@PathParam("objectName") String objectName);
+
+   /**
+    * Copies an object from one container to another.
+    *
+    * <h3>NOTE</h3>
+    * This is a server side copy.
+    *
+    * @param destinationObject
+    *           the destination object name.
+    * @param sourceContainer
+    *           the source container name.
+    * @param sourceObject
+    *           the source object name.
+    *
+    * @return {@code true} if the object was successfully copied, {@code 
false} if not.
+    *
+    * @throws org.jclouds.openstack.swift.v1.CopyObjectException if the source 
or destination container do not exist.
+    */
+   @Named("object:copy")
+   @PUT
+   @Path("/{destinationObject}")
+   @Headers(keys = OBJECT_COPY_FROM, values = 
"/{sourceContainer}/{sourceObject}")
+   @Fallback(FalseOnContainerNotFound.class)
+   boolean copy(@PathParam("destinationObject") String destinationObject,
+                @PathParam("sourceContainer") String sourceContainer,
+                @PathParam("sourceObject") String sourceObject);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
new file mode 100644
index 0000000..51ba30d
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.features;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import 
org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.domain.Segment;
+import org.jclouds.openstack.swift.v1.functions.ETagHeader;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.QueryParams;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.binders.BindToJsonPayload;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Provides access to the OpenStack Object Storage (Swift) Static Large Object 
API features.
+ * <p/>
+ * This API is new to jclouds and hence is in Beta. That means we need people 
to use it and give us feedback. Based
+ * on that feedback, minor changes to the interfaces may happen. This code 
will replace
+ * org.jclouds.openstack.swift.SwiftClient in jclouds 2.0 and it is 
recommended you adopt it sooner than later.
+ */
+@Beta
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(APPLICATION_JSON)
+@Path("/{objectName}")
+public interface StaticLargeObjectApi {
+
+   /**
+    * Creates or updates a static large object's manifest.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    * @param segments
+    *           ordered parts which will be concatenated upon download.
+    * @param metadata
+    *           corresponds to {@link SwiftObject#getMetadata()}.
+    *
+    * @return {@link SwiftObject#getEtag()} of the object, which is the MD5
+    *         checksum of the concatenated ETag values of the {@code segments}.
+    */
+   @Named("staticLargeObject:replaceManifest")
+   @PUT
+   @ResponseParser(ETagHeader.class)
+   @QueryParams(keys = "multipart-manifest", values = "put")
+   String replaceManifest(@PathParam("objectName") String objectName,
+         @BinderParam(BindToJsonPayload.class) List<Segment> segments,
+         @BinderParam(BindObjectMetadataToHeaders.class) Map<String, String> 
metadata);
+
+   /**
+    * Deletes a static large object, if present, including all of its segments.
+    *
+    * @param objectName
+    *           corresponds to {@link SwiftObject#getName()}.
+    */
+   @Named("staticLargeObject:delete")
+   @DELETE
+   @Fallback(VoidOnNotFoundOr404.class)
+   @QueryParams(keys = "multipart-manifest", values = "delete")
+   void delete(@PathParam("objectName") String objectName);
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ETagHeader.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ETagHeader.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ETagHeader.java
new file mode 100644
index 0000000..25a749b
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ETagHeader.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.functions;
+
+import static com.google.common.net.HttpHeaders.ETAG;
+
+import org.jclouds.http.HttpResponse;
+
+import com.google.common.base.Function;
+
+public class ETagHeader implements Function<HttpResponse, String> {
+
+   @Override
+   public String apply(HttpResponse from) {
+      String etag = from.getFirstHeaderOrNull(ETAG);
+      return etag != null ? etag.replace("\"", "") : null;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java
new file mode 100644
index 0000000..473da3e
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.functions;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Extracts entries whose keys start with {@code .*-Meta-}.
+ * 
+ * @param from
+ *           a {@link Multimap} containing the prefixed headers.
+ * 
+ * @return the extracted metadata without the prefixed keys. 
+ */
+public enum EntriesWithoutMetaPrefix implements Function<Multimap<String, 
String>, Map<String, String>> {
+   INSTANCE;
+
+   @Override
+   public Map<String, String> apply(Multimap<String, String> arg0) {
+      ImmutableMap.Builder<String, String> metadata = ImmutableMap.builder();
+      for (Entry<String, String> header : arg0.entries()) {
+         int index = header.getKey().indexOf("-Meta-");
+         if (index != -1) {
+            metadata.put(header.getKey().substring(index + 6), 
header.getValue());
+         }
+      }
+      return metadata.build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/FalseOnAccepted.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/FalseOnAccepted.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/FalseOnAccepted.java
new file mode 100644
index 0000000..68da524
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/FalseOnAccepted.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.functions;
+
+import org.jclouds.http.HttpResponse;
+
+import com.google.common.base.Function;
+
+/** Returns {@code false} on HTTP 202 {@code Accepted}. */
+public class FalseOnAccepted implements Function<HttpResponse, Boolean> {
+
+   @Override
+   public Boolean apply(HttpResponse from) {
+      return from.getStatusCode() == 202 ? false : true;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/MetadataFromHeaders.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/MetadataFromHeaders.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/MetadataFromHeaders.java
new file mode 100644
index 0000000..cdd49f1
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/MetadataFromHeaders.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.functions;
+
+import java.util.Map;
+
+import org.jclouds.http.HttpResponse;
+
+import com.google.common.base.Function;
+
+/** Extracts metadata entries from http response headers. */
+public class MetadataFromHeaders implements Function<HttpResponse, Map<String, 
String>> {
+   @Override
+   public Map<String, String> apply(HttpResponse from) {
+      return EntriesWithoutMetaPrefix.INSTANCE.apply(from.getHeaders());
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java
new file mode 100644
index 0000000..9debe67
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.functions;
+
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_BYTES_USED;
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_CONTAINER_COUNT;
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_OBJECT_COUNT;
+
+import org.jclouds.http.HttpResponse;
+import org.jclouds.openstack.swift.v1.domain.Account;
+
+import com.google.common.base.Function;
+
+public class ParseAccountFromHeaders implements Function<HttpResponse, 
Account> {
+
+   @Override
+   public Account apply(HttpResponse from) {
+      return Account.builder()
+            
.bytesUsed(Long.parseLong(from.getFirstHeaderOrNull(ACCOUNT_BYTES_USED)))
+            
.containerCount(Long.parseLong(from.getFirstHeaderOrNull(ACCOUNT_CONTAINER_COUNT)))
+            
.objectCount(Long.parseLong(from.getFirstHeaderOrNull(ACCOUNT_OBJECT_COUNT)))
+            
.metadata(EntriesWithoutMetaPrefix.INSTANCE.apply(from.getHeaders())).build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/34663f3c/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
new file mode 100644
index 0000000..d616351
--- /dev/null
+++ 
b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+package org.jclouds.openstack.swift.v1.functions;
+
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_ACL_ANYBODY_READ;
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_BYTES_USED;
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_OBJECT_COUNT;
+import static 
org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_READ;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.rest.InvocationContext;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+
+import com.google.common.base.Function;
+
+public class ParseContainerFromHeaders implements Function<HttpResponse, 
Container>,
+      InvocationContext<ParseContainerFromHeaders> {
+
+   String name;
+
+   @Override
+   public Container apply(HttpResponse from) {
+      Container c = 
+      Container.builder()
+            .name(name)
+            
.bytesUsed(Long.parseLong(from.getFirstHeaderOrNull(CONTAINER_BYTES_USED)))
+            
.objectCount(Long.parseLong(from.getFirstHeaderOrNull(CONTAINER_OBJECT_COUNT)))
+            
.anybodyRead(CONTAINER_ACL_ANYBODY_READ.equals(from.getFirstHeaderOrNull(CONTAINER_READ)))
+            
.metadata(EntriesWithoutMetaPrefix.INSTANCE.apply(from.getHeaders())).build();
+      return c;
+   }
+
+   @Override
+   public ParseContainerFromHeaders setContext(HttpRequest request) {
+      this.name = 
GeneratedHttpRequest.class.cast(request).getInvocation().getArgs().get(0).toString();
+      return this;
+   }
+}

Reply via email to