You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2013/09/03 10:06:13 UTC

[3/4] JCLOUDS-245/JCLOUDS-254: Fix live tests

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/domain/Role.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/domain/Role.java b/core/src/main/java/org/jclouds/chef/domain/Role.java
index 95d91f1..1b73609 100644
--- a/core/src/main/java/org/jclouds/chef/domain/Role.java
+++ b/core/src/main/java/org/jclouds/chef/domain/Role.java
@@ -16,55 +16,106 @@
  */
 package org.jclouds.chef.domain;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty;
+
+import java.beans.ConstructorProperties;
 import java.util.List;
 import java.util.Map;
 
 import org.jclouds.domain.JsonBall;
+import org.jclouds.javax.annotation.Nullable;
 
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.gson.annotations.SerializedName;
 
 /**
- * Sandbox object.
+ * Role object.
  * 
  * @author Adrian Cole
+ * @author Ignasi Barrera
  */
 public class Role {
+   public static Builder builder() {
+      return new Builder();
+   }
 
-   private String name;
-   private String description;
+   public static class Builder {
+      private String name;
+      private String description;
+      private ImmutableMap.Builder<String, JsonBall> overrideAttributes = ImmutableMap.builder();
+      private ImmutableMap.Builder<String, JsonBall> defaultAttributes = ImmutableMap.builder();
+      private ImmutableList.Builder<String> runList = ImmutableList.builder();
+
+      public Builder name(String name) {
+         this.name = checkNotNull(name, "name");
+         return this;
+      }
+
+      public Builder description(String description) {
+         this.description = checkNotNull(description, "description");
+         return this;
+      }
+
+      public Builder overrideAttribute(String key, JsonBall value) {
+         this.overrideAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value"));
+         return this;
+      }
+
+      public Builder overrideAttributes(Map<String, JsonBall> overrideAttributes) {
+         this.overrideAttributes.putAll(checkNotNull(overrideAttributes, "overrideAttributes"));
+         return this;
+      }
+
+      public Builder defaultAttribute(String key, JsonBall value) {
+         this.defaultAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value"));
+         return this;
+      }
+
+      public Builder defaultAttributes(Map<String, JsonBall> defaultAttributes) {
+         this.defaultAttributes.putAll(checkNotNull(defaultAttributes, "defaultAttributes"));
+         return this;
+      }
+
+      public Builder runListElement(String element) {
+         this.runList.add(checkNotNull(element, "element"));
+         return this;
+      }
+
+      public Builder runList(Iterable<String> runList) {
+         this.runList.addAll(checkNotNull(runList, "runList"));
+         return this;
+      }
+
+      public Role build() {
+         return new Role(name, description, defaultAttributes.build(), runList.build(), overrideAttributes.build());
+      }
+   }
+
+   private final String name;
+   private final String description;
    @SerializedName("override_attributes")
-   private Map<String, JsonBall> override = Maps.newLinkedHashMap();
+   private final Map<String, JsonBall> overrideAttributes;
    @SerializedName("default_attributes")
-   private Map<String, JsonBall> defaultA = Maps.newLinkedHashMap();
+   private final Map<String, JsonBall> defaultAttributes;
    @SerializedName("run_list")
-   private List<String> runList = Lists.newArrayList();
+   private final List<String> runList;
 
    // internal
    @SerializedName("json_class")
-   private String _jsonClass = "Chef::Role";
+   private final String _jsonClass = "Chef::Role";
    @SerializedName("chef_type")
-   private String _chefType = "role";
+   private final String _chefType = "role";
 
-   public Role(String name, String description, Map<String, JsonBall> defaultA, List<String> runList,
-         Map<String, JsonBall> override) {
+   @ConstructorProperties({ "name", "description", "default_attributes", "run_list", "override_attributes" })
+   protected Role(String name, String description, @Nullable Map<String, JsonBall> defaultAttributes,
+         @Nullable List<String> runList, @Nullable Map<String, JsonBall> overrideAttributes) {
       this.name = name;
       this.description = description;
-      this.defaultA = defaultA;
-      this.runList = runList;
-      this.override = override;
-   }
-
-   public Role(String name, Iterable<String> runList) {
-      this.name = name;
-      Iterables.addAll(this.runList, runList);
-   }
-
-   // hidden but needs to be here for json deserialization to work
-   Role() {
-
+      this.defaultAttributes = copyOfOrEmpty(defaultAttributes);
+      this.runList = copyOfOrEmpty(runList);
+      this.overrideAttributes = copyOfOrEmpty(overrideAttributes);
    }
 
    public String getName() {
@@ -75,12 +126,12 @@ public class Role {
       return description;
    }
 
-   public Map<String, JsonBall> getOverride() {
-      return override;
+   public Map<String, JsonBall> getOverrideAttributes() {
+      return overrideAttributes;
    }
 
-   public Map<String, JsonBall> getDefault() {
-      return defaultA;
+   public Map<String, JsonBall> getDefaultAttributes() {
+      return defaultAttributes;
    }
 
    public List<String> getRunList() {
@@ -93,10 +144,10 @@ public class Role {
       int result = 1;
       result = prime * result + ((_chefType == null) ? 0 : _chefType.hashCode());
       result = prime * result + ((_jsonClass == null) ? 0 : _jsonClass.hashCode());
-      result = prime * result + ((defaultA == null) ? 0 : defaultA.hashCode());
+      result = prime * result + ((defaultAttributes == null) ? 0 : defaultAttributes.hashCode());
       result = prime * result + ((description == null) ? 0 : description.hashCode());
       result = prime * result + ((name == null) ? 0 : name.hashCode());
-      result = prime * result + ((override == null) ? 0 : override.hashCode());
+      result = prime * result + ((overrideAttributes == null) ? 0 : overrideAttributes.hashCode());
       result = prime * result + ((runList == null) ? 0 : runList.hashCode());
       return result;
    }
@@ -120,10 +171,10 @@ public class Role {
             return false;
       } else if (!_jsonClass.equals(other._jsonClass))
          return false;
-      if (defaultA == null) {
-         if (other.defaultA != null)
+      if (defaultAttributes == null) {
+         if (other.defaultAttributes != null)
             return false;
-      } else if (!defaultA.equals(other.defaultA))
+      } else if (!defaultAttributes.equals(other.defaultAttributes))
          return false;
       if (description == null) {
          if (other.description != null)
@@ -135,10 +186,10 @@ public class Role {
             return false;
       } else if (!name.equals(other.name))
          return false;
-      if (override == null) {
-         if (other.override != null)
+      if (overrideAttributes == null) {
+         if (other.overrideAttributes != null)
             return false;
-      } else if (!override.equals(other.override))
+      } else if (!overrideAttributes.equals(other.overrideAttributes))
          return false;
       if (runList == null) {
          if (other.runList != null)
@@ -150,8 +201,8 @@ public class Role {
 
    @Override
    public String toString() {
-      return "[name=" + name + ", description=" + description + ", defaultA=" + defaultA + ", override=" + override
-            + ", runList=" + runList + "]";
+      return "Role [name=" + name + ", description=" + description + ", defaultAttributes=" + defaultAttributes
+            + ", overrideAttributes=" + overrideAttributes + ", runList=" + runList + "]";
    }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/domain/Sandbox.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/domain/Sandbox.java b/core/src/main/java/org/jclouds/chef/domain/Sandbox.java
index 98c8c96..774aa4a 100644
--- a/core/src/main/java/org/jclouds/chef/domain/Sandbox.java
+++ b/core/src/main/java/org/jclouds/chef/domain/Sandbox.java
@@ -16,49 +16,104 @@
  */
 package org.jclouds.chef.domain;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty;
+
+import java.beans.ConstructorProperties;
 import java.util.Date;
 import java.util.Set;
 
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.collect.ImmutableSet;
 import com.google.gson.annotations.SerializedName;
 
 /**
  * Sandbox object.
  * 
  * @author Adrian Cole
+ * @author Ignasi Barrera
  */
 public class Sandbox {
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public static class Builder {
+      private String rev;
+      private boolean isCompleted;
+      private Date createTime;
+      private ImmutableSet.Builder<String> checksums = ImmutableSet.builder();
+      private String name;
+      private String guid;
+
+      public Builder rev(String rev) {
+         this.rev = checkNotNull(rev, "rev");
+         return this;
+      }
+
+      public Builder isCompleted(boolean isCompleted) {
+         this.isCompleted = isCompleted;
+         return this;
+      }
+
+      public Builder createTime(Date createTime) {
+         this.createTime = createTime;
+         return this;
+      }
+
+      public Builder checksum(String checksum) {
+         this.checksums.add(checkNotNull(checksum, "checksum"));
+         return this;
+      }
+
+      public Builder checksums(Iterable<String> checksums) {
+         this.checksums.addAll(checkNotNull(checksums, "checksums"));
+         return this;
+      }
+
+      public Builder name(String name) {
+         this.name = checkNotNull(name, "name");
+         return this;
+      }
+
+      public Builder guid(String guid) {
+         this.guid = checkNotNull(guid, "guid");
+         return this;
+      }
+
+      public Sandbox build() {
+         return new Sandbox(rev, isCompleted, createTime, checksums.build(), name, guid);
+      }
+   }
 
    @SerializedName("_rev")
-   private String rev;
+   private final String rev;
    @SerializedName("is_completed")
-   private boolean isCompleted;
+   private final boolean isCompleted;
    @SerializedName("create_time")
-   private Date createTime;
-   private Set<String> checksums = Sets.newLinkedHashSet();
-   private String name;
-   private String guid;
+   private final Date createTime;
+   private final Set<String> checksums;
+   private final String name;
+   private final String guid;
 
    // internal
    @SerializedName("json_class")
-   private String _jsonClass = "Chef::Sandbox";
+   private final String _jsonClass = "Chef::Sandbox";
    @SerializedName("chef_type")
-   private String _chefType = "sandbox";
+   private final String _chefType = "sandbox";
 
-   public Sandbox(String rev, boolean isCompleted, Date createTime, Iterable<String> checksums, String name, String guid) {
+   @ConstructorProperties({ "_rev", "is_completed", "create_time", "checksums", "name", "guid" })
+   protected Sandbox(String rev, boolean isCompleted, Date createTime, @Nullable Set<String> checksums, String name,
+         String guid) {
       this.rev = rev;
       this.isCompleted = isCompleted;
       this.createTime = createTime;
-      Iterables.addAll(this.checksums, checksums);
+      this.checksums = copyOfOrEmpty(checksums);
       this.name = name;
       this.guid = guid;
    }
 
-   public Sandbox() {
-
-   }
-
    public String getRev() {
       return rev;
    }
@@ -141,4 +196,3 @@ public class Sandbox {
             + isCompleted + ", name=" + name + ", rev=" + rev + "]";
    }
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/domain/SearchResult.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/domain/SearchResult.java b/core/src/main/java/org/jclouds/chef/domain/SearchResult.java
index 91222a2..1e2cced 100644
--- a/core/src/main/java/org/jclouds/chef/domain/SearchResult.java
+++ b/core/src/main/java/org/jclouds/chef/domain/SearchResult.java
@@ -21,11 +21,13 @@ import java.util.LinkedHashSet;
 import com.google.common.collect.Iterables;
 
 /**
+ * A result of a search.
  * 
  * @author Adrian Cole
- * 
+ * @author Ignasi Barrera
  */
 public class SearchResult<T> extends LinkedHashSet<T> {
+   private static final long serialVersionUID = 4000610660948065287L;
    private long start;
 
    SearchResult() {
@@ -36,8 +38,6 @@ public class SearchResult<T> extends LinkedHashSet<T> {
       Iterables.addAll(this, results);
    }
 
-   private static final long serialVersionUID = 4000610660948065287L;
-
    /**
     * 
     * @return the result position this started from from
@@ -47,4 +47,3 @@ public class SearchResult<T> extends LinkedHashSet<T> {
    }
 
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/domain/UploadSandbox.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/domain/UploadSandbox.java b/core/src/main/java/org/jclouds/chef/domain/UploadSandbox.java
index f9bd6f1..868c147 100644
--- a/core/src/main/java/org/jclouds/chef/domain/UploadSandbox.java
+++ b/core/src/main/java/org/jclouds/chef/domain/UploadSandbox.java
@@ -16,31 +16,70 @@
  */
 package org.jclouds.chef.domain;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty;
+
+import java.beans.ConstructorProperties;
 import java.net.URI;
 import java.util.List;
 import java.util.Map;
 
-import com.google.common.collect.Maps;
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.collect.ImmutableMap;
 import com.google.gson.annotations.SerializedName;
 
 /**
+ * An upload sandbox.
  * 
  * @author Adrian Cole
+ * @author Ignasi Barrera
  */
 public class UploadSandbox {
-   private URI uri;
-   private Map<List<Byte>, ChecksumStatus> checksums = Maps.newLinkedHashMap();
-   @SerializedName("sandbox_id")
-   private String sandboxId;
+   public static Builder builder() {
+      return new Builder();
+   }
 
-   public UploadSandbox(URI uri, Map<List<Byte>, ChecksumStatus> checksums, String sandboxId) {
-      this.uri = uri;
-      this.checksums.putAll(checksums);
-      this.sandboxId = sandboxId;
+   public static class Builder {
+      private URI uri;
+      private ImmutableMap.Builder<List<Byte>, ChecksumStatus> checksums = ImmutableMap.builder();
+      private String sandboxId;
+
+      public Builder uri(URI uri) {
+         this.uri = checkNotNull(uri, "uri");
+         return this;
+      }
+
+      public Builder checksum(List<Byte> key, ChecksumStatus value) {
+         this.checksums.put(checkNotNull(key, "key"), checkNotNull(value, "value"));
+         return this;
+      }
+
+      public Builder checksums(Map<List<Byte>, ChecksumStatus> checksums) {
+         this.checksums.putAll(checkNotNull(checksums, "checksums"));
+         return this;
+      }
+
+      public Builder sandboxId(String sandboxId) {
+         this.sandboxId = checkNotNull(sandboxId, "sandboxId");
+         return this;
+      }
+
+      public UploadSandbox build() {
+         return new UploadSandbox(uri, checksums.build(), sandboxId);
+      }
    }
 
-   public UploadSandbox() {
+   private final URI uri;
+   private final Map<List<Byte>, ChecksumStatus> checksums;
+   @SerializedName("sandbox_id")
+   private final String sandboxId;
 
+   @ConstructorProperties({ "uri", "checksums", "sandbox_id" })
+   protected UploadSandbox(URI uri, @Nullable Map<List<Byte>, ChecksumStatus> checksums, String sandboxId) {
+      this.uri = uri;
+      this.checksums = copyOfOrEmpty(checksums);
+      this.sandboxId = sandboxId;
    }
 
    public URI getUri() {
@@ -94,8 +133,7 @@ public class UploadSandbox {
 
    @Override
    public String toString() {
-      return "UploadSite [checksums=" + checksums + ", id=" + sandboxId + ", uri=" + uri + "]";
+      return "UploadSandbox [checksums=" + checksums + ", id=" + sandboxId + ", uri=" + uri + "]";
    }
 
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/functions/ClientForGroup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/functions/ClientForGroup.java b/core/src/main/java/org/jclouds/chef/functions/ClientForGroup.java
index f51b7a2..a9c1c33 100644
--- a/core/src/main/java/org/jclouds/chef/functions/ClientForGroup.java
+++ b/core/src/main/java/org/jclouds/chef/functions/ClientForGroup.java
@@ -49,7 +49,12 @@ public class ClientForGroup implements Function<String, Client> {
       String clientName = findNextClientName(chefApi.listClients(), from + "-client-%02d");
       Client client = chefApi.createClient(clientName);
       // response from create only includes the key
-      return new Client(null, null, clientName, clientName, false, client.getPrivateKey());
+      return Client.builder() //
+            .clientname(clientName) //
+            .name(clientName) //
+            .isValidator(false) //
+            .privateKey(client.getPrivateKey()) //
+            .build();
    }
 
    private static String findNextClientName(Set<String> clients, String pattern) {

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java b/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java
index 28d4e1b..a3ef7c2 100644
--- a/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java
+++ b/core/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java
@@ -82,7 +82,7 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie
       }), and(notNull(), new Predicate<Node>() {
          @Override
          public boolean apply(Node input) {
-            JsonBall dateLong = input.getAutomatic().get("ohai_time");
+            JsonBall dateLong = input.getAutomaticAttributes().get("ohai_time");
             if (dateLong == null)
                return true;
             Calendar nodeUpdate = Calendar.getInstance();

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java b/core/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java
index 54de5e7..d6336b2 100644
--- a/core/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java
+++ b/core/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java
@@ -61,14 +61,25 @@ public class CreateNodeAndPopulateAutomaticAttributesImpl implements CreateNodeA
    @Override
    public Node execute(Node node) {
       logger.trace("creating node %s", node.getName());
-      node.getAutomatic().putAll(automaticSupplier.get());
-      chef.createNode(node);
-      logger.debug("created node %s", node.getName());
+      Node withAutomatic = Node.builder() //
+            .name(node.getName()) //
+            .normalAttributes(node.getNormalAttributes()) //
+            .overrideAttributes(node.getOverrideAttributes()) //
+            .defaultAttributes(node.getDefaultAttributes()) //
+            .automaticAttributes(node.getAutomaticAttributes()) //
+            .automaticAttributes(automaticSupplier.get()) //
+            .runList(node.getRunList()) //
+            .environment(node.getEnvironment()) //
+            .build();
+      
+      
+      chef.createNode(withAutomatic);
+      logger.debug("created node %s", withAutomatic.getName());
       return node;
    }
 
    @Override
    public Node execute(String nodeName, Iterable<String> runList) {
-      return execute(new Node(nodeName, runList, "_default"));
+      return execute(Node.builder().name(nodeName).runList(runList).environment("_default").build());
    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java b/core/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java
index e1af597..4d9bea4 100644
--- a/core/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java
+++ b/core/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java
@@ -61,9 +61,17 @@ public class UpdateAutomaticAttributesOnNodeImpl implements UpdateAutomaticAttri
    public void execute(String nodeName) {
       logger.trace("updating node %s", nodeName);
       Node node = chef.getNode(nodeName);
-      Node mutable = new Node(node.getName(), node.getNormal(), node.getOverride(), node.getDefault(),
-            automaticSupplier.get(), node.getRunList(), node.getChefEnvironment());
-      chef.updateNode(mutable);
+      Node updated = Node.builder() //
+            .name(node.getName()) //
+            .normalAttributes(node.getNormalAttributes()) //
+            .overrideAttributes(node.getOverrideAttributes()) //
+            .defaultAttributes(node.getDefaultAttributes()) //
+            .automaticAttributes(automaticSupplier.get()) //
+            .runList(node.getRunList()) //
+            .environment(node.getEnvironment()) //
+            .build();
+
+      chef.updateNode(updated);
       logger.debug("updated node %s", nodeName);
    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/test/TransientChefApi.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/test/TransientChefApi.java b/core/src/main/java/org/jclouds/chef/test/TransientChefApi.java
index 70a17d9..908ae2f 100644
--- a/core/src/main/java/org/jclouds/chef/test/TransientChefApi.java
+++ b/core/src/main/java/org/jclouds/chef/test/TransientChefApi.java
@@ -104,11 +104,6 @@ public class TransientChefApi implements ChefApi {
    }
 
    @Override
-   public boolean clientExists(String clientname) {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
    public Sandbox commitSandbox(String id, boolean isCompleted) {
       throw new UnsupportedOperationException();
    }
@@ -146,16 +141,6 @@ public class TransientChefApi implements ChefApi {
    }
 
    @Override
-   public boolean databagExists(String databagName) {
-      return databags.containerExists(databagName);
-   }
-
-   @Override
-   public boolean databagItemExists(String databagName, String databagItemId) {
-      return databags.blobExists(databagName, databagItemId);
-   }
-
-   @Override
    public Client deleteClient(String clientname) {
       throw new UnsupportedOperationException();
    }
@@ -263,16 +248,6 @@ public class TransientChefApi implements ChefApi {
    }
 
    @Override
-   public boolean nodeExists(String nodename) {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
-   public boolean roleExists(String rolename) {
-      throw new UnsupportedOperationException();
-   }
-
-   @Override
    public SearchResult<? extends Client> searchClients() {
       throw new UnsupportedOperationException();
    }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/main/java/org/jclouds/chef/util/CollectionUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/chef/util/CollectionUtils.java b/core/src/main/java/org/jclouds/chef/util/CollectionUtils.java
new file mode 100644
index 0000000..0e62804
--- /dev/null
+++ b/core/src/main/java/org/jclouds/chef/util/CollectionUtils.java
@@ -0,0 +1,71 @@
+/*
+ * 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.chef.util;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Utility methods to work with collections.
+ * 
+ * @author Ignasi Barrera
+ */
+public class CollectionUtils {
+
+   /**
+    * Creates an immutable list with the elements of the given list. If the
+    * input list is <code>null</code>, it returns an empty list.
+    * 
+    * @param input
+    *           The list used to build the immutable one.
+    * @return An immutable list with the elements of the given list.
+    */
+   public static <T> ImmutableList<T> copyOfOrEmpty(@Nullable List<T> input) {
+      return input == null ? ImmutableList.<T> of() : ImmutableList.copyOf(input);
+   }
+
+   /**
+    * Creates an immutable set with the elements of the given set. If the input
+    * set is <code>null</code>, it returns an empty set.
+    * 
+    * @param input
+    *           The set used to build the immutable one.
+    * @return An immutable set with the elements of the given set.
+    */
+   public static <T> ImmutableSet<T> copyOfOrEmpty(@Nullable Set<T> input) {
+      return input == null ? ImmutableSet.<T> of() : ImmutableSet.copyOf(input);
+   }
+
+   /**
+    * Creates an immutable map with the elements of the given map. If the input
+    * map is <code>null</code>, it returns an empty map.
+    * 
+    * @param input
+    *           The map used to build the immutable one.
+    * @return An immutable map with the elements of the given map.
+    */
+   public static <K, V> ImmutableMap<K, V> copyOfOrEmpty(@Nullable Map<K, V> input) {
+      return input == null ? ImmutableMap.<K, V> of() : ImmutableMap.copyOf(input);
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/ChefApiTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/ChefApiTest.java b/core/src/test/java/org/jclouds/chef/ChefApiTest.java
index bdb059a..33d6a98 100644
--- a/core/src/test/java/org/jclouds/chef/ChefApiTest.java
+++ b/core/src/test/java/org/jclouds/chef/ChefApiTest.java
@@ -28,7 +28,6 @@ import java.util.Set;
 
 import org.jclouds.Constants;
 import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
-import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.apis.ApiMetadata;
@@ -55,7 +54,6 @@ import org.jclouds.http.HttpRequest;
 import org.jclouds.http.functions.ParseJson;
 import org.jclouds.http.functions.ReleasePayloadAndReturn;
 import org.jclouds.http.functions.ReturnInputStream;
-import org.jclouds.http.functions.ReturnTrueIf2xx;
 import org.jclouds.io.Payload;
 import org.jclouds.io.payloads.StringPayload;
 import org.jclouds.reflect.Invocation;
@@ -172,7 +170,7 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
       Invokable<?, ?> method = method(ChefApi.class, "updateCookbook", String.class, String.class,
             CookbookVersion.class);
       GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method,
-            ImmutableList.<Object> of("cookbook", "1.0.1", new CookbookVersion("cookbook", "1.0.1"))));
+            ImmutableList.<Object> of("cookbook", "1.0.1", CookbookVersion.builder("cookbook", "1.0.1").build())));
 
       assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/cookbooks/cookbook/1.0.1 HTTP/1.1");
       assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
@@ -229,22 +227,6 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
 
    }
 
-   public void testApiExists() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(ChefApi.class, "clientExists", String.class);
-      GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList.<Object> of("api")));
-      assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/clients/api HTTP/1.1");
-      assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
-            + "-test\n");
-      assertPayloadEquals(httpRequest, null, null, false);
-
-      assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseOnNotFoundOr404.class);
-
-      checkFilters(httpRequest);
-
-   }
-
    public void testDeleteClient() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "deleteClient", String.class);
       GeneratedHttpRequest httpRequest = processor
@@ -331,21 +313,6 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
 
    }
 
-   public void testNodeExists() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(ChefApi.class, "nodeExists", String.class);
-      GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList.<Object> of("node")));
-      assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
-            + "-test\n");
-      assertPayloadEquals(httpRequest, null, null, false);
-
-      assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseOnNotFoundOr404.class);
-
-      checkFilters(httpRequest);
-
-   }
-
    public void testDeleteNode() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "deleteNode", String.class);
       GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList.<Object> of("node")));
@@ -364,8 +331,10 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
 
    public void testCreateNode() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "createNode", Node.class);
-      GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method,
-            ImmutableList.<Object> of(new Node("testnode", ImmutableSet.of("recipe[java]"), "_default"))));
+      GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(
+            method,
+            ImmutableList.<Object> of(Node.builder().name("testnode").runListElement("recipe[java]")
+                  .environment("_default").build())));
 
       assertRequestLineEquals(httpRequest, "POST http://localhost:4000/nodes HTTP/1.1");
       assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
@@ -385,8 +354,10 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
 
    public void testUpdateNode() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "updateNode", Node.class);
-      GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method,
-            ImmutableList.<Object> of(new Node("testnode", ImmutableSet.of("recipe[java]"), "_default"))));
+      GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(
+            method,
+            ImmutableList.<Object> of(Node.builder().name("testnode").runListElement("recipe[java]")
+                  .environment("_default").build())));
 
       assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/nodes/testnode HTTP/1.1");
       assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
