Merge branch 'master' of github.com:jclouds/jclouds-chef into 1.5.x

* 'master' of github.com:jclouds/jclouds-chef:
  More changes in support of Chef environments - Add and update constructors for org.jclouds.chef.domain.Node - Make Node.chefEnvironment nullable - Add JavaDoc indicating environments apply since Chef 0.10 - Update unit tests
  Add support for chef_environment on Node domain object
diff --git a/core/src/main/java/org/jclouds/chef/domain/Node.java b/core/src/main/java/org/jclouds/chef/domain/Node.java
index f4dfafc..34dee88 100644
--- a/core/src/main/java/org/jclouds/chef/domain/Node.java
+++ b/core/src/main/java/org/jclouds/chef/domain/Node.java
@@ -21,6 +21,8 @@
 import java.util.List;
 import java.util.Map;
 
+import javax.annotation.Nullable;
+
 import org.jclouds.domain.JsonBall;
 
 import com.google.common.collect.Iterables;
@@ -44,13 +46,30 @@
    @SerializedName("run_list")
    private List<String> runList = Lists.newArrayList();
 
+   /**
+    * @since chef 0.10
+    */
+   @SerializedName("chef_environment")
+   @Nullable
+   private String chefEnvironment;
+
    // internal
    @SerializedName("json_class")
    private String _jsonClass = "Chef::Node";
 
    public Node(String name, Map<String, JsonBall> normal, Map<String, JsonBall> override,
-         Map<String, JsonBall> defaultA, Map<String, JsonBall> automatic, Iterable<String> runList) {
+	     Map<String, JsonBall> defaultA, Map<String, JsonBall> automatic, Iterable<String> runList) {
+	   this(name, normal, override, defaultA, automatic, runList, null);
+   }
+
+   /**
+    * @since chef 0.10
+    */
+   public Node(String name, Map<String, JsonBall> normal, Map<String, JsonBall> override,
+         Map<String, JsonBall> defaultA, Map<String, JsonBall> automatic, Iterable<String> runList,
+         String chefEnvironment) {
       this.name = name;
+      this.chefEnvironment = chefEnvironment;
       this.normal.putAll(normal);
       this.override.putAll(override);
       this.defaultA.putAll(defaultA);
@@ -65,7 +84,15 @@
    }
 
    public Node(String name, Iterable<String> runList) {
+	   this(name, runList, "_default");
+   }
+
+   /**
+    * @since chef 0.10
+    */
+   public Node(String name, Iterable<String> runList, String chefEnvironment) {
       this.name = name;
+      this.chefEnvironment = chefEnvironment;
       Iterables.addAll(this.runList, runList);
    }
 
@@ -98,6 +125,13 @@
       return runList;
    }
 
+   /**
+    * @since chef 0.10
+    */
+   public String getChefEnvironment() {
+      return chefEnvironment;
+   }
+
    @SerializedName("chef_type")
    private String _chefType = "node";
 
@@ -113,6 +147,7 @@
       result = prime * result + ((normal == null) ? 0 : normal.hashCode());
       result = prime * result + ((override == null) ? 0 : override.hashCode());
       result = prime * result + ((runList == null) ? 0 : runList.hashCode());
+      result = prime * result + ((chefEnvironment == null) ? 0 : chefEnvironment.hashCode());
       return result;
    }
 
@@ -165,7 +200,12 @@
             return false;
       } else if (!runList.equals(other.runList))
          return false;
+      if (chefEnvironment == null) {
+         if (other.chefEnvironment != null)
+            return false;
+      } else if (!chefEnvironment.equals(other.chefEnvironment))
+         return false;
       return true;
    }
 
-}
\ No newline at end of file
+}
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 4e17cf7..68cab45 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
@@ -71,6 +71,6 @@
 
    @Override
    public Node execute(String nodeName, Iterable<String> runList) {
-      return execute(new Node(nodeName, runList));
+      return execute(new Node(nodeName, runList, "_default"));
    }
 }
diff --git a/core/src/test/java/org/jclouds/chef/ChefAsyncApiTest.java b/core/src/test/java/org/jclouds/chef/ChefAsyncApiTest.java
index 5afb83b..18b982d 100644
--- a/core/src/test/java/org/jclouds/chef/ChefAsyncApiTest.java
+++ b/core/src/test/java/org/jclouds/chef/ChefAsyncApiTest.java
@@ -341,13 +341,13 @@
    public void testCreateNode() throws SecurityException, NoSuchMethodException, IOException {
       Method method = ChefAsyncApi.class.getMethod("createNode", Node.class);
       GeneratedHttpRequest httpRequest = processor.createRequest(method, new Node("testnode",
-            ImmutableSet.of("recipe[java]")));
+            ImmutableSet.of("recipe[java]"), "_default"));
 
       assertRequestLineEquals(httpRequest, "POST http://localhost:4000/nodes HTTP/1.1");
       assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefAsyncApi.VERSION + "-test\n");
       assertPayloadEquals(
             httpRequest,
-            "{\"name\":\"testnode\",\"normal\":{},\"override\":{},\"default\":{},\"automatic\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Node\",\"chef_type\":\"node\"}",
+            "{\"name\":\"testnode\",\"normal\":{},\"override\":{},\"default\":{},\"automatic\":{},\"run_list\":[\"recipe[java]\"],\"chef_environment\":\"_default\",\"json_class\":\"Chef::Node\",\"chef_type\":\"node\"}",
             "application/json", false);
 
       assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class);
@@ -361,13 +361,13 @@
    public void testUpdateNode() throws SecurityException, NoSuchMethodException, IOException {
       Method method = ChefAsyncApi.class.getMethod("updateNode", Node.class);
       GeneratedHttpRequest httpRequest = processor.createRequest(method, new Node("testnode",
-            ImmutableSet.of("recipe[java]")));
+            ImmutableSet.of("recipe[java]"), "_default"));
 
       assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/nodes/testnode HTTP/1.1");
       assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefAsyncApi.VERSION + "-test\n");
       assertPayloadEquals(
             httpRequest,
-            "{\"name\":\"testnode\",\"normal\":{},\"override\":{},\"default\":{},\"automatic\":{},\"run_list\":[\"recipe[java]\"],\"json_class\":\"Chef::Node\",\"chef_type\":\"node\"}",
+            "{\"name\":\"testnode\",\"normal\":{},\"override\":{},\"default\":{},\"automatic\":{},\"run_list\":[\"recipe[java]\"],\"chef_environment\":\"_default\",\"json_class\":\"Chef::Node\",\"chef_type\":\"node\"}",
             "application/json", false);
 
       assertResponseParserClassEquals(method, httpRequest, ParseJson.class);
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 f1bfb5d..45278cd 100644
--- a/core/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java
+++ b/core/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java
@@ -69,7 +69,7 @@
 
       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]"));
+            ImmutableMap.<String, JsonBall> of(), Collections.singleton("recipe[java]"), "prod");
 
       assertEquals(handler.apply(HttpResponse.builder()
                .statusCode(200)
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 e37023b..aba7468 100644
--- a/core/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java
+++ b/core/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java
@@ -221,7 +221,7 @@
    @Test(dependsOnMethods = "testCreateRole")
    public void testCreateNode() throws Exception {
       chefApi.deleteNode(PREFIX);
-      chefApi.createNode(new Node(PREFIX, Collections.singleton("role[" + PREFIX + "]")));
+      chefApi.createNode(new Node(PREFIX, Collections.singleton("role[" + PREFIX + "]"), "_default"));
       node = chefApi.getNode(PREFIX);
       // TODO check recipes
       assertNotNull(node);
diff --git a/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java b/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java
index 802f9a2..29a2f96 100644
--- a/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java
+++ b/core/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java
@@ -48,12 +48,13 @@
 
       Map<String, JsonBall> automatic = ImmutableMap.<String, JsonBall> of();
 
-      Node node = new Node("name", ImmutableSet.<String> of());
+      Node node = new Node("name", ImmutableSet.<String> of(), "_default");
 
       Supplier<Map<String, JsonBall>> automaticSupplier = Suppliers.<Map<String, JsonBall>> ofInstance(automatic);
 
       Node nodeWithAutomatic = new Node("name", ImmutableMap.<String, JsonBall> of(), ImmutableMap
-            .<String, JsonBall> of(), ImmutableMap.<String, JsonBall> of(), automatic, ImmutableSet.<String> of());
+            .<String, JsonBall> of(), ImmutableMap.<String, JsonBall> of(), automatic, ImmutableSet.<String> of(),
+            "_default");
 
       node.getAutomatic().putAll(automaticSupplier.get());
       chef.createNode(nodeWithAutomatic);
diff --git a/core/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java b/core/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java
index fe87b95..bfc1869 100644
--- a/core/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java
+++ b/core/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java
@@ -53,7 +53,7 @@
    public void testExecute() {
       Set<String> runList = ImmutableSet.of("role[" + prefix + "]");
       try {
-         context.getApi().createNode(new Node(prefix, runList));
+         context.getApi().createNode(new Node(prefix, runList, "_default"));
          context.utils().injector().getInstance(UpdateAutomaticAttributesOnNodeImpl.class).execute(prefix);
          Node node = context.getApi().getNode(prefix);
          assertEquals(node.getName(), prefix);
diff --git a/core/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java b/core/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java
index 517238d..9e27c01 100644
--- a/core/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java
+++ b/core/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java
@@ -49,12 +49,13 @@
 
       Map<String, JsonBall> automatic = ImmutableMap.<String, JsonBall> of();
 
-      Node node = new Node("name", ImmutableSet.<String> of());
+      Node node = new Node("name", ImmutableSet.<String> of(), "_default");
 
       Supplier<Map<String, JsonBall>> automaticSupplier = Suppliers.<Map<String, JsonBall>> ofInstance(automatic);
 
       Node nodeWithAutomatic = new Node("name", ImmutableMap.<String, JsonBall> of(), ImmutableMap
-            .<String, JsonBall> of(), ImmutableMap.<String, JsonBall> of(), automatic, ImmutableSet.<String> of());
+            .<String, JsonBall> of(), ImmutableMap.<String, JsonBall> of(), automatic, ImmutableSet.<String> of(),
+            "_default");
 
       expect(chef.getNode("name")).andReturn(node);
       node.getAutomatic().putAll(automaticSupplier.get());
diff --git a/core/src/test/resources/node.json b/core/src/test/resources/node.json
index a367c3d..ecdb470 100644
--- a/core/src/test/resources/node.json
+++ b/core/src/test/resources/node.json
@@ -1 +1,2 @@
-{"normal":{"tomcat6":{"ssl_port":8433}},"name":"adrian-jcloudstest","override":{},"default":{},"json_class":"Chef::Node","automatic":{},"run_list":["recipe[java]"],"chef_type":"node"}
\ No newline at end of file
+{"normal":{"tomcat6":{"ssl_port":8433}},"name":"adrian-jcloudstest","override":{},"default":{},"json_class":"Chef::Node","automatic":{},"run_list":["recipe[java]"],"chef_type":"node","chef_environment": "prod"}
+