@@ -421,22 +392,6 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
 
    }
 
-   public void testRoleExists() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(ChefApi.class, "roleExists", String.class);
-      GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList.<Object> of("role")));
-      assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/roles/role HTTP/1.1");
-      assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
-            + "-test\n");
-      assertPayloadEquals(httpRequest, null, null, false);
-
-      assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseOnNotFoundOr404.class);
-
-      checkFilters(httpRequest);
-
-   }
-
    public void testDeleteRole() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "deleteRole", String.class);
       GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList.<Object> of("role")));
@@ -456,7 +411,7 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
    public void testCreateRole() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "createRole", Role.class);
       GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method,
-            ImmutableList.<Object> of(new Role("testrole", ImmutableSet.of("recipe[java]")))));
+            ImmutableList.<Object> of(Role.builder().name("testrole").runListElement("recipe[java]").build())));
 
       assertRequestLineEquals(httpRequest, "POST http://localhost:4000/roles HTTP/1.1");
       assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
@@ -476,7 +431,7 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
    public void testUpdateRole() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "updateRole", Role.class);
       GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method,
-            ImmutableList.<Object> of(new Role("testrole", ImmutableSet.of("recipe[java]")))));
+            ImmutableList.<Object> of(Role.builder().name("testrole").runListElement("recipe[java]").build())));
 
       assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/roles/testrole HTTP/1.1");
       assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
@@ -510,23 +465,6 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
 
    }
 
-   public void testDatabagExists() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(ChefApi.class, "databagExists", String.class);
-      GeneratedHttpRequest httpRequest = processor
-            .apply(Invocation.create(method, ImmutableList.<Object> of("databag")));
-      assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/data/databag HTTP/1.1");
-      assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
-            + "-test\n");
-      assertPayloadEquals(httpRequest, null, null, false);
-
-      assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseOnNotFoundOr404.class);
-
-      checkFilters(httpRequest);
-
-   }
-
    public void testDeleteDatabag() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "deleteDatabag", String.class);
       GeneratedHttpRequest httpRequest = processor
@@ -578,23 +516,6 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
 
    }
 
-   public void testDatabagItemExists() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(ChefApi.class, "databagItemExists", String.class, String.class);
-      GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method,
-            ImmutableList.<Object> of("name", "databagItem")));
-      assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/data/name/databagItem HTTP/1.1");
-      assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION
-            + "-test\n");
-      assertPayloadEquals(httpRequest, null, null, false);
-
-      assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseOnNotFoundOr404.class);
-
-      checkFilters(httpRequest);
-
-   }
-
    public void testDeleteDatabagItem() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "deleteDatabagItem", String.class, String.class);
       GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method,
@@ -891,7 +812,7 @@ public class ChefApiTest extends BaseAsyncApiTest<ChefApi> {
    public void testGetResourceContents() throws SecurityException, NoSuchMethodException, IOException {
       Invokable<?, ?> method = method(ChefApi.class, "getResourceContents", Resource.class);
       GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method,
-            ImmutableList.<Object> of(new Resource("test", URI.create("http://foo/bar"), new byte[] {}, null, null))));
+            ImmutableList.<Object> of(Resource.builder().name("test").url(URI.create("http://foo/bar")).build())));
 
       assertRequestLineEquals(httpRequest, "GET http://foo/bar HTTP/1.1");
       assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java b/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java
index c703090..282e68e 100644
--- a/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java
+++ b/core/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java
@@ -17,6 +17,7 @@
 package org.jclouds.chef.binders;
 
 import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.primitives.Bytes.asList;
 import static org.testng.Assert.assertEquals;
 
 import java.io.File;
@@ -56,11 +57,10 @@ public class BindHexEncodedMD5sToJsonPayloadTest {
       binder.bindToRequest(request, new File("foo"));
    }
 
-   @Test(enabled = false)
    public void testCorrect() {
       HttpRequest request = HttpRequest.builder().method(HttpMethod.POST).endpoint("http://localhost").build();
       binder.bindToRequest(request,
-            ImmutableSet.of(base16().lowerCase().decode("abddef"), base16().lowerCase().decode("1234")));
+            ImmutableSet.of(asList(base16().lowerCase().decode("abddef")), asList(base16().lowerCase().decode("1234"))));
       assertEquals(request.getPayload().getRawContent(), "{\"checksums\":{\"abddef\":null,\"1234\":null}}");
    }
 

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/config/ChefParserModuleTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/config/ChefParserModuleTest.java b/core/src/test/java/org/jclouds/chef/config/ChefParserModuleTest.java
new file mode 100644
index 0000000..76db791
--- /dev/null
+++ b/core/src/test/java/org/jclouds/chef/config/ChefParserModuleTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.chef.config;
+
+import static com.google.common.base.Objects.equal;
+import static org.testng.Assert.assertEquals;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import org.jclouds.chef.config.ChefParserModule.KeepLastRepeatedKeyMapTypeAdapterFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * Unit tests for the {@link ChefParserModule} class.
+ * 
+ * @author Ignasi Barrera
+ */
+@Test(groups = "unit", testName = "ChefParserModuleTest")
+public class ChefParserModuleTest {
+
+   private static class KeyValue {
+      private final String key;
+      private final String value;
+
+      private KeyValue(String key, String value) {
+         this.key = key;
+         this.value = value;
+      }
+
+      @Override
+      public int hashCode() {
+         return Objects.hashCode(key, value);
+      }
+
+      @Override
+      public boolean equals(Object obj) {
+         if (this == obj)
+            return true;
+         if (obj == null || getClass() != obj.getClass())
+            return false;
+         KeyValue that = KeyValue.class.cast(obj);
+         return equal(this.key, that.key) && equal(this.value, that.value);
+      }
+   }
+
+   private Gson map = new GsonBuilder().registerTypeAdapterFactory(new KeepLastRepeatedKeyMapTypeAdapterFactory())
+         .create();
+   private Type mapType = new TypeToken<Map<String, String>>() {
+      private static final long serialVersionUID = 1L;
+   }.getType();
+   private Type mapkeyValueType = new TypeToken<Map<String, KeyValue>>() {
+      private static final long serialVersionUID = 1L;
+   }.getType();
+
+   public void testKeepLastRepeatedKeyMapTypeAdapter() {
+      Map<String, String> noNulls = map.fromJson("{\"value\":\"a test string!\"}", mapType);
+      assertEquals(noNulls, ImmutableMap.of("value", "a test string!"));
+      Map<String, String> withNull = map.fromJson("{\"value\":null}", mapType);
+      assertEquals(withNull, ImmutableMap.of());
+      Map<String, String> withEmpty = map.fromJson("{\"value\":\"\"}", mapType);
+      assertEquals(withEmpty, ImmutableMap.of("value", ""));
+      Map<String, KeyValue> keyValues = map.fromJson(
+            "{\"i-foo\":{\"key\":\"i-foo\",\"value\":\"foo\"},\"i-bar\":{\"key\":\"i-bar\",\"value\":\"bar\"}}",
+            mapkeyValueType);
+      assertEquals(keyValues,
+            ImmutableMap.of("i-foo", new KeyValue("i-foo", "foo"), "i-bar", new KeyValue("i-bar", "bar")));
+      Map<String, KeyValue> duplicates = map
+            .fromJson(
+                  "{\"i-foo\":{\"key\":\"i-foo\",\"value\":\"foo\", \"value\":\"foo2\"},\"i-bar\":{\"key\":\"i-bar\",\"value\":\"bar\",\"value\":\"bar2\"}}",
+                  mapkeyValueType);
+      assertEquals(duplicates,
+            ImmutableMap.of("i-foo", new KeyValue("i-foo", "foo2"), "i-bar", new KeyValue("i-bar", "bar2")));
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java b/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java
index 6fd7449..355d9a4 100644
--- a/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java
+++ b/core/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java
@@ -79,8 +79,8 @@ public class ParseClientFromJsonTest {
 
    public void test() throws IOException {
 
-      Client user = new Client(certificate, "jclouds", "adriancole-jcloudstest", "adriancole-jcloudstest", false,
-            privateKey);
+      Client user = Client.builder().certificate(certificate).orgname("jclouds").clientname("adriancole-jcloudstest")
+            .name("adriancole-jcloudstest").isValidator(false).privateKey(privateKey).build();
 
       byte[] encrypted = ByteStreams.toByteArray(new RSAEncryptingPayload(Payloads.newPayload("fooya"), user
             .getCertificate().getPublicKey()));

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java b/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java
index e806fa2..987e45a 100644
--- a/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java
+++ b/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java
@@ -31,12 +31,11 @@ import org.jclouds.rest.annotations.ApiVersion;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 
-@Test(groups = {"unit"}, singleThreaded = true)
+@Test(groups = { "unit" }, singleThreaded = true)
 public class ParseCookbookDefinitionFromJsonv10Test {
 
    private ParseCookbookDefinitionFromJsonv10 handler;
@@ -54,6 +53,13 @@ public class ParseCookbookDefinitionFromJsonv10Test {
    }
 
    public void testCookbokDefinitionParsing() throws URISyntaxException {
+      CookbookDefinition.Version v510 = CookbookDefinition.Version.builder()
+            .url(new URI("http://localhost:4000/cookbooks/apache2/5.1.0")).version("5.1.0").build();
+      CookbookDefinition.Version v420 = CookbookDefinition.Version.builder()
+            .url(new URI("http://localhost:4000/cookbooks/apache2/4.2.0")).version("4.2.0").build();
+      CookbookDefinition definition = CookbookDefinition.builder()
+            .url(new URI("http://localhost:4000/cookbooks/apache2")).version(v510).version(v420).build();
+
       assertEquals(handler.apply(HttpResponse
             .builder()
             .statusCode(200)
@@ -63,9 +69,6 @@ public class ParseCookbookDefinitionFromJsonv10Test {
                         + "\"versions\" => [" + "{\"url\" => \"http://localhost:4000/cookbooks/apache2/5.1.0\","
                         + "\"version\" => \"5.1.0\"},"
                         + "{\"url\" => \"http://localhost:4000/cookbooks/apache2/4.2.0\","
-                        + "\"version\" => \"4.2.0\"}" + "]" + "}" + "}").build()),
-            new CookbookDefinition(new URI("http://localhost:4000/cookbooks/apache2"),
-                  ImmutableSet.of(new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/apache2/5.1.0"), "5.1.0"),
-                        new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/apache2/4.2.0"), "4.2.0"))));
+                        + "\"version\" => \"4.2.0\"}" + "]" + "}" + "}").build()), definition);
    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java b/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java
index 95b26ea..d2cc882 100644
--- a/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java
+++ b/core/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java
@@ -54,6 +54,20 @@ public class ParseCookbookDefinitionListFromJsonv10Test {
    }
 
    public void testCookbokDefinitionListParsing() throws URISyntaxException {
+      CookbookDefinition.Version v510 = CookbookDefinition.Version.builder()
+            .url(new URI("http://localhost:4000/cookbooks/apache2/5.1.0")).version("5.1.0").build();
+      CookbookDefinition.Version v420 = CookbookDefinition.Version.builder()
+            .url(new URI("http://localhost:4000/cookbooks/apache2/4.2.0")).version("4.2.0").build();
+      CookbookDefinition apache2 = CookbookDefinition.builder()
+            .url(new URI("http://localhost:4000/cookbooks/apache2")).version(v510).version(v420).build();
+      
+      CookbookDefinition.Version v100 = CookbookDefinition.Version.builder()
+            .url(new URI("http://localhost:4000/cookbooks/nginx/1.0.0")).version("1.0.0").build();
+      CookbookDefinition.Version v130 = CookbookDefinition.Version.builder()
+            .url(new URI("http://localhost:4000/cookbooks/nginx/0.3.0")).version("0.3.0").build();
+      CookbookDefinition nginx = CookbookDefinition.builder()
+            .url(new URI("http://localhost:4000/cookbooks/nginx")).version(v100).version(v130).build();
+      
       assertEquals(handler.apply(HttpResponse
             .builder()
             .statusCode(200)
@@ -73,11 +87,6 @@ public class ParseCookbookDefinitionListFromJsonv10Test {
                         + "\"version\" => \"0.3.0\"}"
                         + "]}" +
                         "}").build()),
-            ImmutableSet.of(new CookbookDefinition(new URI("http://localhost:4000/cookbooks/apache2"),
-                  ImmutableSet.of(new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/apache2/5.1.0"), "5.1.0"),
-                        new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/apache2/4.2.0"), "4.2.0"))),
-                  new CookbookDefinition(new URI("http://localhost:4000/cookbooks/nginx"),
-                        ImmutableSet.of(new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/nginx/1.0.0"), "1.0.0"),
-                              new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/nginx/0.3.0"), "0.3.0")))));
+            ImmutableSet.of(apache2, nginx));
    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java b/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java
index f5d0f1f..c1f21de 100644
--- a/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java
+++ b/core/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java
@@ -24,7 +24,6 @@ import java.net.URI;
 
 import org.jclouds.chef.ChefApi;
 import org.jclouds.chef.config.ChefParserModule;
-import org.jclouds.chef.domain.Attribute;
 import org.jclouds.chef.domain.CookbookVersion;
 import org.jclouds.chef.domain.Metadata;
 import org.jclouds.chef.domain.Resource;
@@ -36,8 +35,6 @@ import org.jclouds.rest.annotations.ApiVersion;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
@@ -48,6 +45,7 @@ import com.google.inject.TypeLiteral;
  * Tests behavior of {@code ParseCookbookVersionFromJson}
  * 
  * @author Adrian Cole
+ * @author Ignasi Barrera
  */
 @Test(groups = { "unit" }, singleThreaded = true)
 public class ParseCookbookVersionFromJsonTest {
@@ -70,7 +68,6 @@ public class ParseCookbookVersionFromJsonTest {
       }));
    }
 
-   @Test(enabled = false)
    public void testBrew() throws IOException {
       CookbookVersion cookbook = handler.apply(HttpResponse.builder().statusCode(200).message("ok")
             .payload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/brew-cookbook.json")).build());
@@ -79,7 +76,6 @@ public class ParseCookbookVersionFromJsonTest {
             handler.apply(HttpResponse.builder().statusCode(200).message("ok").payload(json.toJson(cookbook)).build()));
    }
 
-   @Test(enabled = false)
    public void testTomcat() {
       CookbookVersion cookbook = handler.apply(HttpResponse.builder().statusCode(200).message("ok")
             .payload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/tomcat-cookbook.json")).build());
@@ -88,7 +84,6 @@ public class ParseCookbookVersionFromJsonTest {
             handler.apply(HttpResponse.builder().statusCode(200).message("ok").payload(json.toJson(cookbook)).build()));
    }
 
-   @Test(enabled = false)
    public void testMysql() throws IOException {
       CookbookVersion cookbook = handler.apply(HttpResponse.builder().statusCode(200).message("ok")
             .payload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/mysql-cookbook.json")).build());
@@ -97,44 +92,41 @@ public class ParseCookbookVersionFromJsonTest {
             handler.apply(HttpResponse.builder().statusCode(200).message("ok").payload(json.toJson(cookbook)).build()));
    }
 
-   @Test(enabled = false)
    public void testApache() {
-
-      assertEquals(
-            handler.apply(HttpResponse
-                  .builder()
-                  .statusCode(200)
-                  .message("ok")
-                  .payload(
-                        ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/apache-chef-demo-cookbook.json"))
-                  .build()),
-            new CookbookVersion(
-                  "apache-chef-demo-0.0.0",
-                  ImmutableSet.<Resource> of(),
-                  ImmutableSet.<Attribute> of(),
-                  ImmutableSet.<Resource> of(),
-                  new Metadata("Apache v2.0", "Your Name", ImmutableMap.<String, String> of(), ImmutableMap
-                        .<String, String> of(), "youremail@example.com", ImmutableMap.<String, String> of(),
-                        "A fabulous new cookbook", ImmutableMap.<String, String> of(), ImmutableMap
-                              .<String, String> of(), "0.0.0", ImmutableMap.<String, String> of(), ImmutableMap
-                              .<String, String> of(), "apache-chef-demo", ImmutableMap.<String, String> of(), "",
-                        ImmutableMap.<String, Attribute> of(), ImmutableMap.<String, String> of()),
-                  ImmutableSet.<Resource> of(),
-                  "apache-chef-demo",
-                  ImmutableSet.<Resource> of(),
-                  ImmutableSet.<Resource> of(),
-                  ImmutableSet.<Resource> of(),
-                  "0.0.0",
-                  ImmutableSet.<Resource> of(),
-                  ImmutableSet.<Resource> of(
-                        new Resource(
-                              "README",
-                              URI.create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-11637f98942eafbf49c71b7f2f048b78?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=zgpNl6wSxjTNovqZu2nJq0JztU8%3D"),
-                              base16().lowerCase().decode("11637f98942eafbf49c71b7f2f048b78"), "README", "default"),
-                        new Resource(
-                              "Rakefile",
-                              URI.create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-ebcf925a1651b4e04b9cd8aac2bc54eb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=EFzzDSKKytTl7b%2FxrCeNLh05zj4%3D"),
-                              base16().lowerCase().decode("ebcf925a1651b4e04b9cd8aac2bc54eb"), "Rakefile", "default"))));
-
+      CookbookVersion fromJson = handler.apply(HttpResponse.builder().statusCode(200).message("ok")
+            .payload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/apache-chef-demo-cookbook.json"))
+            .build());
+
+      CookbookVersion expected = CookbookVersion
+            .builder("apache-chef-demo", "0.0.0")
+            .metadata(Metadata.builder() //
+                  .license("Apache v2.0") //
+                  .maintainer("Your Name") //
+                  .maintainerEmail("youremail@example.com") //
+                  .description("A fabulous new cookbook") //
+                  .version("0.0.0").name("apache-chef-demo") //
+                  .longDescription("") //
+                  .build())
+            .rootFile(
+                  Resource
+                        .builder()
+                        .name("README")
+                        .path("README")
+                        .checksum(base16().lowerCase().decode("11637f98942eafbf49c71b7f2f048b78"))
+                        .url(URI
+                              .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-11637f98942eafbf49c71b7f2f048b78?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=zgpNl6wSxjTNovqZu2nJq0JztU8%3D")) //
+                        .build())
+            .rootFile(
+                  Resource
+                        .builder()
+                        .name("Rakefile")
+                        .path("Rakefile")
+                        .checksum(base16().lowerCase().decode("ebcf925a1651b4e04b9cd8aac2bc54eb"))
+                        .url(URI
+                              .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-ebcf925a1651b4e04b9cd8aac2bc54eb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=EFzzDSKKytTl7b%2FxrCeNLh05zj4%3D"))
+                        .build()) //
+            .build();
+
+      assertEquals(fromJson, expected);
    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java b/core/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java
index d0d9070..5f825dd 100644
--- a/core/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java
+++ b/core/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java
@@ -19,7 +19,6 @@ package org.jclouds.chef.functions;
 import static org.testng.Assert.assertEquals;
 
 import java.io.IOException;
-import java.util.Collections;
 
 import org.jclouds.chef.ChefApi;
 import org.jclouds.chef.config.ChefParserModule;
@@ -32,7 +31,6 @@ import org.jclouds.rest.annotations.ApiVersion;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableMap;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
@@ -63,10 +61,12 @@ public class ParseNodeFromJsonTest {
    }
 
    public void test() {
-
-      Node node = new Node("adrian-jcloudstest", ImmutableMap.<String, JsonBall> of("tomcat6", new JsonBall(
-            "{\"ssl_port\":8433}")), ImmutableMap.<String, JsonBall> of(), ImmutableMap.<String, JsonBall> of(),
-            ImmutableMap.<String, JsonBall> of(), Collections.singleton("recipe[java]"), "prod");
+      Node node = Node.builder() //
+            .name("adrian-jcloudstest") //
+            .normalAttribute("tomcat6", new JsonBall("{\"ssl_port\":8433}")) //
+            .runListElement("recipe[java]") //
+            .environment("prod") //
+            .build();
 
       assertEquals(
             handler.apply(HttpResponse.builder().statusCode(200).message("ok")

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java b/core/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java
index 76edffd..13843ee 100644
--- a/core/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java
+++ b/core/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java
@@ -31,7 +31,6 @@ import org.jclouds.rest.annotations.ApiVersion;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
@@ -67,8 +66,8 @@ public class ParseSandboxFromJsonTest {
       assertEquals(
             handler.apply(HttpResponse.builder().statusCode(200).message("ok")
                   .payload(ParseSandboxFromJsonTest.class.getResourceAsStream("/sandbox.json")).build()),
-            new Sandbox("1-8c27b0ea4c2b7aaedbb44cfbdfcc11b2", false, dateService
-                  .iso8601SecondsDateParse("2010-07-07T03:36:00+00:00"), ImmutableSet.<String> of(),
-                  "f9d6d9b72bae465890aae87969f98a9c", "f9d6d9b72bae465890aae87969f98a9c"));
+            Sandbox.builder().rev("1-8c27b0ea4c2b7aaedbb44cfbdfcc11b2").isCompleted(false)
+                  .createTime(dateService.iso8601SecondsDateParse("2010-07-07T03:36:00+00:00"))
+                  .name("f9d6d9b72bae465890aae87969f98a9c").guid("f9d6d9b72bae465890aae87969f98a9c").build());
    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java b/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java
index e992e79..03e61ca 100644
--- a/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java
+++ b/core/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java
@@ -22,7 +22,6 @@ import static org.testng.Assert.assertEquals;
 
 import java.io.IOException;
 import java.net.URI;
-import java.util.List;
 
 import org.jclouds.chef.ChefApi;
 import org.jclouds.chef.config.ChefParserModule;
@@ -35,7 +34,6 @@ import org.jclouds.rest.annotations.ApiVersion;
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.Test;
 
-import com.google.common.collect.ImmutableMap;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
@@ -70,14 +68,22 @@ public class ParseUploadSandboxFromJsonTest {
       assertEquals(
             handler.apply(HttpResponse.builder().statusCode(200).message("ok")
                   .payload(ParseUploadSandboxFromJsonTest.class.getResourceAsStream("/upload-site.json")).build()),
-            new UploadSandbox(
-                  URI.create("https://api.opscode.com/organizations/jclouds/sandboxes/d454f71e2a5f400c808d0c5d04c2c88c"),
-                  ImmutableMap.<List<Byte>, ChecksumStatus> of(
+            UploadSandbox
+                  .builder()
+                  .uri(URI
+                        .create("https://api.opscode.com/organizations/jclouds/sandboxes/d454f71e2a5f400c808d0c5d04c2c88c"))
+                  .checksum(
                         asList(base16().lowerCase().decode("0c5ecd7788cf4f6c7de2a57193897a6c")),
-                        new ChecksumStatus(
-                              URI.create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/sandbox-d454f71e2a5f400c808d0c5d04c2c88c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277344702&Signature=FtKyqvYEjhhEKmRY%2B0M8aGPMM7g%3D"),
-                              true), asList(base16().lowerCase().decode("0189e76ccc476701d6b374e5a1a27347")),
-                        new ChecksumStatus(), asList(base16().lowerCase().decode("1dda05ed139664f1f89b9dec482b77c0")),
-                        new ChecksumStatus()), "d454f71e2a5f400c808d0c5d04c2c88c"));
+                        ChecksumStatus
+                              .builder()
+                              .url(URI
+                                    .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/sandbox-d454f71e2a5f400c808d0c5d04c2c88c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277344702&Signature=FtKyqvYEjhhEKmRY%2B0M8aGPMM7g%3D"))
+                              .needsUpload(true).build())
+                  .checksum(asList(base16().lowerCase().decode("0189e76ccc476701d6b374e5a1a27347")),
+                        ChecksumStatus.builder().build())
+                  .checksum(asList(base16().lowerCase().decode("1dda05ed139664f1f89b9dec482b77c0")),
+                        ChecksumStatus.builder().build()).sandboxId("d454f71e2a5f400c808d0c5d04c2c88c").build()
+
+      );
    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java b/core/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java
index 2504b53..98c7d07 100644
--- a/core/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java
+++ b/core/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java
@@ -48,7 +48,7 @@ public class UriForResourceTest {
    @Test
    public void testWithValidResource() {
       Function<Object, URI> function = new UriForResource();
-      Resource res = new Resource("test", URI.create("http://foo/bar"), null, null, null);
+      Resource res = Resource.builder().name("test").url(URI.create("http://foo/bar")).build();
       URI result = function.apply(res);
       assertEquals(res.getUrl().toString(), result.toString());
    }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java b/core/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java
index adf11cf..529df68 100644
--- a/core/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java
+++ b/core/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java
@@ -17,6 +17,7 @@
 package org.jclouds.chef.internal;
 
 import static com.google.common.base.Throwables.propagate;
+import static com.google.common.collect.Iterables.isEmpty;
 import static com.google.common.hash.Hashing.md5;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static org.jclouds.io.ByteSources.asByteSource;
@@ -25,6 +26,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
 
 import java.io.File;
 import java.io.IOException;
@@ -40,6 +42,7 @@ import org.jclouds.chef.domain.Client;
 import org.jclouds.chef.domain.CookbookVersion;
 import org.jclouds.chef.domain.DatabagItem;
 import org.jclouds.chef.domain.Environment;
+import org.jclouds.chef.domain.Metadata;
 import org.jclouds.chef.domain.Node;
 import org.jclouds.chef.domain.Resource;
 import org.jclouds.chef.domain.Role;
@@ -78,71 +81,88 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    protected DatabagItem databagItem;
 
    public void testCreateNewCookbook() throws Exception {
-
-      // define the file you want in the cookbook
+      // Define the file you want in the cookbook
       FilePayload content = Payloads.newFilePayload(new File(System.getProperty("user.dir"), "pom.xml"));
       content.getContentMetadata().setContentType("application/x-binary");
 
-      // get an md5 so that you can see if the server already has it or not
+      // Get an md5 so that you can see if the server already has it or not
       Payloads.calculateMD5(content);
 
       // Note that java collections cannot effectively do equals or hashcodes on
-      // byte arrays,
-      // so let's convert to a list of bytes.
+      // byte arrays, so let's convert to a list of bytes.
       List<Byte> md5 = Bytes.asList(content.getContentMetadata().getContentMD5());
 
-      // request an upload site for this file
+      // Request an upload site for this file
       UploadSandbox site = api.getUploadSandboxForChecksums(ImmutableSet.of(md5));
+      assertTrue(site.getChecksums().containsKey(md5), md5 + " not in " + site.getChecksums());
 
       try {
-         assert site.getChecksums().containsKey(md5) : md5 + " not in " + site.getChecksums();
-
+         // Upload the file contents, if still not uploaded
          ChecksumStatus status = site.getChecksums().get(md5);
          if (status.needsUpload()) {
-            // context.utils().http().put(status.getUrl(), content);
             api.uploadContent(status.getUrl(), content);
          }
-
          api.commitSandbox(site.getSandboxId(), true);
-
       } catch (RuntimeException e) {
          api.commitSandbox(site.getSandboxId(), false);
+         fail("Could not upload content");
       }
 
-      // create a new cookbook
-      CookbookVersion cookbook = new CookbookVersion(PREFIX, "0.0.0");
-      cookbook.getRootFiles().add(new Resource(content));
+      // Create the metadata of the cookbook
+      Metadata metadata = Metadata.builder() //
+            .name(PREFIX) //
+            .version("0.0.0") //
+            .description("Jclouds test uploaded cookbook") //
+            .maintainer("jclouds") //
+            .maintainerEmail("someone@jclouds.org") //
+            .license("Apache 2.0") //
+            .build();
+
+      // Create a new cookbook
+      CookbookVersion cookbook = CookbookVersion.builder(PREFIX, "0.0.0") //
+            .metadata(metadata) //
+            .rootFile(Resource.builder().fromPayload(content).build()) //
+            .build();
 
       // upload the cookbook to the remote server
       api.updateCookbook(PREFIX, "0.0.0", cookbook);
    }
 
-   @Test(dependsOnMethods = "testCreateClient")
-   public void testGenerateKeyForClient() throws Exception {
-      String credential = Pems.pem(api.generateKeyForClient(PREFIX).getPrivateKey());
-      assertClientCreated(PREFIX, credential);
-   }
-
-   @Test
    public void testListCookbooks() throws Exception {
       Set<String> cookbookNames = api.listCookbooks();
-      assertFalse(cookbookNames.isEmpty());
-
-      for (String cookbook : cookbookNames) {
-         for (String version : api.getVersionsOfCookbook(cookbook)) {
-            CookbookVersion cookbookO = api.getCookbook(cookbook, version);
-            for (Resource resource : ImmutableList.<Resource> builder().addAll(cookbookO.getDefinitions())
-                  .addAll(cookbookO.getFiles()).addAll(cookbookO.getLibraries()).addAll(cookbookO.getSuppliers())
-                  .addAll(cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll(cookbookO.getRootFiles())
-                  .addAll(cookbookO.getTemplates()).build()) {
-               try {
-                  InputStream stream = api.getResourceContents(resource);
-                  byte[] md5 = asByteSource(stream).hash(md5()).asBytes();
-                  assertEquals(md5, resource.getChecksum());
-               } catch (NullPointerException e) {
-                  assert false : "resource not found: " + resource;
-               }
-            }
+      assertFalse(cookbookNames.isEmpty(), "No cookbooks were found");
+
+      for (String cookbookName : cookbookNames) {
+         Set<String> versions = api.getVersionsOfCookbook(cookbookName);
+         assertFalse(versions.isEmpty(), "There are no versions of the cookbook: " + cookbookName);
+
+         for (String version : api.getVersionsOfCookbook(cookbookName)) {
+            CookbookVersion cookbook = api.getCookbook(cookbookName, version);
+            assertNotNull(cookbook, "Could not get cookbook: " + cookbookName);
+         }
+      }
+   }
+
+   @Test(dependsOnMethods = "testListCookbooks")
+   public void testListCookbookVersionsWithChefService() throws Exception {
+      Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions();
+      assertFalse(isEmpty(cookbooks), "No cookbooks were found");
+   }
+
+   @Test(dependsOnMethods = "testListCookbookVersionsWithChefService")
+   public void testDownloadCookbooks() throws Exception {
+      Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions();
+      for (CookbookVersion cookbook : cookbooks) {
+         for (Resource resource : ImmutableList.<Resource> builder().addAll(cookbook.getDefinitions())
+               .addAll(cookbook.getFiles()).addAll(cookbook.getLibraries()).addAll(cookbook.getSuppliers())
+               .addAll(cookbook.getRecipes()).addAll(cookbook.getResources()).addAll(cookbook.getRootFiles())
+               .addAll(cookbook.getTemplates()).build()) {
+
+            InputStream stream = api.getResourceContents(resource);
+            assertNotNull(stream, "Resource contents are null for resource: " + resource.getName());
+
+            byte[] md5 = asByteSource(stream).hash(md5()).asBytes();
+            assertEquals(md5, resource.getChecksum());
          }
       }
    }
@@ -150,12 +170,13 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    @Test(dependsOnMethods = "testCreateNewCookbook")
    public void testUpdateCookbook() throws Exception {
       CookbookVersion cookbook = api.getCookbook(PREFIX, "0.0.0");
-      assertNotNull(api.updateCookbook(PREFIX, "0.0.0", cookbook));
+      assertNotNull(cookbook, "Cookbook not found: " + PREFIX);
+      assertNotNull(api.updateCookbook(PREFIX, "0.0.0", cookbook), "Updated cookbook was null");
    }
 
    @Test(dependsOnMethods = { "testCreateNewCookbook", "testUpdateCookbook" })
    public void testDeleteCookbook() throws Exception {
-      assertNotNull(api.deleteCookbook(PREFIX, "0.0.0"));
+      assertNotNull(api.deleteCookbook(PREFIX, "0.0.0"), "Deleted cookbook was null");
    }
 
    @Test
@@ -172,34 +193,30 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
       assertClientCreated(ADMIN_PREFIX, credential);
    }
 
-   @Test
-   public void testClientExists() throws Exception {
-      assertNotNull(api.clientExists(identity));
+   @Test(dependsOnMethods = "testCreateClient")
+   public void testGenerateKeyForClient() throws Exception {
+      String credential = Pems.pem(api.generateKeyForClient(PREFIX).getPrivateKey());
+      assertClientCreated(PREFIX, credential);
    }
 
    @Test
    public void testListNodes() throws Exception {
       Set<String> nodes = api.listNodes();
-      assertNotNull(nodes);
+      assertNotNull(nodes, "No nodes were found");
    }
 
    @Test(dependsOnMethods = "testCreateRole")
    public void testCreateNode() throws Exception {
       api.deleteNode(PREFIX);
-      api.createNode(new Node(PREFIX, Collections.singleton("role[" + PREFIX + "]"), "_default"));
+      api.createNode(Node.builder().name(PREFIX).runListElement("role[" + PREFIX + "]").environment("_default").build());
       node = api.getNode(PREFIX);
       // TODO check recipes
-      assertNotNull(node);
+      assertNotNull(node, "Created node should not be null");
       Set<String> nodes = api.listNodes();
-      assert nodes.contains(PREFIX) : String.format("node %s not in %s", PREFIX, nodes);
+      assertTrue(nodes.contains(PREFIX), String.format("node %s not in %s", PREFIX, nodes));
    }
 
    @Test(dependsOnMethods = "testCreateNode")
-   public void testNodeExists() throws Exception {
-      assertNotNull(api.nodeExists(PREFIX));
-   }
-
-   @Test(dependsOnMethods = "testNodeExists")
    public void testUpdateNode() throws Exception {
       for (String nodename : api.listNodes()) {
          Node node = api.getNode(nodename);
@@ -210,25 +227,20 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    @Test
    public void testListRoles() throws Exception {
       Set<String> roles = api.listRoles();
-      assertNotNull(roles);
+      assertNotNull(roles, "Role list was null");
    }
 
    @Test
    public void testCreateRole() throws Exception {
       api.deleteRole(PREFIX);
-      api.createRole(new Role(PREFIX, Collections.singleton("recipe[java]")));
+      api.createRole(Role.builder().name(PREFIX).runListElement("recipe[java]").build());
       role = api.getRole(PREFIX);
-      assertNotNull(role);
+      assertNotNull(role, "Created role should not be null");
       assertEquals(role.getName(), PREFIX);
       assertEquals(role.getRunList(), Collections.singleton("recipe[java]"));
    }
 
    @Test(dependsOnMethods = "testCreateRole")
-   public void testRoleExists() throws Exception {
-      assertNotNull(api.roleExists(PREFIX));
-   }
-
-   @Test(dependsOnMethods = "testRoleExists")
    public void testUpdateRole() throws Exception {
       for (String rolename : api.listRoles()) {
          Role role = api.getRole(rolename);
@@ -239,7 +251,7 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    @Test
    public void testListDatabags() throws Exception {
       Set<String> databags = api.listDatabags();
-      assertNotNull(databags);
+      assertNotNull(databags, "Data bag list was null");
    }
 
    @Test
@@ -248,15 +260,10 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
       api.createDatabag(PREFIX);
    }
 
-   @Test(dependsOnMethods = "testCreateDatabag")
-   public void testDatabagExists() throws Exception {
-      assertNotNull(api.databagExists(PREFIX));
-   }
-
    @Test(dependsOnMethods = "testCreateDatabagItem")
    public void testListDatabagItems() throws Exception {
       Set<String> databagItems = api.listDatabagItems(PREFIX);
-      assertNotNull(databagItems);
+      assertNotNull(databagItems, "Data bag item list was null");
    }
 
    @Test(dependsOnMethods = "testCreateDatabag")
@@ -265,7 +272,7 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
       config.setProperty("foo", "bar");
       api.deleteDatabagItem(PREFIX, PREFIX);
       databagItem = api.createDatabagItem(PREFIX, new DatabagItem("config", json.toJson(config)));
-      assertNotNull(databagItem);
+      assertNotNull(databagItem, "Created data bag item should not be null");
       assertEquals(databagItem.getId(), "config");
 
       // The databagItem json contains extra keys: (the name and the type if the
@@ -278,11 +285,6 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    }
 
    @Test(dependsOnMethods = "testCreateDatabagItem")
-   public void testDatabagItemExists() throws Exception {
-      assertNotNull(api.databagItemExists(PREFIX, PREFIX));
-   }
-
-   @Test(dependsOnMethods = "testDatabagItemExists")
    public void testUpdateDatabagItem() throws Exception {
       for (String databagItemId : api.listDatabagItems(PREFIX)) {
          DatabagItem databagItem = api.getDatabagItem(PREFIX, databagItemId);
@@ -293,16 +295,16 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    @Test
    public void testListSearchIndexes() throws Exception {
       Set<String> indexes = api.listSearchIndexes();
-      assertNotNull(indexes);
-      assert indexes.contains("node") : indexes;
-      assert indexes.contains("client") : indexes;
-      assert indexes.contains("role") : indexes;
+      assertNotNull(indexes, "The index list should not be null");
+      assertTrue(indexes.contains("node"));
+      assertTrue(indexes.contains("client"));
+      assertTrue(indexes.contains("role"));
    }
 
    @Test
    public void testSearchNodes() throws Exception {
       SearchResult<? extends Node> results = api.searchNodes();
-      assertNotNull(results);
+      assertNotNull(results, "Node result list should not be null");
    }
 
    @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateNode" })
@@ -330,7 +332,7 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    @Test
    public void testSearchClients() throws Exception {
       SearchResult<? extends Client> results = api.searchClients();
-      assertNotNull(results);
+      assertNotNull(results, "Client result list should not be null");
    }
 
    @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateClient" })
@@ -358,7 +360,7 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    @Test
    public void testSearchRoles() throws Exception {
       SearchResult<? extends Role> results = api.searchRoles();
-      assertNotNull(results);
+      assertNotNull(results, "Role result list should not be null");
    }
 
    @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateRole" })
@@ -383,13 +385,13 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
       assertTrue(waitForIndex.apply(options));
    }
 
-   @Test(dependsOnMethods = { "testListSearchIndexes", "testDatabagItemExists" })
+   @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" })
    public void testSearchDatabag() throws Exception {
       SearchResult<? extends DatabagItem> results = api.searchDatabag(PREFIX);
-      assertNotNull(results);
+      assertNotNull(results, "Data bag item result list should not be null");
    }
 
-   @Test(dependsOnMethods = { "testListSearchIndexes", "testDatabagItemExists" })
+   @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" })
    public void testSearchDatabagWithOptions() throws Exception {
       Predicate<SearchOptions> waitForIndex = retry(new Predicate<SearchOptions>() {
          @Override
@@ -414,15 +416,15 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    @Test(expectedExceptions = ResourceNotFoundException.class, dependsOnMethods = "testListSearchIndexes")
    public void testSearchDatabagNotFound() throws Exception {
       SearchResult<? extends DatabagItem> results = api.searchDatabag("whoopie");
-      assertNotNull(results);
+      assertNotNull(results, "Data bag item result list should not be null");
    }
 
    @Test
    public void testCreateEnvironment() {
       api.deleteEnvironment(PREFIX);
-      api.createEnvironment(new Environment(PREFIX, PREFIX));
+      api.createEnvironment(Environment.builder().name(PREFIX).description(PREFIX).build());
       Environment env = api.getEnvironment(PREFIX);
-      assertNotNull(env);
+      assertNotNull(env, "Created environment should not be null");
       assertEquals(env.getName(), PREFIX);
       assertEquals(env.getDescription(), PREFIX);
    }
@@ -430,14 +432,14 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
    @Test(dependsOnMethods = "testCreateEnvironment")
    public void testListEnvironment() {
       Set<String> envList = api.listEnvironments();
-      assertNotNull(envList);
+      assertNotNull(envList, "Environment list was null");
       assertTrue(envList.contains(PREFIX));
    }
 
    @Test(dependsOnMethods = "testCreateEnvironment")
    public void testSearchEnvironments() throws Exception {
       SearchResult<? extends Environment> results = api.searchEnvironments();
-      assertNotNull(results);
+      assertNotNull(results, "Environment result list was null");
    }
 
    @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateEnvironment" })
@@ -462,12 +464,6 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
       assertTrue(waitForIndex.apply(options));
    }
 
-   @Test
-   public void testListCookbookVersionsWithChefService() throws Exception {
-      Iterable<? extends CookbookVersion> cookbooks = chefService.listCookbookVersions();
-      assertNotNull(cookbooks);
-   }
-
    @AfterClass(groups = { "live", "integration" })
    @Override
    public void tearDown() {
@@ -489,7 +485,7 @@ public abstract class BaseChefApiLiveTest<A extends ChefApi> extends BaseChefLiv
 
       try {
          Client client = clientApi.getClient(identity);
-         assertNotNull(client);
+         assertNotNull(client, "Client not found: " + identity);
       } finally {
          try {
             Closeables.close(clientApi, true);

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-chef/blob/3f2a196f/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java b/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java
index a904569..4b55efd 100644
--- a/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java
+++ b/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java
@@ -55,7 +55,7 @@ public class CreateNodeAndPopulateAutomaticAttributesImplLiveTest extends BaseCh
          Node node = api.getNode(prefix);
          assertEquals(node.getName(), prefix);
          assertEquals(node.getRunList(), runList);
-         assertEquals(node.getAutomatic().get("current_user").toString(), currentUserProvider.get().toString());
+         assertEquals(node.getAutomaticAttributes().get("current_user").toString(), currentUserProvider.get().toString());
       } finally {
          api.deleteNode(prefix);
       }