You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/14 05:42:30 UTC

[01/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master e5289b84c -> d32d672ad


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java
index 6683cff..610b990 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java
@@ -25,16 +25,14 @@ import java.net.ServerSocket;
 import java.util.Iterator;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppService;
-import org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppServiceImpl;
 import org.jclouds.util.Throwables2;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.net.Networking;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java
index cb4a26e..7717d81 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java
@@ -23,12 +23,11 @@ import static org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppFixtureIntegr
 import static org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppFixtureIntegrationTest.GIT_REPO_URL;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppService;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java
index c9588f8..eb46abe 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java
@@ -23,11 +23,10 @@ import static org.testng.Assert.assertNotNull;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java
index c7442e6..8215e7b 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java
@@ -23,11 +23,10 @@ import static org.testng.Assert.assertNotNull;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerWebAppFixtureIntegrationTest.java
index 756662f..2cc62c1 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerWebAppFixtureIntegrationTest.java
@@ -35,13 +35,12 @@ import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.webapp.AbstractWebAppFixtureIntegrationTest;
 import org.apache.brooklyn.entity.webapp.HttpsSslConfig;
 import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.apache.brooklyn.test.entity.TestApplication;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
index c238a5d..a4c267d 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerDisableRetrieveUsageMetricsIntegrationTest.java
@@ -22,13 +22,12 @@ import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java
index f0ee610..0b591a0 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java
@@ -21,16 +21,13 @@ package org.apache.brooklyn.entity.webapp.tomcat;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
-import java.net.URL;
-
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java
index 61a9c8c..ad9939f 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java
@@ -21,16 +21,13 @@ package org.apache.brooklyn.entity.webapp.tomcat;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
-import java.net.URL;
-
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerWebAppFixtureIntegrationTest.java
index c660fdb..8ad5e29 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerWebAppFixtureIntegrationTest.java
@@ -31,7 +31,6 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.webapp.AbstractWebAppFixtureIntegrationTest;
 import org.apache.brooklyn.entity.webapp.HttpsSslConfig;
 import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -42,7 +41,7 @@ import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.repeat.Repeater;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java b/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java
index 60f0f2c..09cafd2 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java
@@ -32,7 +32,7 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.SoftwareProcessDriverLifecycleEffectorTasks;
 import brooklyn.entity.java.VanillaJavaApp;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.config.ConfigBag;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
----------------------------------------------------------------------
diff --git a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
index 71e06b8..c9b73e0 100644
--- a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
+++ b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.policy.autoscaling.AutoScalerPolicy;
 import brooklyn.util.maven.MavenArtifact;
 import brooklyn.util.maven.MavenRetriever;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/SingleWebServerSample.java
----------------------------------------------------------------------
diff --git a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/SingleWebServerSample.java b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/SingleWebServerSample.java
index dc1b7bc..ac241de 100644
--- a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/SingleWebServerSample.java
+++ b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/SingleWebServerSample.java
@@ -8,7 +8,7 @@ import brooklyn.entity.basic.Attributes;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.maven.MavenArtifact;
 import brooklyn.util.maven.MavenRetriever;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index dc6e97a..53c8eeb 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -53,7 +53,7 @@ import brooklyn.entity.basic.BrooklynTags;
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.proxying.InternalEntityFactory;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.ManagementContextInjectable;
 import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
index 39b1d5f..298b093 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
@@ -24,8 +24,8 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.management.ManagementContext;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
index 7e4d603..6fb5816 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
@@ -41,14 +41,14 @@ import com.google.common.net.HostAndPort;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.DoNothingSoftwareProcess;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.access.PortForwardManager;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.LocationPredicates;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.basic.WinRmMachineLocation;
-import brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.access.PortForwardManager;
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocationPredicates;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import brooklyn.test.Asserts;
 import brooklyn.util.net.UserAndHostAndPort;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
index 34cb894..fc942da 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
@@ -29,8 +29,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.Jsonya;
 
 @Test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
index 72f656b..db185da 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
@@ -59,7 +59,7 @@ import brooklyn.entity.basic.SameServerEntity;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.EntityManagerInternal;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
index bcb0fa5..0f8c839 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
@@ -31,12 +31,12 @@ import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.MultiLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.MultiLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.text.Strings;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
index 7c6ea94..82181d5 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
@@ -25,7 +25,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class TestEntityWithInitConfigImpl extends AbstractEntity implements TestEntityWithInitConfig {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
index 2071eb0..19849b3 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
@@ -36,7 +36,7 @@ import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
 import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityMatcher;
 
 import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.LocationSpec;
 import brooklyn.management.osgi.OsgiVersionMoreEntityTest;
 
 import org.apache.brooklyn.policy.Policy;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
index 14e2989..8788d5b 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
@@ -33,10 +33,10 @@ import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
 
 import brooklyn.catalog.CatalogPredicates;
 import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.osgi.OsgiStandaloneTest;
 
 import org.apache.brooklyn.test.TestResourceUnavailableException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
index 044042a..ba0a25b 100644
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
@@ -39,12 +39,12 @@ import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.options.TemplateOptions;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsUtil;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsUtil;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
 import brooklyn.util.stream.Streams;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
index 5261432..61cc6de 100644
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
@@ -41,8 +41,8 @@ import org.apache.brooklyn.cli.lister.ItemDescriptors;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationResolver;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.net.Urls;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
index 2ab20b1..11a636d 100644
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
@@ -39,7 +39,7 @@ import org.apache.brooklyn.api.event.Sensor;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationResolver;
 
 import org.apache.brooklyn.rest.domain.EffectorSummary;
 import org.apache.brooklyn.rest.domain.EntityConfigSummary;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java b/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
index b70ac33..123acd3 100644
--- a/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
+++ b/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
@@ -44,7 +44,6 @@ import java.util.regex.Pattern;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
-import org.apache.brooklyn.cli.Main;
 import org.apache.brooklyn.cli.AbstractMain.BrooklynCommand;
 import org.apache.brooklyn.cli.AbstractMain.BrooklynCommandCollectingArgs;
 import org.apache.brooklyn.cli.AbstractMain.HelpCommand;
@@ -58,12 +57,6 @@ import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-import org.apache.brooklyn.cli.AbstractMain.BrooklynCommand;
-import org.apache.brooklyn.cli.AbstractMain.BrooklynCommandCollectingArgs;
-import org.apache.brooklyn.cli.AbstractMain.HelpCommand;
-import org.apache.brooklyn.cli.Main.AppShutdownHandler;
-import org.apache.brooklyn.cli.Main.GeneratePasswordCommand;
-import org.apache.brooklyn.cli.Main.LaunchCommand;
 
 import brooklyn.entity.basic.AbstractApplication;
 import brooklyn.entity.basic.AbstractEntity;
@@ -72,8 +65,8 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.StartableApplication;
 import brooklyn.entity.proxying.EntityProxy;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
index 2788426..f5a6b2c 100644
--- a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
+++ b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
@@ -81,11 +81,11 @@ import brooklyn.entity.trait.Startable;
 import org.apache.brooklyn.launcher.config.StopWhichAppsOnShutdown;
 import org.apache.brooklyn.mementos.BrooklynMementoRawData;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.management.ha.HighAvailabilityManagerImpl;
 import brooklyn.management.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import brooklyn.management.internal.LocalManagementContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
index a2a55c7..d63bb68 100644
--- a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
+++ b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
@@ -68,9 +68,9 @@ import brooklyn.internal.BrooklynInitialization;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.launcher.config.CustomResourceLocator;
 
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.management.internal.ManagementContextInternal;
 
 import org.apache.brooklyn.rest.BrooklynRestApi;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/launcher/src/main/java/org/apache/brooklyn/launcher/config/BrooklynGlobalConfig.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/config/BrooklynGlobalConfig.java b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/config/BrooklynGlobalConfig.java
index 2e1b54d..55ed04a 100644
--- a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/config/BrooklynGlobalConfig.java
+++ b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/config/BrooklynGlobalConfig.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.launcher.config;
 import brooklyn.config.BrooklynServiceAttributes;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import brooklyn.management.internal.BrooklynGarbageCollector;
 import org.apache.brooklyn.rest.BrooklynWebConfig;
 import brooklyn.util.internal.BrooklynSystemProperties;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java b/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
index 2320a33..9489ad4 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
@@ -46,7 +46,7 @@ import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.launcher.SimpleYamlLauncherForTests;
 import org.apache.brooklyn.launcher.camp.SimpleYamlLauncher;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.Jsonya;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
index a34a988..13931e4 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
@@ -45,7 +45,7 @@ import brooklyn.entity.basic.StartableApplication;
 import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.exceptions.FatalConfigurationRuntimeException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
index 8376f31..822a0ed 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
@@ -51,8 +51,8 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.config.BrooklynServerConfig;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.exceptions.FatalRuntimeException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
index e40cae9..a3241af 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
@@ -33,8 +33,8 @@ import brooklyn.event.feed.function.FunctionPollConfig;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.guava.Functionals;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
index 8a24f73..7570cc5 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
@@ -30,7 +30,7 @@ import brooklyn.entity.database.mysql.MySqlSshDriver;
 import brooklyn.entity.software.SshEffectorTasks;
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.task.system.ProcessTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
index db5e97e..8a7a824 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
@@ -38,7 +38,7 @@ import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
index b017ae1..bc7b2c3 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
@@ -47,7 +47,7 @@ import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.policy.autoscaling.AutoScalerPolicy;
 import brooklyn.util.CommandLineUtil;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
index a535e91..2748179 100644
--- a/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
@@ -45,8 +45,8 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
-import brooklyn.location.Location;
-import brooklyn.location.jclouds.JcloudsLocationConfig;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig;
 import brooklyn.util.BrooklynMavenArtifacts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
index ac3629f..e7dc4d4 100644
--- a/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.brooklyn.qa.load;
 
-import org.apache.brooklyn.qa.load.SimulatedTheeTierApp;
 import org.apache.brooklyn.test.PerformanceTestUtils;
 
 import static org.testng.Assert.assertEquals;
@@ -47,7 +46,7 @@ import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.os.Os;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/LocationSpec.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/LocationSpec.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/LocationSpec.java
index d6b9d41..8cbb9c5 100644
--- a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/LocationSpec.java
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/LocationSpec.java
@@ -31,7 +31,7 @@ import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableMap;
 
-// FIXME change name, due to confusion with brooklyn.location.LocationSpec <- no need, as we can kill the class instead soon!
+// FIXME change name, due to confusion with LocationSpec <- no need, as we can kill the class instead soon!
 /** @deprecated since 0.7.0 location spec objects will not be used from the client, instead pass yaml location spec strings */
 public class LocationSpec implements HasName, HasConfig, Serializable {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java b/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java
index 15697de..be3a690 100644
--- a/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java
+++ b/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java
@@ -36,7 +36,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.StartableApplication;
-import brooklyn.location.basic.BasicLocationRegistry;
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 import brooklyn.management.internal.LocalManagementContext;
 
 import org.apache.brooklyn.api.entity.Application;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java b/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
index dbda216..9c5c20e 100644
--- a/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
+++ b/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
@@ -35,7 +35,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.StartableApplication;
-import brooklyn.location.basic.BasicLocationRegistry;
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 import brooklyn.management.internal.LocalManagementContext;
 
 import org.apache.brooklyn.api.entity.Application;
@@ -45,7 +45,6 @@ import org.apache.brooklyn.rest.BrooklynRestApiLauncherTest;
 import org.apache.brooklyn.rest.domain.ApplicationSummary;
 import org.apache.brooklyn.rest.domain.CatalogLocationSummary;
 import org.apache.brooklyn.rest.security.provider.TestSecurityProvider;
-import org.apache.brooklyn.test.HttpTestUtils;
 
 @Test
 public class BrooklynApiRestClientTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
index aaabaac..ef9d8e6 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
@@ -22,7 +22,7 @@ import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigMap;
 import brooklyn.config.ConfigPredicates;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.PortRange;
+import org.apache.brooklyn.location.PortRange;
 import org.apache.brooklyn.rest.security.provider.DelegatingSecurityProvider;
 import org.apache.brooklyn.rest.security.provider.ExplicitUsersSecurityProvider;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index 2073cd8..96b098f 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -52,7 +52,7 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.EntitlementPredicates;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
index 1ddb219..31ee26c 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
@@ -46,8 +46,8 @@ import brooklyn.catalog.internal.BasicBrooklynCatalog;
 import brooklyn.catalog.internal.CatalogDto;
 import brooklyn.catalog.internal.CatalogItemComparator;
 import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
index 19b2df7..bbe921c 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
@@ -41,7 +41,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.BrooklynTags;
 import brooklyn.entity.basic.BrooklynTags.NamedStringTag;
 import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.EntitlementPredicates;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.internal.EntityManagementUtils;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java
index 60fc3e9..9694747 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java
@@ -32,9 +32,9 @@ import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 
 import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
 
 import org.apache.brooklyn.rest.api.LocationApi;
 import org.apache.brooklyn.rest.domain.LocationSpec;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java
index e82fc82..18cb2ad 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java
@@ -37,7 +37,7 @@ import javax.annotation.Nullable;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.rest.domain.ApplicationSpec;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
index c74ea43..53a0f85 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
@@ -36,8 +36,8 @@ import org.apache.brooklyn.api.event.Sensor;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.EntityDynamicType;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
 
 import org.apache.brooklyn.policy.Policy;
 import org.apache.brooklyn.policy.PolicySpec;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
index c2a9267..1e2e8d4 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
@@ -25,11 +25,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Sanitizer;
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.basic.BasicLocationDefinition;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.basic.BasicLocationDefinition;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.basic.LocationInternal;
 
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.rest.domain.LocationSummary;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
index 5a2287a..f0de6d9 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
@@ -58,8 +58,8 @@ import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.policy.basic.AbstractPolicy;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java
index 076bfa7..20f5eb0 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java
@@ -24,8 +24,8 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.management.ManagementContext;
 
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
 
 public class EntityLocationUtils {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java
index 046cbe2..f4fe4e9 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java
@@ -34,7 +34,7 @@ import org.codehaus.jackson.map.JsonSerializer;
 import org.codehaus.jackson.map.SerializerProvider;
 import org.codehaus.jackson.map.module.SimpleModule;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class BidiSerialization {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
index 20c092b..c4dc88e 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
@@ -59,10 +59,10 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityFunctions;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.basic.Lifecycle;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java
index 90ab476..25351fe 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java
@@ -42,9 +42,9 @@ import com.google.common.collect.Iterables;
 import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.GenericType;
 
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
-import brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import org.apache.brooklyn.rest.domain.CatalogLocationSummary;
 import org.apache.brooklyn.rest.domain.LocationSummary;
 import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java
index b31dda0..dae1a6b 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java
@@ -24,7 +24,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.rest.domain.ScriptExecutionSummary;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java
index 57149e4..4e1fd22 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java
@@ -38,11 +38,11 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.SoftwareProcessEntityTest;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.internal.LocalUsageManager;
 import brooklyn.management.internal.ManagementContextInternal;
 import org.apache.brooklyn.rest.domain.ApplicationSpec;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
index 3b73ecd..8194547 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
@@ -32,8 +32,8 @@ import com.sun.jersey.test.framework.JerseyTest;
 import com.sun.jersey.test.framework.LowLevelAppDescriptor;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.basic.BasicLocationRegistry;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 import brooklyn.management.ManagementContextInjectable;
 import brooklyn.management.internal.LocalManagementContext;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
index af13fa3..04baadf 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
@@ -34,7 +34,7 @@ import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.flags.SetFromFlag;
 
 public class RestMockSimpleEntity extends SoftwareProcessImpl {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java
index 25f0c28..4647c13 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java
@@ -31,10 +31,10 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.rest.testing.mocks.RestMockSimpleEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/utils/test-bundles/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java b/utils/test-bundles/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java
index 253a2b0..bf64795 100644
--- a/utils/test-bundles/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java
+++ b/utils/test-bundles/entities/src/main/java/brooklyn/osgi/tests/SimpleLocation.java
@@ -20,7 +20,7 @@ package brooklyn.osgi.tests;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.AbstractLocation;
 import brooklyn.util.flags.SetFromFlag;
 
 public class SimpleLocation extends AbstractLocation {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/utils/test-bundles/more-entities-v1/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/more-entities-v1/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java b/utils/test-bundles/more-entities-v1/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java
index 75a9ff4..19f0f59 100644
--- a/utils/test-bundles/more-entities-v1/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java
+++ b/utils/test-bundles/more-entities-v1/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java
@@ -19,7 +19,7 @@
 package brooklyn.osgi.tests.more;
 
 
-import brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.AbstractLocation;
 
 public class MoreLocation extends AbstractLocation {
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/utils/test-bundles/more-entities-v2/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/more-entities-v2/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java b/utils/test-bundles/more-entities-v2/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java
index f2bbbea..dfcf311 100644
--- a/utils/test-bundles/more-entities-v2/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java
+++ b/utils/test-bundles/more-entities-v2/src/main/java/brooklyn/osgi/tests/more/MoreLocation.java
@@ -20,7 +20,7 @@ package brooklyn.osgi.tests.more;
 
 
 import org.apache.brooklyn.api.catalog.Catalog;
-import brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.AbstractLocation;
 
 @Catalog(name="More Location", description="Cataliog item OSGi test location")
 public class MoreLocation extends AbstractLocation {


[14/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsWinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsWinRmMachineLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsWinRmMachineLocation.java
new file mode 100644
index 0000000..753d772
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsWinRmMachineLocation.java
@@ -0,0 +1,154 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.net.Networking;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.net.HostAndPort;
+
+public class JcloudsWinRmMachineLocation extends WinRmMachineLocation implements JcloudsMachineLocation {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsWinRmMachineLocation.class);
+
+    @SetFromFlag
+    JcloudsLocation jcloudsParent;
+    
+    @SetFromFlag
+    NodeMetadata node;
+    
+    @SetFromFlag
+    Template template;
+
+    public JcloudsWinRmMachineLocation() {
+    }
+
+    @Override
+    public String toVerboseString() {
+        return Objects.toStringHelper(this).omitNullValues()
+                .add("id", getId()).add("name", getDisplayName())
+                .add("user", getUser())
+                .add("address", getAddress())
+                .add("port", getPort())
+                .add("node", getNode())
+                .add("jcloudsId", getJcloudsId())
+                .add("privateAddresses", node.getPrivateAddresses())
+                .add("publicAddresses", node.getPublicAddresses())
+                .add("parentLocation", getParent())
+                .add("osDetails", getOsDetails())
+                .toString();
+    }
+
+    @Override
+    public int getPort() {
+        return getConfig(WINRM_PORT);
+    }
+    
+    @Override
+    public NodeMetadata getNode() {
+        return node;
+    }
+    
+    @Override
+    public Template getTemplate() {
+        return template;
+    }
+    
+    @Override
+    public JcloudsLocation getParent() {
+        return jcloudsParent;
+    }
+    
+    @Override
+    public String getHostname() {
+        InetAddress address = getAddress();
+        return (address != null) ? address.getHostAddress() : null;
+    }
+    
+    @Override
+    public Set<String> getPublicAddresses() {
+        return node.getPublicAddresses();
+    }
+    
+    @Override
+    public Set<String> getPrivateAddresses() {
+        return node.getPrivateAddresses();
+    }
+
+    @Override
+    public String getSubnetHostname() {
+        // TODO: TEMP FIX: WAS:
+        // String publicHostname = jcloudsParent.getPublicHostname(node, Optional.<HostAndPort>absent(), config().getBag());
+        // but this causes a call to JcloudsUtil.getFirstReachableAddress, which searches for accessible SSH service.
+        // This workaround is good for public nodes but not private-subnet ones.
+        return getHostname();
+    }
+
+    @Override
+    public String getSubnetIp() {
+        Optional<String> privateAddress = getPrivateAddress();
+        if (privateAddress.isPresent()) {
+            return privateAddress.get();
+        }
+
+        String hostname = jcloudsParent.getPublicHostname(node, Optional.<HostAndPort>absent(), config().getBag());
+        if (hostname != null && !Networking.isValidIp4(hostname)) {
+            try {
+                return InetAddress.getByName(hostname).getHostAddress();
+            } catch (UnknownHostException e) {
+                LOG.debug("Cannot resolve IP for hostname {} of machine {} (so returning hostname): {}", new Object[] {hostname, this, e});
+            }
+        }
+        return hostname;
+    }
+
+    protected Optional<String> getPrivateAddress() {
+        if (groovyTruth(node.getPrivateAddresses())) {
+            Iterator<String> pi = node.getPrivateAddresses().iterator();
+            while (pi.hasNext()) {
+                String p = pi.next();
+                // disallow local only addresses
+                if (Networking.isLocalOnly(p)) continue;
+                // other things may be public or private, but either way, return it
+                return Optional.of(p);
+            }
+        }
+        return Optional.absent();
+    }
+    
+    @Override
+    public String getJcloudsId() {
+        return node.getId();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/SudoTtyFixingCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/SudoTtyFixingCustomizer.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/SudoTtyFixingCustomizer.java
new file mode 100644
index 0000000..d48a67c
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/SudoTtyFixingCustomizer.java
@@ -0,0 +1,58 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.jclouds.compute.ComputeService;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+
+import brooklyn.util.task.DynamicTasks;
+import brooklyn.util.task.ssh.SshTasks;
+import brooklyn.util.task.ssh.SshTasks.OnFailingTask;
+
+/**
+ * Wraps Brooklyn's sudo-tty mitigations in a {@link JcloudsLocationCustomizer} for easy(-ish) consumption
+ * in YAML blueprints:
+ *
+ * <pre>
+ *   name: My App
+ *   brooklyn.config:
+ *     provisioning.properties:
+ *       customizerType: SudoTtyFixingCustomizer
+ *   services: ...
+ * </pre>
+ *
+ * <p>This class should be seen as a temporary workaround and might disappear completely if/when Brooklyn takes care of this automatically.
+ *
+ * <p>See
+ * <a href='http://unix.stackexchange.com/questions/122616/why-do-i-need-a-tty-to-run-sudo-if-i-can-sudo-without-a-password'>http://unix.stackexchange.com/questions/122616/why-do-i-need-a-tty-to-run-sudo-if-i-can-sudo-without-a-password</a>
+ * for background.
+ */
+@Beta
+public class SudoTtyFixingCustomizer extends BasicJcloudsLocationCustomizer {
+
+    @Override
+    public void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine) {
+        Preconditions.checkArgument(machine instanceof SshMachineLocation, "machine must be SshMachineLocation, but is %s", machine.getClass());
+        DynamicTasks.queueIfPossible(SshTasks.dontRequireTtyForSudo((SshMachineLocation)machine, OnFailingTask.FAIL)).orSubmitAndBlock();
+        DynamicTasks.waitForLast();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
new file mode 100644
index 0000000..687a486
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
@@ -0,0 +1,563 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.networking;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.location.geo.LocalhostExternalIpLoader;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocationCustomizer;
+import org.apache.brooklyn.location.jclouds.JcloudsMachineLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation;
+import org.jclouds.aws.AWSResponseException;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.domain.Location;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.providers.Providers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.location.jclouds.BasicJcloudsLocationCustomizer;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.net.Cidr;
+import brooklyn.util.task.Tasks;
+import brooklyn.util.time.Duration;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.base.Throwables;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+/**
+ * Configures custom security groups on Jclouds locations.
+ *
+ * @see SecurityGroupExtension is an optional extension to jclouds compute service. It allows the manipulation of
+ * {@link SecurityGroup}s.
+ *
+ * This customizer can be injected into {@link JcloudsLocation#obtainOnce} using
+ * It will be executed after the provisiioning of the {@link JcloudsMachineLocation} to apply app-specific
+ * customization related to the security groups.
+ *
+ * @since 0.7.0
+ */
+@Beta
+public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocationCustomizer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsLocationSecurityGroupCustomizer.class);
+
+    // Caches instances of JcloudsLocationSecurityGroupCustomizer by application IDs.
+    private static final LoadingCache<String, JcloudsLocationSecurityGroupCustomizer> CUSTOMISERS = CacheBuilder.newBuilder()
+            .build(new CacheLoader<String, JcloudsLocationSecurityGroupCustomizer>() {
+                @Override
+                public JcloudsLocationSecurityGroupCustomizer load(final String appContext) throws Exception {
+                    return new JcloudsLocationSecurityGroupCustomizer(appContext);
+                }
+            });
+
+    /** Caches the base security group that should be shared between all instances in the same Jclouds location */
+    private final Cache<Location, SecurityGroup> sharedGroupCache = CacheBuilder.newBuilder().build();
+
+    /** Caches security groups unique to instances */
+    private final Cache<String, SecurityGroup> uniqueGroupCache = CacheBuilder.newBuilder().build();
+
+    /** The context for this location customizer. */
+    private final String applicationId;
+
+    /** The CIDR for addresses that may SSH to machines. */
+    private Supplier<Cidr> sshCidrSupplier;
+
+    /**
+     * A predicate indicating whether the customiser can retry a request to add a security group
+     * or a rule after an throwable is thrown.
+     */
+    private Predicate<Exception> isExceptionRetryable = Predicates.alwaysFalse();
+
+    protected JcloudsLocationSecurityGroupCustomizer(String applicationId) {
+        // Would be better to restrict with something like LocalhostExternalIpCidrSupplier, but
+        // we risk making machines inaccessible from Brooklyn when HA fails over.
+        this(applicationId, Suppliers.ofInstance(new Cidr("0.0.0.0/0")));
+    }
+
+    protected JcloudsLocationSecurityGroupCustomizer(String applicationId, Supplier<Cidr> sshCidrSupplier) {
+        this.applicationId = applicationId;
+        this.sshCidrSupplier = sshCidrSupplier;
+    }
+
+    /**
+     * Gets the customizer for the given applicationId. Multiple calls to this method with the
+     * same application context will return the same JcloudsLocationSecurityGroupCustomizer instance.
+     * @param applicationId An identifier for the application the customizer is to be used for
+     * @return the unique customizer for the given context
+     */
+    public static JcloudsLocationSecurityGroupCustomizer getInstance(String applicationId) {
+        return CUSTOMISERS.getUnchecked(applicationId);
+    }
+
+    /**
+     * Gets a customizer for the given entity's application. Multiple calls to this method with entities
+     * in the same application will return the same JcloudsLocationSecurityGroupCustomizer instance.
+     * @param entity The entity the customizer is to be used for
+     * @return the unique customizer for the entity's owning application
+     */
+    public static JcloudsLocationSecurityGroupCustomizer getInstance(Entity entity) {
+        return getInstance(entity.getApplicationId());
+    }
+
+    /**
+     * @param predicate
+     *          A predicate whose return value indicates whether a request to add a security group
+     *          or permission may be retried after its input {@link Exception} was thrown.
+     * @return this
+     */
+    public JcloudsLocationSecurityGroupCustomizer setRetryExceptionPredicate(Predicate<Exception> predicate) {
+        this.isExceptionRetryable = checkNotNull(predicate, "predicate");
+        return this;
+    }
+
+    /**
+     * @param cidrSupplier A supplier returning a CIDR for hosts that are allowed to SSH to locations.
+     */
+    public JcloudsLocationSecurityGroupCustomizer setSshCidrSupplier(Supplier<Cidr> cidrSupplier) {
+        this.sshCidrSupplier = checkNotNull(cidrSupplier, "cidrSupplier");
+        return this;
+    }
+
+    /** @see #addPermissionsToLocation(JcloudsSshMachineLocation, java.lang.Iterable) */
+    public JcloudsLocationSecurityGroupCustomizer addPermissionsToLocation(final JcloudsMachineLocation location, IpPermission... permissions) {
+        addPermissionsToLocation(location, ImmutableList.copyOf(permissions));
+        return this;
+    }
+
+    /** @see #addPermissionsToLocation(JcloudsSshMachineLocation, java.lang.Iterable) */
+    public JcloudsLocationSecurityGroupCustomizer addPermissionsToLocation(final JcloudsMachineLocation location, SecurityGroupDefinition securityGroupDefinition) {
+        addPermissionsToLocation(location, securityGroupDefinition.getPermissions());
+        return this;
+    }
+
+    /**
+     * Applies the given security group permissions to the given location.
+     * <p>
+     * Takes no action if the location's compute service does not have a security group extension.
+     * @param permissions The set of permissions to be applied to the location
+     * @param location Location to gain permissions
+     */
+    public JcloudsLocationSecurityGroupCustomizer addPermissionsToLocation(final JcloudsMachineLocation location, final Iterable<IpPermission> permissions) {
+        ComputeService computeService = location.getParent().getComputeService();
+        String nodeId = location.getNode().getId();
+        addPermissionsToLocation(permissions, nodeId, computeService);
+        return this;
+    }
+
+    /**
+     * Applies the given security group permissions to the given node with the given compute service.
+     * <p>
+     * Takes no action if the compute service does not have a security group extension.
+     * @param permissions The set of permissions to be applied to the node
+     * @param nodeId The id of the node to update
+     * @param computeService The compute service to use to apply the changes
+     */
+    @VisibleForTesting
+    void addPermissionsToLocation(Iterable<IpPermission> permissions, final String nodeId, ComputeService computeService) {
+        if (!computeService.getSecurityGroupExtension().isPresent()) {
+            LOG.warn("Security group extension for {} absent; cannot update node {} with {}",
+                    new Object[] {computeService, nodeId, permissions});
+            return;
+        }
+        final SecurityGroupExtension securityApi = computeService.getSecurityGroupExtension().get();
+        final String locationId = computeService.getContext().unwrap().getId();
+
+        // Expect to have two security groups on the node: one shared between all nodes in the location,
+        // that is cached in sharedGroupCache, and one created by Jclouds that is unique to the node.
+        // Relies on customize having been called before. This should be safe because the arguments
+        // needed to call this method are not available until post-instance creation.
+        SecurityGroup machineUniqueSecurityGroup;
+        Tasks.setBlockingDetails("Loading unique security group for node: " + nodeId);
+        try {
+            machineUniqueSecurityGroup = uniqueGroupCache.get(nodeId, new Callable<SecurityGroup>() {
+                @Override public SecurityGroup call() throws Exception {
+                    SecurityGroup sg = getUniqueSecurityGroupForNodeCachingSharedGroupIfPreviouslyUnknown(nodeId, locationId, securityApi);
+                    if (sg == null) {
+                        throw new IllegalStateException("Failed to find machine-unique group on node: " + nodeId);
+                    }
+                    return sg;
+                }
+            });
+        } catch (ExecutionException e) {
+            throw Throwables.propagate(new Exception(e.getCause()));
+        } finally {
+            Tasks.resetBlockingDetails();
+        }
+        for (IpPermission permission : permissions) {
+            addPermission(permission, machineUniqueSecurityGroup, securityApi);
+        }
+    }
+
+    /**
+     * Loads the security groups attached to the node with the given ID and returns the group
+     * that is unique to the node, per the application context. This method will also update
+     * {@link #sharedGroupCache} if no mapping for the shared group's location previously
+     * existed (e.g. Brooklyn was restarted and rebound to an existing application).
+     *
+     * Notice that jclouds will attach 2 securityGroups to the node if the locationId is `aws-ec2` so it needs to
+     * look for the uniqueSecurityGroup rather than the shared securityGroup.
+     *
+     * @param nodeId The id of the node in question
+     * @param locationId The id of the location in question
+     * @param securityApi The API to use to list security groups
+     * @return the security group unique to the given node, or null if one could not be determined.
+     */
+    private SecurityGroup getUniqueSecurityGroupForNodeCachingSharedGroupIfPreviouslyUnknown(String nodeId, String locationId, SecurityGroupExtension securityApi) {
+        Set<SecurityGroup> groupsOnNode = securityApi.listSecurityGroupsForNode(nodeId);
+        SecurityGroup unique;
+        if (locationId.equals("aws-ec2")) {
+            if (groupsOnNode.size() != 2) {
+                LOG.warn("Expected to find two security groups on node {} in app {} (one shared, one unique). Found {}: {}",
+                        new Object[]{nodeId, applicationId, groupsOnNode.size(), groupsOnNode});
+                return null;
+            }
+            String expectedSharedName = getNameForSharedSecurityGroup();
+            Iterator<SecurityGroup> it = groupsOnNode.iterator();
+            SecurityGroup shared = it.next();
+            if (shared.getName().endsWith(expectedSharedName)) {
+                unique = it.next();
+            } else {
+                unique = shared;
+                shared = it.next();
+            }
+            if (!shared.getName().endsWith(expectedSharedName)) {
+                LOG.warn("Couldn't determine which security group is shared between instances in app {}. Expected={}, found={}",
+                        new Object[]{applicationId, expectedSharedName, groupsOnNode});
+                return null;
+            }
+            // Shared entry might be missing if Brooklyn has rebound to an application
+            SecurityGroup old = sharedGroupCache.asMap().putIfAbsent(shared.getLocation(), shared);
+            LOG.info("Loaded unique security group for node {} (in {}): {}",
+                    new Object[]{nodeId, applicationId, unique});
+            if (old == null) {
+                LOG.info("Proactively set shared group for app {} to: {}", applicationId, shared);
+            }
+            return unique;
+        }
+        return Iterables.getOnlyElement(groupsOnNode);
+    }
+
+    /**
+     * Replaces security groups configured on the given template with one that allows
+     * SSH access on port 22 and allows communication on all ports between machines in
+     * the same group. Security groups are reused when templates have equal
+     * {@link org.jclouds.compute.domain.Template#getLocation locations}.
+     * <p>
+     * This method is called by Brooklyn when obtaining machines, as part of the
+     * {@link JcloudsLocationCustomizer} contract. It
+     * should not be called from anywhere else.
+     *
+     * @param location The Brooklyn location that has called this method while obtaining a machine
+     * @param computeService The compute service being used by the location argument to provision a machine
+     * @param template The machine template created by the location argument
+     */
+    @Override
+    public void customize(JcloudsLocation location, ComputeService computeService, Template template) {
+        if (!computeService.getSecurityGroupExtension().isPresent()) {
+            LOG.warn("Security group extension for {} absent; cannot configure security groups in context: {}", computeService, applicationId);
+        } else if (template.getLocation() == null) {
+            LOG.warn("No location has been set on {}; cannot configure security groups in context: {}", template, applicationId);
+        } else {
+            LOG.info("Configuring security groups on location {} in context {}", location, applicationId);
+            setSecurityGroupOnTemplate(location, template, computeService.getSecurityGroupExtension().get());
+        }
+    }
+
+    private void setSecurityGroupOnTemplate(final JcloudsLocation location, final Template template, final SecurityGroupExtension securityApi) {
+        SecurityGroup shared;
+        Tasks.setBlockingDetails("Loading security group shared by instances in " + template.getLocation() +
+                " in app " + applicationId);
+        try {
+            shared = sharedGroupCache.get(template.getLocation(), new Callable<SecurityGroup>() {
+                @Override public SecurityGroup call() throws Exception {
+                    return getOrCreateSharedSecurityGroup(template.getLocation(), securityApi);
+                }
+            });
+        } catch (ExecutionException e) {
+            throw Throwables.propagate(new Exception(e.getCause()));
+        } finally {
+            Tasks.resetBlockingDetails();
+        }
+
+        Set<String> originalGroups = template.getOptions().getGroups();
+        template.getOptions().securityGroups(shared.getName());
+        if (!originalGroups.isEmpty()) {
+            LOG.info("Replaced configured security groups: configured={}, replaced with={}", originalGroups, template.getOptions().getGroups());
+        } else {
+            LOG.debug("Configured security groups at {} to: {}", location, template.getOptions().getGroups());
+        }
+    }
+
+    /**
+     * Loads the security group to be shared between nodes in the same application in the
+     * given Location. If no such security group exists it is created.
+     *
+     * @param location The location in which the security group will be found
+     * @param securityApi The API to use to list and create security groups
+     * @return the security group to share between instances in the given location in this application
+     */
+    private SecurityGroup getOrCreateSharedSecurityGroup(Location location, SecurityGroupExtension securityApi) {
+        final String groupName = getNameForSharedSecurityGroup();
+        // Could sort-and-search if straight search is too expensive
+        Optional<SecurityGroup> shared = Iterables.tryFind(securityApi.listSecurityGroupsInLocation(location), new Predicate<SecurityGroup>() {
+            @Override
+            public boolean apply(final SecurityGroup input) {
+                // endsWith because Jclouds prepends 'jclouds#' to security group names.
+                return input.getName().endsWith(groupName);
+            }
+        });
+        if (shared.isPresent()) {
+            LOG.info("Found existing shared security group in {} for app {}: {}",
+                    new Object[]{location, applicationId, groupName});
+            return shared.get();
+        } else {
+            LOG.info("Creating new shared security group in {} for app {}: {}",
+                    new Object[]{location, applicationId, groupName});
+            return createBaseSecurityGroupInLocation(groupName, location, securityApi);
+        }
+    }
+
+    /**
+     * Creates a security group with rules to:
+     * <ul>
+     *     <li>Allow SSH access on port 22 from the world</li>
+     *     <li>Allow TCP, UDP and ICMP communication between machines in the same group</li>
+     * </ul>
+     *
+     * It needs to consider locationId as port ranges and groupId are cloud provider-dependent e.g openstack nova
+     * wants from 1-65535 while aws-ec2 accepts from 0-65535.
+     *
+     *
+     * @param groupName The name of the security group to create
+     * @param location The location in which the security group will be created
+     * @param securityApi The API to use to create the security group
+     *
+     * @return the created security group
+     */
+    private SecurityGroup createBaseSecurityGroupInLocation(String groupName, Location location, SecurityGroupExtension securityApi) {
+        SecurityGroup group = addSecurityGroupInLocation(groupName, location, securityApi);
+
+        Set<String> openstackNovaIds = getJcloudsLocationIds("openstack-nova");
+
+        String groupId = group.getProviderId();
+        int fromPort = 0;
+        if (location.getParent() != null && Iterables.contains(openstackNovaIds, location.getParent().getId())) {
+            groupId = group.getId();
+            fromPort = 1;
+        }
+        // Note: For groupName to work with GCE we also need to tag the machines with the same ID.
+        // See sourceTags section at https://developers.google.com/compute/docs/networking#firewalls
+        IpPermission.Builder allWithinGroup = IpPermission.builder()
+                .groupId(groupId)
+                .fromPort(fromPort)
+                .toPort(65535);
+        addPermission(allWithinGroup.ipProtocol(IpProtocol.TCP).build(), group, securityApi);
+        addPermission(allWithinGroup.ipProtocol(IpProtocol.UDP).build(), group, securityApi);
+        addPermission(allWithinGroup.ipProtocol(IpProtocol.ICMP).fromPort(-1).toPort(-1).build(), group, securityApi);
+
+        IpPermission sshPermission = IpPermission.builder()
+                .fromPort(22)
+                .toPort(22)
+                .ipProtocol(IpProtocol.TCP)
+                .cidrBlock(getBrooklynCidrBlock())
+                .build();
+        addPermission(sshPermission, group, securityApi);
+
+        return group;
+    }
+
+    private Set<String> getJcloudsLocationIds(final String jcloudsApiId) {
+        Set<String> openstackNovaProviders = FluentIterable.from(Providers.all())
+                .filter(new Predicate<ProviderMetadata>() {
+            @Override
+            public boolean apply(ProviderMetadata providerMetadata) {
+                return providerMetadata.getApiMetadata().getId().equals(jcloudsApiId);
+            }
+        }).transform(new Function<ProviderMetadata, String>() {
+            @Nullable
+            @Override
+            public String apply(ProviderMetadata input) {
+                return input.getId();
+            }
+        }).toSet();
+
+        return new ImmutableSet.Builder<String>()
+                .addAll(openstackNovaProviders)
+                .add(jcloudsApiId)
+                .build();
+    }
+
+    protected SecurityGroup addSecurityGroupInLocation(final String groupName, final Location location, final SecurityGroupExtension securityApi) {
+        LOG.debug("Creating security group {} in {}", groupName, location);
+        Callable<SecurityGroup> callable = new Callable<SecurityGroup>() {
+            @Override
+            public SecurityGroup call() throws Exception {
+                return securityApi.createSecurityGroup(groupName, location);
+            }
+        };
+        return runOperationWithRetry(callable);
+    }
+
+    protected SecurityGroup addPermission(final IpPermission permission, final SecurityGroup group, final SecurityGroupExtension securityApi) {
+        LOG.debug("Adding permission to security group {}: {}", group.getName(), permission);
+        Callable<SecurityGroup> callable = new Callable<SecurityGroup>() {
+            @Override
+            public SecurityGroup call() throws Exception {
+                return securityApi.addIpPermission(permission, group);
+            }
+        };
+        return runOperationWithRetry(callable);
+    }
+
+    /** @return the CIDR block used to configure Brooklyn's in security groups */
+    public String getBrooklynCidrBlock() {
+        return sshCidrSupplier.get().toString();
+    }
+
+    /**
+     * @return The name to be used by security groups that will be shared between machines
+     *         in the same location for this instance's application context.
+     */
+    @VisibleForTesting
+    String getNameForSharedSecurityGroup() {
+        return "brooklyn-" + applicationId.toLowerCase() + "-shared";
+    }
+
+    /**
+     * Invalidates all entries in {@link #sharedGroupCache} and {@link #uniqueGroupCache}.
+     * Use to simulate the effects of rebinding Brooklyn to a deployment.
+     */
+    @VisibleForTesting
+    void clearSecurityGroupCaches() {
+        LOG.info("Clearing security group caches");
+        sharedGroupCache.invalidateAll();
+        uniqueGroupCache.invalidateAll();
+    }
+
+    /**
+     * Runs the given callable. Repeats until the operation succeeds or {@link #isExceptionRetryable} indicates
+     * that the request cannot be retried.
+     */
+    protected <T> T runOperationWithRetry(Callable<T> operation) {
+        int backoff = 64;
+        Exception lastException = null;
+        for (int retries = 0; retries < 100; retries++) {
+            try {
+                return operation.call();
+            } catch (Exception e) {
+                lastException = e;
+                if (isExceptionRetryable.apply(e)) {
+                    LOG.debug("Attempt #{} failed to add security group: {}", retries + 1, e.getMessage());
+                    try {
+                        Thread.sleep(backoff);
+                    } catch (InterruptedException e1) {
+                        throw Exceptions.propagate(e1);
+                    }
+                    backoff = backoff << 1;
+                } else {
+                    break;
+                }
+            }
+        }
+
+        throw new RuntimeException("Unable to add security group rule; repeated errors from provider", lastException);
+    }
+
+    /**
+     * @return
+     *      A predicate that is true if an exception contains an {@link org.jclouds.aws.AWSResponseException}
+     *      whose error code is either <code>InvalidGroup.InUse</code>, <code>DependencyViolation</code> or
+     *      <code>RequestLimitExceeded</code>.
+     */
+    public static Predicate<Exception> newAwsExceptionRetryPredicate() {
+        return new AwsExceptionRetryPredicate();
+    }
+
+    private static class AwsExceptionRetryPredicate implements Predicate<Exception> {
+        // Error reference: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html
+        private static final Set<String> AWS_ERRORS_TO_RETRY = ImmutableSet.of(
+                "InvalidGroup.InUse", "DependencyViolation", "RequestLimitExceeded");
+
+        @Override
+        public boolean apply(Exception input) {
+            @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+            AWSResponseException exception = Exceptions.getFirstThrowableOfType(input, AWSResponseException.class);
+            if (exception != null) {
+                String code = exception.getError().getCode();
+                return AWS_ERRORS_TO_RETRY.contains(code);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * A supplier of CIDRs that loads the external IP address of the localhost machine.
+     */
+    private static class LocalhostExternalIpCidrSupplier implements Supplier<Cidr> {
+
+        private volatile Cidr cidr;
+
+        @Override
+        public Cidr get() {
+            Cidr local = cidr;
+            if (local == null) {
+                synchronized (this) {
+                    local = cidr;
+                    if (local == null) {
+                        String externalIp = LocalhostExternalIpLoader.getLocalhostIpWithin(Duration.seconds(5));
+                        cidr = local = new Cidr(externalIp + "/32");
+                    }
+                }
+            }
+            return local;
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/JcloudsPortForwarderExtension.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/JcloudsPortForwarderExtension.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/JcloudsPortForwarderExtension.java
new file mode 100644
index 0000000..00fd7f8
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/JcloudsPortForwarderExtension.java
@@ -0,0 +1,45 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.networking;
+
+import org.jclouds.compute.domain.NodeMetadata;
+
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.PortForwardManager;
+import brooklyn.util.net.Cidr;
+import brooklyn.util.net.Protocol;
+
+import com.google.common.base.Optional;
+import com.google.common.net.HostAndPort;
+
+public interface JcloudsPortForwarderExtension {
+
+    /**
+     * Opens port forwarding (e.g. DNAT or iptables port-forwarding) to reach the given given 
+     * target port on this node (from the given cidr).
+     * 
+     * This should also register the port with the {@link PortForwardManager}, via 
+     * {@code portForwardManager.associate(node.getId(), result, targetPort)} so that
+     * subsequent calls to {@link BrooklynAccessUtils#getBrooklynAccessibleAddress(brooklyn.entity.Entity, int)}
+     * will know about the mapped port.
+     */
+    public HostAndPort openPortForwarding(NodeMetadata node, int targetPort, Optional<Integer> optionalPublicPort, Protocol protocol, Cidr accessingCidr);
+
+    public void closePortForwarding(NodeMetadata node, int targetPort, HostAndPort publicHostAndPort, Protocol protocol);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupDefinition.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupDefinition.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupDefinition.java
new file mode 100644
index 0000000..8b95d1e
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupDefinition.java
@@ -0,0 +1,103 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.networking;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.jclouds.net.util.IpPermissions;
+
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.net.Cidr;
+import brooklyn.util.text.Identifiers;
+
+import com.google.common.annotations.Beta;
+
+/** WIP to define a security group in an up-front way, where subsequently it can be applied to a jclouds location */
+@Beta
+public class SecurityGroupDefinition {
+
+    private Callable<String> groupNameFactory = new Callable<String>() { public String call() { return "br-sg-"+Identifiers.makeRandomId(8); } };
+    private List<IpPermission> ipPerms = MutableList.of();
+    
+    public void createGroupInAwsRegion(ComputeServiceContext computeServiceContext, String region) {
+        AWSEC2Api ec2Client = computeServiceContext.unwrapApi(AWSEC2Api.class);
+        String sgId = ec2Client.getSecurityGroupApi().get().createSecurityGroupInRegionAndReturnId(region, getName(), "Brooklyn-managed security group "+getName());
+        ec2Client.getSecurityGroupApi().get().authorizeSecurityGroupIngressInRegion(region, sgId, ipPerms);
+    }
+
+    /** allows access to the given port on TCP from within the subnet */
+    public SecurityGroupDefinition allowingInternalPort(int port) {
+        return allowing(IpPermissions.permit(IpProtocol.TCP).port(port));
+    }
+    public SecurityGroupDefinition allowingInternalPorts(int port1, int port2, int ...ports) {
+        allowing(IpPermissions.permit(IpProtocol.TCP).port(port1));
+        allowing(IpPermissions.permit(IpProtocol.TCP).port(port2));
+        for (int port: ports)
+            allowing(IpPermissions.permit(IpProtocol.TCP).port(port));
+        return this;
+    }
+    public SecurityGroupDefinition allowingInternalPortRange(int portRangeStart, int portRangeEnd) {
+        return allowing(IpPermissions.permit(IpProtocol.TCP).fromPort(portRangeStart).to(portRangeEnd));
+    }
+    public SecurityGroupDefinition allowingInternalPing() {
+        return allowing(IpPermissions.permit(IpProtocol.ICMP));
+    }
+    
+    public SecurityGroupDefinition allowingPublicPort(int port) {
+        return allowing(IpPermissions.permit(IpProtocol.TCP).port(port).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
+    }
+    public SecurityGroupDefinition allowingPublicPorts(int port1, int port2, int ...ports) {
+        allowing(IpPermissions.permit(IpProtocol.TCP).port(port1).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
+        allowing(IpPermissions.permit(IpProtocol.TCP).port(port2).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
+        for (int port: ports)
+            allowing(IpPermissions.permit(IpProtocol.TCP).port(port).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
+        return this;
+    }
+    public SecurityGroupDefinition allowingPublicPortRange(int portRangeStart, int portRangeEnd) {
+        return allowing(IpPermissions.permit(IpProtocol.TCP).fromPort(portRangeStart).to(portRangeEnd).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
+    }
+    public SecurityGroupDefinition allowingPublicPing() {
+        return allowing(IpPermissions.permit(IpProtocol.ICMP).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
+    }
+    
+    public SecurityGroupDefinition allowing(IpPermission permission) {
+        ipPerms.add(permission);
+        return this;
+    }
+    
+    // TODO use cloud machine namer
+    public SecurityGroupDefinition named(final String name) {
+        groupNameFactory = new Callable<String>() { public String call() { return name; } };
+        return this;
+    }
+    public String getName() { 
+        try { return groupNameFactory.call(); } 
+        catch (Exception e) { throw Exceptions.propagate(e); } 
+    }
+
+    public Iterable<IpPermission> getPermissions() {
+        return ipPerms;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupTool.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupTool.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupTool.java
new file mode 100644
index 0000000..bf33f68
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupTool.java
@@ -0,0 +1,167 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.networking;
+
+import java.util.Set;
+
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig;
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.rest.ApiContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.text.Strings;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/** WIP to apply a security group to a jclouds endpoint.
+ * <p>
+ * sections of this code have been used but overall it is not yet in a working state,
+ * but merged May 2014 to make it easier to pick up if and when needed.
+ * (if not needed after several months this may simply be removed.) */
+@Beta
+public class SecurityGroupTool {
+
+    private static final Logger log = LoggerFactory.getLogger(SecurityGroupTool.class);
+    
+    protected final JcloudsLocation location;
+    protected final SecurityGroupDefinition sgDef;
+
+    public SecurityGroupTool(JcloudsLocation location, SecurityGroupDefinition sgDef) {
+        this.location = Preconditions.checkNotNull(location);
+        this.sgDef = Preconditions.checkNotNull(sgDef);
+    }
+    
+    public String getName() {
+        return sgDef.getName();
+    }
+    
+    public void apply() {
+        Optional<SecurityGroupExtension> sgExtO = location.getComputeService().getSecurityGroupExtension();
+        if (!sgExtO.isPresent()) {
+            throw new IllegalStateException("Advanced networking not supported in this location ("+location+")");
+        }
+        SecurityGroupExtension sgExt = sgExtO.get();
+        
+        SecurityGroup sg = findSecurityGroupWithName(sgExt, getName());
+        if (sg==null) {
+            // TODO initialize the location
+            org.jclouds.domain.Location sgLoc = null;
+
+            // TODO record that we created it
+            // create it
+            try {
+                // FIXME this will always fail for providers which need a location, until we set it above
+                // https://github.com/brooklyncentral/brooklyn/pull/1343#discussion_r12275188
+                sg = sgExt.createSecurityGroup(getName(), sgLoc);
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                // check if someone else already created it
+                sg = findSecurityGroupWithName(sgExt, getName());
+                if (sg==null) {
+                    // no - so propagate error
+                    throw Exceptions.propagate(e);
+                } else {
+                    log.debug("Looks like parallel thread created security group "+getName()+"; ignoring error in our thread ("+e+") as we now have an SG");
+                }
+            }
+        }
+        
+        if (sg==null)
+            throw new IllegalStateException("Unable to find or create security group ID for "+getName());
+
+        addPermissions(sgExt, sg);
+    }
+    
+    protected SecurityGroup findSecurityGroupWithName(SecurityGroupExtension sgExt, String name) {
+        Set<SecurityGroup> groups = sgExt.listSecurityGroups();
+        // jclouds appends this sometimes so for portability let's add this
+        String nameAlt = name.startsWith("jclouds#") ? Strings.removeFromStart(name, "jclouds#") : "jclouds#"+name;
+        for (SecurityGroup g: groups) {
+            if (name.equals(g.getName())) return g;
+            if (nameAlt.equals(g.getName())) return g;
+        }
+        return null;
+    }
+
+    protected void addPermissions(SecurityGroupExtension sgExt, SecurityGroup sg) {
+
+        Object api = ((ApiContext<?>)location.getComputeService().getContext().unwrap()).getApi();
+        if (api instanceof AWSEC2Api) {
+            // optimization for AWS where rules can be added all at once, and it cuts down Req Limit Exceeded problems!
+            String region = AWSUtils.getRegionFromLocationOrNull(sg.getLocation());
+            String id = sg.getProviderId();
+            
+            ((AWSEC2Api)api).getSecurityGroupApi().get().authorizeSecurityGroupIngressInRegion(region, id, sgDef.getPermissions());
+            
+        } else {
+            for (IpPermission p: sgDef.getPermissions()) {
+                sgExt.addIpPermission(p, sg);
+            }
+        }
+    }
+    
+    
+    // TODO remove this method once we've confirmed the above works nicely (this is an early attempt)
+    protected void applyOldEc2(AWSEC2Api client) {
+        String region = location.getConfig(JcloudsLocationConfig.CLOUD_REGION_ID);
+        if (region==null) {
+            // TODO where does the default come from?
+            log.warn("No region set for "+location+"; assuming EC2");
+            region = "us-east-1"; 
+        }
+        
+        Set<org.jclouds.ec2.domain.SecurityGroup> groups = client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, getName());
+        String id = null;
+        if (groups.isEmpty()) {
+            // create it
+            try {
+                id = client.getSecurityGroupApi().get().createSecurityGroupInRegionAndReturnId(region , getName(), "Brooklyn-managed security group "+getName());
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                // check if someone else already created it!
+                groups = client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, getName());
+                if (groups.isEmpty()) {
+                    // no - so propagate error
+                    throw Exceptions.propagate(e);
+                } else {
+                    log.debug("Looks like parallel thread created security group "+getName()+"; ignoring error in our thread ("+e+") as we now have an SG");
+                }
+            }
+        }
+        if (!groups.isEmpty()) {
+            if (groups.size()>1)
+                log.warn("Multiple security groups matching '"+getName()+"' (using the first): "+groups);
+            id = groups.iterator().next().getId();
+        }
+        if (id==null)
+            throw new IllegalStateException("Unable to find or create security group ID for "+getName());
+
+        client.getSecurityGroupApi().get().authorizeSecurityGroupIngressInRegion(region, id, sgDef.getPermissions());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePool.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePool.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePool.java
new file mode 100644
index 0000000..79a3dc8
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePool.java
@@ -0,0 +1,395 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.pool;
+
+import static org.apache.brooklyn.location.jclouds.pool.MachinePoolPredicates.compose;
+import static org.apache.brooklyn.location.jclouds.pool.MachinePoolPredicates.matching;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+/**
+ * Contains details of machines detected at a given cloud (ComputeService),
+ * and records claims made against those machines via this pool.
+ * <p>
+ * Machine instances themselves are persisted and rescanned as new instances of this class are created.
+ * Claims however are specific to this instance of the class, i.e. <b>not</b> persisted.
+ * <p>
+ * This class is believed to be thread-safe.
+ * Refreshes to the remote detected machines are synchronized on the pool instance.
+ * Details of detected and claimed machines are also synchronized on the pool instance.
+ * (If it is necessary to claim machines whilst the pool is being rescanned,
+ * we can investigate a more sophisticated threading model.
+ * Access to some fields is clearly independent and uses a tighter synchonization
+ * strategy, e.g. templates.  
+ * Synchronization of fields within a synch block on the class instance
+ * is permitted, but not the other way round,
+ * and synching on multiple fields is also not permitted.)
+ * <p>
+ * Callers wishing to guarantee results of e.g. ensureUnclaimed remaining available
+ * can synchronize on this class for the duration that they wish to have that guarantee
+ * (at the cost, of course, of any other threads being able to access this pool).
+ * <p>
+ * If underlying provisioning/destroying operations fail, the pool
+ * currently may be in an unknown state, currently.
+ * If more robustness is needed this can be added.
+ * 
+ * @deprecated since 0.6.0; never used in production setting, and thus of dubious value; best avoided as unlikely to be supported in future versions
+ */
+@Deprecated
+public class MachinePool {
+    
+    private static final Logger log = LoggerFactory.getLogger(MachinePool.class);
+    
+    protected final ComputeService computeService;
+    final AtomicBoolean refreshNeeded = new AtomicBoolean(true);
+    final List<ReusableMachineTemplate> templates = new ArrayList<ReusableMachineTemplate>();
+    String poolName = null;
+    
+    /** all machines detected, less those in the black list */
+    volatile MachineSet detectedMachines = new MachineSet();
+    volatile MachineSet matchedMachines = new MachineSet();
+    volatile MachineSet claimedMachines = new MachineSet();
+    volatile MachineSet blacklistedMachines = new MachineSet();
+    
+    public MachinePool(ComputeService computeService) {
+        this.computeService = computeService;
+    }
+    
+    protected synchronized void init() {
+        if (!refreshNeeded.get()) return;
+        refresh();
+    }
+    
+    public void setPoolName(String poolName) {
+        if (poolName!=null)
+            log.warn("Changing pool name of "+this+" (from "+this.poolName+" to "+poolName+") is discouraged.");
+        this.poolName = poolName;
+    }
+    /** pool name is used as a group/label by jclouds, for convenience only; 
+     * it has no special properties for detecting matching instances
+     * (use explicit tags on the templates, for that). 
+     * defaults to name of pool class and user name.
+     * callers should set pool name before getting, if using a custom name. */
+    public synchronized String getPoolName() {
+        if (poolName==null)
+            poolName = getClass().getSimpleName()+"-"+System.getProperty("user.name");
+        return poolName;
+    }
+    
+    /** refreshes the pool of machines from the server (finding all instances matching the registered templates) */
+    public synchronized void refresh() {
+        refreshNeeded.set(false);
+        Set<? extends ComputeMetadata> computes = computeService.listNodes();
+        Set<NodeMetadata> nodes = new LinkedHashSet<NodeMetadata>();
+        for (ComputeMetadata c: computes) {
+            if (c instanceof NodeMetadata) {
+                nodes.add((NodeMetadata)c);
+            } else {
+                // TODO should we try to fetch more info?
+                log.warn("MachinePool "+this+" ignoring non-Node record for remote machine: "+c);
+            }
+        }
+
+        MachineSet allNewDetectedMachines = new MachineSet(nodes);
+        MachineSet newDetectedMachines = filterForAllowedMachines(allNewDetectedMachines);
+        MachineSet oldDetectedMachines = detectedMachines;
+        MachineSet newMatchedMachines = new MachineSet();
+        detectedMachines = newDetectedMachines;
+
+        MachineSet appearedMachinesIncludingBlacklist = allNewDetectedMachines.removed(oldDetectedMachines);
+        MachineSet appearedMachines = filterForAllowedMachines(appearedMachinesIncludingBlacklist);
+        if (appearedMachinesIncludingBlacklist.size()>appearedMachines.size())
+            if (log.isDebugEnabled()) log.debug("Pool "+this+", ignoring "+(appearedMachinesIncludingBlacklist.size()-appearedMachines.size())+" disallowed");
+        int matchedAppeared = 0;
+        for (NodeMetadata m: appearedMachines) {
+            if (m.getStatus() != NodeMetadata.Status.RUNNING) {
+                if (log.isDebugEnabled()) 
+                    log.debug("Pool "+this+", newly detected machine "+m+", not running ("+m.getStatus()+")");
+            } else {
+                Set<ReusableMachineTemplate> ts = getTemplatesMatchingInstance(m);
+                if (!ts.isEmpty()) {
+                    matchedAppeared++;
+                    newMatchedMachines = newMatchedMachines.added(new MachineSet(m));
+                    if (log.isDebugEnabled()) 
+                        log.debug("Pool "+this+", newly detected machine "+m+", matches pool templates "+ts);
+                } else {
+                    if (log.isDebugEnabled()) 
+                        log.debug("Pool "+this+", newly detected machine "+m+", does not match any pool templates");
+                }
+            }
+        }
+        if (matchedAppeared>0) {
+            log.info("Pool "+this+" discovered "+matchedAppeared+" matching machines (of "+appearedMachines.size()+" total new; "+newDetectedMachines.size()+" total including claimed and unmatched)");
+        } else {
+            if (log.isDebugEnabled()) 
+                log.debug("Pool "+this+" discovered "+matchedAppeared+" matching machines (of "+appearedMachines.size()+" total new; "+newDetectedMachines.size()+" total including claimed and unmatched)");
+        }
+        matchedMachines = newMatchedMachines;
+    }
+
+    protected MachineSet filterForAllowedMachines(MachineSet input) {
+        return input.removed(blacklistedMachines);
+    }
+
+    // TODO template registry and claiming from a template could be a separate responsibility
+    
+    protected ReusableMachineTemplate registerTemplate(ReusableMachineTemplate template) {
+        registerTemplates(template);
+        return template;
+    }
+    protected void registerTemplates(ReusableMachineTemplate ...templatesToReg) {
+        synchronized (templates) { 
+            for (ReusableMachineTemplate template: templatesToReg)
+                templates.add(template); 
+        }
+    }
+    
+    protected ReusableMachineTemplate newTemplate(String name) {
+        return registerTemplate(new ReusableMachineTemplate(name));
+    }
+
+    
+    public List<ReusableMachineTemplate> getTemplates() {
+        List<ReusableMachineTemplate> result;
+        synchronized (templates) { result = ImmutableList.copyOf(templates); }
+        return result;
+    }
+    
+    /** all machines matching any templates */
+    public MachineSet all() {
+        init();
+        return matchedMachines;
+    }
+
+    /** machines matching any templates which have not been claimed */
+    public MachineSet unclaimed() {
+        init();
+        synchronized (this) {
+            return matchedMachines.removed(claimedMachines);
+        }
+    }
+    
+    /** returns all machines matching the given criteria (may be claimed) */
+    @SuppressWarnings("unchecked")
+    public MachineSet all(Predicate<NodeMetadata> criterion) {
+        // To avoid generics complaints in callers caused by varargs, overload here
+        return all(new Predicate[] {criterion});
+    }
+    
+    /** returns all machines matching the given criteria (may be claimed) */
+    public MachineSet all(Predicate<NodeMetadata> ...ops) {
+        return new MachineSet(Iterables.filter(all(), compose(ops)));
+    }
+
+    /** returns unclaimed machines matching the given criteria */
+    @SuppressWarnings("unchecked")
+    public MachineSet unclaimed(Predicate<NodeMetadata> criterion) {
+        // To avoid generics complaints in callers caused by varargs, overload here
+        return unclaimed(new Predicate[] {criterion});
+    }
+    
+    /** returns unclaimed machines matching the given criteria */
+    public MachineSet unclaimed(Predicate<NodeMetadata> ...criteria) {
+        return new MachineSet(Iterables.filter(unclaimed(), compose(criteria)));
+    }
+
+    /** creates machines if necessary so that this spec exists (may already be claimed however) 
+     * returns a set of all matching machines, guaranteed non-empty 
+     * (but possibly some are already claimed) */
+    public MachineSet ensureExists(ReusableMachineTemplate template) {
+        return ensureExists(1, template);
+    }
+
+    public synchronized void addToBlacklist(MachineSet newToBlacklist) {
+        setBlacklist(blacklistedMachines.added(newToBlacklist));
+    }
+    
+    /** replaces the blacklist set; callers should generally perform a refresh()
+     * afterwards, to trigger re-detection of blacklisted machines
+     */
+    public synchronized void setBlacklist(MachineSet newBlacklist) {
+        blacklistedMachines = newBlacklist;
+        detectedMachines = detectedMachines.removed(blacklistedMachines);
+        matchedMachines = matchedMachines.removed(blacklistedMachines);
+    }
+    
+    /** creates machines if necessary so that this spec exists (may already be claimed however);
+     * returns a set of all matching machines, of size at least count (but possibly some are already claimed).
+     * (the pool can change at any point, so this set is a best-effort but may be out of date.
+     * see javadoc comments on this class.) */
+    public MachineSet ensureExists(int count, ReusableMachineTemplate template) {
+        MachineSet current;
+        current = all(matching(template));
+        if (current.size() >= count)
+            return current;
+        //have to create more
+        MachineSet moreNeeded = create(count-current.size(), template);
+        return current.added(moreNeeded);
+    }
+    
+    /** creates machines if necessary so that this spec can subsequently be claimed;
+     * returns all such unclaimed machines, guaranteed to be non-empty.
+    * (the pool can change at any point, so this set is a best-effort but may be out of date.
+    * see javadoc comments on this class.) */
+    public MachineSet ensureUnclaimed(ReusableMachineTemplate template) {
+        return ensureUnclaimed(1, template);
+    }
+
+    /** creates machines if necessary so that this spec can subsequently be claimed;
+     * returns a set of at least count unclaimed machines */
+    public MachineSet ensureUnclaimed(int count, ReusableMachineTemplate template) {
+        MachineSet current;
+        current = unclaimed(matching(template));
+        if (current.size() >= count)
+            return current;
+        //have to create more
+        MachineSet moreNeeded = create(count-current.size(), template);
+        return current.added(moreNeeded);
+    }
+
+    public Set<ReusableMachineTemplate> getTemplatesMatchingInstance(NodeMetadata nm) {
+        Set<ReusableMachineTemplate> result = new LinkedHashSet<ReusableMachineTemplate>(); 
+        for (ReusableMachineTemplate t: getTemplates()) {
+            if (matching(t).apply(nm)) {
+               result.add(t); 
+            }
+        }        
+        return result;
+    }
+    
+    /** creates the given number of machines of the indicated template */
+    public MachineSet create(int count, ReusableMachineTemplate template) {
+        Set<? extends NodeMetadata> nodes;
+        try {
+            Template t = template.newJcloudsTemplate(computeService);
+            if (log.isDebugEnabled()) log.debug("Creating "+count+" new instances of "+t);
+            nodes = computeService.createNodesInGroup(getPoolName(), count, t);
+        } catch (RunNodesException e) {
+            throw Throwables.propagate(e);
+        }
+        MachineSet result = new MachineSet(nodes);
+        registerNewNodes(result, template);
+        return result;
+    }
+    protected void registerNewNodes(MachineSet result, ReusableMachineTemplate template) {
+        for (NodeMetadata m: result) {
+            Set<ReusableMachineTemplate> ts = getTemplatesMatchingInstance(m);
+            if (ts.isEmpty()) {
+                log.error("Pool "+this+", created machine "+m+" from template "+template+", but no pool templates match!");
+            } else {
+                if (log.isDebugEnabled())
+                    log.debug("Pool "+this+", created machine "+m+" from template "+template+", matching templates "+ts);
+            }
+        }
+        synchronized (this) {
+            detectedMachines = detectedMachines.added(result);
+            matchedMachines = matchedMachines.added(result);
+        }
+    }
+
+    /** claims the indicated number of machines with the indicated spec, creating if necessary */
+    public MachineSet claim(int count, ReusableMachineTemplate t) {
+        init();
+        Set<NodeMetadata> claiming = new LinkedHashSet<NodeMetadata>();
+        while (claiming.size() < count) {
+            MachineSet mm = ensureUnclaimed(count - claiming.size(), t);
+            for (NodeMetadata m : mm) {
+                synchronized (this) {
+                    if (claiming.size() < count && !claimedMachines.contains(m)) {
+                        claiming.add(m);
+                        claimedMachines = claimedMachines.added(new MachineSet(m));
+                    }
+                }
+            }
+        }
+        MachineSet result = new MachineSet(claiming);
+        return result;
+    }
+
+
+    /** claims the indicated set of machines;
+     * throws exception if cannot all be claimed;
+     * returns the set passed in if successful */
+    public MachineSet claim(MachineSet set) {
+        init();
+        synchronized (this) {
+            MachineSet originalClaimed = claimedMachines;
+            claimedMachines = claimedMachines.added(set);
+            MachineSet newlyClaimed = claimedMachines.removed(originalClaimed);
+            if (newlyClaimed.size() != set.size()) {
+                //did not claim all; unclaim and fail
+                claimedMachines = originalClaimed;
+                MachineSet unavailable = set.removed(newlyClaimed); 
+                throw new IllegalArgumentException("Could not claim all requested machines; failed to claim "+unavailable);
+            }
+            return newlyClaimed;
+        }
+    }
+    
+    public int unclaim(MachineSet set) {
+        init();
+        synchronized (this) {
+            MachineSet originalClaimed = claimedMachines;
+            claimedMachines = claimedMachines.removed(set);
+            return originalClaimed.size() - claimedMachines.size();
+        }
+    }
+
+    
+    public int destroy(final MachineSet set) {
+        init();
+        synchronized (this) {
+            detectedMachines = detectedMachines.removed(set);
+            matchedMachines = matchedMachines.removed(set);
+            claimedMachines = claimedMachines.removed(set);
+        }
+        Set<? extends NodeMetadata> destroyed = computeService.destroyNodesMatching(new Predicate<NodeMetadata>() {
+            @Override
+            public boolean apply(NodeMetadata input) {
+                return set.contains(input);
+            }
+        });
+        synchronized (this) {
+            //in case a rescan happened while we were destroying
+            detectedMachines = detectedMachines.removed(set);
+            matchedMachines = matchedMachines.removed(set);
+            claimedMachines = claimedMachines.removed(set);
+        }
+        return destroyed.size();        
+    }
+        
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePoolPredicates.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePoolPredicates.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePoolPredicates.java
new file mode 100644
index 0000000..a988ab6
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePoolPredicates.java
@@ -0,0 +1,149 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.pool;
+
+import java.util.Map;
+
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.domain.Location;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Throwables;
+
+public class MachinePoolPredicates {
+
+    private static final Logger log = LoggerFactory.getLogger(MachinePoolPredicates.class);
+    
+    public static Predicate<NodeMetadata> except(final MachineSet removedItems) {
+        return new Predicate<NodeMetadata>() {
+            @Override
+            public boolean apply(NodeMetadata input) {
+                return !removedItems.contains(input);
+            }
+        };
+    }
+
+    public static Predicate<NodeMetadata> except(final Predicate<NodeMetadata> predicateToExclude) {
+        return Predicates.not(predicateToExclude);
+    }
+
+    public static Predicate<NodeMetadata> matching(final ReusableMachineTemplate template) {
+        return new Predicate<NodeMetadata>() {
+            @Override
+            public boolean apply(NodeMetadata input) {
+                return matches(template, input);
+            }
+        };
+    }
+
+    public static Predicate<NodeMetadata> withTag(final String tag) {
+        return new Predicate<NodeMetadata>() {
+            @Override
+            public boolean apply(NodeMetadata input) {
+                return input.getTags().contains(tag);
+            }
+        };
+    }
+
+    public static Predicate<NodeMetadata> compose(final Predicate<NodeMetadata> ...predicates) {
+        return Predicates.and(predicates);
+    }
+
+    /** True iff the node matches the criteria specified in this template. 
+     * <p>
+     * NB: This only checks some of the most common fields, 
+     * plus a hashcode (in strict mode).  
+     * In strict mode you're practically guaranteed to match only machines created by this template.
+     * (Add a tag(uid) and you _will_ be guaranteed, strict mode or not.)
+     * <p> 
+     * Outside strict mode, some things (OS and hypervisor) can fall through the gaps.  
+     * But if that is a problem we can easily add them in.
+     * <p>
+     * (Caveat: If explicit Hardware, Image, and/or Template were specified in the template,
+     * then the hash code probably will not detect it.)   
+     **/
+    public static boolean matches(ReusableMachineTemplate template, NodeMetadata m) {
+        try {
+            // tags and user metadata
+
+            if (! m.getTags().containsAll( template.getTags(false) )) return false;
+
+            if (! isSubMapOf(template.getUserMetadata(false), m.getUserMetadata())) return false;
+
+
+            // common hardware parameters
+
+            if (template.getMinRam()!=null && m.getHardware().getRam() < template.getMinRam()) return false;
+
+            if (template.getMinCores()!=null) {
+                double numCores = 0;
+                for (Processor p: m.getHardware().getProcessors()) numCores += p.getCores();
+                if (numCores+0.001 < template.getMinCores()) return false;
+            }
+
+            if (template.getIs64bit()!=null) {
+                if (m.getOperatingSystem().is64Bit() != template.getIs64bit()) return false;
+            }
+
+            if (template.getOsFamily()!=null) {
+                if (m.getOperatingSystem() == null || 
+                        !template.getOsFamily().equals(m.getOperatingSystem().getFamily())) return false;
+            }
+            if (template.getOsNameMatchesRegex()!=null) {
+                if (m.getOperatingSystem() == null || m.getOperatingSystem().getName()==null ||
+                        !m.getOperatingSystem().getName().matches(template.getOsNameMatchesRegex())) return false;
+            }
+
+            if (template.getLocationId()!=null) {
+                if (!isLocationContainedIn(m.getLocation(), template.getLocationId())) return false;
+            }
+
+            // TODO other TemplateBuilder fields and TemplateOptions
+
+            return true;
+            
+        } catch (Exception e) {
+            log.warn("Error (rethrowing) trying to match "+m+" against "+template+": "+e, e);
+            throw Throwables.propagate(e);
+        }
+    }
+
+    private static boolean isLocationContainedIn(Location location, String locationId) {
+        if (location==null) return false;
+        if (locationId.equals(location.getId())) return true;
+        return isLocationContainedIn(location.getParent(), locationId);
+    }
+
+    public static boolean isSubMapOf(Map<String, String> sub, Map<String, String> bigger) {
+        for (Map.Entry<String, String> e: sub.entrySet()) {
+            if (e.getValue()==null) {
+                if (!bigger.containsKey(e.getKey())) return false;
+                if (bigger.get(e.getKey())!=null) return false;
+            } else {
+                if (!e.getValue().equals(bigger.get(e.getKey()))) return false;
+            }
+        }
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachineSet.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachineSet.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachineSet.java
new file mode 100644
index 0000000..53116ab
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachineSet.java
@@ -0,0 +1,98 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.pool;
+
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import javax.annotation.concurrent.Immutable;
+
+import org.jclouds.compute.domain.NodeMetadata;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+@Immutable
+public class MachineSet implements Iterable<NodeMetadata> {
+
+    final Set<NodeMetadata> members;
+    
+    public MachineSet(Iterable<? extends NodeMetadata> m) { 
+        members = ImmutableSet.copyOf(m); 
+    }
+    public MachineSet(NodeMetadata ...nodes) {
+        members = ImmutableSet.copyOf(nodes); 
+    }
+
+    @Override
+    public Iterator<NodeMetadata> iterator() {
+        return members.iterator();
+    }
+
+    public MachineSet removed(MachineSet toRemove) {
+        Set<NodeMetadata> s = new LinkedHashSet<NodeMetadata>(members);
+        for (NodeMetadata m: toRemove) s.remove(m);
+        return new MachineSet(s);
+    }
+    public MachineSet added(MachineSet toAdd) {
+        Set<NodeMetadata> s = new LinkedHashSet<NodeMetadata>(members);
+        for (NodeMetadata m: toAdd) s.add(m);
+        return new MachineSet(s);
+    }
+
+    @SuppressWarnings("unchecked")
+    public MachineSet filtered(Predicate<NodeMetadata> criterion) {
+        // To avoid generics complaints in callers caused by varargs, overload here
+        return filtered(new Predicate[] {criterion});
+    }
+
+    public MachineSet filtered(Predicate<NodeMetadata> ...criteria) {
+        return new MachineSet(Iterables.filter(members, MachinePoolPredicates.compose(criteria)));
+    }
+
+    public int size() {
+        return members.size();
+    }
+    
+    public boolean isEmpty() {
+        return members.isEmpty();
+    }
+    
+    public boolean contains(NodeMetadata input) {
+        return members.contains(input);
+    }
+    
+    @Override
+    public String toString() {
+        return members.toString();
+    }
+    
+    @Override
+    public int hashCode() {
+        return members.hashCode();
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        return (obj instanceof MachineSet) && (members.equals( ((MachineSet)obj).members ));
+    }
+    
+}


[07/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
new file mode 100644
index 0000000..535b6a8
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
@@ -0,0 +1,150 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.rebind.RebindTestUtils;
+import org.apache.brooklyn.location.OsDetails;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.io.Files;
+
+public class RebindJcloudsLocationLiveTest extends AbstractJcloudsLiveTest {
+
+    public static final String AWS_EC2_REGION_NAME = AWS_EC2_USEAST_REGION_NAME;
+    public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + ":" + AWS_EC2_REGION_NAME;
+
+    private ClassLoader classLoader = getClass().getClassLoader();
+    private TestApplication origApp;
+    private LiveTestEntity origEntity;
+    private File mementoDir;
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        origApp = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class), managementContext);
+        origEntity = origApp.createAndManageChild(EntitySpec.create(LiveTestEntity.class));
+
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        jcloudsLocation.setConfig(JcloudsLocation.HARDWARE_ID, AWS_EC2_SMALL_HARDWARE_ID);
+    }
+
+    @AfterMethod(alwaysRun = true)
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (origApp != null) Entities.destroyAll(origApp.getManagementContext());
+        if (mementoDir != null) RebindTestUtils.deleteMementoDir(mementoDir);
+    }
+    
+    @Override
+    protected LocalManagementContext newManagementContext() {
+        mementoDir = Files.createTempDir();
+        return RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
+    }
+    
+    @Test(groups="Live")
+    public void testRebindsToJcloudsMachine() throws Exception {
+        origApp.start(ImmutableList.of(jcloudsLocation));
+        JcloudsLocation origJcloudsLocation = jcloudsLocation;
+        System.out.println("orig locations: " + origEntity.getLocations());
+        JcloudsSshMachineLocation origMachine = (JcloudsSshMachineLocation) Iterables.find(origEntity.getLocations(), Predicates.instanceOf(JcloudsSshMachineLocation.class));
+
+        TestApplication newApp = rebind();
+        LiveTestEntity newEntity = (LiveTestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(LiveTestEntity.class));
+        JcloudsSshMachineLocation newMachine = (JcloudsSshMachineLocation) Iterables.find(newEntity.getLocations(), Predicates.instanceOf(JcloudsSshMachineLocation.class));
+
+        assertMachineEquals(newMachine, origMachine);
+        assertTrue(newMachine.isSshable());
+
+        JcloudsLocation newJcloudsLoction = newMachine.getParent();
+        assertJcloudsLocationEquals(newJcloudsLoction, origJcloudsLocation);
+    }
+
+    private void assertMachineEquals(JcloudsSshMachineLocation actual, JcloudsSshMachineLocation expected) {
+        String errmsg = "actual="+actual.toVerboseString()+"; expected="+expected.toVerboseString();
+        assertEquals(actual.getId(), expected.getId(), errmsg);
+        assertEquals(actual.getJcloudsId(), expected.getJcloudsId(), errmsg);
+        assertOsDetailEquals(actual.getOsDetails(), expected.getOsDetails());
+        assertEquals(actual.getSshHostAndPort(), expected.getSshHostAndPort());
+        assertEquals(actual.getPrivateAddress(), expected.getPrivateAddress());
+        assertConfigBagEquals(actual.config().getBag(), expected.config().getBag(), errmsg);
+    }
+
+    private void assertOsDetailEquals(OsDetails actual, OsDetails expected) {
+        String errmsg = "actual="+actual+"; expected="+expected;
+        if (actual == null) assertNull(expected, errmsg);
+        assertEquals(actual.isWindows(), expected.isWindows());
+        assertEquals(actual.isLinux(), expected.isLinux());
+        assertEquals(actual.isMac(), expected.isMac());
+        assertEquals(actual.getName(), expected.getName());
+        assertEquals(actual.getArch(), expected.getArch());
+        assertEquals(actual.getVersion(), expected.getVersion());
+        assertEquals(actual.is64bit(), expected.is64bit());
+    }
+
+    private void assertJcloudsLocationEquals(JcloudsLocation actual, JcloudsLocation expected) {
+        String errmsg = "actual="+actual.toVerboseString()+"; expected="+expected.toVerboseString();
+        assertEquals(actual.getId(), expected.getId(), errmsg);
+        assertEquals(actual.getProvider(), expected.getProvider(), errmsg);
+        assertEquals(actual.getRegion(), expected.getRegion(), errmsg);
+        assertEquals(actual.getIdentity(), expected.getIdentity(), errmsg);
+        assertEquals(actual.getCredential(), expected.getCredential(), errmsg);
+        assertEquals(actual.getHostGeoInfo(), expected.getHostGeoInfo(), errmsg);
+        assertConfigBagEquals(actual.config().getBag(), expected.config().getBag(), errmsg);
+    }
+
+    private void assertConfigBagEquals(ConfigBag actual, ConfigBag expected, String errmsg) {
+        // TODO revisit the strong assertion that configBags are equal
+        
+//        // TODO Can we include all of these things (e.g. when locations are entities, so flagged fields not treated special)?
+//        List<String> configToIgnore = ImmutableList.of("id", "template", "usedPorts", "machineCreationSemaphore", "config");
+//        MutableMap<Object, Object> actualMap = MutableMap.builder().putAll(actual.getAllConfig())
+//                .removeAll(configToIgnore)
+//                .build();
+//        MutableMap<Object, Object> expectedMap = MutableMap.builder().putAll(expected.getAllConfig())
+//                .removeAll(configToIgnore)
+//                .build();
+//        
+//        assertEquals(actualMap, expectedMap, errmsg+"; actualBag="+actualMap+"; expectedBag="+expectedMap);
+    }
+    
+    private TestApplication rebind() throws Exception {
+        RebindTestUtils.waitForPersisted(origApp);
+        return (TestApplication) RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationTest.java
new file mode 100644
index 0000000..cc52ef2
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNull;
+
+import org.jclouds.domain.LoginCredentials;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.net.HostAndPort;
+
+public class RebindJcloudsLocationTest extends RebindTestFixtureWithApp {
+
+    public static final String LOC_SPEC = "jclouds:aws-ec2:us-east-1";
+
+    private JcloudsLocation origLoc;
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        origLoc = (JcloudsLocation) origManagementContext.getLocationRegistry().resolve(LOC_SPEC);
+    }
+
+    // Previously, the rebound config contained "id" which was then passed to createTemporarySshMachineLocation, causing
+    // that to fail (because the LocationSpec should not have had "id" in its config)
+    @Test
+    public void testReboundConfigDoesNotContainId() throws Exception {
+        rebind();
+        
+        JcloudsLocation newLoc = (JcloudsLocation) newManagementContext.getLocationManager().getLocation(origLoc.getId());
+        
+        ConfigBag newLocConfig = newLoc.config().getBag();
+        ConfigBag config = ConfigBag.newInstanceCopying(newLocConfig);
+        
+        assertNull(newLocConfig.getStringKey(("id")));
+        
+        SshMachineLocation tempMachine = newLoc.createTemporarySshMachineLocation(
+                HostAndPort.fromParts("localhost", 1234), 
+                LoginCredentials.builder().identity("myuser").password("mypass").noPrivateKey().build(), 
+                config);
+        assertNotEquals(tempMachine.getId(), newLoc.getId());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
new file mode 100644
index 0000000..3e33ce8
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
@@ -0,0 +1,249 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.text.Identifiers;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+public class SimpleJcloudsLocationUserLoginAndConfigLiveTest extends AbstractJcloudsLiveTest {
+
+    // FIXME And tidy up this one
+    
+    private static final String LOCATION_SPEC = AWS_EC2_PROVIDER + ":" + AWS_EC2_USEAST_REGION_NAME;
+    
+    private static final Logger log = LoggerFactory.getLogger(SimpleJcloudsLocationUserLoginAndConfigLiveTest.class);
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        jcloudsLocation = resolve(LOCATION_SPEC);
+    }
+    
+    @SuppressWarnings("rawtypes")
+    @Test(groups="Live")
+    public void testJcloudsCreateBogStandard() throws Exception {
+        log.info("TEST testJcloudsCreateBogStandard");
+        JcloudsSshMachineLocation m1 = obtainMachine(ImmutableMap.of());
+
+        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
+        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
+        String result;
+        // echo conflates spaces of arguments
+        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m1"));
+        
+        log.info("now trying rebind "+m1);
+        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
+        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m2"));
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test(groups="Live")
+    public void testJcloudsCreateBogStandardWithUserBrooklyn() throws Exception {
+        log.info("TEST testJcloudsCreateBogStandardWithUserBrooklyn");
+        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of("user", "brooklyn"));
+
+        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
+        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
+        String result;
+        // echo conflates spaces of arguments
+        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m1"));
+        
+        log.info("now trying rebind "+m1);
+        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
+        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m2"));
+        
+        Assert.assertEquals(m2.getUser(), "brooklyn");
+    }
+    
+    @SuppressWarnings("rawtypes")
+    @Test(groups="Live")
+    public void testJcloudsCreateUserMetadata() throws Exception {
+        log.info("TEST testJcloudsCreateBogStandard");
+        String key = "brooklyn-test-user-data";
+        String value = "test-"+Identifiers.makeRandomId(4);
+        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of("userMetadata", key+"="+value));
+
+        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser(),
+                "userMetadata", key+"="+value);
+        Assert.assertEquals(m1.node.getUserMetadata().get(key), value);
+        
+        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
+        String result;
+        // echo conflates spaces of arguments
+        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m1"));
+        
+        log.info("now trying rebind "+m1);
+        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
+        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m2"));
+        Assert.assertEquals(m2.node.getUserMetadata().get(key), value);
+    }
+
+    // a curious image, centos, but user is ec2-user, and handily not correctly auto-detected
+    // test we can specify a loginUser different from user, and that user is created etc...
+    // imageId=us-east-1/ami-f95cf390
+    public static final String EC2_CENTOS_IMAGE = "us-east-1/ami-f95cf390";
+    
+    @Test(groups="Live")
+    public void testJcloudsMissingUser() throws Exception {
+        log.info("TEST testJcloudsMissingUser");
+        try {
+            // wait up to 30s for login (override default of 5m so test runs faster)
+            obtainMachine(MutableMap.of("imageId", EC2_CENTOS_IMAGE, "waitForSshable", 30*1000));
+            log.info("whoops we logged in");
+        } catch (NoMachinesAvailableException e) {
+            log.info("got error as expected, for missing user: "+e); // success
+        }
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test(groups="Live")
+    public void testJcloudsWithSpecificLoginUserAndSameUser() throws Exception {
+        log.info("TEST testJcloudsWithSpecificLoginUserAndSameUser");
+        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of(
+                "imageId", EC2_CENTOS_IMAGE,
+                "loginUser", "ec2-user",
+                "user", "ec2-user",
+                "waitForSshable", 30*1000));
+
+        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
+        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
+        String result;
+        // echo conflates spaces of arguments
+        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m1"));
+        
+        log.info("now trying rebind "+m1);
+        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
+        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m2"));
+        
+        Assert.assertEquals(m2.getUser(), "ec2-user");
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test(groups="Live")
+    public void testJcloudsWithSpecificLoginUserAndNewUser() throws Exception {
+        log.info("TEST testJcloudsWithSpecificLoginUserAndNewUser");
+        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of(
+                "imageId", EC2_CENTOS_IMAGE,
+                "loginUser", "ec2-user",
+                "user", "newbob",
+                "waitForSshable", 30*1000));
+
+        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
+        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
+        String result;
+        // echo conflates spaces of arguments
+        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m1"));
+        
+        log.info("now trying rebind "+m1);
+        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
+        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m2"));
+        
+        Assert.assertEquals(m2.getUser(), "newbob");
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Test(groups="Live")
+    public void testJcloudsWithSpecificLoginUserAndDefaultUser() throws Exception {
+        log.info("TEST testJcloudsWithSpecificLoginUserAndDefaultUser");
+        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of(
+                "imageId", EC2_CENTOS_IMAGE,
+                "loginUser", "ec2-user",
+                "waitForSshable", 30*1000));
+
+        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
+        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
+        String result;
+        // echo conflates spaces of arguments
+        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m1"));
+        
+        log.info("now trying rebind "+m1);
+        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
+        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
+        Assert.assertTrue(result.contains("trying m2"));
+    }
+
+    @Test(groups="Live")
+    public void testJcloudsCreateWithNoSudoGranted() throws Exception {
+        log.info("TEST testJcloudsCreateWithNoSudoGranted");
+        JcloudsSshMachineLocation m = obtainMachine(MutableMap.of(
+                "grantUserSudo", false,
+                "waitForSshable", 30*1000));
+
+        int exitCode = execWithExitCode(m, ImmutableList.of(BashCommands.sudo("echo yes")));
+        Assert.assertFalse(exitCode == 0, "exit code for sudo command should not have been 0");
+    }
+
+    private String execWithOutput(SshMachineLocation m, List<String> commands) {
+        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+        exec(m, commands, stdout, stderr);
+        return new String(stdout.toByteArray());
+    }
+
+    private int execWithExitCode(SshMachineLocation m, List<String> commands) {
+        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+        return exec(m, commands, stdout, stderr);
+    }
+
+    private int exec(SshMachineLocation m, List<String> commands, ByteArrayOutputStream stdout, ByteArrayOutputStream stderr) {
+        Map<String, Object> flags = Maps.newLinkedHashMap();
+        flags.put("out", stdout);
+        flags.put("err", stderr);
+        int exitCode = m.execCommands(flags, "test", commands);
+        log.info("stdout from "+commands+":\n"+new String(stdout.toByteArray()));
+        log.info("stderr from "+commands+":\n"+new String(stderr.toByteArray()));
+        log.info("exit code: " + exitCode);
+        return exitCode;
+    }
+
+    private JcloudsLocation resolve(String spec) {
+        return (JcloudsLocation) managementContext.getLocationRegistry().resolve("jclouds:"+spec);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
new file mode 100644
index 0000000..e9b9dd8
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.ConfigKeys;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.SingleMachineProvisioningLocation;
+
+public class SingleMachineProvisioningLocationJcloudsLiveTest extends AbstractJcloudsLiveTest {
+private static final Logger log = LoggerFactory.getLogger(SingleMachineProvisioningLocation.class);
+    
+    private SingleMachineProvisioningLocation<JcloudsSshMachineLocation> location;
+
+    private static final String JCLOUDS_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + ":" + AWS_EC2_USEAST_REGION_NAME;
+    
+    @Test(groups="Live")
+    public void testJcloudsSingle() throws Exception {
+        location = resolve("single:(target='"+JCLOUDS_LOCATION_SPEC+"')");
+        
+        MachineLocation m1 = obtainMachine();
+        assertNotNull(m1);
+
+        log.info("GOT "+m1);
+    }
+    
+    @Test(groups="Live")
+    public void testJcloudsSingleRelease() throws Exception {
+        location = resolve("single:(target='"+JCLOUDS_LOCATION_SPEC+"')");
+        
+        JcloudsSshMachineLocation m1 = obtainMachine();
+        log.info("GOT " + m1);
+        JcloudsSshMachineLocation m2 = obtainMachine();
+        log.info("GOT " + m2);
+        assertSame(m1, m2);
+        
+        location.release(m1);
+        assertTrue(m2.isSshable());
+
+        location.release(m2);
+        assertFalse(m2.isSshable());
+    }
+    
+    @Test(groups="Live")
+    public void testJcloudsSingleObtainReleaseObtain() throws Exception {
+        location = resolve("single:(target='"+JCLOUDS_LOCATION_SPEC+"')");
+        
+        JcloudsSshMachineLocation m1 = obtainMachine();
+        log.info("GOT " + m1);
+        
+        location.release(m1);
+        assertFalse(m1.isSshable());
+        
+        JcloudsSshMachineLocation m2 = obtainMachine();
+        assertTrue(m2.isSshable());
+        assertNotEquals(m1, m2);
+        
+        location.release(m2);
+        assertFalse(m2.isSshable());
+    }
+    
+    @Test(groups="Live")
+    public void testJCloudsNamedSingle() throws Exception {
+        brooklynProperties.put(ConfigKeys.newStringConfigKey("brooklyn.location.named.FooServers"), JCLOUDS_LOCATION_SPEC);
+        location = resolve("single:(target='named:FooServers')");
+        
+        JcloudsSshMachineLocation m1 = obtainMachine();
+        assertTrue(m1.isSshable());
+        
+        location.release(m1);
+        assertFalse(m1.isSshable());
+    }
+    
+    @Override
+    protected JcloudsSshMachineLocation obtainMachine(Map<?, ?> conf) throws Exception {
+        JcloudsSshMachineLocation result = location.obtain(conf);
+        machines.add(result);
+        return result;
+    }
+    
+    @Override
+    protected void releaseMachine(JcloudsSshMachineLocation machine) {
+        if (location.getChildren().contains(machine)) {
+            machines.remove(machine);
+            location.release(machine);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private SingleMachineProvisioningLocation<JcloudsSshMachineLocation> resolve(String spec) {
+        SingleMachineProvisioningLocation<JcloudsSshMachineLocation> result = (SingleMachineProvisioningLocation<JcloudsSshMachineLocation>) 
+                managementContext.getLocationRegistry().resolve(spec);
+        // FIXME Do we really need to setManagementContext?!
+        //result.setManagementContext(managementContext);
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/StandaloneJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/StandaloneJcloudsLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/StandaloneJcloudsLiveTest.java
new file mode 100644
index 0000000..b08a087
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/StandaloneJcloudsLiveTest.java
@@ -0,0 +1,254 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertNotNull;
+
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+
+import org.jclouds.Constants;
+import org.jclouds.ContextBuilder;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.RunScriptOptions;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.jclouds.scriptbuilder.statements.login.AdminAccess;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.util.text.Identifiers;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Iterables;
+import com.google.common.io.Files;
+
+public class StandaloneJcloudsLiveTest {
+
+    // FIXME Why do this?
+    // Were we seeing bugs in jclouds for which this was easier to debug and report
+    // Is it because testProvisioningVmWithCustomUsername is disabled and not working?
+    
+    public static final Logger LOG = LoggerFactory.getLogger(StandaloneJcloudsLiveTest.class);
+    
+    private static final String PROVIDER = AbstractJcloudsLiveTest.AWS_EC2_PROVIDER;
+    private static final String REGION = AbstractJcloudsLiveTest.AWS_EC2_USEAST_REGION_NAME;
+    private static final String PRIVATE_IMAGE_ID = "us-east-1/ami-f95cf390";
+    
+    static BrooklynProperties globals = BrooklynProperties.Factory.newDefault();
+
+    String identity = globals.getFirst("brooklyn.location.jclouds.aws-ec2.identity");
+    String credential = globals.getFirst("brooklyn.location.jclouds.aws-ec2.credential");
+    
+    @Test(enabled=false, groups={"WIP","Live"})
+    public void createVm() {
+        String groupId = "mygroup-"+System.getProperty("user.name")+"-"+UUID.randomUUID().toString();
+ 
+        Properties properties = new Properties();
+        properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
+        properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
+        // handy to list all images... but very slow!
+//        properties.setProperty(AWSEC2Constants.PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine");
+
+        ComputeServiceContext computeServiceContext = ContextBuilder.newBuilder(PROVIDER).
+                modules(Arrays.asList(new SshjSshClientModule(), new SLF4JLoggingModule())).
+                credentials(identity, credential).
+                overrides(properties).
+                build(ComputeServiceContext.class);
+        
+        final ComputeService computeService = computeServiceContext.getComputeService();
+        
+        NodeMetadata node = null;
+        try {
+            LOG.info("Creating VM for "+identity);
+
+            TemplateBuilder templateBuilder = computeService.templateBuilder();
+            templateBuilder.locationId(REGION);
+            
+            Template template = templateBuilder.build();
+            Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(groupId, 1, template);
+            node = Iterables.getOnlyElement(nodes, null);
+            if (node == null) throw new IllegalStateException("No nodes returned");
+
+            assertNotNull(node.getOperatingSystem());
+
+            Credentials nodeCredentials = node.getCredentials();
+            final LoginCredentials expectedCredentials = LoginCredentials.fromCredentials(nodeCredentials);
+            
+            LOG.info("Started VM, waiting for it to be sshable");
+            boolean reachable = false;
+            for (int i=0; i<120; i++) {
+                try {
+                    Statement statement = Statements.newStatementList(Statements.exec("date"));
+                    ExecResponse response = computeService.runScriptOnNode(node.getId(), statement,
+                            RunScriptOptions.Builder.overrideLoginCredentials(expectedCredentials));
+                    if (response.getExitStatus() == 0) {
+                        LOG.info("ssh 'date' succeeded");
+                        reachable = true;
+                        break;
+                    }
+                    LOG.info("ssh 'date' failed, exit "+response.getExitStatus()+", but still in retry loop");
+                } catch (Exception e) {
+                    if (i<120)
+                        LOG.info("ssh 'date' failed, but still in retry loop: "+e);
+                    else {
+                        LOG.error("ssh 'date' failed after timeout: "+e, e);
+                        Throwables.propagate(e);
+                    }
+                }
+                Thread.sleep(1000);
+            }
+        
+            if (!reachable) {
+                throw new IllegalStateException("SSH failed, never reachable");
+            }
+
+        } catch (RunNodesException e) {
+            if (e.getNodeErrors().size() > 0) {
+                node = Iterables.get(e.getNodeErrors().keySet(), 0);
+            }
+            LOG.error("Failed to start VM: "+e, e);
+            throw Throwables.propagate(e);
+        } catch (Exception e) {
+            LOG.error("Failed to start VM: "+e, e);
+            throw Throwables.propagate(e);
+        } finally {
+            LOG.info("Now destroying VM: "+node);
+            computeService.destroyNode( node.getId() );
+
+            computeService.getContext().close();
+        }
+        
+    }
+    
+    @Test(enabled=false, groups={"WIP","Live"})
+    public void createVmWithAdminUser() {
+        String groupId = "mygroup-"+System.getProperty("user.name")+"-"+UUID.randomUUID().toString();
+ 
+        Properties properties = new Properties();
+        properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
+        properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
+
+        ComputeServiceContext computeServiceContext = ContextBuilder.newBuilder(PROVIDER).
+                modules(Arrays.asList(new SshjSshClientModule(), new SLF4JLoggingModule())).
+                credentials(identity, credential).
+                overrides(properties).
+                build(ComputeServiceContext.class);
+        
+        final ComputeService computeService = computeServiceContext.getComputeService();
+        
+        NodeMetadata node = null;
+        try {
+            LOG.info("Creating VM for "+identity);
+            String myPubKey = Files.toString(new File(System.getProperty("user.home")+"/.ssh/aws-id_rsa.pub"), Charset.defaultCharset());
+            String myPrivKey = Files.toString(new File(System.getProperty("user.home")+"/.ssh/aws-id_rsa"), Charset.defaultCharset());
+
+            TemplateBuilder templateBuilder = computeService.templateBuilder();
+            templateBuilder.locationId(REGION);
+            TemplateOptions opts = new TemplateOptions();
+            
+//            templateBuilder.imageId("us-east-1/ami-2342a94a");  //rightscale
+            // either use above, or below
+            templateBuilder.imageId(PRIVATE_IMAGE_ID);  //private one (to test when user isn't autodetected)
+            opts.overrideLoginUser("ec2-user");
+            
+            AdminAccess.Builder adminBuilder = AdminAccess.builder().
+                    adminUsername("bob").
+                    grantSudoToAdminUser(true).
+                    authorizeAdminPublicKey(true).adminPublicKey(myPubKey).
+                    // items below aren't wanted but values for some are required otherwise AdminAccess uses all defaults
+                    lockSsh(true).adminPassword(Identifiers.makeRandomId(12)).
+                    resetLoginPassword(false).loginPassword(Identifiers.makeRandomId(12)).
+                    installAdminPrivateKey(false).adminPrivateKey("ignored");
+            opts.runScript(adminBuilder.build());
+            
+            templateBuilder.options(opts);
+            
+            Template template = templateBuilder.build();
+            Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(groupId, 1, template);
+            node = Iterables.getOnlyElement(nodes, null);
+            if (node == null) throw new IllegalStateException("No nodes returned");
+
+            LOG.info("Started VM, waiting for it to be sshable on "+node.getPublicAddresses());
+            final LoginCredentials crds =
+//                    node.getCredentials();
+                    LoginCredentials.builder().user("bob").privateKey(myPrivKey).build();
+            boolean reachable = false;
+            for (int i=0; i<120; i++) {
+                try {
+                    Statement statement = Statements.newStatementList(Statements.exec("date"));
+                    ExecResponse response = computeService.runScriptOnNode(node.getId(), statement,
+                            RunScriptOptions.Builder.overrideLoginCredentials(crds));
+                    if (response.getExitStatus() == 0) {
+                        LOG.info("ssh 'date' succeeded");
+                        reachable = true;
+                        break;
+                    }
+                    LOG.info("ssh 'date' failed, exit "+response.getExitStatus()+", but still in retry loop");
+                } catch (Exception e) {
+                    if (i<120)
+                        LOG.info("ssh 'date' failed, but still in retry loop: "+e);
+                    else {
+                        LOG.error("ssh 'date' failed after timeout: "+e, e); 
+                        Throwables.propagate(e);
+                    }
+                }
+                Thread.sleep(1000);
+            }
+        
+            if (!reachable) {
+                throw new IllegalStateException("SSH failed, never reachable");
+            }
+            
+        } catch (RunNodesException e) {
+            if (e.getNodeErrors().size() > 0) {
+                node = Iterables.get(e.getNodeErrors().keySet(), 0);
+            }
+            LOG.error("Failed to start VM: "+e, e);
+            throw Throwables.propagate(e);
+        } catch (Exception e) {
+            LOG.error("Failed to start VM: "+e, e);
+            throw Throwables.propagate(e);
+        } finally {
+            LOG.info("Now destroying VM: "+node);
+            computeService.destroyNode( node.getId() );
+
+            computeService.getContext().close();
+        }
+        
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
new file mode 100644
index 0000000..c6025ba
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
@@ -0,0 +1,311 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.networking;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Collections;
+
+import org.jclouds.aws.AWSResponseException;
+import org.jclouds.aws.domain.AWSError;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.Location;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.mockito.Answers;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Cidr;
+
+public class JcloudsLocationSecurityGroupCustomizerTest {
+
+    JcloudsLocationSecurityGroupCustomizer customizer;
+    ComputeService computeService;
+    Location location;
+    SecurityGroupExtension securityApi;
+
+    /** Used to skip external checks in unit tests. */
+    private static class TestCidrSupplier implements Supplier<Cidr> {
+        @Override public Cidr get() {
+            return new Cidr("192.168.10.10/32");
+        }
+    }
+
+    @BeforeMethod
+    public void setUp() {
+        customizer = new JcloudsLocationSecurityGroupCustomizer("testapp", new TestCidrSupplier());
+        location = mock(Location.class);
+        securityApi = mock(SecurityGroupExtension.class);
+        computeService = mock(ComputeService.class, Answers.RETURNS_DEEP_STUBS.get());
+        when(computeService.getSecurityGroupExtension()).thenReturn(Optional.of(securityApi));
+    }
+
+    @Test
+    public void testSameInstanceReturnedForSameApplication() {
+        assertEquals(JcloudsLocationSecurityGroupCustomizer.getInstance("a"),
+                JcloudsLocationSecurityGroupCustomizer.getInstance("a"));
+        assertNotEquals(JcloudsLocationSecurityGroupCustomizer.getInstance("a"),
+                JcloudsLocationSecurityGroupCustomizer.getInstance("b"));
+    }
+
+    @Test
+    public void testSecurityGroupAddedWhenJcloudsLocationCustomised() {
+        Template template = mock(Template.class);
+        TemplateOptions templateOptions = mock(TemplateOptions.class);
+        when(template.getLocation()).thenReturn(location);
+        when(template.getOptions()).thenReturn(templateOptions);
+        SecurityGroup group = newGroup("id");
+        when(securityApi.createSecurityGroup(anyString(), eq(location))).thenReturn(group);
+
+        // Two Brooklyn.JcloudsLocations added to same Jclouds.Location
+        JcloudsLocation jcloudsLocationA = new JcloudsLocation(MutableMap.of("deferConstruction", true));
+        JcloudsLocation jcloudsLocationB = new JcloudsLocation(MutableMap.of("deferConstruction", true));
+        customizer.customize(jcloudsLocationA, computeService, template);
+        customizer.customize(jcloudsLocationB, computeService, template);
+
+        // One group with three permissions shared by both locations.
+        // Expect TCP, UDP and ICMP between members of group and SSH to Brooklyn
+        verify(securityApi).createSecurityGroup(anyString(), eq(location));
+        verify(securityApi, times(4)).addIpPermission(any(IpPermission.class), eq(group));
+        // New groups set on options
+        verify(templateOptions, times(2)).securityGroups(anyString());
+    }
+
+    @Test
+    public void testSharedGroupLoadedWhenItExistsButIsNotCached() {
+        Template template = mock(Template.class);
+        TemplateOptions templateOptions = mock(TemplateOptions.class);
+        when(template.getLocation()).thenReturn(location);
+        when(template.getOptions()).thenReturn(templateOptions);
+        JcloudsLocation jcloudsLocation = new JcloudsLocation(MutableMap.of("deferConstruction", true));
+        SecurityGroup shared = newGroup(customizer.getNameForSharedSecurityGroup());
+        SecurityGroup irrelevant = newGroup("irrelevant");
+        when(securityApi.listSecurityGroupsInLocation(location)).thenReturn(ImmutableSet.of(irrelevant, shared));
+
+        customizer.customize(jcloudsLocation, computeService, template);
+
+        verify(securityApi).listSecurityGroupsInLocation(location);
+        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
+    }
+
+    @Test
+    public void testAddPermissionsToNode() {
+        IpPermission ssh = newPermission(22);
+        IpPermission jmx = newPermission(31001);
+        String nodeId = "node";
+        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
+        SecurityGroup group = newGroup("id");
+        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, group));
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
+
+        customizer.addPermissionsToLocation(ImmutableList.of(ssh, jmx), nodeId, computeService);
+
+        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
+        verify(securityApi, times(1)).addIpPermission(ssh, group);
+        verify(securityApi, times(1)).addIpPermission(jmx, group);
+    }
+
+    @Test
+    public void testAddPermissionsToNodeUsesUncachedSecurityGroup() {
+        JcloudsLocation jcloudsLocation = new JcloudsLocation(MutableMap.of("deferConstruction", true));
+        IpPermission ssh = newPermission(22);
+        String nodeId = "nodeId";
+        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
+        SecurityGroup uniqueGroup = newGroup("unique");
+
+        Template template = mock(Template.class);
+        TemplateOptions templateOptions = mock(TemplateOptions.class);
+        when(template.getLocation()).thenReturn(location);
+        when(template.getOptions()).thenReturn(templateOptions);
+        when(securityApi.createSecurityGroup(anyString(), eq(location))).thenReturn(sharedGroup);
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
+
+        // Call customize to cache the shared group
+        customizer.customize(jcloudsLocation, computeService, template);
+        reset(securityApi);
+        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(uniqueGroup, sharedGroup));
+        customizer.addPermissionsToLocation(ImmutableSet.of(ssh), nodeId, computeService);
+
+        // Expect the per-machine group to have been altered, not the shared group
+        verify(securityApi).addIpPermission(ssh, uniqueGroup);
+        verify(securityApi, never()).addIpPermission(any(IpPermission.class), eq(sharedGroup));
+    }
+
+    @Test
+    public void testSecurityGroupsLoadedWhenAddingPermissionsToUncachedNode() {
+        IpPermission ssh = newPermission(22);
+        String nodeId = "nodeId";
+        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
+        SecurityGroup uniqueGroup = newGroup("unique");
+
+        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
+
+        // Expect first call to list security groups on nodeId, second to use cached version
+        customizer.addPermissionsToLocation(ImmutableSet.of(ssh), nodeId, computeService);
+        customizer.addPermissionsToLocation(ImmutableSet.of(ssh), nodeId, computeService);
+
+        verify(securityApi, times(1)).listSecurityGroupsForNode(nodeId);
+        verify(securityApi, times(2)).addIpPermission(ssh, uniqueGroup);
+        verify(securityApi, never()).addIpPermission(any(IpPermission.class), eq(sharedGroup));
+    }
+
+    @Test
+    public void testAddRuleNotRetriedByDefault() {
+        IpPermission ssh = newPermission(22);
+        String nodeId = "node";
+        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
+        SecurityGroup uniqueGroup = newGroup("unique");
+        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
+        when(securityApi.addIpPermission(eq(ssh), eq(uniqueGroup)))
+                .thenThrow(new RuntimeException("exception creating " + ssh));
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
+
+        try {
+            customizer.addPermissionsToLocation(ImmutableList.of(ssh), nodeId, computeService);
+        } catch (Exception e) {
+            assertTrue(e.getMessage().contains("repeated errors from provider"), "message=" + e.getMessage());
+        }
+        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
+        verify(securityApi, times(1)).addIpPermission(ssh, uniqueGroup);
+    }
+
+    @Test
+    public void testCustomExceptionRetryablePredicate() {
+        final String message = "testCustomExceptionRetryablePredicate";
+        Predicate<Exception> messageChecker = new Predicate<Exception>() {
+            @Override
+            public boolean apply(Exception input) {
+                Throwable t = input;
+                while (t != null) {
+                    if (t.getMessage().contains(message)) {
+                        return true;
+                    } else {
+                        t = t.getCause();
+                    }
+                }
+                return false;
+            }
+        };
+        customizer.setRetryExceptionPredicate(messageChecker);
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
+
+        IpPermission ssh = newPermission(22);
+        String nodeId = "node";
+        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
+        SecurityGroup uniqueGroup = newGroup("unique");
+        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
+        when(securityApi.addIpPermission(eq(ssh), eq(uniqueGroup)))
+                .thenThrow(new RuntimeException(new Exception(message)))
+                .thenThrow(new RuntimeException(new Exception(message)))
+                .thenReturn(sharedGroup);
+
+        customizer.addPermissionsToLocation(ImmutableList.of(ssh), nodeId, computeService);
+
+        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
+        verify(securityApi, times(3)).addIpPermission(ssh, uniqueGroup);
+    }
+
+    @Test
+    public void testAddRuleRetriedOnAwsFailure() {
+        IpPermission ssh = newPermission(22);
+        String nodeId = "nodeId";
+        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
+        SecurityGroup uniqueGroup = newGroup("unique");
+        customizer.setRetryExceptionPredicate(JcloudsLocationSecurityGroupCustomizer.newAwsExceptionRetryPredicate());
+        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
+        when(securityApi.addIpPermission(any(IpPermission.class), eq(uniqueGroup)))
+                .thenThrow(newAwsResponseExceptionWithCode("InvalidGroup.InUse"))
+                .thenThrow(newAwsResponseExceptionWithCode("DependencyViolation"))
+                .thenThrow(newAwsResponseExceptionWithCode("RequestLimitExceeded"))
+                .thenThrow(newAwsResponseExceptionWithCode("Blocked"))
+                .thenReturn(sharedGroup);
+        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
+
+        try {
+            customizer.addPermissionsToLocation(ImmutableList.of(ssh), nodeId, computeService);
+        } catch (Exception e) {
+            String expected = "repeated errors from provider";
+            assertTrue(e.getMessage().contains(expected), "expected exception message to contain " + expected + ", was: " + e.getMessage());
+        }
+
+        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
+        verify(securityApi, times(4)).addIpPermission(ssh, uniqueGroup);
+    }
+
+    private SecurityGroup newGroup(String id) {
+        URI uri = null;
+        String ownerId = null;
+        return new SecurityGroup(
+                "providerId",
+                id,
+                id,
+                location,
+                uri,
+                Collections.<String, String>emptyMap(),
+                ImmutableSet.<String>of(),
+                ImmutableSet.<IpPermission>of(),
+                ownerId);
+    }
+
+    private IpPermission newPermission(int port) {
+        return IpPermission.builder()
+                .ipProtocol(IpProtocol.TCP)
+                .fromPort(port)
+                .toPort(port)
+                .cidrBlock("0.0.0.0/0")
+                .build();
+    }
+
+    private AWSError newAwsErrorWithCode(String code) {
+        AWSError e = new AWSError();
+        e.setCode(code);
+        return e;
+    }
+
+    private Exception newAwsResponseExceptionWithCode(String code) {
+        AWSResponseException e = new AWSResponseException("irrelevant message", null, null, newAwsErrorWithCode(code));
+        return new RuntimeException(e);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/JcloudsPortForwardingStubbedLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/JcloudsPortForwardingStubbedLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/JcloudsPortForwardingStubbedLiveTest.java
new file mode 100644
index 0000000..860a8e3
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/JcloudsPortForwardingStubbedLiveTest.java
@@ -0,0 +1,196 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.networking;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import java.util.List;
+
+import org.apache.brooklyn.location.jclouds.AbstractJcloudsStubbedLiveTest;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadata.Status;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.domain.LoginCredentials;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import org.apache.brooklyn.location.access.PortForwardManager;
+import org.apache.brooklyn.location.access.PortForwardManagerImpl;
+import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation;
+import brooklyn.util.net.Cidr;
+import brooklyn.util.net.Protocol;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.net.HostAndPort;
+
+/**
+ * The VM creation is stubbed out, but it still requires live access (i.e. real account credentials)
+ * to generate the template etc.
+ * 
+ * We supply a ComputeServiceRegistry that delegates to the real instance for everything except
+ * VM creation and deletion. For those operations, it delegates to a NodeCreator that 
+ * returns a dummy NodeMetadata, recording all calls made to it.
+ */
+public class JcloudsPortForwardingStubbedLiveTest extends AbstractJcloudsStubbedLiveTest {
+
+    @SuppressWarnings("unused")
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsPortForwardingStubbedLiveTest.class);
+
+    static class RecordingJcloudsPortForwarderExtension implements JcloudsPortForwarderExtension {
+        final PortForwardManager pfm;
+        final List<List<Object>> opens = Lists.newCopyOnWriteArrayList();
+        final List<List<Object>> closes = Lists.newCopyOnWriteArrayList();
+        int nextPublicPort = 12345;
+        
+        RecordingJcloudsPortForwarderExtension(PortForwardManager pfm) {
+            this.pfm = pfm;
+        }
+        @Override public HostAndPort openPortForwarding(NodeMetadata node, int targetPort, Optional<Integer> optionalPublicPort, Protocol protocol, Cidr accessingCidr) {
+            opens.add(ImmutableList.of(node, targetPort, optionalPublicPort, protocol, accessingCidr));
+            HostAndPort result = HostAndPort.fromParts("1.2.3.4", nextPublicPort++);
+            pfm.associate(node.getId(), result, targetPort);
+            return result;
+        }
+        @Override public void closePortForwarding(NodeMetadata node, int targetPort, HostAndPort publicHostAndPort, Protocol protocol) {
+            closes.add(ImmutableList.of(node, targetPort, publicHostAndPort, protocol));
+            pfm.forgetPortMapping(node.getId(), publicHostAndPort.getPort());
+        }
+    }
+
+    @Override
+    protected NodeCreator newNodeCreator() {
+        return new NodeCreator() {
+            int nextIpSuffix = 2;
+            @Override
+            protected NodeMetadata newNode(String group, Template template) {
+                int ipSuffix = nextIpSuffix++;
+                NodeMetadata result = new NodeMetadataBuilder()
+                        .id("myid-"+ipSuffix)
+                        .credentials(LoginCredentials.builder().identity("myuser").credential("mypassword").build())
+                        .loginPort(22)
+                        .status(Status.RUNNING)
+                        .publicAddresses(ImmutableList.of("173.194.32."+ipSuffix))
+                        .privateAddresses(ImmutableList.of("172.168.10."+ipSuffix))
+                        .build();
+                return result;
+            }
+        };
+    }
+
+    @Test(groups = {"Live", "Live-sanity"})
+    protected void testPortForwardingCallsForwarder() throws Exception {
+        PortForwardManager pfm = new PortForwardManagerImpl();
+        RecordingJcloudsPortForwarderExtension portForwarder = new RecordingJcloudsPortForwarderExtension(pfm);
+        
+        JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.<ConfigKey<?>,Object>of(
+                JcloudsLocation.USE_PORT_FORWARDING, true,
+                JcloudsLocation.PORT_FORWARDER, portForwarder));
+        
+        NodeMetadata created = nodeCreator.created.get(0);
+        assertEquals(nodeCreator.created.size(), 1, "created="+nodeCreator.created+"; machine="+machine);
+        assertEquals(machine.getNode(), created);
+        assertEquals(portForwarder.opens.size(), 1, "opens="+portForwarder.opens+"; machine="+machine);
+        assertEquals(portForwarder.opens.get(0).get(0), created);
+        assertEquals(portForwarder.opens.get(0).get(1), 22);
+        assertEquals(portForwarder.opens.get(0).get(3), Protocol.TCP);
+        assertEquals(portForwarder.opens.get(0).get(4), Cidr.UNIVERSAL);
+        assertEquals(machine.getSshHostAndPort(), HostAndPort.fromParts("1.2.3.4", 12345));
+        
+        releaseMachine(machine);
+        String destroyed = nodeCreator.destroyed.get(0);
+        assertEquals(nodeCreator.destroyed.size(), 1, "destroyed="+nodeCreator.destroyed+"; machine="+machine);
+        assertEquals(destroyed, created.getId());
+        assertEquals(portForwarder.closes.size(), 1, "closes="+portForwarder.closes+"; machine="+machine);
+        assertEquals(portForwarder.closes.get(0).get(0), created);
+        assertEquals(portForwarder.closes.get(0).get(1), 22);
+        assertEquals(portForwarder.closes.get(0).get(2), HostAndPort.fromParts("1.2.3.4", 12345));
+        assertEquals(portForwarder.closes.get(0).get(3), Protocol.TCP);
+    }
+    
+    @Test(groups = {"Live", "Live-sanity"})
+    protected void testDeregistersWithPortForwardManagerOnRelease() throws Exception {
+        PortForwardManager pfm = new PortForwardManagerImpl();
+        RecordingJcloudsPortForwarderExtension portForwarder = new RecordingJcloudsPortForwarderExtension(pfm);
+        
+        JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.<ConfigKey<?>,Object>of(
+                JcloudsLocation.PORT_FORWARDER, portForwarder,
+                JcloudsLocation.PORT_FORWARDING_MANAGER, pfm));
+        
+        // Add an association for this machine - expect that to be deleted when the machine is released.
+        HostAndPort publicHostAndPort = HostAndPort.fromParts("1.2.3.4", 1234);
+        pfm.associate("mypublicip", publicHostAndPort, machine, 80);
+        assertEquals(pfm.lookup(machine, 80), publicHostAndPort);
+        assertEquals(pfm.lookup("mypublicip", 80), publicHostAndPort);
+
+        // Release
+        releaseMachine(machine);
+        
+        // Expect to have been cleared from PortForwardManager's records
+        assertNull(pfm.lookup(machine, 80));
+        assertNull(pfm.lookup("mypublicip", 80));
+        
+        // And for port-forwarding to have been closed
+        assertEquals(portForwarder.closes.size(), 1, "closes="+portForwarder.closes+"; machine="+machine);
+        assertEquals(portForwarder.closes.get(0).get(1), 80);
+        assertEquals(portForwarder.closes.get(0).get(2), HostAndPort.fromParts("1.2.3.4", 1234));
+        assertEquals(portForwarder.closes.get(0).get(3), Protocol.TCP);
+    }
+    
+    @Test(groups = {"Live", "Live-sanity"})
+    protected void testReleaseVmDoesNotImpactOtherVms() throws Exception {
+        PortForwardManager pfm = new PortForwardManagerImpl();
+        RecordingJcloudsPortForwarderExtension portForwarder = new RecordingJcloudsPortForwarderExtension(pfm);
+        
+        JcloudsSshMachineLocation machine1 = obtainMachine(ImmutableMap.<ConfigKey<?>,Object>of(
+                JcloudsLocation.USE_PORT_FORWARDING, true,
+                JcloudsLocation.PORT_FORWARDER, portForwarder,
+                JcloudsLocation.PORT_FORWARDING_MANAGER, pfm));
+        
+        JcloudsSshMachineLocation machine2 = obtainMachine(ImmutableMap.<ConfigKey<?>,Object>of(
+                JcloudsLocation.USE_PORT_FORWARDING, true,
+                JcloudsLocation.PORT_FORWARDER, portForwarder,
+                JcloudsLocation.PORT_FORWARDING_MANAGER, pfm));
+        
+        NodeMetadata node1 = nodeCreator.created.get(0);
+
+        // Add an association for machine2 - expect that not to be touched when machine1 is released.
+        HostAndPort publicHostAndPort = HostAndPort.fromParts("1.2.3.4", 1234);
+        pfm.associate("mypublicip", publicHostAndPort, machine2, 80);
+
+        // Release machine1
+        releaseMachine(machine1);
+        
+        // Expect machine2 to still be registered
+        assertEquals(pfm.lookup(machine2, 80), publicHostAndPort);
+        assertEquals(pfm.lookup("mypublicip", 80), publicHostAndPort);
+        
+        // And no calls to "close" for machine2; just for machine1's port 22
+        assertEquals(portForwarder.closes.size(), 1, "closes="+portForwarder.closes+"; machine1="+machine1);
+        assertEquals(portForwarder.closes.get(0).get(0), node1);
+        assertEquals(portForwarder.closes.get(0).get(1), 22);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupLiveTest.java
new file mode 100644
index 0000000..0eed616
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/SecurityGroupLiveTest.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.jclouds.networking;
+
+import org.testng.annotations.Test;
+
+@Test(groups = {"Live", "WIP"})
+public class SecurityGroupLiveTest {
+
+    public void testCreateEc2WithSecurityGroup() {
+        SecurityGroupDefinition sgDef = new SecurityGroupDefinition()
+            .allowingInternalPorts(8097, 8098).allowingInternalPortRange(6000, 7999)
+            .allowingPublicPort(8099);
+        // TODO create machine and test
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/pool/JcloudsMachinePoolLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/pool/JcloudsMachinePoolLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/pool/JcloudsMachinePoolLiveTest.java
new file mode 100644
index 0000000..4d30c80
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/pool/JcloudsMachinePoolLiveTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.pool;
+
+import java.util.Arrays;
+
+import org.apache.brooklyn.location.jclouds.AbstractJcloudsLiveTest;
+import org.jclouds.ContextBuilder;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+
+public class JcloudsMachinePoolLiveTest extends AbstractJcloudsLiveTest {
+
+    public static final Logger log = LoggerFactory.getLogger(JcloudsMachinePoolLiveTest.class);
+    
+    private static final String PROVIDER = AWS_EC2_PROVIDER;
+    private static final String LOCATION_SPEC = PROVIDER + ":" + AWS_EC2_EUWEST_REGION_NAME;
+    
+    public static class SamplePool extends MachinePool {
+        public SamplePool(ComputeService svc) {
+            super(svc);
+        }
+
+        public final static ReusableMachineTemplate 
+            USUAL_VM = 
+                new ReusableMachineTemplate("usual").templateOwnedByMe().
+                tagOptional("tagForUsualVm").
+                metadataOptional("metadataForUsualVm", "12345").
+                minRam(1024).minCores(2);
+
+        public final static ReusableMachineTemplate 
+            ANYONE_NOT_TINY_VM = 
+                new ReusableMachineTemplate("anyone").
+                minRam(512).minCores(1).strict(false);
+
+        public static final ReusableMachineTemplate 
+            VM_LARGE1 = 
+                new ReusableMachineTemplate("vm.large1").templateOwnedByMe().
+                minRam(16384).minCores(4),
+            VM_SMALL1 = 
+                new ReusableMachineTemplate("vm.small1").templateOwnedByMe().smallest();
+        
+        { registerTemplates(USUAL_VM, ANYONE_NOT_TINY_VM, VM_LARGE1, VM_SMALL1); }
+    }
+    
+    private ComputeServiceContext context;
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(LOCATION_SPEC);
+        
+        context = ContextBuilder.newBuilder(PROVIDER)
+                .modules(Arrays.asList(new SshjSshClientModule(), new SLF4JLoggingModule()))
+                .credentials(jcloudsLocation.getIdentity(), jcloudsLocation.getCredential())
+                .build(ComputeServiceContext.class);
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            super.tearDown();
+        } finally {
+            if (context != null) context.close();
+        }
+    }
+    
+    @Test(groups={"Live","WIP"})
+    public void buildClaimAndDestroy() {
+        ComputeService svc = context.getComputeService();
+        SamplePool p = new SamplePool(svc);
+        log.info("buildClaimAndDestroy: created pool");
+        p.refresh();
+        log.info("buildClaimAndDestroy: refreshed pool");
+        p.ensureExists(2, SamplePool.USUAL_VM);
+        log.info("buildClaimAndDestroy: ensure have 2");
+        MachineSet l = p.claim(1, SamplePool.USUAL_VM);
+        Assert.assertEquals(l.size(), 1);
+        log.info("buildClaimAndDestroy: claimed 1");
+        MachineSet unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM));
+        log.info("buildClaimAndDestroy: unclaimed now "+unclaimedUsual);
+        Assert.assertTrue(!unclaimedUsual.isEmpty());
+        p.destroy(unclaimedUsual);
+        unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM));
+        log.info("buildClaimAndDestroy: destroyed, unclaimed now "+unclaimedUsual);
+        log.info("end");
+    }
+    
+
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
new file mode 100644
index 0000000..fd93a7a
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.provider;
+
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.testng.collections.Lists;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+public abstract class AbstractJcloudsLocationTest {
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractJcloudsLocationTest.class);
+
+    private final String provider;
+
+    protected JcloudsLocation loc;
+    protected List<SshMachineLocation> machines = MutableList.of();
+    protected ManagementContext ctx;
+
+    protected AbstractJcloudsLocationTest(String provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * The location and image id tuplets to test.
+     */
+    @DataProvider(name = "fromImageId")
+    public abstract Object[][] cloudAndImageIds();
+
+    /**
+     * A single location and image id tuplet to test.
+     */
+    @DataProvider(name = "fromFirstImageId")
+    public Object[][] cloudAndImageFirstId() {
+        Object[][] all = cloudAndImageIds();
+        return (all != null) ? new Object[][] { all[0] } : new Object[][] { };
+    }
+
+    /**
+     * The location and image name pattern tuplets to test.
+     */
+    @DataProvider(name = "fromImageNamePattern")
+    public abstract Object[][] cloudAndImageNamePatterns();
+
+    /**
+     * The location, image pattern and image owner tuplets to test.
+     */
+    @DataProvider(name = "fromImageDescriptionPattern")
+    public abstract Object[][] cloudAndImageDescriptionPatterns();
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() {
+        BrooklynProperties props = BrooklynProperties.Factory.newDefault().addFromMap(ImmutableMap.of("provider", provider));
+        ctx = Entities.newManagementContext(props.asMapWithStringKeys());
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() {
+        List<Exception> exceptions = Lists.newArrayList();
+        for (SshMachineLocation machine : machines) {
+            try {
+                loc.release(machine);
+            } catch (Exception e) {
+                LOG.warn("Error releasing {}: {}; continuing...", machine, e.getMessage());
+                exceptions.add(e);
+            }
+        }
+        if (!exceptions.isEmpty()) {
+            LOG.info("Exception during tearDown: {}", Exceptions.collapseText(exceptions.get(0)));
+        }
+        machines.clear();
+        
+        if (ctx != null) Entities.destroyAllCatching(ctx);
+    }
+
+    @Test(dataProvider="fromImageId")
+    public void testTagMapping(String regionName, String imageId, String imageOwner) {
+        Map<String, Object> dummy = ImmutableMap.<String, Object>of("identity", "DUMMY", "credential", "DUMMY");
+        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(provider + (regionName == null ? "" : ":" + regionName), dummy);
+        ImmutableMap.Builder<String, Object> builder = ImmutableMap.<String, Object>builder().put("imageId", imageId);
+        if (imageOwner != null) builder.put("imageOwner", imageOwner);
+        Map<String, Object> tagMapping = builder.build();
+        loc.setTagMapping(ImmutableMap.<String, Map<String, ? extends Object>>of("MyEntityType", tagMapping));
+
+        Map<String, Object> flags = loc.getProvisioningFlags(ImmutableList.of("MyEntityType"));
+        assertTrue(Maps.<String, Object>difference(flags, tagMapping).entriesOnlyOnRight().isEmpty(), "flags="+flags);
+    }
+
+    @Test(groups = "Live", dataProvider="fromImageId")
+    public void testProvisionVmUsingImageId(String regionName, String imageId, String imageOwner) {
+        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(provider + (regionName == null ? "" : ":" + regionName));
+        SshMachineLocation machine = obtainMachine(MutableMap.of("imageId", imageId, "imageOwner", imageOwner, JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 2));
+
+        LOG.info("Provisioned {} vm {}; checking if ssh'able", provider, machine);
+        assertTrue(machine.isSshable());
+    }
+    
+    @Test(groups = "Live", dataProvider="fromImageNamePattern")
+    public void testProvisionVmUsingImageNamePattern(String regionName, String imageNamePattern, String imageOwner) {
+        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(provider + (regionName == null ? "" : ":" + regionName));
+        SshMachineLocation machine = obtainMachine(MutableMap.of("imageNameRegex", imageNamePattern, "imageOwner", imageOwner, JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 2));
+        
+        LOG.info("Provisioned {} vm {}; checking if ssh'able", provider, machine);
+        assertTrue(machine.isSshable());
+    }
+    
+    @Test(groups = "Live", dataProvider="fromImageDescriptionPattern")
+    public void testProvisionVmUsingImageDescriptionPattern(String regionName, String imageDescriptionPattern, String imageOwner) {
+        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(provider + (regionName == null ? "" : ":" + regionName));
+        SshMachineLocation machine = obtainMachine(MutableMap.of("imageDescriptionRegex", imageDescriptionPattern, "imageOwner", imageOwner, JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 2));
+        
+        LOG.info("Provisioned {} vm {}; checking if ssh'able", provider, machine);
+        assertTrue(machine.isSshable());
+    }
+
+    // Use this utility method to ensure machines are released on tearDown
+    protected SshMachineLocation obtainMachine(Map flags) {
+        try {
+            SshMachineLocation result = (SshMachineLocation)loc.obtain(flags);
+            machines.add(result);
+            return result;
+        } catch (NoMachinesAvailableException nmae) {
+            LOG.warn("No machines available", nmae);
+            throw Exceptions.propagate(nmae);
+        }
+    }
+    
+    protected SshMachineLocation release(SshMachineLocation machine) {
+        machines.remove(machine);
+        loc.release(machine);
+        return machine;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationLiveTest.java
new file mode 100644
index 0000000..6644645
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationLiveTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.provider;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class AwsEc2LocationLiveTest extends AbstractJcloudsLocationTest {
+
+    private static final String PROVIDER = "aws-ec2";
+    private static final String EUWEST_REGION_NAME = "eu-west-1";
+    private static final String USEAST_REGION_NAME = "us-east-1";
+    private static final String EUWEST_IMAGE_ID = EUWEST_REGION_NAME+"/"+"ami-89def4fd"; // RightImage_CentOS_5.4_i386_v5.5.9_EBS
+    private static final String USEAST_IMAGE_ID = USEAST_REGION_NAME+"/"+"ami-2342a94a"; // RightImage_CentOS_5.4_i386_v5.5.9_EBS
+    private static final String IMAGE_OWNER = "411009282317";
+    private static final String IMAGE_PATTERN = "RightImage_CentOS_5.4_i386_v5.5.9_EBS";
+
+    public AwsEc2LocationLiveTest() {
+        super(PROVIDER);
+    }
+
+    @Override
+    @DataProvider(name = "fromImageId")
+    public Object[][] cloudAndImageIds() {
+        return new Object[][] {
+                new Object[] { EUWEST_REGION_NAME, EUWEST_IMAGE_ID, IMAGE_OWNER },
+                new Object[] { USEAST_REGION_NAME, USEAST_IMAGE_ID, IMAGE_OWNER }
+            };
+    }
+
+    @Override
+    @DataProvider(name = "fromImageDescriptionPattern")
+    public Object[][] cloudAndImageDescriptionPatterns() {
+        return new Object[][] {
+                new Object[] { EUWEST_REGION_NAME, IMAGE_PATTERN, IMAGE_OWNER },
+                new Object[] { USEAST_REGION_NAME, IMAGE_PATTERN, IMAGE_OWNER }
+            };
+    }
+
+    @Override
+    @DataProvider(name = "fromImageNamePattern")
+    public Object[][] cloudAndImageNamePatterns() {
+        return new Object[][] {
+                new Object[] { USEAST_REGION_NAME, IMAGE_PATTERN, IMAGE_OWNER }
+            };
+    }
+
+    @Test(enabled = false)
+    public void noop() { } /* just exists to let testNG IDE run the test */
+}


[08/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
new file mode 100644
index 0000000..8cd20b9
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
@@ -0,0 +1,357 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.event.basic.MapConfigKey;
+import brooklyn.event.basic.SetConfigKey;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
+
+public class JcloudsLocationResolverTest {
+
+    private static final Logger log = LoggerFactory.getLogger(JcloudsLocationResolverTest.class);
+    
+    private LocalManagementContext managementContext;
+    private BrooklynProperties brooklynProperties;
+
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+        brooklynProperties = managementContext.getBrooklynProperties();
+
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.identity", "aws-ec2-id");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.credential", "aws-ec2-cred");
+        brooklynProperties.put("brooklyn.location.jclouds.rackspace-cloudservers-uk.identity", "cloudservers-uk-id");
+        brooklynProperties.put("brooklyn.location.jclouds.rackspace-cloudservers-uk.credential", "cloudservers-uk-cred");
+    }
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() throws Exception {
+        if (managementContext != null)
+            managementContext.terminate();
+    }
+
+    @Test
+    public void testJcloudsTakesDotSeparateProperty() {
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.loginUser.privateKeyFile", "myfile");
+        String file = resolve("jclouds:aws-ec2").getConfig(JcloudsLocation.LOGIN_USER_PRIVATE_KEY_FILE);
+        assertEquals(file, "myfile");
+    }
+
+    @Test
+    public void testJcloudsTakesProviderScopedProperties() {
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyFile", "myprivatekeyfile");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.publicKeyFile", "mypublickeyfile");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyData", "myprivateKeyData");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.publicKeyData", "myPublicKeyData");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyPassphrase", "myprivateKeyPassphrase");
+        Map<String, Object> conf = resolve("jclouds:aws-ec2").config().getBag().getAllConfig();
+
+        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
+        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
+        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
+        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
+        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
+    }
+
+    @Test
+    public void testJcloudsTakesGenericScopedProperties() {
+        brooklynProperties.put("brooklyn.location.jclouds.privateKeyFile", "myprivatekeyfile");
+        brooklynProperties.put("brooklyn.location.jclouds.publicKeyFile", "mypublickeyfile");
+        brooklynProperties.put("brooklyn.location.jclouds.privateKeyData", "myprivateKeyData");
+        brooklynProperties.put("brooklyn.location.jclouds.publicKeyData", "myPublicKeyData");
+        brooklynProperties.put("brooklyn.location.jclouds.privateKeyPassphrase", "myprivateKeyPassphrase");
+        Map<String, Object> conf = resolve("jclouds:aws-ec2").config().getBag().getAllConfig();
+
+        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
+        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
+        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
+        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
+        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
+    }
+
+    @Test
+    public void testJcloudsTakesDeprecatedProperties() {
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.private-key-file", "myprivatekeyfile");
+        brooklynProperties.put("brooklyn.location.jclouds.public-key-file", "mypublickeyfile");
+        brooklynProperties.put("brooklyn.location.jclouds.private-key-data", "myprivateKeyData");
+        brooklynProperties.put("brooklyn.location.jclouds.public-key-data", "myPublicKeyData");
+        brooklynProperties.put("brooklyn.location.jclouds.private-key-passphrase", "myprivateKeyPassphrase");
+        brooklynProperties.put("brooklyn.location.jclouds.image-id", "myimageid");
+        Map<String, Object> conf = resolve("jclouds:aws-ec2").config().getBag().getAllConfig();
+
+        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
+        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
+        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
+        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
+        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
+        assertEquals(conf.get("imageId"), "myimageid");
+    }
+
+    @Test
+    public void testJcloudsPropertiesPrecedence() {
+        brooklynProperties.put("brooklyn.location.named.myaws-ec2", "jclouds:aws-ec2");
+
+        // prefer those in "named" over everything else
+        brooklynProperties.put("brooklyn.location.named.myaws-ec2.privateKeyFile", "privateKeyFile-inNamed");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyFile", "privateKeyFile-inProviderSpecific");
+        brooklynProperties.put("brooklyn.location.jclouds.privateKeyFile", "privateKeyFile-inJcloudsGeneric");
+
+        // prefer those in provider-specific over generic
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.publicKeyFile", "publicKeyFile-inProviderSpecific");
+        brooklynProperties.put("brooklyn.location.jclouds.publicKeyFile", "publicKeyFile-inJcloudsGeneric");
+
+        // prefer deprecated properties in "named" over those less specific
+        brooklynProperties.put("brooklyn.location.named.myaws-ec2.private-key-data", "privateKeyData-inNamed");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyData", "privateKeyData-inProviderSpecific");
+        brooklynProperties.put("brooklyn.location.jclouds.privateKeyData", "privateKeyData-inJcloudsGeneric");
+
+        // prefer generic if nothing else
+        brooklynProperties.put("brooklyn.location.jclouds.publicKeyData", "publicKeyData-inJcloudsGeneric");
+
+        // prefer "named" over everything else: confirm deprecated don't get
+        // transformed to overwrite it accidentally
+        brooklynProperties
+                .put("brooklyn.location.named.myaws-ec2.privateKeyPassphrase", "privateKeyPassphrase-inNamed");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.private-key-passphrase",
+                "privateKeyPassphrase-inProviderSpecific");
+        brooklynProperties.put("brooklyn.location.jclouds.private-key-passphrase", "privateKeyPassphrase-inJcloudsGeneric");
+
+        Map<String, Object> conf = resolve("named:myaws-ec2").config().getBag().getAllConfig();
+
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
+        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
+        assertEquals(conf.get("privateKeyData"), "privateKeyData-inNamed");
+        assertEquals(conf.get("publicKeyData"), "publicKeyData-inJcloudsGeneric");
+        assertEquals(conf.get("privateKeyPassphrase"), "privateKeyPassphrase-inNamed");
+    }
+
+    @Test
+    public void testJcloudsLoads() {
+        Assert.assertTrue(resolve("jclouds:aws-ec2") instanceof JcloudsLocation);
+    }
+
+    @Test
+    public void testJcloudsImplicitLoads() {
+        Assert.assertTrue(resolve("aws-ec2") instanceof JcloudsLocation);
+    }
+
+    @Test
+    public void testJcloudsLocationLoads() {
+        Assert.assertTrue(resolve("aws-ec2:eu-west-1") instanceof JcloudsLocation);
+    }
+
+    @Test
+    public void testJcloudsRegionOnlyLoads() {
+        Assert.assertTrue(resolve("eu-west-1") instanceof JcloudsLocation);
+    }
+
+    @Test
+    public void testJcloudsEndpointLoads() {
+        JcloudsLocation loc = resolve("jclouds:openstack-nova:http://foo/api");
+        assertEquals(loc.getProvider(), "openstack-nova");
+        assertEquals(loc.getEndpoint(), "http://foo/api");
+    }
+
+    @Test
+    public void testJcloudsEndpointLoadsAsProperty() {
+        brooklynProperties.put("brooklyn.location.jclouds.openstack-nova.endpoint", "myendpoint");
+        JcloudsLocation loc = resolve("jclouds:openstack-nova");
+        // just checking
+        Assert.assertEquals(loc.config().getLocalBag().getStringKey("endpoint"), "myendpoint");
+        Assert.assertEquals(loc.getConfig(CloudLocationConfig.CLOUD_ENDPOINT), "myendpoint");
+        // this is the one we really care about!:
+        assertEquals(loc.getEndpoint(), "myendpoint");
+    }
+
+    @Test
+    public void testJcloudsLegacyRandomProperty() {
+        brooklynProperties.put("brooklyn.location.jclouds.openstack-nova.foo", "bar");
+        JcloudsLocation loc = resolve("jclouds:openstack-nova");
+        Assert.assertEquals(loc.config().getLocalBag().getStringKey("foo"), "bar");
+    }
+
+    @Test
+    public void testJcloudsRandomProperty() {
+        brooklynProperties.put("brooklyn.location.jclouds.openstack-nova.foo", "bar");
+        JcloudsLocation loc = resolve("jclouds:openstack-nova");
+        Assert.assertEquals(loc.config().getLocalBag().getStringKey("foo"), "bar");
+    }
+
+    @Test
+    public void testThrowsOnInvalid() throws Exception {
+        // Tries to treat "wrongprefix" as a cloud provider
+        assertThrows("wrongprefix:aws-ec2:us-east-1", NoSuchElementException.class);
+
+        // no provider
+        assertThrows("jclouds", IllegalArgumentException.class);
+
+        // empty provider
+        assertThrows("jclouds:", IllegalArgumentException.class);
+
+        // invalid provider
+        assertThrows("jclouds:doesnotexist", NoSuchElementException.class);
+    }
+
+    @Test
+    public void testResolvesJclouds() throws Exception {
+        // test with provider + region
+        assertJcloudsEquals(resolve("jclouds:aws-ec2:us-east-1"), "aws-ec2", "us-east-1");
+
+        // test with provider that has no region
+        assertJcloudsEquals(resolve("jclouds:rackspace-cloudservers-uk"), "rackspace-cloudservers-uk", null);
+    }
+
+    @Test
+    public void testJcloudsRegionOverridesParent() {
+        Map<String, Object> conf;
+        
+        brooklynProperties.put("brooklyn.location.named.softlayer-was", "jclouds:softlayer:was01");
+        brooklynProperties.put("brooklyn.location.named.softlayer-was2", "jclouds:softlayer:was01");
+        brooklynProperties.put("brooklyn.location.named.softlayer-was2.region", "was02");
+        conf = resolve("named:softlayer-was").config().getBag().getAllConfig();
+        assertEquals(conf.get("region"), "was01");
+        
+        conf = resolve("named:softlayer-was2").config().getBag().getAllConfig();
+        assertEquals(conf.get("region"), "was02");
+        
+        conf = ((LocationInternal) managementContext.getLocationRegistry().resolve("named:softlayer-was2", MutableMap.of("region", "was03")))
+            .config().getBag().getAllConfig();;
+        assertEquals(conf.get("region"), "was03");
+    }
+    
+    // TODO Visual inspection test that it logs warnings
+    @Test
+    public void testLogsWarnings() throws Exception {
+        assertJcloudsEquals(resolve("jclouds:jclouds:aws-ec2:us-east-1"), "aws-ec2", "us-east-1");
+        assertJcloudsEquals(resolve("us-east-1"), "aws-ec2", "us-east-1");
+
+        // TODO Should we enforce a jclouds prefix? Currently we don't
+        // assertJcloudsEquals(resolve("aws-ec2:us-east-1"), "aws-ec2",
+        // "us-east-1");
+
+    }
+
+    @Test
+    public void testResolvesJcloudsFromNamedOfNamedWithPropertiesOverriddenCorrectly() throws Exception {
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop1", "1");
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop2", "1");
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop3", "1");
+        brooklynProperties.put("brooklyn.location.named.foo", "jclouds:softlayer:138124");
+        brooklynProperties.put("brooklyn.location.named.foo.prop2", "2");
+        brooklynProperties.put("brooklyn.location.named.foo.prop3", "2");
+        brooklynProperties.put("brooklyn.location.named.bar", "named:foo");
+        brooklynProperties.put("brooklyn.location.named.bar.prop3", "3");
+        
+        JcloudsLocation l = resolve("named:bar");
+        assertJcloudsEquals(l, "softlayer", "138124");
+        Assert.assertEquals(l.config().getLocalBag().getStringKey("prop3"), "3");
+        Assert.assertEquals(l.config().getLocalBag().getStringKey("prop2"), "2");
+        Assert.assertEquals(l.config().getLocalBag().getStringKey("prop1"), "1");
+    }
+
+    @Test
+    public void testResolvesListAndMapProperties() throws Exception {
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop1", "[ a, b ]");
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop2", "{ a: 1, b: 2 }");
+        brooklynProperties.put("brooklyn.location.named.foo", "jclouds:softlayer:ams01");
+        
+        JcloudsLocation l = resolve("named:foo");
+        assertJcloudsEquals(l, "softlayer", "ams01");
+        assertEquals(l.config().get(new SetConfigKey<String>(String.class, "prop1")), MutableSet.of("a", "b"));
+        assertEquals(l.config().get(new MapConfigKey<String>(String.class, "prop2")), MutableMap.of("a", 1, "b", 2));
+    }
+    
+    @Test
+    public void testResolvesListAndMapPropertiesWithoutMergeOnInheritance() throws Exception {
+        // when we have a yaml way to specify config we may wish to have different semantics;
+        // it could depend on the collection config key whether to merge on inheritance
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop1", "[ a, b ]");
+        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop2", "{ a: 1, b: 2 }");
+        brooklynProperties.put("brooklyn.location.named.foo", "jclouds:softlayer:ams01");
+        
+        brooklynProperties.put("brooklyn.location.named.foo.prop1", "[ a: 1, c: 3 ]");
+        brooklynProperties.put("brooklyn.location.named.foo.prop2", "{ b: 3, c: 3 }");
+        brooklynProperties.put("brooklyn.location.named.bar", "named:foo");
+        brooklynProperties.put("brooklyn.location.named.bar.prop2", "{ c: 4, d: 4 }");
+        
+        // these do NOT affect the maps
+        brooklynProperties.put("brooklyn.location.named.foo.prop2.z", "9");
+        brooklynProperties.put("brooklyn.location.named.foo.prop3.z", "9");
+        
+        JcloudsLocation l = resolve("named:bar");
+        assertJcloudsEquals(l, "softlayer", "ams01");
+        
+        Set<? extends String> prop1 = l.config().get(new SetConfigKey<String>(String.class, "prop1"));
+        log.info("prop1: "+prop1);
+        assertEquals(prop1, MutableSet.of("a: 1", "c: 3"));
+        
+        Map<String, String> prop2 = l.config().get(new MapConfigKey<String>(String.class, "prop2"));
+        log.info("prop2: "+prop2);
+        assertEquals(prop2, MutableMap.of("c", 4, "d", 4));
+        
+        Map<String, String> prop3 = l.config().get(new MapConfigKey<String>(String.class, "prop3"));
+        log.info("prop3: "+prop3);
+        assertEquals(prop3, null);
+    }
+
+    private void assertJcloudsEquals(JcloudsLocation loc, String expectedProvider, String expectedRegion) {
+        assertEquals(loc.getProvider(), expectedProvider);
+        assertEquals(loc.getRegion(), expectedRegion);
+    }
+
+    private void assertThrows(String val, Class<?> expectedExceptionType) throws Exception {
+        try {
+            resolve(val);
+            fail();
+        } catch (Exception e) {
+            if (!expectedExceptionType.isInstance(e))
+                throw e; // otherwise success
+
+        }
+    }
+
+    @Test(expectedExceptions = { NoSuchElementException.class, IllegalArgumentException.class }, expectedExceptionsMessageRegExp = ".*insufficient.*")
+    public void testJcloudsOnlyFails() {
+        resolve("jclouds");
+    }
+
+    private JcloudsLocation resolve(String spec) {
+        return (JcloudsLocation) managementContext.getLocationRegistry().resolve(spec);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTemplateOptionsCustomisersLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTemplateOptionsCustomisersLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTemplateOptionsCustomisersLiveTest.java
new file mode 100644
index 0000000..f173646
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTemplateOptionsCustomisersLiveTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.util.config.ConfigBag;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.ec2.domain.BlockDeviceMapping;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+public class JcloudsLocationTemplateOptionsCustomisersLiveTest extends AbstractJcloudsLiveTest {
+
+    private static final String LOCATION_SPEC = AWS_EC2_PROVIDER + ":" + AWS_EC2_USEAST_REGION_NAME;
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        jcloudsLocation = resolve(LOCATION_SPEC);
+    }
+
+    // Doesn't actually do much with the cloud, but jclouds requires identity and credential before it will work
+    @Test(groups = "Live")
+    public void testGeneralPurposeTemplateOptionCustomisation() throws Exception {
+        ConfigKey<Map<String, Object>> key = JcloudsLocationConfig.TEMPLATE_OPTIONS;
+
+        ConfigBag config = ConfigBag.newInstance()
+                .configure(key, ImmutableMap.of("iamInstanceProfileName", (Object)"helloworld"));
+        AWSEC2TemplateOptions templateOptions = jcloudsLocation.getComputeService().templateOptions().as(AWSEC2TemplateOptions.class);
+
+        invokeCustomizeTemplateOptions(templateOptions, JcloudsLocationConfig.TEMPLATE_OPTIONS, config);
+
+        assertEquals(templateOptions.getIAMInstanceProfileName(), "helloworld");
+    }
+
+    // Doesn't actually do much with the cloud, but jclouds requires identity and credential before it will work
+    @Test(groups = "Live")
+    public void testGeneralPurposeTemplateOptionCustomisationWithList() throws Exception {
+        ConfigKey<Map<String, Object>> key = JcloudsLocationConfig.TEMPLATE_OPTIONS;
+
+        ConfigBag config = ConfigBag.newInstance()
+                        .configure(key, ImmutableMap.of(
+                                "iamInstanceProfileName", (Object) "helloworld",
+                                "mapNewVolumeToDeviceName", (Object) ImmutableList.of("/dev/sda1/", 123, true)));
+        AWSEC2TemplateOptions templateOptions = jcloudsLocation.getComputeService().templateOptions().as(AWSEC2TemplateOptions.class);
+
+        invokeCustomizeTemplateOptions(templateOptions, JcloudsLocationConfig.TEMPLATE_OPTIONS, config);
+
+        assertEquals(templateOptions.getIAMInstanceProfileName(), "helloworld");
+        assertEquals(templateOptions.getBlockDeviceMappings().size(), 1);
+        BlockDeviceMapping blockDeviceMapping = templateOptions.getBlockDeviceMappings().iterator().next();
+        assertEquals(blockDeviceMapping.getDeviceName(), "/dev/sda1/");
+        assertEquals(blockDeviceMapping.getEbsVolumeSize(), (Integer)123);
+        assertTrue(blockDeviceMapping.getEbsDeleteOnTermination());
+    }
+
+    /**
+     * Invoke a specific template options customizer on a TemplateOptions instance.
+     *
+     * @param templateOptions the TemplateOptions instance that you expect the customizer to modify.
+     * @param keyToTest the config key that identifies the customizer. This must be present in both @{code locationConfig} and @{link JcloudsLocation.SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES}.
+     * @param locationConfig simulated configuration for the location. This must contain at least an entry for @{code keyToTest}.
+     */
+    private void invokeCustomizeTemplateOptions(TemplateOptions templateOptions, ConfigKey<?> keyToTest, ConfigBag locationConfig) {
+        checkNotNull(templateOptions, "templateOptions");
+        checkNotNull(keyToTest, "keyToTest");
+        checkNotNull(locationConfig, "locationConfig");
+        checkState(JcloudsLocation.SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.containsKey(keyToTest),
+                "SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES does not contain a customiser for the key " + keyToTest.getName());
+        checkState(locationConfig.containsKey(keyToTest),
+                "location config does not contain the key " + keyToTest.getName());
+
+        JcloudsLocation.CustomizeTemplateOptions code = JcloudsLocation.SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.get(keyToTest);
+        code.apply(templateOptions, locationConfig, locationConfig.get(keyToTest));
+    }
+
+    private JcloudsLocation resolve(String spec) {
+        return (JcloudsLocation) managementContext.getLocationRegistry().resolve("jclouds:"+spec);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java
new file mode 100644
index 0000000..4c5788f
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java
@@ -0,0 +1,510 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.location.MachineLocationCustomizer;
+import org.apache.brooklyn.location.cloud.names.CustomMachineNamer;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.jclouds.scriptbuilder.domain.OsFamily;
+import org.jclouds.scriptbuilder.domain.StatementList;
+import org.mockito.Mockito;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation.UserCreation;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+
+/**
+ * @author Shane Witbeck
+ */
+public class JcloudsLocationTest implements JcloudsLocationConfig {
+
+    private static final Logger log = LoggerFactory.getLogger(JcloudsLocationTest.class);
+    
+    public static Predicate<ConfigBag> checkerFor(final String user, final Integer minRam, final Integer minCores) {
+        return new Predicate<ConfigBag>() {
+            @Override
+            public boolean apply(@Nullable ConfigBag input) {
+                Assert.assertEquals(input.get(USER), user);
+                Assert.assertEquals(input.get(MIN_RAM), minRam);
+                Assert.assertEquals(input.get(MIN_CORES), minCores);
+                return true;
+            }
+        };
+    }
+    
+    public static Predicate<ConfigBag> templateCheckerFor(final String ports) {
+        return new Predicate<ConfigBag>() {
+            @Override
+            public boolean apply(@Nullable ConfigBag input) {
+                Assert.assertEquals(input.get(INBOUND_PORTS), ports);
+                return false;
+            }
+        };
+    }
+    
+    private LocalManagementContext managementContext;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance(BrooklynProperties.Factory.builderEmpty().build());
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearUp() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testCreateWithFlagsDirectly() throws Exception {
+        BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
+        jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 2), checkerFor("fred", 16, 2));
+    }
+
+    @Test
+    public void testCreateWithFlagsDirectlyAndOverride() throws Exception {
+        BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
+        jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 2, MIN_RAM, 8), checkerFor("fred", 8, 2));
+    }
+
+    @Test
+    public void testCreateWithFlagsSubLocation() throws Exception {
+        BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
+        jcl = (BailOutJcloudsLocation) jcl.newSubLocation(MutableMap.of(USER, "jon", MIN_CORES, 2));
+        jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 3), checkerFor("jon", 16, 3));
+    }
+
+    @Test
+    public void testStringListToIntArray() {
+        String listString = "[1, 2, 3, 4]";
+        int[] intArray = new int[] {1, 2, 3, 4};
+        Assert.assertEquals(JcloudsLocation.toIntArray(listString), intArray);
+    }
+    
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testMalformedStringListToIntArray() {
+        String listString = "1, 2, 3, 4";
+        JcloudsLocation.toIntArray(listString);
+    }
+    
+    @Test
+    public void testEmptyStringListToIntArray() {
+        String listString = "[]";
+        int[] intArray = new int[] {};
+        Assert.assertEquals(JcloudsLocation.toIntArray(listString), intArray);
+    }
+    
+    @Test
+    public void testIntArrayToIntArray() {
+        int[] intArray = new int[] {1, 2, 3, 4};
+        Assert.assertEquals(JcloudsLocation.toIntArray(intArray), intArray);
+    }
+    
+    @Test
+    public void testObjectArrayToIntArray() {
+        Object[] longArray = new Object[] {1, 2, 3, 4};
+        int[] intArray = new int[] {1, 2, 3, 4};
+        Assert.assertEquals(JcloudsLocation.toIntArray(longArray), intArray);
+    }
+    
+    @Test(expectedExceptions = ClassCastException.class)
+    public void testInvalidObjectArrayToIntArray() {
+        String[] stringArray = new String[] {"1", "2", "3"};
+        JcloudsLocation.toIntArray(stringArray);
+    }
+
+    @Test
+    public void testVMCreationIsRetriedOnFailure() {
+        final AtomicInteger count = new AtomicInteger();
+        Function<ConfigBag, Void> countingInterceptor = new Function<ConfigBag, Void>() {
+            @Override public Void apply(ConfigBag input) {
+                count.incrementAndGet();
+                return null;
+            }
+        };
+        BailOutJcloudsLocation loc = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
+                MACHINE_CREATE_ATTEMPTS, 3,
+                BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, countingInterceptor));
+        loc.tryObtain();
+        Assert.assertEquals(count.get(), 3);
+    }
+
+    @Test(groups={"Live", "Live-sanity"})
+    public void testCreateWithInboundPorts() {
+        BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocationForLiveTest(managementContext);
+        jcloudsLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
+        jcloudsLocation.tryObtainAndCheck(MutableMap.of(), templateCheckerFor("[22, 80, 9999]"));
+        int[] ports = new int[] {22, 80, 9999};
+        Assert.assertEquals(jcloudsLocation.getTemplate().getOptions().getInboundPorts(), ports);
+    }
+    
+    @Test(groups={"Live", "Live-sanity"})
+    public void testCreateWithInboundPortsOverride() {
+        BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocationForLiveTest(managementContext);
+        jcloudsLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
+        jcloudsLocation.tryObtainAndCheck(MutableMap.of(INBOUND_PORTS, "[23, 81, 9998]"), templateCheckerFor("[23, 81, 9998]"));
+        int[] ports = new int[] {23, 81, 9998};
+        Assert.assertEquals(jcloudsLocation.getTemplate().getOptions().getInboundPorts(), ports);
+    }
+
+    @Test
+    public void testCreateWithMaxConcurrentCallsUnboundedByDefault() throws Exception {
+        final int numCalls = 20;
+        ConcurrencyTracker interceptor = new ConcurrencyTracker();
+        ExecutorService executor = Executors.newCachedThreadPool();
+
+        try {
+            final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
+                    managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
+                            BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor));
+            for (int i = 0; i < numCalls; i++) {
+                executor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        jcloudsLocation.tryObtain();
+                    }
+                });
+            }
+            interceptor.assertCallCountEventually(numCalls);
+            interceptor.unblock();
+            executor.shutdown();
+            executor.awaitTermination(10, TimeUnit.SECONDS);
+        } finally {
+            executor.shutdownNow();
+        }
+    }
+
+    @Test(groups="Integration") // because takes 1 sec
+    public void testCreateWithMaxConcurrentCallsRespectsConfig() throws Exception {
+        final int numCalls = 4;
+        final int maxConcurrentCreations = 2;
+        ConcurrencyTracker interceptor = new ConcurrencyTracker();
+        ExecutorService executor = Executors.newCachedThreadPool();
+        
+        try {
+            final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
+                    managementContext, ImmutableMap.of(
+                            BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor,
+                            MAX_CONCURRENT_MACHINE_CREATIONS, maxConcurrentCreations));
+
+            for (int i = 0; i < numCalls; i++) {
+                executor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        jcloudsLocation.tryObtain();
+                    }
+                });
+            }
+
+            interceptor.assertCallCountEventually(maxConcurrentCreations);
+            interceptor.assertCallCountContinually(maxConcurrentCreations);
+
+            interceptor.unblock();
+            interceptor.assertCallCountEventually(numCalls);
+            executor.shutdown();
+            executor.awaitTermination(10, TimeUnit.SECONDS);
+
+        } finally {
+            executor.shutdownNow();
+        }
+    }
+
+    @Test(groups="Integration") // because takes 1 sec
+    public void testCreateWithMaxConcurrentCallsAppliesToSubLocations() throws Exception {
+        final int numCalls = 4;
+        final int maxConcurrentCreations = 2;
+        ConcurrencyTracker interceptor = new ConcurrencyTracker();
+        ExecutorService executor = Executors.newCachedThreadPool();
+
+        try {
+            final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
+                    managementContext, ImmutableMap.of(
+                            BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor,
+                            MAX_CONCURRENT_MACHINE_CREATIONS, maxConcurrentCreations));
+
+            for (int i = 0; i < numCalls; i++) {
+                final BailOutJcloudsLocation subLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
+                executor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        subLocation.tryObtain();
+                    }
+                });
+            }
+
+            interceptor.assertCallCountEventually(maxConcurrentCreations);
+            interceptor.assertCallCountContinually(maxConcurrentCreations);
+
+            interceptor.unblock();
+            interceptor.assertCallCountEventually(numCalls);
+            executor.shutdown();
+            executor.awaitTermination(10, TimeUnit.SECONDS);
+
+        } finally {
+            executor.shutdownNow();
+        }
+    }
+    
+    @Test
+    public void testCreateWithCustomMachineNamer() {
+        final String machineNamerClass = CustomMachineNamer.class.getName();
+        BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
+                managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
+                        LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS, machineNamerClass));
+        jcloudsLocation.tryObtainAndCheck(ImmutableMap.of(CustomMachineNamer.MACHINE_NAME_TEMPLATE, "ignored"), new Predicate<ConfigBag>() {
+            public boolean apply(ConfigBag input) {
+                Assert.assertEquals(input.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS), machineNamerClass);
+                return true;
+            }
+        });
+    }
+    
+    @Test
+    public void testCreateWithCustomMachineNamerOnObtain() {
+        final String machineNamerClass = CustomMachineNamer.class.getName();
+        BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
+        ImmutableMap<ConfigKey<String>, String> flags = ImmutableMap.of(
+                CustomMachineNamer.MACHINE_NAME_TEMPLATE, "ignored",
+                LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS, machineNamerClass);
+        jcloudsLocation.tryObtainAndCheck(flags, new Predicate<ConfigBag>() {
+            public boolean apply(ConfigBag input) {
+                Assert.assertEquals(input.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS), machineNamerClass);
+                return true;
+            }
+        });
+    }
+
+    public static class ConcurrencyTracker implements Function<ConfigBag,Void> {
+        final AtomicInteger concurrentCallsCounter = new AtomicInteger();
+        final CountDownLatch continuationLatch = new CountDownLatch(1);
+        
+        @Override public Void apply(ConfigBag input) {
+            concurrentCallsCounter.incrementAndGet();
+            try {
+                continuationLatch.await();
+            } catch (InterruptedException e) {
+                throw Exceptions.propagate(e);
+            }
+            return null;
+        }
+        
+        public void unblock() {
+            continuationLatch.countDown();
+        }
+
+        public void assertCallCountEventually(final int expected) {
+            Asserts.succeedsEventually(new Runnable() {
+                @Override public void run() {
+                    Assert.assertEquals(concurrentCallsCounter.get(), expected);
+                }
+            });
+        }
+        
+        public void assertCallCountContinually(final int expected) {
+            Asserts.succeedsContinually(new Runnable() {
+                @Override public void run() {
+                    Assert.assertEquals(concurrentCallsCounter.get(), expected);
+                }
+            });
+        }
+    }
+
+    
+    @SuppressWarnings("serial")
+    public static class FakeLocalhostWithParentJcloudsLocation extends JcloudsLocation {
+        public static final ConfigKey<Function<ConfigBag,Void>> BUILD_TEMPLATE_INTERCEPTOR = ConfigKeys.newConfigKey(new TypeToken<Function<ConfigBag,Void>>() {}, "buildtemplateinterceptor");
+        
+        ConfigBag lastConfigBag;
+
+        public FakeLocalhostWithParentJcloudsLocation() {
+            super();
+        }
+
+        public FakeLocalhostWithParentJcloudsLocation(Map<?, ?> conf) {
+            super(conf);
+        }
+
+        @Override
+        public JcloudsSshMachineLocation obtain(Map<?, ?> flags) throws NoMachinesAvailableException {
+            JcloudsSshMachineLocation result = getManagementContext().getLocationManager().createLocation(LocationSpec.create(JcloudsSshMachineLocation.class)
+                .configure("address", "127.0.0.1") 
+                .configure("port", 22) 
+                .configure("user", "bob")
+                .configure("jcloudsParent", this));
+            registerJcloudsMachineLocation("bogus", result);
+            
+            // explicitly invoke this customizer, to comply with tests
+            for (JcloudsLocationCustomizer customizer : getCustomizers(config().getBag())) {
+                customizer.customize(this, null, (JcloudsMachineLocation)result);
+            }
+            for (MachineLocationCustomizer customizer : getMachineCustomizers(config().getBag())) {
+                customizer.customize((JcloudsMachineLocation)result);
+            }
+
+            return result;
+        }
+        
+        @Override
+        protected void releaseNode(String instanceId) {
+            // no-op
+        }
+    }
+
+    @Test
+    public void testInheritsGeo() throws Exception {
+        ConfigBag allConfig = ConfigBag.newInstance()
+            .configure(IMAGE_ID, "bogus")
+            .configure(CLOUD_PROVIDER, "aws-ec2")
+            .configure(CLOUD_REGION_ID, "bogus")
+            .configure(ACCESS_IDENTITY, "bogus")
+            .configure(ACCESS_CREDENTIAL, "bogus")
+            .configure(LocationConfigKeys.LATITUDE, 42d)
+            .configure(LocationConfigKeys.LONGITUDE, -20d)
+            .configure(MACHINE_CREATE_ATTEMPTS, 1);
+        FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class).configure(allConfig.getAllConfig()));
+        MachineLocation l = ll.obtain();
+        log.info("loc:" +l);
+        HostGeoInfo geo = HostGeoInfo.fromLocation(l);
+        log.info("geo: "+geo);
+        Assert.assertEquals(geo.latitude, 42d, 0.00001);
+        Assert.assertEquals(geo.longitude, -20d, 0.00001);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testInheritsGeoFromLocationMetadataProperties() throws Exception {
+        // in location-metadata.properties:
+//        brooklyn.location.jclouds.softlayer@wdc01.latitude=38.909202
+//        brooklyn.location.jclouds.softlayer@wdc01.longitude=-77.47314
+        ConfigBag allConfig = ConfigBag.newInstance()
+            .configure(IMAGE_ID, "bogus")
+            .configure(CLOUD_PROVIDER, "softlayer")
+            .configure(CLOUD_REGION_ID, "wdc01")
+            .configure(ACCESS_IDENTITY, "bogus")
+            .configure(ACCESS_CREDENTIAL, "bogus")
+            .configure(MACHINE_CREATE_ATTEMPTS, 1);
+        FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class)
+            .configure(new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties("softlayer", "wdc01", null, managementContext.getBrooklynProperties()))
+            .configure(allConfig.getAllConfig()));
+        MachineLocation l = ll.obtain();
+        log.info("loc:" +l);
+        HostGeoInfo geo = HostGeoInfo.fromLocation(l);
+        log.info("geo: "+geo);
+        Assert.assertEquals(geo.latitude, 38.909202d, 0.00001);
+        Assert.assertEquals(geo.longitude, -77.47314d, 0.00001);
+    }
+
+    @Test
+    public void testInvokesCustomizerCallbacks() throws Exception {
+        JcloudsLocationCustomizer customizer = Mockito.mock(JcloudsLocationCustomizer.class);
+        MachineLocationCustomizer machineCustomizer = Mockito.mock(MachineLocationCustomizer.class);
+//        Mockito.when(customizer.customize(Mockito.any(JcloudsLocation.class), Mockito.any(ComputeService.class), Mockito.any(JcloudsSshMachineLocation.class)));
+        ConfigBag allConfig = ConfigBag.newInstance()
+            .configure(CLOUD_PROVIDER, "aws-ec2")
+            .configure(ACCESS_IDENTITY, "bogus")
+            .configure(ACCESS_CREDENTIAL, "bogus")
+            .configure(JcloudsLocationConfig.JCLOUDS_LOCATION_CUSTOMIZERS, ImmutableList.of(customizer))
+            .configure(JcloudsLocation.MACHINE_LOCATION_CUSTOMIZERS, ImmutableList.of(machineCustomizer))
+            .configure(MACHINE_CREATE_ATTEMPTS, 1);
+        FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class).configure(allConfig.getAllConfig()));
+        JcloudsMachineLocation l = (JcloudsMachineLocation)ll.obtain();
+        Mockito.verify(customizer, Mockito.times(1)).customize(ll, null, l);
+        Mockito.verify(customizer, Mockito.never()).preRelease(l);
+        Mockito.verify(customizer, Mockito.never()).postRelease(l);
+        Mockito.verify(machineCustomizer, Mockito.times(1)).customize(l);
+        Mockito.verify(machineCustomizer, Mockito.never()).preRelease(l);
+        
+        ll.release(l);
+        Mockito.verify(customizer, Mockito.times(1)).preRelease(l);
+        Mockito.verify(customizer, Mockito.times(1)).postRelease(l);
+        Mockito.verify(machineCustomizer, Mockito.times(1)).preRelease(l);
+    }
+
+    // now test creating users
+    
+    protected String getCreateUserStatementsFor(Map<ConfigKey<?>,?> config) {
+        BailOutJcloudsLocation jl = BailOutJcloudsLocation.newBailOutJcloudsLocation(
+                managementContext, MutableMap.<ConfigKey<?>, Object>builder()
+                        .put(JcloudsLocationConfig.LOGIN_USER, "root").put(JcloudsLocationConfig.LOGIN_USER_PASSWORD, "m0ck")
+                        .put(JcloudsLocationConfig.USER, "bob").put(JcloudsLocationConfig.LOGIN_USER_PASSWORD, "b0b")
+                        .putAll(config).build());
+
+        UserCreation creation = jl.createUserStatements(null, jl.config().getBag());
+        return new StatementList(creation.statements).render(OsFamily.UNIX);
+    }
+    
+    @Test
+    public void testDisablesRoot() {
+        String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of());
+        Assert.assertTrue(statements.contains("PermitRootLogin"), "Error:\n"+statements);
+        Assert.assertTrue(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
+    }
+
+    @Test
+    public void testDisableRootFalse() {
+        String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of(
+                JcloudsLocationConfig.DISABLE_ROOT_AND_PASSWORD_SSH, false));
+        Assert.assertFalse(statements.contains("PermitRootLogin"), "Error:\n"+statements);
+        Assert.assertTrue(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
+    }
+    
+    @Test
+    public void testDisableRootAndSudoFalse() {
+        String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of(
+            JcloudsLocationConfig.DISABLE_ROOT_AND_PASSWORD_SSH, false,
+            JcloudsLocationConfig.GRANT_USER_SUDO, false));
+        Assert.assertFalse(statements.contains("PermitRootLogin"), "Error:\n"+statements);
+        Assert.assertFalse(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
+    }
+
+    // TODO more tests, where flags come in from resolver, named locations, etc
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
new file mode 100644
index 0000000..5a17a5a
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
@@ -0,0 +1,407 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.os.Os;
+import brooklyn.util.stream.Streams;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Tests different login options for ssh keys, passwords, etc.
+ */
+public class JcloudsLoginLiveTest extends AbstractJcloudsLiveTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsLoginLiveTest.class);
+
+    public static final String AWS_EC2_REGION_NAME = AWS_EC2_USEAST_REGION_NAME;
+    public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + (AWS_EC2_REGION_NAME == null ? "" : ":" + AWS_EC2_REGION_NAME);
+    
+    // Image: {id=us-east-1/ami-7d7bfc14, providerId=ami-7d7bfc14, name=RightImage_CentOS_6.3_x64_v5.8.8.5, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=6.0, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, version=5.8.8.5, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
+    public static final String AWS_EC2_CENTOS_IMAGE_ID = "us-east-1/ami-7d7bfc14";
+
+    // Image: {id=us-east-1/ami-d0f89fb9, providerId=ami-d0f89fb9, name=ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=12.04, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, is64Bit=true}, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, version=20130411.1, status=AVAILABLE[available], loginUser=ubuntu, userMetadata={owner=099720109477, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
+    public static final String AWS_EC2_UBUNTU_IMAGE_ID = "us-east-1/ami-d0f89fb9";
+    
+    // Image: {id=us-east-1/ami-5e008437, providerId=ami-5e008437, name=RightImage_Ubuntu_10.04_x64_v5.8.8.3, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=10.04, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, version=5.8.8.3, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
+    // Uses "root" as loginUser
+    public static final String AWS_EC2_UBUNTU_10_IMAGE_ID = "us-east-1/ami-5e008437";
+
+    public static final String RACKSPACE_LOCATION_SPEC = "jclouds:" + RACKSPACE_PROVIDER;
+    
+    // Image: {id=LON/c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, providerId=c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, name=CentOS 6.0, location={scope=ZONE, id=LON, description=LON, parent=rackspace-cloudservers-uk, iso3166Codes=[GB-SLG]}, os={family=centos, name=CentOS 6.0, version=6.0, description=CentOS 6.0, is64Bit=true}, description=CentOS 6.0, status=AVAILABLE, loginUser=root, userMetadata={os_distro=centos, com.rackspace__1__visible_core=1, com.rackspace__1__build_rackconnect=1, com.rackspace__1__options=0, image_type=base, cache_in_nova=True, com.rackspace__1__source=kickstart, org.openstack__1__os_distro=org.centos, com.rackspace__1__release_build_date=2013-07-25_18-56-29, auto_disk_config=True, com.rackspace__1__release_version=5, os_type=linux, com.rackspace__1__visible_rackconnect=1, com.rackspace__1__release_id=210, com.rackspace__1__visible_managed=0, com.rackspace__1__build_core=1, org.openstack__1__os_version=6.0, org.openstack__1__architecture=x64, com.rackspace__1__build_ma
 naged=0}}
+    public static final String RACKSPACE_CENTOS_IMAGE_NAME_REGEX = "CentOS 6.0";
+    
+    // Image: {id=LON/29fe3e2b-f119-4715-927b-763e99ebe23e, providerId=29fe3e2b-f119-4715-927b-763e99ebe23e, name=Debian 6.06 (Squeeze), location={scope=ZONE, id=LON, description=LON, parent=rackspace-cloudservers-uk, iso3166Codes=[GB-SLG]}, os={family=debian, name=Debian 6.06 (Squeeze), version=6.0, description=Debian 6.06 (Squeeze), is64Bit=true}, description=Debian 6.06 (Squeeze), status=AVAILABLE, loginUser=root, userMetadata={os_distro=debian, com.rackspace__1__visible_core=1, com.rackspace__1__build_rackconnect=1, com.rackspace__1__options=0, image_type=base, cache_in_nova=True, com.rackspace__1__source=kickstart, org.openstack__1__os_distro=org.debian, com.rackspace__1__release_build_date=2013-08-06_13-05-36, auto_disk_config=True, com.rackspace__1__release_version=4, os_type=linux, com.rackspace__1__visible_rackconnect=1, com.rackspace__1__release_id=300, com.rackspace__1__visible_managed=0, com.rackspace__1__build_core=1, org.openstack__1__os_version=6.06, org.openstack__1_
 _architecture=x64, com.rackspace__1__build_managed=0}}
+    public static final String RACKSPACE_DEBIAN_IMAGE_NAME_REGEX = "Debian 6";
+    
+    protected JcloudsSshMachineLocation machine;
+    
+    private File privateRsaFile = new File(Os.tidyPath("~/.ssh/id_rsa"));
+    private File privateDsaFile = new File(Os.tidyPath("~/.ssh/id_dsa"));
+    private File privateRsaFileTmp = new File(privateRsaFile.getAbsoluteFile()+".tmp");
+    private File privateDsaFileTmp = new File(privateDsaFile.getAbsoluteFile()+".tmp");
+    private File publicRsaFile = new File(Os.tidyPath("~/.ssh/id_rsa.pub"));
+    private File publicDsaFile = new File(Os.tidyPath("~/.ssh/id_dsa.pub"));
+    private File publicRsaFileTmp = new File(publicRsaFile.getAbsoluteFile()+".tmp");
+    private File publicDsaFileTmp = new File(publicDsaFile.getAbsoluteFile()+".tmp");
+    private boolean privateRsaFileMoved;
+    private boolean privateDsaFileMoved;
+    private boolean publicRsaFileMoved;
+    private boolean publicDsaFileMoved;
+
+    @Test(groups = {"Live"})
+    protected void testAwsEc2SpecifyingJustPrivateSshKeyInDeprecatedForm() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.LEGACY_PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        
+        machine = createEc2Machine(ImmutableMap.<String,Object>of());
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "myname")
+                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+                .build());
+    }
+    
+    @Test(groups = {"Live"})
+    protected void testAwsEc2SpecifyingPrivateAndPublicSshKeyInDeprecatedForm() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.LEGACY_PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.LEGACY_PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        
+        machine = createEc2Machine(ImmutableMap.<String,Object>of());
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "myname")
+                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+                .build());
+    }
+
+    // Uses default key files
+    @Test(groups = {"Live"})
+    protected void testAwsEc2SpecifyingNoKeyFiles() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        
+        machine = createEc2Machine(ImmutableMap.<String,Object>of());
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "myname")
+                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+                .build());
+    }
+    
+    @Test(groups = {"Live"})
+    public void testSpecifyingPasswordAndNoDefaultKeyFilesExist() throws Exception {
+        try {
+            moveSshKeyFiles();
+            
+            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
+            jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
+            
+            machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
+            assertSshable(machine);
+            
+            assertSshable(ImmutableMap.builder()
+                    .put("address", machine.getAddress())
+                    .put("user", "myname")
+                    .put(SshMachineLocation.PASSWORD, "mypassword")
+                    .build());
+        } finally {
+            restoreSshKeyFiles();
+        }
+    }
+
+    // Generates and uses a random password
+    @Test(groups = {"Live"})
+    protected void testSpecifyingNothingAndNoDefaultKeyFilesExist() throws Exception {
+        try {
+            moveSshKeyFiles();
+            
+            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+            jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
+            
+            machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
+            assertSshable(machine);
+            assertEquals(machine.getUser(), "myname");
+        } finally {
+            restoreSshKeyFiles();
+        }
+    }
+
+    @Test(groups = {"Live"})
+    protected void testSpecifyingPasswordAndSshKeysPrefersKeys() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
+        
+        machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "myname")
+                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+                .build());
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "myname")
+                .put(SshMachineLocation.PASSWORD, "mypassword")
+                .build());
+    }
+
+    @Test(groups = {"Live"})
+    protected void testSpecifyingPasswordIgnoresDefaultSshKeys() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
+        
+        machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "myname")
+                .put(SshMachineLocation.PASSWORD, "mypassword")
+                .build());
+        
+        assertNotSshable(ImmutableMap.builder()
+            .put("address", machine.getAddress())
+            .put("user", "myname")
+            .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+            .build());
+    }
+
+    @Test(groups = {"Live"})
+    protected void testSpecifyingPasswordWithPublicKeyAllowsKeyAccess() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
+        
+        machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "myname")
+                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+                .build());
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "myname")
+                .put(SshMachineLocation.PASSWORD, "mypassword")
+                .build());
+    }
+
+    // user "root" matches the loginUser=root
+    @Test(groups = {"Live"})
+    protected void testSpecifyingPasswordWhenNoDefaultKeyFilesExistWithRootUser() throws Exception {
+        try {
+            moveSshKeyFiles();
+            
+            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "root");
+            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
+            jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
+            
+            machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
+            assertSshable(machine);
+            
+            assertSshable(ImmutableMap.builder()
+                    .put("address", machine.getAddress())
+                    .put("user", "root")
+                    .put(SshMachineLocation.PASSWORD, "mypassword")
+                    .build());
+        } finally {
+            restoreSshKeyFiles();
+        }
+    }
+
+    @Test(groups = {"Live"})
+    protected void testAwsEc2SpecifyingRootUser() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "root");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        
+        machine = createEc2Machine(ImmutableMap.<String,Object>of("imageId", AWS_EC2_UBUNTU_10_IMAGE_ID));
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "root")
+                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+                .build());
+    }
+    
+    @Test(groups = {"Live"})
+    protected void testAwsEc2WhenBlankUserSoUsesRootLoginUser() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        
+        machine = createEc2Machine(ImmutableMap.<String,Object>of("imageId", AWS_EC2_UBUNTU_10_IMAGE_ID));
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "root")
+                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+                .build());
+    }
+    
+    // In JcloudsLocation.NON_ADDABLE_USERS, "ec2-user" was treated special and was not added!
+    // That was very bad for if someone is running brooklyn on a new AWS VM, and just installs brooklyn+runs as the default ec2-user.
+    @Test(groups = {"Live"})
+    protected void testAwsEc2SpecifyingSpecialUser() throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "ec2-user");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        
+        machine = createEc2Machine(ImmutableMap.<String,Object>of("imageId", AWS_EC2_UBUNTU_10_IMAGE_ID));
+        assertSshable(machine);
+        
+        assertSshable(ImmutableMap.builder()
+                .put("address", machine.getAddress())
+                .put("user", "ec2-user")
+                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
+                .build());
+    }
+    
+    @Override
+    protected void releaseMachine(JcloudsSshMachineLocation machine) {
+        jcloudsLocation.release(machine);
+    }
+    
+    private JcloudsSshMachineLocation createEc2Machine(Map<String,? extends Object> conf) throws Exception {
+        return obtainMachine(MutableMap.<String,Object>builder()
+                .putAll(conf)
+                .putIfAbsent("imageId", AWS_EC2_CENTOS_IMAGE_ID)
+                .putIfAbsent("hardwareId", AWS_EC2_SMALL_HARDWARE_ID)
+                .putIfAbsent("inboundPorts", ImmutableList.of(22))
+                .build());
+    }
+    
+    private JcloudsSshMachineLocation createRackspaceMachine(Map<String,? extends Object> conf) throws Exception {
+        return obtainMachine(MutableMap.<String,Object>builder()
+                .putAll(conf)
+                .putIfAbsent("inboundPorts", ImmutableList.of(22))
+                .build());
+    }
+    
+    protected void assertSshable(Map<?,?> machineConfig) {
+        SshMachineLocation machineWithThatConfig = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure(machineConfig));
+        try {
+            assertSshable(machineWithThatConfig);
+        } finally {
+            Streams.closeQuietly(machineWithThatConfig);
+        }
+    }
+    
+    protected void assertNotSshable(Map<?,?> machineConfig) {
+        try {
+            assertSshable(machineConfig);
+            Assert.fail("ssh should not have succeeded "+machineConfig);
+        } catch (Exception e) {
+            // expected
+            LOG.debug("Exception as expected when testing sshable "+machineConfig);
+        }
+    }
+    
+    private void moveSshKeyFiles() throws Exception {
+        privateRsaFileMoved = false;
+        privateDsaFileMoved = false;
+        publicRsaFileMoved = false;
+        publicDsaFileMoved = false;
+
+        if (privateRsaFile.exists()) {
+            LOG.info("Moving {} to {}", privateRsaFile, privateRsaFileTmp);
+            Runtime.getRuntime().exec("mv "+privateRsaFile.getAbsolutePath()+" "+privateRsaFileTmp.getAbsolutePath());
+            privateRsaFileMoved = true;
+        }
+        if (privateDsaFile.exists()) {
+            LOG.info("Moving {} to {}", privateDsaFile, privateDsaFileTmp);
+            Runtime.getRuntime().exec("mv "+privateDsaFile.getAbsolutePath()+" "+privateDsaFileTmp.getAbsolutePath());
+            privateDsaFileMoved = true;
+        }
+        if (publicRsaFile.exists()) {
+            LOG.info("Moving {} to {}", publicRsaFile, publicRsaFileTmp);
+            Runtime.getRuntime().exec("mv "+publicRsaFile.getAbsolutePath()+" "+publicRsaFileTmp.getAbsolutePath());
+            publicRsaFileMoved = true;
+        }
+        if (publicDsaFile.exists()) {
+            LOG.info("Moving {} to {}", publicDsaFile, publicDsaFileTmp);
+            Runtime.getRuntime().exec("mv "+publicDsaFile.getAbsolutePath()+" "+publicDsaFileTmp.getAbsolutePath());
+            publicDsaFileMoved = true;
+        }
+    }
+    
+    private void restoreSshKeyFiles() throws Exception {
+        if (privateRsaFileMoved) {
+            LOG.info("Restoring {} form {}", privateRsaFile, privateRsaFileTmp);
+            Runtime.getRuntime().exec("mv "+privateRsaFileTmp.getAbsolutePath()+" "+privateRsaFile.getAbsolutePath());
+            privateRsaFileMoved = false;
+        }
+        if (privateDsaFileMoved) {
+            LOG.info("Restoring {} form {}", privateDsaFile, privateDsaFileTmp);
+            Runtime.getRuntime().exec("mv "+privateDsaFileTmp.getAbsolutePath()+" "+privateDsaFile.getAbsolutePath());
+            privateDsaFileMoved = false;
+        }
+        if (publicRsaFileMoved) {
+            LOG.info("Restoring {} form {}", publicRsaFile, publicRsaFileTmp);
+            Runtime.getRuntime().exec("mv "+publicRsaFileTmp.getAbsolutePath()+" "+publicRsaFile.getAbsolutePath());
+            publicRsaFileMoved = false;
+        }
+        if (publicDsaFileMoved) {
+            LOG.info("Restoring {} form {}", publicDsaFile, publicDsaFileTmp);
+            Runtime.getRuntime().exec("mv "+publicDsaFileTmp.getAbsolutePath()+" "+publicDsaFile.getAbsolutePath());
+            publicDsaFileMoved = false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsMachineNamerTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsMachineNamerTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsMachineNamerTest.java
new file mode 100644
index 0000000..5e25a8c
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsMachineNamerTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.text.Strings;
+
+public class JcloudsMachineNamerTest {
+
+    private static final Logger log = LoggerFactory.getLogger(JcloudsMachineNamerTest.class);
+    
+    @Test
+    public void testGenerateGroupIdInVcloud() {
+        ConfigBag cfg = new ConfigBag()
+            .configure(JcloudsLocationConfig.CLOUD_PROVIDER, "vcloud")
+            .configure(JcloudsLocationConfig.CALLER_CONTEXT, "!mycontext!");
+        
+        String result = new JcloudsMachineNamer().generateNewGroupId(cfg);
+        
+        log.info("test mycontext vcloud group id gives: "+result);
+        // brooklyn-user-!mycontext!-1234
+        // br-<code>-<user>-myco-1234
+        Assert.assertTrue(result.length() <= 24-4-1, "result: "+result);
+        
+        String user = Strings.maxlen(System.getProperty("user.name"), 2).toLowerCase();
+        // (length 2 will happen if user is brooklyn, to avoid brooklyn-brooklyn at start!)
+        Assert.assertTrue(result.indexOf(user) >= 0);
+        Assert.assertTrue(result.indexOf("-myc") >= 0);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynPropertiesTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynPropertiesTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynPropertiesTest.java
new file mode 100644
index 0000000..69eda84
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynPropertiesTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.util.Map;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Maps;
+
+public class JcloudsPropertiesFromBrooklynPropertiesTest {
+    
+    protected static Map<String, Object> sampleProviderOrApiProps() {
+        Map<String, Object> map = Maps.newHashMap();
+        map.put("brooklyn.location.jclouds.FooServers.identity", "bob");
+        map.put("brooklyn.location.jclouds.FooServers.credential", "s3cr3t");
+        map.put("brooklyn.location.jclouds.FooServers.jclouds.ssh.max-retries", "100");
+        return map;
+    }
+
+    protected static Map<String, Object> sampleNamedProps() {
+        Map<String, Object> map = Maps.newHashMap();
+        map.put("brooklyn.location.named.cloudfirst", "jclouds:openstack-nova");
+        map.put("brooklyn.location.named.cloudfirst.identity", "myId");
+        map.put("brooklyn.location.named.cloudfirst.credential", "password");
+        map.put("brooklyn.location.named.cloudfirst.imageId", "RegionOne/1");
+        map.put("brooklyn.location.named.cloudfirst.securityGroups", "universal");
+        return map;
+    }
+
+    protected static Map<String, Object> unsupportedSampleProviderOrApiProps() {
+        Map<String, Object> map = Maps.newHashMap();
+        map.put("brooklyn.location.jclouds.FooServers.image-id", "invalid-image-id");
+        return map;
+    }
+    
+    protected static Map<String, Object> unsupportedNamedProps() {
+        Map<String, Object> map = Maps.newHashMap();
+        map.put("brooklyn.location.named.cloudfirst", "jclouds:openstack-nova");
+        map.put("brooklyn.location.named.cloudfirst.hardware-id", "invalid-hardware-id");
+        return map;
+    }
+    
+    private JcloudsPropertiesFromBrooklynProperties parser;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        parser = new JcloudsPropertiesFromBrooklynProperties();
+    }
+    
+    @Test
+    public void testProviderOrApiProperties() {
+        Map<String, Object> map = parser.getJcloudsProperties("FooServers", null, null, sampleProviderOrApiProps());
+        Assert.assertEquals(map.get("identity"), "bob");
+        Assert.assertEquals(map.get("credential"), "s3cr3t");
+        Assert.assertEquals(map.get("provider"), "FooServers");
+    }
+
+    @Test
+    public void testNamedProperties() {
+        Map<String, Object> map = parser.getJcloudsProperties("openstack-nova", null, "cloudfirst", sampleNamedProps());
+        Assert.assertEquals(map.get("provider"), "openstack-nova");
+        Assert.assertEquals(map.get("identity"), "myId");
+        Assert.assertEquals(map.get("credential"), "password");
+        Assert.assertEquals(map.get("imageId"), "RegionOne/1");
+        Assert.assertEquals(map.get("securityGroups"), "universal");
+    }
+    
+    @Test
+    public void testOrderOfPreference() {
+        Map<String, Object> allProperties = Maps.newHashMap();
+        allProperties.putAll(sampleProviderOrApiProps());
+        allProperties.putAll(sampleNamedProps());
+        Map<String, Object> map = parser.getJcloudsProperties("openstack-nova", null, "cloudfirst", allProperties);
+        Assert.assertEquals(map.get("provider"), "openstack-nova");
+        Assert.assertEquals(map.get("identity"), "myId");
+        Assert.assertEquals(map.get("credential"), "password");
+        Assert.assertEquals(map.get("imageId"), "RegionOne/1");
+        Assert.assertEquals(map.get("securityGroups"), "universal");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsSshingLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsSshingLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsSshingLiveTest.java
new file mode 100644
index 0000000..48ce9cf
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsSshingLiveTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+import brooklyn.util.collections.MutableMap;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Tests the initial ssh command execution (e.g. user creation), using jclouds TemplateOptions
+ * and using just brooklyn.
+ */
+public class JcloudsSshingLiveTest extends AbstractJcloudsLiveTest {
+
+    public static final String SOFTLAYER_REGION_NAME = SOFTLAYER_AMS01_REGION_NAME;
+    public static final String SOTLAYER_LOCATION_SPEC = "jclouds:" + SOFTLAYER_PROVIDER + (SOFTLAYER_REGION_NAME == null ? "" : ":" + SOFTLAYER_REGION_NAME);
+    
+    protected JcloudsSshMachineLocation machine;
+    
+    @Test(groups = {"Live"})
+    public void testCreatesUserUsingJcloudsTemplateOptions() throws Exception {
+        runCreatesUser(true);
+    }
+    
+    @Test(groups = {"Live"})
+    public void testCreatesUserWithoutUsingJcloudsTemplateOptions() throws Exception {
+        runCreatesUser(false);
+    }
+    
+    protected void runCreatesUser(boolean useJcloudsSshInit) throws Exception {
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USE_JCLOUDS_SSH_INIT.getName(), Boolean.toString(useJcloudsSshInit));
+        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(SOTLAYER_LOCATION_SPEC);
+        
+        JcloudsSshMachineLocation machine = obtainMachine(MutableMap.<String,Object>builder()
+                .putIfAbsent("inboundPorts", ImmutableList.of(22))
+                .build());
+        assertSshable(machine);
+        assertEquals(machine.getUser(), "myname");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java
new file mode 100644
index 0000000..0ff4474
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.jclouds;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.test.entity.TestEntity;
+import org.apache.brooklyn.test.entity.TestEntityImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.basic.Lifecycle;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocationInternal;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+@ImplementedBy(LiveTestEntity.LiveTestEntityImpl.class)
+public interface LiveTestEntity extends TestEntity {
+
+    MachineProvisioningLocation<?> getProvisioningLocation();
+    JcloudsSshMachineLocation getObtainedLocation();
+
+    public static class LiveTestEntityImpl extends TestEntityImpl implements LiveTestEntity {
+
+        private static final Logger LOG = LoggerFactory.getLogger(LiveTestEntityImpl.class);
+        private JcloudsLocation provisioningLocation;
+        private JcloudsSshMachineLocation obtainedLocation;
+
+        @Override
+        public void start(final Collection<? extends Location> locs) {
+            LOG.trace("Starting {}", this);
+            callHistory.add("start");
+            setAttribute(SERVICE_STATE, Lifecycle.STARTING);
+            counter.incrementAndGet();
+            addLocations(locs);
+            provisioningLocation = (JcloudsLocation) Iterables.find(locs, Predicates.instanceOf(JcloudsLocation.class));
+            try {
+                obtainedLocation = (JcloudsSshMachineLocation)provisioningLocation.obtain(((LocationInternal)provisioningLocation).config().getBag().getAllConfig());
+            } catch (NoMachinesAvailableException e) {
+                throw Throwables.propagate(e);
+            }
+            addLocations(ImmutableList.of(obtainedLocation));
+            setAttribute(SERVICE_STATE, Lifecycle.RUNNING);
+        }
+
+        @Override
+        public void stop() {
+            LOG.trace("Stopping {}", this);
+            callHistory.add("stop");
+            setAttribute(SERVICE_STATE, Lifecycle.STOPPING);
+            counter.decrementAndGet();
+            if (provisioningLocation != null && obtainedLocation != null) {
+                provisioningLocation.release(obtainedLocation);
+            }
+            setAttribute(SERVICE_STATE, Lifecycle.STOPPED);
+        }
+
+        public MachineProvisioningLocation<?> getProvisioningLocation() {
+            return provisioningLocation;
+        }
+
+        public JcloudsSshMachineLocation getObtainedLocation() {
+            return obtainedLocation;
+        }
+    }
+
+}



[43/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/MachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineProvisioningLocation.java b/api/src/main/java/org/apache/brooklyn/location/MachineProvisioningLocation.java
new file mode 100644
index 0000000..c3bc346
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/MachineProvisioningLocation.java
@@ -0,0 +1,72 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * A location that is able to provision new machines within its location.
+ *
+ * This interface extends {@link Location} to add the ability to provision {@link MachineLocation}s in this location.
+ */
+public interface MachineProvisioningLocation<T extends MachineLocation> extends ProvisioningLocation<T> {
+    /**
+     * Obtain a machine in this location.
+     * 
+     * @param flags Details of the desired machine (e.g. image, size, open ports, etc; some flag support is limited to selected providers).
+     * "callerContext" can be specified to have custom logging and error messages (useful if starting machines in parallel)
+     * @return a machine that is a child of this location.
+     * @throws NoMachinesAvailableException if there are no machines available in this location (or impls may return null, but that is discouraged)
+     */
+    @Override
+    T obtain(Map<?,?> flags) throws NoMachinesAvailableException;
+
+    /**
+     * Creates a new location of the same type, but with additional creation instructions in the form of flags,
+     * e.g. for specifying subnets, security groups, etc
+     * <p>
+     * Implementers who wish to subclass this provisioning location for additional functionality
+     * in a specific cloud can use the relevant implementation of this method as a guide. 
+     */
+    MachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags);
+    
+    /**
+     * Release a previously-obtained machine.
+     *
+     * @param machine a {@link MachineLocation} previously obtained from a call to {@link #obtain()}
+     * @throws IllegalStateException if the machine did not come from a call to {@link #obtain()} or it has already been released.
+     */
+    @Override
+    void release(T machine);
+    
+    /**
+     * Gets flags, suitable as an argument to {@link #obtain(Map)}. The tags provided give
+     * hints about the machine required. The provisioning-location could be configured to 
+     * understand those tags. 
+     * 
+     * For example, an AWS-location could be configured to understand that a particular entity
+     * type (e.g. "TomcatServer") requires a particular AMI in that region, so would return the 
+     * required image id.
+     *  
+     * @param tags
+     * @return
+     */
+    Map<String,Object> getProvisioningFlags(Collection<String> tags);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/NoMachinesAvailableException.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/NoMachinesAvailableException.java b/api/src/main/java/org/apache/brooklyn/location/NoMachinesAvailableException.java
new file mode 100644
index 0000000..d8f16ce
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/NoMachinesAvailableException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.apache.brooklyn.location;
+
+
+/**
+ * Indicates no machines are available in a given location.
+ */
+public class NoMachinesAvailableException extends LocationNotAvailableException {
+    private static final long serialVersionUID = 1079817235289265761L;
+    
+    public NoMachinesAvailableException(String s) {
+        super(s);
+    }
+
+    public NoMachinesAvailableException(String s, Throwable throwable) {
+        super(s, throwable);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/OsDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/OsDetails.java b/api/src/main/java/org/apache/brooklyn/location/OsDetails.java
new file mode 100644
index 0000000..c5aea67
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/OsDetails.java
@@ -0,0 +1,46 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import javax.annotation.Nullable;
+
+public interface OsDetails {
+
+    /** The name of the operating system, e.g. "Debian" or "Red Hat Enterprise Linux Server" */
+    @Nullable
+    String getName();
+
+    /**
+     * The version of the operating system. Generally numeric (e.g. "6.3") but occasionally
+     * alphabetic (e.g. Debian's "Squeeze").
+     */
+    @Nullable
+    String getVersion();
+
+    /** The operating system's architecture, e.g. "x86" or "x86_64" */
+    @Nullable
+    String getArch();
+
+    boolean is64bit();
+
+    boolean isWindows();
+    boolean isLinux();
+    boolean isMac();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/PortRange.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/PortRange.java b/api/src/main/java/org/apache/brooklyn/location/PortRange.java
new file mode 100644
index 0000000..25dd621
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/PortRange.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location;
+
+/**
+ * A range of ports (indicator for Location and other APIs).
+ * Using methods {@code PortRanges.fromXxx(...)} this is adaptable from a number, a string, or a collection of numbers or a strings.
+ * String may be of the form:
+ *   <li> "80": just 80
+ *   <li> "8080-8090": limited range sequentially; ie try 8080, then 8081, ..., then 8090, then give up
+ *   <li> "8080-8000": as above, but descending; ie try 8080, then 8079, ..., then 8000, then give up
+ *   <li> "8000+": unlimited range sequentially; ie try 8000, then 8001, then 8002, etc
+ *   <li> "80,8080,8000,8080-8099": different ranges, in order; ie try 80, then 8080, then 8000, then 8080 (again), then 8081, ..., then 8099, then give up
+ * Ranges (but not lists) may be preceeded by "!" to indicate a randomly selected port:
+ * 
+ * @see brooklyn.location.basic.PortRanges
+ */
+//MAYDO could have:   <li> "~32168-65535" (or "~32168-"): try randomly selected numbers in range 32168-65535 (MAX_PORT) until all have been tried
+public interface PortRange extends Iterable<Integer> {
+    /**
+     * Whether there are any ports in the range.
+     */
+    boolean isEmpty();
+    
+    /**
+     * Note: this method is only here for use with "groovy truth". Users are strongly discouraged  
+     * from calling it directly.
+     *  
+     * @return {@code !isEmpty()}; i.e. true if there is at least one port in the range; false otherwise
+     */
+    boolean asBoolean();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/PortSupplier.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/PortSupplier.java b/api/src/main/java/org/apache/brooklyn/location/PortSupplier.java
new file mode 100644
index 0000000..24572a0
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/PortSupplier.java
@@ -0,0 +1,50 @@
+/*
+ * 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.apache.brooklyn.location;
+
+/** Mixin interface for location which allows it to supply ports from a given range */
+public interface PortSupplier {
+
+    /**
+     * Reserve a specific port for an application. If your application requires a specific port - for example, port 80 for a web
+     * server - you should reserve this port before starting your application. Using this method, you will be able to detect if
+     * another application has already claimed this port number.
+     *
+     * @param portNumber the required port number.
+     * @return {@code true} if the port was successfully reserved; {@code false} if it has been previously reserved.
+     */
+    boolean obtainSpecificPort(int portNumber);
+
+    /**
+     * Reserve a port for your application, with a port number in a specific range. If your application requires a port, but it does
+     * not mind exactly which port number - for example, a port for internal JMX monitoring - call this method.
+     *
+     * @param range the range of acceptable port numbers.
+     * @return the port number that has been reserved, or -1 if there was no available port in the acceptable range.
+     */
+    int obtainPort(PortRange range);
+
+    /**
+     * Release a previously reserved port.
+     *
+     * @param portNumber the port number from a call to {@link #obtainPort(PortRange)} or {@link #obtainSpecificPort(int)}
+     */
+    void releasePort(int portNumber);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/ProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/ProvisioningLocation.java b/api/src/main/java/org/apache/brooklyn/location/ProvisioningLocation.java
new file mode 100644
index 0000000..3cc3f92
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/ProvisioningLocation.java
@@ -0,0 +1,44 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import java.util.Map;
+
+/**
+ * A location that is able to provision new locations within it.
+ */
+public interface ProvisioningLocation<T extends Location> extends Location {
+    /**
+     * Obtain a new (sub)-location in the location represented by this class.
+     * 
+     * @param flags Constraints and details of the location to be provisioned
+     * @return the location provisioned
+     * @throws LocationNotAvailableException if could not provision such a location
+     */
+    T obtain(Map<?,?> flags) throws LocationNotAvailableException;
+
+    /**
+     * Release a previously-obtained location.
+     *
+     * @param location a location previously obtained
+     * @throws IllegalStateException if the machine did not come from a call to {@link #obtain()} or it has already been released.
+     */
+    void release(T machine);
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java b/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java
index e9a9a58..8c6f7e1 100644
--- a/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java
+++ b/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java
@@ -37,7 +37,7 @@ import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.time.Duration;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/basic/BrooklynTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypes.java b/core/src/main/java/brooklyn/basic/BrooklynTypes.java
index 8db853d..4ccbfd0 100644
--- a/core/src/main/java/brooklyn/basic/BrooklynTypes.java
+++ b/core/src/main/java/brooklyn/basic/BrooklynTypes.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.policy.Policy;
 import brooklyn.config.ConfigKey;
 import brooklyn.enricher.basic.EnricherDynamicType;
 import brooklyn.entity.basic.EntityDynamicType;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.policy.basic.PolicyDynamicType;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/CatalogPredicates.java b/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
index 99e1a8f..e9778ab 100644
--- a/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
+++ b/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
@@ -30,8 +30,8 @@ import org.apache.brooklyn.policy.Policy;
 import org.apache.brooklyn.policy.PolicySpec;
 
 import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
 import brooklyn.management.entitlement.Entitlements;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
index b1d5385..a3bb808 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -54,9 +54,9 @@ import org.apache.brooklyn.policy.PolicySpec;
 import brooklyn.catalog.CatalogPredicates;
 import brooklyn.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
 import brooklyn.config.BrooklynServerConfig;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.BasicLocationRegistry;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java b/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
index 0f9bde9..af0e53d 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
@@ -39,7 +39,7 @@ import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
 import org.apache.brooklyn.policy.Policy;
 
 import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java b/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
index e8bf2ec..8d12b1a 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
@@ -18,8 +18,8 @@
  */
 package brooklyn.catalog.internal;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
 
 
 public class CatalogLocationItemDto extends CatalogItemDtoAbstract<Location,LocationSpec<?>> {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java b/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java
index dc99712..0e570b7 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java
@@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.trait.StartableMethods;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.RuntimeInterruptedException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
index c7a017c..db1c26f 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -76,8 +76,8 @@ import brooklyn.internal.BrooklynInitialization;
 import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.internal.storage.Reference;
 import brooklyn.internal.storage.impl.BasicReference;
-import brooklyn.location.Location;
-import brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.Locations;
 import brooklyn.management.internal.EffectorUtils;
 import brooklyn.management.internal.EntityManagementSupport;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/BasicStartable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/BasicStartable.java b/core/src/main/java/brooklyn/entity/basic/BasicStartable.java
index 8ddc794..00d87c3 100644
--- a/core/src/main/java/brooklyn/entity/basic/BasicStartable.java
+++ b/core/src/main/java/brooklyn/entity/basic/BasicStartable.java
@@ -25,8 +25,8 @@ import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.Locations;
 
 import com.google.common.collect.ImmutableList;
 
@@ -51,6 +51,6 @@ public interface BasicStartable extends Entity, Startable {
         };
     }
 
-    public static final ConfigKey<brooklyn.location.basic.Locations.LocationsFilter> LOCATIONS_FILTER = ConfigKeys.newConfigKey(brooklyn.location.basic.Locations.LocationsFilter.class,
+    public static final ConfigKey<Locations.LocationsFilter> LOCATIONS_FILTER = ConfigKeys.newConfigKey(Locations.LocationsFilter.class,
             "brooklyn.locationsFilter", "Provides a hook for customizing locations to be used for a given context");
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java b/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java
index 0552f75..630bdd8 100644
--- a/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java
+++ b/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java
@@ -24,12 +24,13 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.location.basic.Locations;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Predicates;
@@ -51,7 +52,7 @@ public class BasicStartableImpl extends AbstractEntity implements BasicStartable
             // essentially does StartableMethods.start(this, locations),
             // but optionally filters locations for each child
 
-            brooklyn.location.basic.Locations.LocationsFilter filter = getConfig(LOCATIONS_FILTER);
+            Locations.LocationsFilter filter = getConfig(LOCATIONS_FILTER);
             Iterable<Entity> startables = filterStartableManagedEntities(getChildren());
             if (!Iterables.isEmpty(startables)) {
                 List<Task<?>> tasks = Lists.newArrayListWithCapacity(Iterables.size(startables));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java b/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
index 3c641cb..ac3de30 100644
--- a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
+++ b/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
@@ -24,7 +24,7 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.basic.TemplatedStringAttributeSensorAndConfigKey;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.internal.ssh.ShellTool;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java b/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
index d6a465c..52ba52e 100644
--- a/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
+++ b/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.api.event.AttributeSensor;
 
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Functions;
 import com.google.common.base.Supplier;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java b/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java
index 92a1e68..1bbb4c1 100644
--- a/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java
+++ b/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java
@@ -27,7 +27,7 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.annotation.Effector;
 import brooklyn.entity.annotation.EffectorParam;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.config.ConfigBag;
 
 import com.google.common.reflect.TypeToken;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/Entities.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/Entities.java b/core/src/main/java/brooklyn/entity/basic/Entities.java
index d49dad3..c1cac26 100644
--- a/core/src/main/java/brooklyn/entity/basic/Entities.java
+++ b/core/src/main/java/brooklyn/entity/basic/Entities.java
@@ -69,10 +69,10 @@ import brooklyn.entity.proxying.EntityProxyImpl;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.basic.Locations;
 import brooklyn.management.internal.EffectorUtils;
 import brooklyn.management.internal.EntityManagerInternal;
 import brooklyn.management.internal.LocalManagementContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java b/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java
index f1644aa..eb7ef3a 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java
@@ -20,7 +20,7 @@ package brooklyn.entity.basic;
 
 import org.apache.brooklyn.api.entity.Entity;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * dispatch interface to allow an EntityFactory to indicate it might be able to discover

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java b/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
index 97f6618..1250d40 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
@@ -31,7 +31,7 @@ import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.management.ManagementContext;
 
 import brooklyn.config.ConfigKey;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Functionals;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java b/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
index 8fe53d2..08c3e19 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
@@ -34,7 +34,7 @@ import org.apache.brooklyn.mementos.EntityMemento;
 
 import brooklyn.basic.BrooklynObjectInternal;
 import brooklyn.config.ConfigKey;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.EntityManagementSupport;
 import brooklyn.util.config.ConfigBag;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java b/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java
index ac5adbf..7c7d2f3 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.api.event.AttributeSensor;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.guava.SerializablePredicate;
 import brooklyn.util.javalang.Reflections;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/EntitySuppliers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntitySuppliers.java b/core/src/main/java/brooklyn/entity/basic/EntitySuppliers.java
index c0f30b9..0a5defd 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntitySuppliers.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntitySuppliers.java
@@ -20,8 +20,8 @@ package brooklyn.entity.basic;
 
 import org.apache.brooklyn.api.entity.Entity;
 
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.base.Supplier;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java b/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java
index 0325171..70a1667 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java
@@ -20,9 +20,7 @@ package brooklyn.entity.basic;
 
 import java.util.Collection;
 import java.util.Map;
-import java.util.Set;
 
-import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.basic.BrooklynObject.TagSupport;
@@ -43,7 +41,7 @@ import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
 import brooklyn.entity.basic.EntityInternal.FeedSupport;
 import brooklyn.entity.proxying.EntityProxyImpl;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.EntityManagementSupport;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/basic/Lifecycle.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/Lifecycle.java b/core/src/main/java/brooklyn/entity/basic/Lifecycle.java
index 9918bde..75b32b4 100644
--- a/core/src/main/java/brooklyn/entity/basic/Lifecycle.java
+++ b/core/src/main/java/brooklyn/entity/basic/Lifecycle.java
@@ -31,6 +31,7 @@ import com.google.common.base.CaseFormat;
 import com.google.common.base.Function;
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
+import org.apache.brooklyn.location.Location;
 
 /**
  * An enumeration representing the status of an {@link org.apache.brooklyn.api.entity.Entity}.
@@ -41,7 +42,7 @@ public enum Lifecycle {
      *
      * This stage encompasses the contruction. Once this stage is
      * complete, the basic set of {@link brooklyn.event.Sensor}s will be available, apart from any that require the entity to be active or
-     * deployed to a {@link brooklyn.location.Location}.
+     * deployed to a {@link Location}.
      */
     CREATED,
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java b/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java
index 3a9ed09..889a05a 100644
--- a/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java
+++ b/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java
@@ -24,7 +24,7 @@ import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
 
 import com.google.common.annotations.Beta;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class BasicEntityDriverManager implements EntityDriverManager {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java b/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java
index 3c3836a..86591b3 100644
--- a/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java
+++ b/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java
@@ -28,10 +28,10 @@ import org.apache.brooklyn.api.entity.drivers.EntityDriver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.paas.PaasLocation;
-import brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.paas.PaasLocation;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java b/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java
index 84265dc..2c1243f 100644
--- a/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java
+++ b/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java
@@ -30,7 +30,7 @@ import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
 import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Throwables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/effector/EffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/effector/EffectorTasks.java b/core/src/main/java/brooklyn/entity/effector/EffectorTasks.java
index 353d721..e7657ea 100644
--- a/core/src/main/java/brooklyn/entity/effector/EffectorTasks.java
+++ b/core/src/main/java/brooklyn/entity/effector/EffectorTasks.java
@@ -33,9 +33,9 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 import brooklyn.management.internal.EffectorUtils;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.javalang.Reflections;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/DynamicCluster.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicCluster.java b/core/src/main/java/brooklyn/entity/group/DynamicCluster.java
index 27e158e..e6f31de 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicCluster.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicCluster.java
@@ -45,7 +45,7 @@ import brooklyn.entity.trait.MemberReplaceable;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.basic.BasicNotificationSensor;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
index 287abc8..eafb161 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
@@ -52,10 +52,10 @@ import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
-import brooklyn.location.Location;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.cloud.AvailabilityZoneExtension;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java b/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java
index d6b0884..60f437e 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java
@@ -45,7 +45,7 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.trait.Changeable;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.GroovyJavaMethods;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java b/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java
index a165f62..eeab8e2 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java
@@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java b/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java
index d2082ca..62b07eb 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java
@@ -26,7 +26,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.brooklyn.api.entity.Entity;
 
 import brooklyn.entity.group.DynamicCluster.ZoneFailureDetector;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Ticker;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java b/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java
index 2393f47..700b0b5 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java
@@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.group.DynamicCluster.NodePlacementStrategy;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java b/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java
index f318106..b7ea052 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java
@@ -23,7 +23,7 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.Entity;
 
 import brooklyn.entity.group.DynamicCluster.ZoneFailureDetector;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java b/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java
index 6691985..ecdf73f 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java
@@ -18,7 +18,7 @@
  */
 package brooklyn.entity.group.zoneaware;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java b/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java
index dfec84a..13a9ed0 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java
@@ -18,7 +18,7 @@
  */
 package brooklyn.entity.group.zoneaware;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Ticker;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java b/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
index 3c665f6..f44602f 100644
--- a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
@@ -25,11 +25,10 @@ import java.util.Map.Entry;
 import org.apache.brooklyn.api.management.ManagementContext;
 
 import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocationInternal;
 import brooklyn.management.internal.LocalLocationManager;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
index c0139ae..29aa938 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
@@ -40,7 +40,7 @@ import brooklyn.entity.basic.AbstractGroupImpl;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.dto.MementosGenerators;
 import brooklyn.event.feed.AbstractFeed;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
index 13c6d83..1719eff 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
@@ -30,8 +30,8 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.rebind.dto.MementosGenerators;
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.AbstractLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.flags.FlagUtils;
 import brooklyn.util.flags.TypeCoercions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
index 3039e89..d92fa72 100644
--- a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
@@ -38,8 +38,8 @@ import org.apache.brooklyn.mementos.PolicyMemento;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocationInternal;
 
 import com.google.common.collect.Maps;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
index 8b68aec..538eaf4 100644
--- a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
@@ -50,7 +50,7 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
 import brooklyn.entity.rebind.persister.PersistenceActivityMetrics;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java
index 85f4851..4e0f887 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java
@@ -34,7 +34,7 @@ import org.apache.brooklyn.mementos.BrooklynMementoPersister.LookupContext;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.Maps;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java b/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java
index 98e0586..f093089 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java
@@ -35,7 +35,7 @@ import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
 import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /** Looks in {@link RebindContext} <i>and</i> {@link ManagementContext} to find entities, locations, etc. */
 public class RebindContextLookupContext implements LookupContext {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
index 5fdb335..f08eb01 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
@@ -39,7 +39,7 @@ import org.apache.brooklyn.api.entity.rebind.RebindManager.RebindFailureMode;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.QuorumCheck;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
index bd33c1b..d27ea65 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
@@ -80,9 +80,9 @@ import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker;
 import brooklyn.entity.rebind.persister.PersistenceActivityMetrics;
 import brooklyn.event.feed.AbstractFeed;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocationInternal;
 import brooklyn.management.internal.BrooklynObjectManagementMode;
 import brooklyn.management.internal.BrooklynObjectManagerInternal;
 import brooklyn.management.internal.EntityManagerInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java b/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java
index 4574cd6..983bb45 100644
--- a/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java
+++ b/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java
@@ -23,7 +23,7 @@ import java.util.Collection;
 import java.util.Deque;
 import java.util.Set;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.Sets;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
index c65444f..1a5ae1f 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
@@ -58,8 +58,8 @@ import brooklyn.entity.rebind.AbstractBrooklynObjectRebindSupport;
 import brooklyn.entity.rebind.TreeUtils;
 import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
 import brooklyn.event.feed.AbstractFeed;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocationInternal;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
index f52f2d2..c874060 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
@@ -48,9 +48,9 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.PersistenceExceptionHandlerImpl;
 import brooklyn.entity.rebind.transformer.CompoundTransformer;
 import brooklyn.entity.rebind.transformer.CompoundTransformerLoader;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import brooklyn.management.internal.LocalLocationManager;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java b/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
index e78af93..c936526 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
@@ -57,7 +57,7 @@ import brooklyn.entity.rebind.dto.BasicPolicyMemento;
 import brooklyn.entity.rebind.dto.MutableBrooklynMemento;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.classloading.BrooklynClassLoadingContextSequential;
 import brooklyn.management.classloading.ClassLoaderFromBrooklynClassLoadingContext;
 import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/trait/Startable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/trait/Startable.java b/core/src/main/java/brooklyn/entity/trait/Startable.java
index 71f25f4..97674eb 100644
--- a/core/src/main/java/brooklyn/entity/trait/Startable.java
+++ b/core/src/main/java/brooklyn/entity/trait/Startable.java
@@ -32,7 +32,7 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.effector.Effectors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.Tasks;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/entity/trait/StartableMethods.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/trait/StartableMethods.java b/core/src/main/java/brooklyn/entity/trait/StartableMethods.java
index b89a018..acfbde3 100644
--- a/core/src/main/java/brooklyn/entity/trait/StartableMethods.java
+++ b/core/src/main/java/brooklyn/entity/trait/StartableMethods.java
@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.effector.Effectors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.CompoundRuntimeException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java b/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java
index 9611bd5..ccfcc63 100644
--- a/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java
+++ b/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java
@@ -30,11 +30,11 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.internal.BrooklynInitialization;
-import brooklyn.location.Location;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.PortRange;
-import brooklyn.location.PortSupplier;
-import brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.PortSupplier;
+import org.apache.brooklyn.location.basic.Locations;
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Maybe;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/event/feed/ssh/SshFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/ssh/SshFeed.java b/core/src/main/java/brooklyn/event/feed/ssh/SshFeed.java
index f7975d9..200e2fb 100644
--- a/core/src/main/java/brooklyn/event/feed/ssh/SshFeed.java
+++ b/core/src/main/java/brooklyn/event/feed/ssh/SshFeed.java
@@ -39,9 +39,9 @@ import brooklyn.event.feed.AbstractFeed;
 import brooklyn.event.feed.AttributePollHandler;
 import brooklyn.event.feed.DelegatingPollHandler;
 import brooklyn.event.feed.Poller;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/event/feed/ssh/SshPollValue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/ssh/SshPollValue.java b/core/src/main/java/brooklyn/event/feed/ssh/SshPollValue.java
index 65dad55..7bdde17 100644
--- a/core/src/main/java/brooklyn/event/feed/ssh/SshPollValue.java
+++ b/core/src/main/java/brooklyn/event/feed/ssh/SshPollValue.java
@@ -20,7 +20,7 @@ package brooklyn.event.feed.ssh;
 
 import javax.annotation.Nullable;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 public class SshPollValue {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
index 04f87ba..040d887 100644
--- a/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/core/src/main/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeed.java
@@ -49,7 +49,7 @@ import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.AbstractFeed;
 import brooklyn.event.feed.PollHandler;
 import brooklyn.event.feed.Poller;
-import brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/internal/BrooklynInitialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/internal/BrooklynInitialization.java b/core/src/main/java/brooklyn/internal/BrooklynInitialization.java
index 83d8d9d..70eea9f 100644
--- a/core/src/main/java/brooklyn/internal/BrooklynInitialization.java
+++ b/core/src/main/java/brooklyn/internal/BrooklynInitialization.java
@@ -20,7 +20,7 @@ package brooklyn.internal;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.crypto.SecureKeys;
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/access/BrooklynAccessUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/access/BrooklynAccessUtils.java b/core/src/main/java/brooklyn/location/access/BrooklynAccessUtils.java
deleted file mode 100644
index 9bf0f9b..0000000
--- a/core/src/main/java/brooklyn/location/access/BrooklynAccessUtils.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import java.util.Collection;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.basic.SupportsPortForwarding;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.net.Cidr;
-import brooklyn.util.task.DynamicTasks;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.task.ssh.SshTasks;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Supplier;
-import com.google.common.net.HostAndPort;
-
-public class BrooklynAccessUtils {
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynAccessUtils.class);
-    
-    public static final ConfigKey<PortForwardManager> PORT_FORWARDING_MANAGER = new BasicConfigKey<PortForwardManager>(
-            PortForwardManager.class, "brooklyn.portforwarding.manager", "A port-forwarding manager to use at an entity "
-                + "or a location, where supported; note this should normally be a serializable client instance to prevent "
-                + "the creation of multiple disconnected instances via config duplication");
-    
-    public static final ConfigKey<Cidr> MANAGEMENT_ACCESS_CIDR = new BasicConfigKey<Cidr>(
-            Cidr.class, "brooklyn.portforwarding.management.cidr", "CIDR to enable by default for port-forwarding for management",
-            null);  // TODO should be a list
-
-    public static HostAndPort getBrooklynAccessibleAddress(Entity entity, int port) {
-        String host;
-        
-        // look up port forwarding
-        PortForwardManager pfw = entity.getConfig(PORT_FORWARDING_MANAGER);
-        if (pfw!=null) {
-            Collection<Location> ll = entity.getLocations();
-            Maybe<SupportsPortForwarding> machine = Machines.findUniqueElement(ll, SupportsPortForwarding.class);
-            if (machine.isPresent()) {
-                synchronized (BrooklynAccessUtils.class) {
-                    // TODO finer-grained synchronization
-                    
-                    HostAndPort hp = pfw.lookup((MachineLocation)machine.get(), port);
-                    if (hp!=null) return hp;
-                    
-                    Location l = (Location) machine.get();
-                    if (l instanceof SupportsPortForwarding) {
-                        Cidr source = entity.getConfig(MANAGEMENT_ACCESS_CIDR);
-                        if (source!=null) {
-                            log.debug("BrooklynAccessUtils requesting new port-forwarding rule to access "+port+" on "+entity+" (at "+l+", enabled for "+source+")");
-                            // TODO discuss, is this the best way to do it
-                            // (will probably _create_ the port forwarding rule!)
-                            hp = ((SupportsPortForwarding) l).getSocketEndpointFor(source, port);
-                            if (hp!=null) return hp;
-                        } else {
-                            log.warn("No "+MANAGEMENT_ACCESS_CIDR.getName()+" configured for "+entity+", so cannot forward port "+port+" " +
-                                    "even though "+PORT_FORWARDING_MANAGER.getName()+" was supplied");
-                        }
-                    }
-                }
-            }
-        }
-        
-        host = entity.getAttribute(Attributes.HOSTNAME);
-        if (host!=null) return HostAndPort.fromParts(host, port);
-        
-        throw new IllegalStateException("Cannot find way to access port "+port+" on "+entity+" from Brooklyn (no host.name)");
-    }
-
-    /** attempts to resolve hostnameTarget from origin
-     * @return null if it definitively can't be resolved,  
-     * best-effort IP address if possible, or blank if we could not run ssh or make sense of the output */
-    public static String getResolvedAddress(Entity entity, SshMachineLocation origin, String hostnameTarget) {
-        ProcessTaskWrapper<Integer> task = SshTasks.newSshExecTaskFactory(origin, "ping -c 1 -t 1 "+hostnameTarget)
-            .summary("checking resolution of "+hostnameTarget).allowingNonZeroExitCode().newTask();
-        DynamicTasks.queueIfPossible(task).orSubmitAndBlock(entity).asTask().blockUntilEnded();
-        if (task.asTask().isError()) {
-            log.warn("ping could not be run, at "+entity+" / "+origin+": "+Tasks.getError(task.asTask()));
-            return "";
-        }
-        if (task.getExitCode()==null || task.getExitCode()!=0) {
-            if (task.getExitCode()!=null && task.getExitCode()<10) {
-                // small number means ping failed to resolve or ping the hostname
-                log.debug("not able to resolve "+hostnameTarget+" from "+origin+" for "+entity+" because exit code was "+task.getExitCode());
-                return null;
-            }
-            // large number means ping probably did not run
-            log.warn("ping not run as expected, at "+entity+" / "+origin+" (code "+task.getExitCode()+"):\n"+task.getStdout().trim()+" --- "+task.getStderr().trim());
-            return "";
-        }
-        String out = task.getStdout();
-        try {
-            String line1 = Strings.getFirstLine(out);
-            String ip = Strings.getFragmentBetween(line1, "(", ")");
-            if (Strings.isNonBlank(ip)) 
-                return ip;
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            /* ignore non-parseable output */ 
-        }
-        if (out.contains("127.0.0.1")) return "127.0.0.1";
-        return "";
-    }
-
-    public static Supplier<String> resolvedAddressSupplier(final Entity entity, final SshMachineLocation origin, final String hostnameTarget) {
-        return new Supplier<String>() {
-            @Override
-            public String get() {
-                return getResolvedAddress(entity, origin, hostnameTarget);
-            }
-        };
-    }
-
-}


[53/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/NoMachinesAvailableException.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/NoMachinesAvailableException.java b/api/src/main/java/org/apache/brooklyn/api/location/NoMachinesAvailableException.java
new file mode 100644
index 0000000..f13c1ff
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/NoMachinesAvailableException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+
+/**
+ * Indicates no machines are available in a given location.
+ */
+public class NoMachinesAvailableException extends LocationNotAvailableException {
+    private static final long serialVersionUID = 1079817235289265761L;
+    
+    public NoMachinesAvailableException(String s) {
+        super(s);
+    }
+
+    public NoMachinesAvailableException(String s, Throwable throwable) {
+        super(s, throwable);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/OsDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/OsDetails.java b/api/src/main/java/org/apache/brooklyn/api/location/OsDetails.java
new file mode 100644
index 0000000..9baac9e
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/OsDetails.java
@@ -0,0 +1,46 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import javax.annotation.Nullable;
+
+public interface OsDetails {
+
+    /** The name of the operating system, e.g. "Debian" or "Red Hat Enterprise Linux Server" */
+    @Nullable
+    String getName();
+
+    /**
+     * The version of the operating system. Generally numeric (e.g. "6.3") but occasionally
+     * alphabetic (e.g. Debian's "Squeeze").
+     */
+    @Nullable
+    String getVersion();
+
+    /** The operating system's architecture, e.g. "x86" or "x86_64" */
+    @Nullable
+    String getArch();
+
+    boolean is64bit();
+
+    boolean isWindows();
+    boolean isLinux();
+    boolean isMac();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/PortRange.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/PortRange.java b/api/src/main/java/org/apache/brooklyn/api/location/PortRange.java
new file mode 100644
index 0000000..108f0dd
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/PortRange.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.api.location;
+
+/**
+ * A range of ports (indicator for Location and other APIs).
+ * Using methods {@code PortRanges.fromXxx(...)} this is adaptable from a number, a string, or a collection of numbers or a strings.
+ * String may be of the form:
+ *   <li> "80": just 80
+ *   <li> "8080-8090": limited range sequentially; ie try 8080, then 8081, ..., then 8090, then give up
+ *   <li> "8080-8000": as above, but descending; ie try 8080, then 8079, ..., then 8000, then give up
+ *   <li> "8000+": unlimited range sequentially; ie try 8000, then 8001, then 8002, etc
+ *   <li> "80,8080,8000,8080-8099": different ranges, in order; ie try 80, then 8080, then 8000, then 8080 (again), then 8081, ..., then 8099, then give up
+ * Ranges (but not lists) may be preceeded by "!" to indicate a randomly selected port:
+ * 
+ * @see brooklyn.location.basic.PortRanges
+ */
+//MAYDO could have:   <li> "~32168-65535" (or "~32168-"): try randomly selected numbers in range 32168-65535 (MAX_PORT) until all have been tried
+public interface PortRange extends Iterable<Integer> {
+    /**
+     * Whether there are any ports in the range.
+     */
+    boolean isEmpty();
+    
+    /**
+     * Note: this method is only here for use with "groovy truth". Users are strongly discouraged  
+     * from calling it directly.
+     *  
+     * @return {@code !isEmpty()}; i.e. true if there is at least one port in the range; false otherwise
+     */
+    boolean asBoolean();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/PortSupplier.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/PortSupplier.java b/api/src/main/java/org/apache/brooklyn/api/location/PortSupplier.java
new file mode 100644
index 0000000..02c4398
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/PortSupplier.java
@@ -0,0 +1,50 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+/** Mixin interface for location which allows it to supply ports from a given range */
+public interface PortSupplier {
+
+    /**
+     * Reserve a specific port for an application. If your application requires a specific port - for example, port 80 for a web
+     * server - you should reserve this port before starting your application. Using this method, you will be able to detect if
+     * another application has already claimed this port number.
+     *
+     * @param portNumber the required port number.
+     * @return {@code true} if the port was successfully reserved; {@code false} if it has been previously reserved.
+     */
+    boolean obtainSpecificPort(int portNumber);
+
+    /**
+     * Reserve a port for your application, with a port number in a specific range. If your application requires a port, but it does
+     * not mind exactly which port number - for example, a port for internal JMX monitoring - call this method.
+     *
+     * @param range the range of acceptable port numbers.
+     * @return the port number that has been reserved, or -1 if there was no available port in the acceptable range.
+     */
+    int obtainPort(PortRange range);
+
+    /**
+     * Release a previously reserved port.
+     *
+     * @param portNumber the port number from a call to {@link #obtainPort(PortRange)} or {@link #obtainSpecificPort(int)}
+     */
+    void releasePort(int portNumber);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/ProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/ProvisioningLocation.java b/api/src/main/java/org/apache/brooklyn/api/location/ProvisioningLocation.java
new file mode 100644
index 0000000..25bd209
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/ProvisioningLocation.java
@@ -0,0 +1,44 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import java.util.Map;
+
+/**
+ * A location that is able to provision new locations within it.
+ */
+public interface ProvisioningLocation<T extends Location> extends Location {
+    /**
+     * Obtain a new (sub)-location in the location represented by this class.
+     * 
+     * @param flags Constraints and details of the location to be provisioned
+     * @return the location provisioned
+     * @throws LocationNotAvailableException if could not provision such a location
+     */
+    T obtain(Map<?,?> flags) throws LocationNotAvailableException;
+
+    /**
+     * Release a previously-obtained location.
+     *
+     * @param location a location previously obtained
+     * @throws IllegalStateException if the machine did not come from a call to {@link #obtain()} or it has already been released.
+     */
+    void release(T machine);
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java b/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java
index a8b6939..d326045 100644
--- a/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java
+++ b/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java
@@ -19,8 +19,7 @@
 package org.apache.brooklyn.api.management;
 
 import org.apache.brooklyn.api.entity.Entity;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.annotations.Beta;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java b/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java
index 9e4377c..379ab62 100644
--- a/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java
+++ b/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.api.management;
 import java.util.Collection;
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 
 /**
  * For managing and querying entities.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java b/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java
index 615982b..84085fc 100644
--- a/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java
+++ b/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java
@@ -30,11 +30,11 @@ import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
+import org.apache.brooklyn.api.location.LocationRegistry;
 import org.apache.brooklyn.api.management.entitlement.EntitlementManager;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityManager;
 
 import brooklyn.config.StringConfigMap;
-import org.apache.brooklyn.location.LocationRegistry;
 import brooklyn.util.guava.Maybe;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/AddressableLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/AddressableLocation.java b/api/src/main/java/org/apache/brooklyn/location/AddressableLocation.java
deleted file mode 100644
index ba44467..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/AddressableLocation.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.net.InetAddress;
-
-/** A location that has an IP address.
- * <p>
- * This IP address may be a machine (usually the MachineLocation sub-interface), 
- * or often an entry point for a service.
- */
-public interface AddressableLocation extends Location {
-
-    /**
-     * Return the single most appropriate address for this location.
-     * (An implementation or sub-interface definition may supply more information
-     * on the precise semantics of the address.)
-     * 
-     * Should not return null, but in some "special cases" (e.g. CloudFoundryLocation it
-     * may return null if the location is not configured correctly). Users should expect
-     * a non-null result and treat null as a programming error or misconfiguration. 
-     * Implementors of this interface should strive to not return null (and then we'll
-     * remove this caveat from the javadoc!).
-     */
-    InetAddress getAddress();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/BasicMachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/BasicMachineLocationCustomizer.java b/api/src/main/java/org/apache/brooklyn/location/BasicMachineLocationCustomizer.java
deleted file mode 100644
index bbf53d3..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/BasicMachineLocationCustomizer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import com.google.common.annotations.Beta;
-
-/**
- * A default no-op implementation, which can be extended to override the appropriate methods.
- * 
- * Sub-classing will give the user some protection against future API changes - note that 
- * {@link MachineLocationCustomizer} is marked {@link Beta}.
- */
-@Beta
-public class BasicMachineLocationCustomizer implements MachineLocationCustomizer {
-
-    @Override
-    public void customize(MachineLocation machine) {
-        // no-op
-    }
-    
-    @Override
-    public void preRelease(MachineLocation machine) {
-        // no-op
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/HardwareDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/HardwareDetails.java b/api/src/main/java/org/apache/brooklyn/location/HardwareDetails.java
deleted file mode 100644
index 58acb0b..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/HardwareDetails.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import javax.annotation.Nullable;
-
-/**
- * @since 0.7.0
- */
-public interface HardwareDetails {
-
-    /**
-     * The number of CPUs on the machine
-     */
-    @Nullable
-    Integer getCpuCount();
-
-    /**
-     * Amount of RAM in megabytes
-     */
-    @Nullable
-    Integer getRam();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/Location.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/Location.java b/api/src/main/java/org/apache/brooklyn/location/Location.java
deleted file mode 100644
index 88a5bfb..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/Location.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.brooklyn.api.basic.BrooklynObject;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-
-/**
- * A location that an entity can be in. Examples of locations include a single machine
- * or a pool of machines, or a region within a given cloud. 
- * 
- * See {@link brooklyn.entity.trait.Startable#start(Collection)}.
- * 
- * Locations may not be {@link Serializable} in subsequent releases!
- */
-public interface Location extends Serializable, BrooklynObject {
-
-    /**
-     * A unique id for this location.
-     */
-    @Override
-    String getId();
-
-    /**
-     * Get the name assigned to this location.
-     *
-     * @return the name assigned to the location.
-     * @since 0.6 (previously getName())
-     */
-    @Override
-    String getDisplayName();
-
-    /**
-     * Get the 'parent' of this location. Locations are organized into a tree hierarchy, and this method will return a reference
-     * to the parent of this location, or {@code null} if this location is the tree root.
-     *
-     * @return a reference to the parent of this location, or {@code null} if this location is the tree root.
-     * @since 0.6 (previously getParentLocation())
-     */
-    Location getParent();
-
-    /**
-     * Get the 'children' of this location. Locations are organized into a tree hierarchy, and this method will return a
-     * collection containing the children of this location. This collection is an unmodifiable view of the data.
-     *
-     * @return a collection containing the children of this location.
-     * @since 0.6 (previously getChildLocations())
-     */
-    Collection<Location> getChildren();
-
-    /**
-     * Set the 'parent' of this location. If this location was previously a child of a different location, it is removed from
-     * the other location first. It is valid to pass in {@code null} to indicate that the location should be disconnected
-     * from its parent.
-     * 
-     * Adds this location as a child of the new parent (see {@code getChildLocations()}).
-     *
-     * @param newParent the new parent location object, or {@code null} to clear the parent reference.
-     * @since 0.6 (previously setParentLocation(Location))
-     */
-    void setParent(Location newParent);
-
-    /**
-     * @return meta-data about the location (usually a long line, or a small number of lines).
-     * 
-     * @since 0.6
-     */
-    String toVerboseString();
-    
-    /**
-     * Answers true if this location equals or is an ancestor of the given location.
-     */
-    boolean containsLocation(Location potentialDescendent);
-
-    /** 
-     * Returns configuration set at this location or inherited or default.
-     * 
-     * Convenience method for {@code config().get(key)}
-     */
-    <T> T getConfig(ConfigKey<T> key);
-
-    /**
-     * Convenience method for {@code config().get(key)}
-     * 
-     * @see {@link #getConfig(ConfigKey)}
-     */
-    <T> T getConfig(HasConfigKey<T> key);
-
-    /** 
-     * True iff the indication config key is set, either inherited (second argument true) or locally-only (second argument false).
-     * 
-     * @deprecated since 0.7.0; use {@link #config()}, such as {@code ((LocationInternal)location).config().getRaw(key).isPresent()}
-     */
-    @Deprecated
-    boolean hasConfig(ConfigKey<?> key, boolean includeInherited);
-
-    /** 
-     * Returns all config set, either inherited (argument true) or locally-only (argument false).
-     * 
-     * @deprecated since 0.7.0; use {@link #config()}, such as {@code policy.config().getBag()}
-     */
-    @Deprecated
-    public Map<String,Object> getAllConfig(boolean includeInherited);
-    
-    /**
-     * Whether this location has support for the given extension type.
-     * See additional comments in {@link #getExtension(Class)}.
-     * 
-     * @throws NullPointerException if extensionType is null
-     */
-    boolean hasExtension(Class<?> extensionType);
-
-    /**
-     * Returns an extension of the given type. Note that the type must be an exact match for
-     * how the extension was registered (e.g. {@code getExtension(Object.class)} will not match
-     * anything, even though registered extension extend {@link Object}.
-     * <p>
-     * This will not look at extensions of {@link #getParent()}.
-     * 
-     * @throws IllegalArgumentException if this location does not support the given extension type
-     * @throws NullPointerException if extensionType is null
-     */
-    <T> T getExtension(Class<T> extensionType);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/LocationDefinition.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationDefinition.java b/api/src/main/java/org/apache/brooklyn/location/LocationDefinition.java
deleted file mode 100644
index 3dd58f6..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/LocationDefinition.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-
-/**
- * Defines a location, where the {@link #getSpec()} is like a serialized representation
- * of the location so that Brooklyn can create a corresponding location.
- * 
- * Examples include a complete description (e.g. giving a list of machines in a pool), or
- * a name that matches a named location defined in the brooklyn poperties.
- * 
- * Users are not expected to implement this, or to use the interface directly. See
- * {@link LocationRegistry#resolve(String)} and {@link ManagementContext#getLocationRegistry()}.
- */
-public interface LocationDefinition {
-
-    public String getId();
-    public String getName();
-    public String getSpec();
-    public Map<String,Object> getConfig();
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/LocationNotAvailableException.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationNotAvailableException.java b/api/src/main/java/org/apache/brooklyn/location/LocationNotAvailableException.java
deleted file mode 100644
index 543fb36..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/LocationNotAvailableException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-
-/**
- * Indicates that a {@link ProvisioningLocation} is not able to provision a requested location
- */
-public class LocationNotAvailableException extends Exception {
-    private static final long serialVersionUID = 1079817235289265761L;
-    
-    public LocationNotAvailableException(String s) {
-        super(s);
-    }
-
-    public LocationNotAvailableException(String s, Throwable throwable) {
-        super(s, throwable);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/LocationRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationRegistry.java b/api/src/main/java/org/apache/brooklyn/location/LocationRegistry.java
deleted file mode 100644
index 83096d1..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/LocationRegistry.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.annotation.Nullable;
-
-import brooklyn.util.guava.Maybe;
-
-import com.google.common.annotations.Beta;
-
-/**
- * The registry of the sorts of locations that brooklyn knows about. Given a
- * {@LocationDefinition} or a {@link String} representation of a spec, this can
- * be used to create a {@link Location} instance.
- */
-@SuppressWarnings("rawtypes")
-public interface LocationRegistry {
-
-    /** map of ID (possibly randomly generated) to the definition (spec, name, id, and props; 
-     * where spec is the spec as defined, for instance possibly another named:xxx location) */
-    public Map<String,LocationDefinition> getDefinedLocations();
-    
-    /** returns a LocationDefinition given its ID (usually a random string), or null if none */
-    public LocationDefinition getDefinedLocationById(String id);
-    
-    /** returns a LocationDefinition given its name (e.g. for named locations, supply the bit after the "named:" prefix), 
-     * or null if none */
-    public LocationDefinition getDefinedLocationByName(String name);
-
-    /** adds or updates the given defined location */
-    public void updateDefinedLocation(LocationDefinition l);
-
-    /** removes the defined location from the registry (applications running there are unaffected) */
-    public void removeDefinedLocation(String id);
-
-    /** Returns a fully populated (config etc) location from the given definition, with optional add'l flags.
-     * the location will be managed by default, unless the manage parameter is false, 
-     * or the manage parameter is null and the CREATE_UNMANAGED flag is set.
-     * <p>
-     * The manage parameter is {@link Boolean} so that null can be used to say rely on anything in the flags.
-     * 
-     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
-    @Beta
-    public Maybe<Location> resolve(LocationDefinition ld, Boolean manage, Map locationFlags);
-    
-    /** As {@link #resolve(LocationDefinition, Boolean, Map), with the location managed, and no additional flags,
-     * unwrapping the result (throwing if not resolvable) */
-    public Location resolve(LocationDefinition l);
-
-    /** Returns a location created from the given spec, which might correspond to a definition, or created on-the-fly.
-     * Optional flags can be passed through to underlying the location. 
-     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
-    @Beta
-    public Maybe<Location> resolve(String spec, Boolean manage, Map locationFlags);
-    
-    /** efficiently returns for inspection only a fully populated (config etc) location from the given definition; 
-     * the value might be unmanaged so it is not meant for any use other than inspection,
-     * but callers should prefer this when they don't wish to create a new location which will be managed in perpetuity!
-     * 
-     * @deprecated since 0.7.0, use {@link #resolve(LocationDefinition, Boolean, Map)} */
-    @Deprecated
-    public Location resolveForPeeking(LocationDefinition l);
-
-    /** returns fully populated (config etc) location from the given definition, with overrides;
-     * @deprecated since 0.7.0, use {@link #resolve(LocationDefinition, Boolean, Map)} */
-    @Deprecated
-    public Location resolve(LocationDefinition l, Map<?,?> locationFlags);
-    
-    /** See {@link #resolve(String, Boolean, Map)}; asks for the location to be managed, and supplies no additional flags,
-     * and unwraps the result (throwing if the spec cannot be resolve) */
-    public Location resolve(String spec);
-    
-    /** Returns true/false depending whether spec seems like a valid location,
-     * that is it has a chance of being resolved (depending on the spec) but NOT guaranteed,
-     * as it is not passed to the spec;
-     * see {@link #resolve(String, Boolean, Map)} which has stronger guarantees 
-     * @deprecated since 0.7.0, not really needed, and semantics are weak; use {@link #resolve(String, Boolean, Map)} */
-    @Deprecated
-    public boolean canMaybeResolve(String spec);
-    
-    /** As {@link #resolve(String, Boolean, Map)}, but unwrapped
-     * @throws NoSuchElementException if the spec cannot be resolved */
-    public Location resolve(String spec, @Nullable Map locationFlags);
-    
-    /** as {@link #resolve(String)} but returning null (never throwing)
-     * @deprecated since 0.7.0 use {@link #resolve(String, Boolean, Map)} */
-    @Deprecated
-    public Location resolveIfPossible(String spec);
-
-    /**
-     * As {@link #resolve(String)} but takes collections (of strings or locations)
-     * <p>
-     * Expects a collection of elements being individual location spec strings or locations, 
-     * and returns a list of resolved (newly created and managed) locations.
-     * <p>
-     * From 0.7.0 this no longer flattens lists (nested lists are disallowed) 
-     * or parses comma-separated elements (they are resolved as-is)
-     */
-    public List<Location> resolve(Iterable<?> spec);
-    
-    /** Takes a string, interpreted as a comma-separated (or JSON style, when you need internal double quotes or commas) list;
-     * or a list, passed to {@link #resolve(Iterable)}; or null/empty (empty list),
-     * and returns a list of resolved (created and managed) locations */
-    public List<Location> resolveList(Object specList);
-    
-    public Map getProperties();
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/LocationResolver.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationResolver.java b/api/src/main/java/org/apache/brooklyn/location/LocationResolver.java
deleted file mode 100644
index 1b9bd18..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/LocationResolver.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Provides a way of creating location instances of a particular type.
- */
-public interface LocationResolver {
-
-    void init(ManagementContext managementContext);
-    
-    /** the prefix that this resolver will attend to */
-    String getPrefix();
-    
-    /** whether the spec is something which should be passed to this resolver */
-    boolean accepts(String spec, LocationRegistry registry);
-
-    /**
-     * Similar to {@link #newLocationFromString(Map, String)} 
-     * but passing in a reference to the registry itself (from which the base properties are discovered)
-     * and including flags (e.g. user, key, cloud credential) which are known to be for this location.
-     * <p>
-     * introduced to support locations which refer to other locations, e.g. NamedLocationResolver  
-     **/ 
-    @SuppressWarnings("rawtypes")
-    Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry);
-
-    /** @since 0.7.0 exploring this as a mechanism to disable locations */
-    @Beta
-    public interface EnableableLocationResolver extends LocationResolver {
-        /** whether the location is enabled */
-        boolean isEnabled();
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/LocationSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationSpec.java b/api/src/main/java/org/apache/brooklyn/location/LocationSpec.java
deleted file mode 100644
index 6713cb7..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/LocationSpec.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.brooklyn.api.basic.AbstractBrooklynObjectSpec;
-import org.apache.brooklyn.api.management.Task;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-
-import com.google.common.collect.Maps;
-
-/**
- * Gives details of a location to be created. It describes the location's configuration, and is
- * reusable to create multiple locations with the same configuration.
- * 
- * To create a LocationSpec, it is strongly encouraged to use {@code create(...)} methods.
- * 
- * @param <T> The type of location to be created
- * 
- * @author aled
- */
-public class LocationSpec<T extends Location> extends AbstractBrooklynObjectSpec<T,LocationSpec<T>> {
-
-    // TODO Would like to add `configure(ConfigBag)`, but `ConfigBag` is in core rather than api
-    
-    private static final Logger log = LoggerFactory.getLogger(LocationSpec.class);
-
-    private final static long serialVersionUID = 1L;
-
-    /**
-     * Creates a new {@link LocationSpec} instance for a location of the given type. The returned 
-     * {@link LocationSpec} can then be customized.
-     * 
-     * @param type A {@link Location} class
-     */
-    public static <T extends Location> LocationSpec<T> create(Class<T> type) {
-        return new LocationSpec<T>(type);
-    }
-    
-    /**
-     * Creates a new {@link LocationSpec} instance with the given config, for a location of the given type.
-     * 
-     * This is primarily for groovy code; equivalent to {@code LocationSpec.create(type).configure(config)}.
-     * 
-     * @param config The spec's configuration (see {@link LocationSpec#configure(Map)}).
-     * @param type   A {@link Location} class
-     */
-    public static <T extends Location> LocationSpec<T> create(Map<?,?> config, Class<T> type) {
-        return LocationSpec.create(type).configure(config);
-    }
-    
-    /**
-     * Copies entity spec so its configuration can be overridden without modifying the 
-     * original entity spec.
-     */
-    public static <T extends Location> LocationSpec<T> create(LocationSpec<T> spec) {
-        // need this to get LocationSpec<T> rather than LocationSpec<? extends T>
-        @SuppressWarnings("unchecked")
-        Class<T> exactType = (Class<T>)spec.getType();
-        
-        LocationSpec<T> result = create(exactType)
-                .displayName(spec.getDisplayName())
-                .tags(spec.getTags())
-                .configure(spec.getConfig())
-                .configure(spec.getFlags())
-                .catalogItemId(spec.getCatalogItemId())
-                .extensions(spec.getExtensions());
-        
-        if (spec.getParent() != null) result.parent(spec.getParent());
-        
-        return (LocationSpec<T>) result;
-    }
-
-    private String id;
-    private Location parent;
-    private final Map<String, Object> flags = Maps.newLinkedHashMap();
-    private final Map<ConfigKey<?>, Object> config = Maps.newLinkedHashMap();
-    private final Map<Class<?>, Object> extensions = Maps.newLinkedHashMap();
-
-    protected LocationSpec(Class<T> type) {
-        super(type);
-    }
-     
-    protected void checkValidType(Class<? extends T> type) {
-        checkIsImplementation(type, Location.class);
-        checkIsNewStyleImplementation(type);
-    }
-
-    /**
-     * @deprecated since 0.7.0; instead let the management context pick a random+unique id
-     */
-    @Deprecated
-    public LocationSpec<T> id(String val) {
-        id = val;
-        return this;
-    }
-
-    public LocationSpec<T> parent(Location val) {
-        parent = checkNotNull(val, "parent");
-        return this;
-    }
-
-    public LocationSpec<T> configure(Map<?,?> val) {
-        for (Map.Entry<?, ?> entry: val.entrySet()) {
-            if (entry.getKey()==null) throw new NullPointerException("Null key not permitted");
-            if (entry.getKey() instanceof CharSequence)
-                flags.put(entry.getKey().toString(), entry.getValue());
-            else if (entry.getKey() instanceof ConfigKey<?>)
-                config.put((ConfigKey<?>)entry.getKey(), entry.getValue());
-            else if (entry.getKey() instanceof HasConfigKey<?>)
-                config.put(((HasConfigKey<?>)entry.getKey()).getConfigKey(), entry.getValue());
-            else {
-                log.warn("Spec "+this+" ignoring unknown config key "+entry.getKey());
-            }
-        }
-        return this;
-    }
-    
-    public LocationSpec<T> configure(CharSequence key, Object val) {
-        flags.put(checkNotNull(key, "key").toString(), val);
-        return this;
-    }
-    
-    public <V> LocationSpec<T> configure(ConfigKey<V> key, V val) {
-        config.put(checkNotNull(key, "key"), val);
-        return this;
-    }
-
-    public <V> LocationSpec<T> configureIfNotNull(ConfigKey<V> key, V val) {
-        return (val != null) ? configure(key, val) : this;
-    }
-
-    public <V> LocationSpec<T> configure(ConfigKey<V> key, Task<? extends V> val) {
-        config.put(checkNotNull(key, "key"), val);
-        return this;
-    }
-
-    public <V> LocationSpec<T> configure(HasConfigKey<V> key, V val) {
-        config.put(checkNotNull(key, "key").getConfigKey(), val);
-        return this;
-    }
-
-    public <V> LocationSpec<T> configure(HasConfigKey<V> key, Task<? extends V> val) {
-        config.put(checkNotNull(key, "key").getConfigKey(), val);
-        return this;
-    }
-
-    public <V> LocationSpec<T> removeConfig(ConfigKey<V> key) {
-        config.remove( checkNotNull(key, "key") );
-        return this;
-    }
-
-    public <E> LocationSpec<T> extension(Class<E> extensionType, E extension) {
-        extensions.put(checkNotNull(extensionType, "extensionType"), checkNotNull(extension, "extension"));
-        return this;
-    }
-    
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public <E> LocationSpec<T> extensions(Map<Class<?>, ?> extensions) {
-        for (Map.Entry<Class<?>, ?> entry : extensions.entrySet()) {
-            extension((Class)entry.getKey(), entry.getValue());
-        }
-        return this;
-    }
-    
-    /**
-     * @return The id of the location to be created, or null if brooklyn can auto-generate an id
-     * 
-     * @deprecated since 0.7.0; instead let the management context pick a random+unique id
-     */
-    @Deprecated
-    public String getId() {
-        return id;
-    }
-    
-    /**
-     * @return The location's parent
-     */
-    public Location getParent() {
-        return parent;
-    }
-    
-    /**
-     * @return Read-only construction flags
-     * @see SetFromFlag declarations on the location type
-     */
-    public Map<String, ?> getFlags() {
-        return Collections.unmodifiableMap(flags);
-    }
-    
-    /**
-     * @return Read-only configuration values
-     */
-    public Map<ConfigKey<?>, Object> getConfig() {
-        return Collections.unmodifiableMap(config);
-    }
-        
-    /**
-     * @return Read-only extension values
-     */
-    public Map<Class<?>, Object> getExtensions() {
-        return Collections.unmodifiableMap(extensions);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/LocationType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationType.java b/api/src/main/java/org/apache/brooklyn/location/LocationType.java
deleted file mode 100644
index d7b52ed..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/LocationType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import org.apache.brooklyn.api.basic.BrooklynType;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Gives type information for a {@link Location}. It is immutable.
- 
- * @since 0.7.0
- */
-@Beta
-public interface LocationType extends BrooklynType {
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/MachineDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineDetails.java b/api/src/main/java/org/apache/brooklyn/location/MachineDetails.java
deleted file mode 100644
index c72d6d9..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/MachineDetails.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import javax.annotation.Nonnull;
-
-/**
- * @since 0.7.0
- */
-public interface MachineDetails {
-
-    @Nonnull
-    HardwareDetails getHardwareDetails();
-
-    @Nonnull
-    OsDetails getOsDetails();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/MachineLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineLocation.java b/api/src/main/java/org/apache/brooklyn/location/MachineLocation.java
deleted file mode 100644
index aef8d04..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/MachineLocation.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.net.InetAddress;
-
-import brooklyn.util.net.HasNetworkAddresses;
-
-/**
- * A location that is a machine.
- *
- * This interface marks a {@link Location} being a network node with an IP address, 
- * and supports appropriate operations on the node.
- */
-public interface MachineLocation extends AddressableLocation, HasNetworkAddresses {
-    /**
-     * @return the machine's network address.
-     */
-    InetAddress getAddress();
-
-    /** @deprecated since 0.7.0. Use getMachineDetails().getOsDetails() instead. */
-    @Deprecated
-    OsDetails getOsDetails();
-
-    /*
-     * @return hardware and operating system-specific details for the machine.
-     */
-    MachineDetails getMachineDetails();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/MachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineLocationCustomizer.java b/api/src/main/java/org/apache/brooklyn/location/MachineLocationCustomizer.java
deleted file mode 100644
index 1c81896..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/MachineLocationCustomizer.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Customization hooks to allow apps to perform specific customisation of obtained machines.
- * <p>
- * Users are strongly encouraged to sub-class {@link BasicMachineLocationCustomizer}, to give
- * some protection against this {@link Beta} API changing in future releases.
- */
-@Beta
-public interface MachineLocationCustomizer {
-
-    /**
-     * Override to configure the given machine once it has been created (prior to any use).
-     */
-    void customize(MachineLocation machine);
-    
-    /**
-     * Override to handle machine-related cleanup prior to {@link MachineProvisioningLocation} 
-     * releasing the machine.
-     */
-    void preRelease(MachineLocation machine);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/MachineManagementMixins.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineManagementMixins.java b/api/src/main/java/org/apache/brooklyn/location/MachineManagementMixins.java
deleted file mode 100644
index 7e0de8a..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/MachineManagementMixins.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.util.Map;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Defines mixins for interesting locations.
- */
-public class MachineManagementMixins {
-    
-    public interface RichMachineProvisioningLocation<T extends MachineLocation> extends
-            MachineProvisioningLocation<T>, ListsMachines, GivesMachineMetadata, KillsMachines {}
-
-    public interface ListsMachines {
-        /**
-         * @return A map of machine ID to metadata record for all machines known in a given cloud location.
-         */
-        Map<String,MachineMetadata> listMachines();
-    }
-    
-    public interface GivesMachineMetadata {
-        /**
-         * @return the {@link MachineMetadata} for a given (brooklyn) machine location instance,
-         * or null if not matched.
-         */
-        MachineMetadata getMachineMetadata(MachineLocation location);
-    }
-    
-    public interface KillsMachines {
-        /** Kills the indicated machine; throws if not recognised or possible */
-        void killMachine(MachineLocation machine);
-        
-        /** Kills the machine indicated by the given (server-side) machine id;
-         *  note, the ID is the _cloud-service_ ID,
-         *  that is, pass in getMetadata(machineLocation).getId() not the machineLocation.getId() */
-        void killMachine(String cloudServiceId);
-    }
-    
-    /** very lightweight machine record */
-    public interface MachineMetadata {
-        /** The cloud service ID -- distinct from any Brooklyn {@link Location#getId()} */
-        String getId();
-        String getName();
-        String getPrimaryIp();
-        Boolean isRunning();
-        /** original metadata object, if available; e.g. ComputeMetadata when using jclouds */ 
-        Object getOriginalMetadata();
-    }
-
-    /**
-     * Implement to indicate that a location can suspend and resume machines.
-     */
-    @Beta
-    public interface SuspendResumeLocation extends SuspendsMachines, ResumesMachines {};
-
-
-    @Beta
-    public interface SuspendsMachines {
-        /**
-         * Suspend the indicated machine.
-         */
-        void suspendMachine(MachineLocation location);
-    }
-
-    @Beta
-    public interface ResumesMachines {
-        /**
-         * Resume the indicated machine.
-         */
-        void resumeMachine(MachineLocation location);
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/MachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineProvisioningLocation.java b/api/src/main/java/org/apache/brooklyn/location/MachineProvisioningLocation.java
deleted file mode 100644
index c3bc346..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/MachineProvisioningLocation.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * A location that is able to provision new machines within its location.
- *
- * This interface extends {@link Location} to add the ability to provision {@link MachineLocation}s in this location.
- */
-public interface MachineProvisioningLocation<T extends MachineLocation> extends ProvisioningLocation<T> {
-    /**
-     * Obtain a machine in this location.
-     * 
-     * @param flags Details of the desired machine (e.g. image, size, open ports, etc; some flag support is limited to selected providers).
-     * "callerContext" can be specified to have custom logging and error messages (useful if starting machines in parallel)
-     * @return a machine that is a child of this location.
-     * @throws NoMachinesAvailableException if there are no machines available in this location (or impls may return null, but that is discouraged)
-     */
-    @Override
-    T obtain(Map<?,?> flags) throws NoMachinesAvailableException;
-
-    /**
-     * Creates a new location of the same type, but with additional creation instructions in the form of flags,
-     * e.g. for specifying subnets, security groups, etc
-     * <p>
-     * Implementers who wish to subclass this provisioning location for additional functionality
-     * in a specific cloud can use the relevant implementation of this method as a guide. 
-     */
-    MachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags);
-    
-    /**
-     * Release a previously-obtained machine.
-     *
-     * @param machine a {@link MachineLocation} previously obtained from a call to {@link #obtain()}
-     * @throws IllegalStateException if the machine did not come from a call to {@link #obtain()} or it has already been released.
-     */
-    @Override
-    void release(T machine);
-    
-    /**
-     * Gets flags, suitable as an argument to {@link #obtain(Map)}. The tags provided give
-     * hints about the machine required. The provisioning-location could be configured to 
-     * understand those tags. 
-     * 
-     * For example, an AWS-location could be configured to understand that a particular entity
-     * type (e.g. "TomcatServer") requires a particular AMI in that region, so would return the 
-     * required image id.
-     *  
-     * @param tags
-     * @return
-     */
-    Map<String,Object> getProvisioningFlags(Collection<String> tags);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/NoMachinesAvailableException.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/NoMachinesAvailableException.java b/api/src/main/java/org/apache/brooklyn/location/NoMachinesAvailableException.java
deleted file mode 100644
index d8f16ce..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/NoMachinesAvailableException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-
-/**
- * Indicates no machines are available in a given location.
- */
-public class NoMachinesAvailableException extends LocationNotAvailableException {
-    private static final long serialVersionUID = 1079817235289265761L;
-    
-    public NoMachinesAvailableException(String s) {
-        super(s);
-    }
-
-    public NoMachinesAvailableException(String s, Throwable throwable) {
-        super(s, throwable);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/OsDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/OsDetails.java b/api/src/main/java/org/apache/brooklyn/location/OsDetails.java
deleted file mode 100644
index c5aea67..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/OsDetails.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import javax.annotation.Nullable;
-
-public interface OsDetails {
-
-    /** The name of the operating system, e.g. "Debian" or "Red Hat Enterprise Linux Server" */
-    @Nullable
-    String getName();
-
-    /**
-     * The version of the operating system. Generally numeric (e.g. "6.3") but occasionally
-     * alphabetic (e.g. Debian's "Squeeze").
-     */
-    @Nullable
-    String getVersion();
-
-    /** The operating system's architecture, e.g. "x86" or "x86_64" */
-    @Nullable
-    String getArch();
-
-    boolean is64bit();
-
-    boolean isWindows();
-    boolean isLinux();
-    boolean isMac();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/PortRange.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/PortRange.java b/api/src/main/java/org/apache/brooklyn/location/PortRange.java
deleted file mode 100644
index 25dd621..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/PortRange.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-/**
- * A range of ports (indicator for Location and other APIs).
- * Using methods {@code PortRanges.fromXxx(...)} this is adaptable from a number, a string, or a collection of numbers or a strings.
- * String may be of the form:
- *   <li> "80": just 80
- *   <li> "8080-8090": limited range sequentially; ie try 8080, then 8081, ..., then 8090, then give up
- *   <li> "8080-8000": as above, but descending; ie try 8080, then 8079, ..., then 8000, then give up
- *   <li> "8000+": unlimited range sequentially; ie try 8000, then 8001, then 8002, etc
- *   <li> "80,8080,8000,8080-8099": different ranges, in order; ie try 80, then 8080, then 8000, then 8080 (again), then 8081, ..., then 8099, then give up
- * Ranges (but not lists) may be preceeded by "!" to indicate a randomly selected port:
- * 
- * @see brooklyn.location.basic.PortRanges
- */
-//MAYDO could have:   <li> "~32168-65535" (or "~32168-"): try randomly selected numbers in range 32168-65535 (MAX_PORT) until all have been tried
-public interface PortRange extends Iterable<Integer> {
-    /**
-     * Whether there are any ports in the range.
-     */
-    boolean isEmpty();
-    
-    /**
-     * Note: this method is only here for use with "groovy truth". Users are strongly discouraged  
-     * from calling it directly.
-     *  
-     * @return {@code !isEmpty()}; i.e. true if there is at least one port in the range; false otherwise
-     */
-    boolean asBoolean();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/PortSupplier.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/PortSupplier.java b/api/src/main/java/org/apache/brooklyn/location/PortSupplier.java
deleted file mode 100644
index 24572a0..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/PortSupplier.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-/** Mixin interface for location which allows it to supply ports from a given range */
-public interface PortSupplier {
-
-    /**
-     * Reserve a specific port for an application. If your application requires a specific port - for example, port 80 for a web
-     * server - you should reserve this port before starting your application. Using this method, you will be able to detect if
-     * another application has already claimed this port number.
-     *
-     * @param portNumber the required port number.
-     * @return {@code true} if the port was successfully reserved; {@code false} if it has been previously reserved.
-     */
-    boolean obtainSpecificPort(int portNumber);
-
-    /**
-     * Reserve a port for your application, with a port number in a specific range. If your application requires a port, but it does
-     * not mind exactly which port number - for example, a port for internal JMX monitoring - call this method.
-     *
-     * @param range the range of acceptable port numbers.
-     * @return the port number that has been reserved, or -1 if there was no available port in the acceptable range.
-     */
-    int obtainPort(PortRange range);
-
-    /**
-     * Release a previously reserved port.
-     *
-     * @param portNumber the port number from a call to {@link #obtainPort(PortRange)} or {@link #obtainSpecificPort(int)}
-     */
-    void releasePort(int portNumber);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/location/ProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/ProvisioningLocation.java b/api/src/main/java/org/apache/brooklyn/location/ProvisioningLocation.java
deleted file mode 100644
index 3cc3f92..0000000
--- a/api/src/main/java/org/apache/brooklyn/location/ProvisioningLocation.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.apache.brooklyn.location;
-
-import java.util.Map;
-
-/**
- * A location that is able to provision new locations within it.
- */
-public interface ProvisioningLocation<T extends Location> extends Location {
-    /**
-     * Obtain a new (sub)-location in the location represented by this class.
-     * 
-     * @param flags Constraints and details of the location to be provisioned
-     * @return the location provisioned
-     * @throws LocationNotAvailableException if could not provision such a location
-     */
-    T obtain(Map<?,?> flags) throws LocationNotAvailableException;
-
-    /**
-     * Release a previously-obtained location.
-     *
-     * @param location a location previously obtained
-     * @throws IllegalStateException if the machine did not come from a call to {@link #obtain()} or it has already been released.
-     */
-    void release(T machine);
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java b/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java
index 8c6f7e1..4727f50 100644
--- a/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java
+++ b/api/src/main/java/org/apache/brooklyn/mementos/BrooklynMementoPersister.java
@@ -33,11 +33,11 @@ import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.PersistenceExceptionHandler;
 import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.time.Duration;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/basic/BrooklynTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypes.java b/core/src/main/java/brooklyn/basic/BrooklynTypes.java
index 4ccbfd0..4423bed 100644
--- a/core/src/main/java/brooklyn/basic/BrooklynTypes.java
+++ b/core/src/main/java/brooklyn/basic/BrooklynTypes.java
@@ -23,13 +23,13 @@ import java.util.Map;
 import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.enricher.basic.EnricherDynamicType;
 import brooklyn.entity.basic.EntityDynamicType;
-import org.apache.brooklyn.location.Location;
 import brooklyn.policy.basic.PolicyDynamicType;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/CatalogPredicates.java b/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
index e9778ab..e8e0e7e 100644
--- a/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
+++ b/core/src/main/java/brooklyn/catalog/CatalogPredicates.java
@@ -25,13 +25,13 @@ import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.policy.Policy;
 import org.apache.brooklyn.policy.PolicySpec;
 
 import brooklyn.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
 import brooklyn.management.entitlement.Entitlements;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
index a3bb808..5dec71b 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -46,6 +46,8 @@ import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.policy.Policy;
@@ -54,9 +56,9 @@ import org.apache.brooklyn.policy.PolicySpec;
 import brooklyn.catalog.CatalogPredicates;
 import brooklyn.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
 import brooklyn.config.BrooklynServerConfig;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
+
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java b/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
index af0e53d..af0713a 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogClasspathDo.java
@@ -36,10 +36,10 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.Policy;
 
 import brooklyn.entity.basic.ApplicationBuilder;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java b/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
index 8d12b1a..da185f2 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogLocationItemDto.java
@@ -18,8 +18,8 @@
  */
 package brooklyn.catalog.internal;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 
 
 public class CatalogLocationItemDto extends CatalogItemDtoAbstract<Location,LocationSpec<?>> {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java b/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java
index 0e570b7..65ef309 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractApplication.java
@@ -23,13 +23,13 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.trait.StartableMethods;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.RuntimeInterruptedException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
index db1c26f..09d41c6 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -40,6 +40,7 @@ import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.Sensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.EntityManager;
 import org.apache.brooklyn.api.management.ExecutionContext;
 import org.apache.brooklyn.api.management.ManagementContext;
@@ -76,8 +77,9 @@ import brooklyn.internal.BrooklynInitialization;
 import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.internal.storage.Reference;
 import brooklyn.internal.storage.impl.BasicReference;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.Locations;
+
 import brooklyn.management.internal.EffectorUtils;
 import brooklyn.management.internal.EntityManagementSupport;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/BasicStartable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/BasicStartable.java b/core/src/main/java/brooklyn/entity/basic/BasicStartable.java
index 00d87c3..7f8722f 100644
--- a/core/src/main/java/brooklyn/entity/basic/BasicStartable.java
+++ b/core/src/main/java/brooklyn/entity/basic/BasicStartable.java
@@ -22,10 +22,11 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.Locations;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java b/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java
index 630bdd8..e4a59f9 100644
--- a/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java
+++ b/core/src/main/java/brooklyn/entity/basic/BasicStartableImpl.java
@@ -23,6 +23,7 @@ import java.util.Collection;
 import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.location.basic.Locations;
 import org.slf4j.Logger;
@@ -30,7 +31,6 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Predicates;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java b/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
index ac3de30..7910267 100644
--- a/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
+++ b/core/src/main/java/brooklyn/entity/basic/BrooklynConfigKeys.java
@@ -24,7 +24,9 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.basic.TemplatedStringAttributeSensorAndConfigKey;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
+
 import brooklyn.util.internal.ssh.ShellTool;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.time.Duration;



[52/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java b/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
index 52ba52e..bd33a17 100644
--- a/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
+++ b/core/src/main/java/brooklyn/entity/basic/DataEntityImpl.java
@@ -22,10 +22,10 @@ import java.util.Collection;
 import java.util.Map;
 
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Functions;
 import com.google.common.base.Supplier;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java b/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java
index 1bbb4c1..0abb90c 100644
--- a/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java
+++ b/core/src/main/java/brooklyn/entity/basic/EffectorStartableImpl.java
@@ -27,7 +27,9 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.annotation.Effector;
 import brooklyn.entity.annotation.EffectorParam;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
+
 import brooklyn.util.config.ConfigBag;
 
 import com.google.common.reflect.TypeToken;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/Entities.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/Entities.java b/core/src/main/java/brooklyn/entity/basic/Entities.java
index c1cac26..45be84b 100644
--- a/core/src/main/java/brooklyn/entity/basic/Entities.java
+++ b/core/src/main/java/brooklyn/entity/basic/Entities.java
@@ -49,6 +49,8 @@ import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ExecutionContext;
 import org.apache.brooklyn.api.management.LocationManager;
 import org.apache.brooklyn.api.management.ManagementContext;
@@ -69,10 +71,10 @@ import brooklyn.entity.proxying.EntityProxyImpl;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
 import brooklyn.event.basic.DependentConfiguration;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocationInternal;
 import org.apache.brooklyn.location.basic.Locations;
+
 import brooklyn.management.internal.EffectorUtils;
 import brooklyn.management.internal.EntityManagerInternal;
 import brooklyn.management.internal.LocalManagementContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java b/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java
index eb7ef3a..c4dfa44 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityFactoryForLocation.java
@@ -19,8 +19,7 @@
 package brooklyn.entity.basic;
 
 import org.apache.brooklyn.api.entity.Entity;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * dispatch interface to allow an EntityFactory to indicate it might be able to discover

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java b/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
index 1250d40..4e02948 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityFunctions.java
@@ -28,10 +28,10 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.trait.Identifiable;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 
 import brooklyn.config.ConfigKey;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Functionals;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java b/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
index 08c3e19..3a8b22b 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
@@ -27,6 +27,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.rebind.RebindSupport;
 import org.apache.brooklyn.api.entity.rebind.Rebindable;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ExecutionContext;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.SubscriptionContext;
@@ -34,7 +35,6 @@ import org.apache.brooklyn.mementos.EntityMemento;
 
 import brooklyn.basic.BrooklynObjectInternal;
 import brooklyn.config.ConfigKey;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.EntityManagementSupport;
 import brooklyn.util.config.ConfigBag;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java b/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java
index 7c7d2f3..892afc7 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityPredicates.java
@@ -26,10 +26,10 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.guava.SerializablePredicate;
 import brooklyn.util.javalang.Reflections;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java b/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java
index 70a1667..1f60c41 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityTransientCopyInternal.java
@@ -31,6 +31,7 @@ import org.apache.brooklyn.api.entity.EntityType;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.rebind.RebindSupport;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ExecutionContext;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.mementos.EntityMemento;
@@ -41,7 +42,6 @@ import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
 import brooklyn.entity.basic.EntityInternal.FeedSupport;
 import brooklyn.entity.proxying.EntityProxyImpl;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.EntityManagementSupport;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/basic/Lifecycle.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/Lifecycle.java b/core/src/main/java/brooklyn/entity/basic/Lifecycle.java
index 75b32b4..9bb0177 100644
--- a/core/src/main/java/brooklyn/entity/basic/Lifecycle.java
+++ b/core/src/main/java/brooklyn/entity/basic/Lifecycle.java
@@ -31,7 +31,8 @@ import com.google.common.base.CaseFormat;
 import com.google.common.base.Function;
 import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * An enumeration representing the status of an {@link org.apache.brooklyn.api.entity.Entity}.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java b/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java
index 889a05a..afdce06 100644
--- a/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java
+++ b/core/src/main/java/brooklyn/entity/drivers/BasicEntityDriverManager.java
@@ -21,11 +21,10 @@ package brooklyn.entity.drivers;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
 import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.annotations.Beta;
 
-import org.apache.brooklyn.location.Location;
-
 public class BasicEntityDriverManager implements EntityDriverManager {
 
     private final RegistryEntityDriverFactory registry;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java b/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java
index 86591b3..0def1c9 100644
--- a/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java
+++ b/core/src/main/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactory.java
@@ -25,13 +25,13 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.paas.PaasLocation;
 import org.apache.brooklyn.location.basic.WinRmMachineLocation;
+
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java b/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java
index 2c1243f..abbc2a6 100644
--- a/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java
+++ b/core/src/main/java/brooklyn/entity/drivers/RegistryEntityDriverFactory.java
@@ -29,8 +29,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
 import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Throwables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/DynamicCluster.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicCluster.java b/core/src/main/java/brooklyn/entity/group/DynamicCluster.java
index e6f31de..ab14f49 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicCluster.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicCluster.java
@@ -28,6 +28,7 @@ import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.annotation.Effector;
@@ -45,7 +46,6 @@ import brooklyn.entity.trait.MemberReplaceable;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.basic.BasicNotificationSensor;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
index eafb161..ba487de 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
@@ -34,6 +34,8 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.policy.Policy;
 import org.slf4j.Logger;
@@ -52,10 +54,10 @@ import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.Locations;
 import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java b/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java
index 60f437e..da31efd 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicFabricImpl.java
@@ -30,6 +30,7 @@ import java.util.concurrent.ExecutionException;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -45,7 +46,6 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.trait.Changeable;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.GroovyJavaMethods;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java b/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java
index eeab8e2..c3d3ac7 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicRegionsFabricImpl.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
 import java.util.Collection;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -29,7 +30,6 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java b/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java
index 62b07eb..02e87cf 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/AbstractZoneFailureDetector.java
@@ -24,9 +24,9 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.entity.group.DynamicCluster.ZoneFailureDetector;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Ticker;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java b/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java
index 700b0b5..35b580b 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategy.java
@@ -25,12 +25,12 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.group.DynamicCluster.NodePlacementStrategy;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java b/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java
index b7ea052..3db3e2a 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/CombiningZoneFailureDetector.java
@@ -21,9 +21,9 @@ package brooklyn.entity.group.zoneaware;
 import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.entity.group.DynamicCluster.ZoneFailureDetector;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java b/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java
index ecdf73f..7b2a167 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/CriticalCauseZoneFailureDetector.java
@@ -18,7 +18,8 @@
  */
 package brooklyn.entity.group.zoneaware;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
+
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java b/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java
index 13a9ed0..d3dc284 100644
--- a/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java
+++ b/core/src/main/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetector.java
@@ -18,7 +18,8 @@
  */
 package brooklyn.entity.group.zoneaware;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
+
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Ticker;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java b/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
index f44602f..58c7dfc 100644
--- a/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
+++ b/core/src/main/java/brooklyn/entity/proxying/InternalLocationFactory.java
@@ -22,13 +22,15 @@ import java.lang.reflect.InvocationTargetException;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 
 import brooklyn.config.ConfigKey;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationInternal;
+
 import brooklyn.management.internal.LocalLocationManager;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
index 29aa938..4fd14d8 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicEntityRebindSupport.java
@@ -29,6 +29,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.RebindContext;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.mementos.EntityMemento;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,7 +41,6 @@ import brooklyn.entity.basic.AbstractGroupImpl;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.dto.MementosGenerators;
 import brooklyn.event.feed.AbstractFeed;
-import org.apache.brooklyn.location.Location;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
index 1719eff..75cf659 100644
--- a/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/BasicLocationRebindSupport.java
@@ -24,14 +24,16 @@ import java.util.Map;
 import java.util.NoSuchElementException;
 
 import org.apache.brooklyn.api.entity.rebind.RebindContext;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.mementos.LocationMemento;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.rebind.dto.MementosGenerators;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.flags.FlagUtils;
 import brooklyn.util.flags.TypeCoercions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
index d92fa72..f830261 100644
--- a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
@@ -28,6 +28,7 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.rebind.ChangeListener;
 import org.apache.brooklyn.api.entity.rebind.PersistenceExceptionHandler;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.mementos.BrooklynMementoPersister;
 import org.apache.brooklyn.mementos.CatalogItemMemento;
 import org.apache.brooklyn.mementos.EnricherMemento;
@@ -37,8 +38,6 @@ import org.apache.brooklyn.mementos.Memento;
 import org.apache.brooklyn.mementos.PolicyMemento;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
-
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.location.basic.LocationInternal;
 
 import com.google.common.collect.Maps;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
index 538eaf4..0eb1993 100644
--- a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.ChangeListener;
 import org.apache.brooklyn.api.entity.rebind.PersistenceExceptionHandler;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ExecutionContext;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.mementos.BrooklynMementoPersister;
@@ -50,7 +51,6 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
 import brooklyn.entity.rebind.persister.PersistenceActivityMetrics;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java
index 4e0f887..745f030 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindContextImpl.java
@@ -29,12 +29,12 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.rebind.RebindContext;
 import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.mementos.BrooklynMementoPersister.LookupContext;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.Maps;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java b/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java
index f093089..8cd6e54 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindContextLookupContext.java
@@ -29,13 +29,13 @@ import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.RebindContext;
 import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.mementos.BrooklynMementoPersister.LookupContext;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
 import brooklyn.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.location.Location;
 
 /** Looks in {@link RebindContext} <i>and</i> {@link ManagementContext} to find entities, locations, etc. */
 public class RebindContextLookupContext implements LookupContext {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java b/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
index f08eb01..51b94ec 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindExceptionHandlerImpl.java
@@ -36,10 +36,10 @@ import org.apache.brooklyn.api.entity.rebind.RebindContext;
 import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
 import org.apache.brooklyn.api.entity.rebind.RebindManager.RebindFailureMode;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.QuorumCheck;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
index d27ea65..45f1457 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
@@ -46,6 +46,7 @@ import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.RebindContext;
 import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler;
 import org.apache.brooklyn.api.entity.rebind.RebindSupport;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.api.management.ha.ManagementNodeState;
 import org.apache.brooklyn.mementos.BrooklynMemento;
@@ -80,9 +81,10 @@ import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker;
 import brooklyn.entity.rebind.persister.PersistenceActivityMetrics;
 import brooklyn.event.feed.AbstractFeed;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationInternal;
+
 import brooklyn.management.internal.BrooklynObjectManagementMode;
 import brooklyn.management.internal.BrooklynObjectManagerInternal;
 import brooklyn.management.internal.EntityManagerInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java b/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java
index 983bb45..a48672a 100644
--- a/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java
+++ b/core/src/main/java/brooklyn/entity/rebind/TreeUtils.java
@@ -23,7 +23,7 @@ import java.util.Collection;
 import java.util.Deque;
 import java.util.Set;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.collect.Sets;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
index 1a5ae1f..5a8d146 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.AttributeSensor.SensorPersistenceMode;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.mementos.BrooklynMemento;
@@ -58,8 +59,9 @@ import brooklyn.entity.rebind.AbstractBrooklynObjectRebindSupport;
 import brooklyn.entity.rebind.TreeUtils;
 import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
 import brooklyn.event.feed.AbstractFeed;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocationInternal;
+
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
index c874060..a424a31 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
@@ -31,6 +31,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.PersistenceExceptionHandler;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.api.management.ha.ManagementNodeState;
@@ -48,9 +50,9 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.PersistenceExceptionHandlerImpl;
 import brooklyn.entity.rebind.transformer.CompoundTransformer;
 import brooklyn.entity.rebind.transformer.CompoundTransformerLoader;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.management.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import brooklyn.management.internal.LocalLocationManager;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java b/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
index c936526..fe7e26f 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/XmlMementoSerializer.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.trait.Identifiable;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.api.management.classloading.BrooklynClassLoadingContext;
@@ -57,7 +58,6 @@ import brooklyn.entity.rebind.dto.BasicPolicyMemento;
 import brooklyn.entity.rebind.dto.MutableBrooklynMemento;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.basic.BasicConfigKey;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.classloading.BrooklynClassLoadingContextSequential;
 import brooklyn.management.classloading.ClassLoaderFromBrooklynClassLoadingContext;
 import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/trait/Startable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/trait/Startable.java b/core/src/main/java/brooklyn/entity/trait/Startable.java
index 97674eb..19c7f9d 100644
--- a/core/src/main/java/brooklyn/entity/trait/Startable.java
+++ b/core/src/main/java/brooklyn/entity/trait/Startable.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 
 import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,7 +33,6 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.effector.Effectors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.Tasks;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/entity/trait/StartableMethods.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/trait/StartableMethods.java b/core/src/main/java/brooklyn/entity/trait/StartableMethods.java
index acfbde3..6188d14 100644
--- a/core/src/main/java/brooklyn/entity/trait/StartableMethods.java
+++ b/core/src/main/java/brooklyn/entity/trait/StartableMethods.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.TaskAdaptable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,7 +32,6 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.effector.Effectors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.CompoundRuntimeException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java b/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java
index ccfcc63..b086b98 100644
--- a/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java
+++ b/core/src/main/java/brooklyn/event/basic/PortAttributeSensorAndConfigKey.java
@@ -23,6 +23,10 @@ import java.util.Iterator;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.PortRange;
+import org.apache.brooklyn.api.location.PortSupplier;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,11 +34,9 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.internal.BrooklynInitialization;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.PortRange;
-import org.apache.brooklyn.location.PortSupplier;
+
 import org.apache.brooklyn.location.basic.Locations;
+
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Maybe;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java b/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
index b933e6b..c4489fe 100644
--- a/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
+++ b/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
@@ -32,6 +32,7 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityManager;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
@@ -60,7 +61,6 @@ import brooklyn.entity.rebind.plane.dto.BasicManagementNodeSyncRecord;
 import brooklyn.entity.rebind.plane.dto.ManagementPlaneSyncRecordImpl;
 import brooklyn.entity.rebind.plane.dto.ManagementPlaneSyncRecordImpl.Builder;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.ha.BasicMasterChooser.AlphabeticMasterChooser;
 import brooklyn.management.internal.BrooklynObjectManagementMode;
 import brooklyn.management.internal.LocalEntityManager;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
index 4c790b6..5e7f4a6 100644
--- a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
@@ -42,6 +42,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
+import org.apache.brooklyn.api.location.LocationRegistry;
 import org.apache.brooklyn.api.management.ExecutionContext;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.SubscriptionContext;
@@ -66,8 +67,9 @@ import brooklyn.internal.storage.DataGrid;
 import brooklyn.internal.storage.DataGridFactory;
 import brooklyn.internal.storage.impl.BrooklynStorageImpl;
 import brooklyn.internal.storage.impl.inmemory.InMemoryDataGridFactory;
-import org.apache.brooklyn.location.LocationRegistry;
+
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
+
 import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.ha.HighAvailabilityManagerImpl;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java b/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
index 5bb6eac..0c54909 100644
--- a/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
+++ b/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
@@ -36,6 +36,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.HasTaskChildren;
 import org.apache.brooklyn.api.management.Task;
 import org.slf4j.Logger;
@@ -49,7 +50,6 @@ import brooklyn.entity.basic.BrooklynTaskTags.WrappedStream;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
 import brooklyn.internal.storage.BrooklynStorage;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java b/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java
index 3874d3d..696d0f0 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java
@@ -21,10 +21,9 @@ package brooklyn.management.internal;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.AccessController;
 
-import org.apache.brooklyn.location.Location;
-
 import com.google.common.annotations.Beta;
 
 @Beta

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
index 3d6acfd..31dc036 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
@@ -25,6 +25,9 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.ProvisioningLocation;
 import org.apache.brooklyn.api.management.AccessController;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -36,11 +39,10 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.internal.storage.BrooklynStorage;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.ProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationInternal;
+
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java b/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java
index 73a362f..db9b33b 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java
@@ -34,6 +34,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.AccessController;
 import org.apache.brooklyn.api.management.ExecutionContext;
 import org.apache.brooklyn.api.management.ExecutionManager;
@@ -53,7 +54,6 @@ import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.internal.BrooklynFeatureEnablement;
 import brooklyn.internal.storage.DataGridFactory;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.ha.OsgiManager;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java b/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
index 31084a4..6da41c8 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
@@ -33,6 +33,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.entitlement.EntitlementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,10 +42,11 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.internal.storage.BrooklynStorage;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.basic.LocationInternal;
+
 import brooklyn.management.ManagementContextInjectable;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.usage.ApplicationUsage;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java b/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java
index 2d126bc..17ecd5a 100644
--- a/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java
+++ b/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java
@@ -18,10 +18,9 @@
  */
 package brooklyn.management.internal;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.LocationManager;
 
-import org.apache.brooklyn.location.Location;
-
 public interface LocationManagerInternal extends LocationManager, BrooklynObjectManagerInternal<Location> {
 
     public Iterable<String> getLocationIds();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java b/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java
index 699b34f..b21f73f 100644
--- a/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java
+++ b/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java
@@ -26,6 +26,7 @@ import java.util.concurrent.ExecutionException;
 
 import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
 
@@ -36,7 +37,6 @@ import brooklyn.entity.proxying.InternalEntityFactory;
 import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.internal.storage.BrooklynStorage;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.ha.OsgiManager;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.task.TaskTags;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java b/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java
index eaad030..5d68db6 100644
--- a/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java
+++ b/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java
@@ -22,11 +22,10 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-
 public class NonDeploymentLocationManager implements LocationManagerInternal {
 
     private final ManagementContext initialManagementContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java b/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
index eff0417..67a9d1b 100644
--- a/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
@@ -42,6 +42,8 @@ import org.apache.brooklyn.api.entity.rebind.ChangeListener;
 import org.apache.brooklyn.api.entity.rebind.PersistenceExceptionHandler;
 import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
 import org.apache.brooklyn.api.management.AccessController;
 import org.apache.brooklyn.api.management.EntityManager;
 import org.apache.brooklyn.api.management.ExecutionContext;
@@ -66,8 +68,6 @@ import brooklyn.entity.proxying.InternalEntityFactory;
 import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.internal.storage.BrooklynStorage;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.ha.OsgiManager;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java b/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java
index 55577d4..ec2cd10 100644
--- a/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java
+++ b/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java
@@ -21,9 +21,9 @@ package brooklyn.management.internal;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.entity.basic.Lifecycle;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.usage.ApplicationUsage;
 import brooklyn.management.usage.LocationUsage;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/UsageListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/UsageListener.java b/core/src/main/java/brooklyn/management/internal/UsageListener.java
index 3914802..5a2af3a 100644
--- a/core/src/main/java/brooklyn/management/internal/UsageListener.java
+++ b/core/src/main/java/brooklyn/management/internal/UsageListener.java
@@ -21,8 +21,8 @@ package brooklyn.management.internal;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.location.Location;
 
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.usage.ApplicationUsage.ApplicationEvent;
 import brooklyn.management.usage.LocationUsage.LocationEvent;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/management/internal/UsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/UsageManager.java b/core/src/main/java/brooklyn/management/internal/UsageManager.java
index bc4dfe5..5105faf 100644
--- a/core/src/main/java/brooklyn/management/internal/UsageManager.java
+++ b/core/src/main/java/brooklyn/management/internal/UsageManager.java
@@ -25,11 +25,11 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Lifecycle;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.usage.ApplicationUsage;
 import brooklyn.management.usage.ApplicationUsage.ApplicationEvent;
 import brooklyn.management.usage.LocationUsage;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java b/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
index b13b43c..9f6fbb9 100644
--- a/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
+++ b/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
@@ -23,6 +23,7 @@ import java.util.Map;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.api.management.TaskAdaptable;
@@ -35,10 +36,11 @@ import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigUtils;
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationInternal;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.internal.ssh.SshTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/brooklyn/util/text/TemplateProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/text/TemplateProcessor.java b/core/src/main/java/brooklyn/util/text/TemplateProcessor.java
index f936e93..b5d8b2d 100644
--- a/core/src/main/java/brooklyn/util/text/TemplateProcessor.java
+++ b/core/src/main/java/brooklyn/util/text/TemplateProcessor.java
@@ -28,6 +28,7 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,7 +38,6 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java b/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java
index eebee14..9daf1c5 100644
--- a/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java
@@ -21,17 +21,19 @@ package org.apache.brooklyn.location.access;
 import java.util.Collection;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.event.basic.BasicConfigKey;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.basic.Machines;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.basic.SupportsPortForwarding;
+
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.net.Cidr;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java
index 922231b..935dff3 100644
--- a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java
@@ -20,7 +20,9 @@ package org.apache.brooklyn.location.access;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
+
 import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java
index 09aea72..5e2d3ca 100644
--- a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java
@@ -23,10 +23,10 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java
index 6493f30..af1a496 100644
--- a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java
@@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.brooklyn.api.entity.rebind.RebindContext;
 import org.apache.brooklyn.api.entity.rebind.RebindSupport;
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.mementos.LocationMemento;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java
index dcb9048..db35a34 100644
--- a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java
@@ -20,16 +20,16 @@ package org.apache.brooklyn.location.access;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.LocationConfigUtils;
 import org.apache.brooklyn.location.basic.LocationInternal;
 import org.apache.brooklyn.location.basic.LocationPredicates;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import org.apache.brooklyn.location.basic.AbstractLocationResolver;
+
 import brooklyn.util.config.ConfigBag;
 
 import com.google.common.base.Optional;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java b/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java
index 086b67c..169cf71 100644
--- a/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java
@@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import javax.annotation.Nullable;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
index eee375b..7280927 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
@@ -31,8 +31,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.brooklyn.api.entity.rebind.RebindSupport;
 import org.apache.brooklyn.api.entity.trait.Configurable;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.mementos.LocationMemento;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -48,9 +49,10 @@ import brooklyn.internal.BrooklynFeatureEnablement;
 import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.internal.storage.Reference;
 import brooklyn.internal.storage.impl.BasicReference;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.geo.HasHostGeoInfo;
 import org.apache.brooklyn.location.geo.HostGeoInfo;
+
 import brooklyn.management.internal.LocalLocationManager;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.SetFromLiveMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java
index 59a0771..26f895c 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java
@@ -26,15 +26,15 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
-import org.apache.brooklyn.location.LocationSpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import org.apache.brooklyn.location.basic.AbstractLocationResolver.SpecParser.ParsedSpec;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.text.KeyValueParser;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
index 33e8efa..c814209 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
@@ -26,9 +26,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
+
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.stream.Streams;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java
index fc90a68..4393884 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java
@@ -22,7 +22,7 @@ import javax.annotation.concurrent.Immutable;
 
 import com.google.common.base.Objects;
 
-import org.apache.brooklyn.location.HardwareDetails;
+import org.apache.brooklyn.api.location.HardwareDetails;
 
 @Immutable
 public class BasicHardwareDetails implements HardwareDetails {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java
index 550ca12..9072074 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java
@@ -20,7 +20,8 @@ package org.apache.brooklyn.location.basic;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.api.location.LocationDefinition;
+
 import brooklyn.util.text.Identifiers;
 
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
index 1c21e32..490335a 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
@@ -30,15 +30,15 @@ import java.util.NoSuchElementException;
 import java.util.ServiceLoader;
 import java.util.Set;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
-import org.apache.brooklyn.location.LocationSpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 
 import brooklyn.catalog.CatalogPredicates;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java
index e4b4575..d6b51c6 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java
@@ -28,13 +28,13 @@ import java.util.Map;
 import javax.annotation.Nonnull;
 import javax.annotation.concurrent.Immutable;
 
+import org.apache.brooklyn.api.location.HardwareDetails;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.location.MachineDetails;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.brooklyn.location.HardwareDetails;
-import org.apache.brooklyn.location.OsDetails;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.stream.Streams;
 import brooklyn.util.task.DynamicTasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java
index ff1c0af..95c8f0e 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java
@@ -19,7 +19,8 @@
 package org.apache.brooklyn.location.basic;
 
 import com.google.common.base.Objects;
-import org.apache.brooklyn.location.MachineManagementMixins;
+
+import org.apache.brooklyn.api.location.MachineManagementMixins;
 
 public class BasicMachineMetadata implements MachineManagementMixins.MachineMetadata {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java
index 364e5f3..7ab72c7 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java
@@ -19,12 +19,13 @@
 package org.apache.brooklyn.location.basic;
 
 import java.util.regex.Pattern;
+
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
 
 import com.google.common.base.Objects;
 
-import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.api.location.OsDetails;
 
 @Immutable
 public class BasicOsDetails implements OsDetails {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
index a93d3dd..127a665 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
@@ -24,9 +24,10 @@ import java.net.InetAddress;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,7 +40,6 @@ import com.google.common.net.HostAndPort;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Sanitizer;
-import org.apache.brooklyn.location.MachineLocation;
 import brooklyn.management.internal.LocalLocationManager;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java
index 7d55d57..0866649 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java
@@ -22,13 +22,13 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
-import org.apache.brooklyn.location.LocationSpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 
 import brooklyn.catalog.internal.CatalogUtils;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java
index 7277fc9..38fef17 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java
@@ -22,11 +22,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
index 45bc585..7b9d73e 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
@@ -28,11 +28,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineLocationCustomizer;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.LocationManager;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocationCustomizer;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -48,9 +50,9 @@ import com.google.common.reflect.TypeToken;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;



[10/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
deleted file mode 100644
index a40660a..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.SingleMachineProvisioningLocation;
-
-public class SingleMachineProvisioningLocationJcloudsLiveTest extends AbstractJcloudsLiveTest {
-private static final Logger log = LoggerFactory.getLogger(SingleMachineProvisioningLocation.class);
-    
-    private SingleMachineProvisioningLocation<JcloudsSshMachineLocation> location;
-
-    private static final String JCLOUDS_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + ":" + AWS_EC2_USEAST_REGION_NAME;
-    
-    @Test(groups="Live")
-    public void testJcloudsSingle() throws Exception {
-        location = resolve("single:(target='"+JCLOUDS_LOCATION_SPEC+"')");
-        
-        MachineLocation m1 = obtainMachine();
-        assertNotNull(m1);
-
-        log.info("GOT "+m1);
-    }
-    
-    @Test(groups="Live")
-    public void testJcloudsSingleRelease() throws Exception {
-        location = resolve("single:(target='"+JCLOUDS_LOCATION_SPEC+"')");
-        
-        JcloudsSshMachineLocation m1 = obtainMachine();
-        log.info("GOT " + m1);
-        JcloudsSshMachineLocation m2 = obtainMachine();
-        log.info("GOT " + m2);
-        assertSame(m1, m2);
-        
-        location.release(m1);
-        assertTrue(m2.isSshable());
-
-        location.release(m2);
-        assertFalse(m2.isSshable());
-    }
-    
-    @Test(groups="Live")
-    public void testJcloudsSingleObtainReleaseObtain() throws Exception {
-        location = resolve("single:(target='"+JCLOUDS_LOCATION_SPEC+"')");
-        
-        JcloudsSshMachineLocation m1 = obtainMachine();
-        log.info("GOT " + m1);
-        
-        location.release(m1);
-        assertFalse(m1.isSshable());
-        
-        JcloudsSshMachineLocation m2 = obtainMachine();
-        assertTrue(m2.isSshable());
-        assertNotEquals(m1, m2);
-        
-        location.release(m2);
-        assertFalse(m2.isSshable());
-    }
-    
-    @Test(groups="Live")
-    public void testJCloudsNamedSingle() throws Exception {
-        brooklynProperties.put(ConfigKeys.newStringConfigKey("brooklyn.location.named.FooServers"), JCLOUDS_LOCATION_SPEC);
-        location = resolve("single:(target='named:FooServers')");
-        
-        JcloudsSshMachineLocation m1 = obtainMachine();
-        assertTrue(m1.isSshable());
-        
-        location.release(m1);
-        assertFalse(m1.isSshable());
-    }
-    
-    @Override
-    protected JcloudsSshMachineLocation obtainMachine(Map<?, ?> conf) throws Exception {
-        JcloudsSshMachineLocation result = location.obtain(conf);
-        machines.add(result);
-        return result;
-    }
-    
-    @Override
-    protected void releaseMachine(JcloudsSshMachineLocation machine) {
-        if (location.getChildren().contains(machine)) {
-            machines.remove(machine);
-            location.release(machine);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private SingleMachineProvisioningLocation<JcloudsSshMachineLocation> resolve(String spec) {
-        SingleMachineProvisioningLocation<JcloudsSshMachineLocation> result = (SingleMachineProvisioningLocation<JcloudsSshMachineLocation>) 
-                managementContext.getLocationRegistry().resolve(spec);
-        // FIXME Do we really need to setManagementContext?!
-        //result.setManagementContext(managementContext);
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/StandaloneJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/StandaloneJcloudsLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/StandaloneJcloudsLiveTest.java
deleted file mode 100644
index d8b3915..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/StandaloneJcloudsLiveTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertNotNull;
-
-import java.io.File;
-import java.nio.charset.Charset;
-import java.util.Arrays;
-import java.util.Properties;
-import java.util.Set;
-import java.util.UUID;
-
-import org.jclouds.Constants;
-import org.jclouds.ContextBuilder;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.RunNodesException;
-import org.jclouds.compute.domain.ExecResponse;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.options.RunScriptOptions;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.domain.Credentials;
-import org.jclouds.domain.LoginCredentials;
-import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
-import org.jclouds.scriptbuilder.domain.Statement;
-import org.jclouds.scriptbuilder.domain.Statements;
-import org.jclouds.scriptbuilder.statements.login.AdminAccess;
-import org.jclouds.sshj.config.SshjSshClientModule;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.util.text.Identifiers;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.Iterables;
-import com.google.common.io.Files;
-
-public class StandaloneJcloudsLiveTest {
-
-    // FIXME Why do this?
-    // Were we seeing bugs in jclouds for which this was easier to debug and report
-    // Is it because testProvisioningVmWithCustomUsername is disabled and not working?
-    
-    public static final Logger LOG = LoggerFactory.getLogger(StandaloneJcloudsLiveTest.class);
-    
-    private static final String PROVIDER = AbstractJcloudsLiveTest.AWS_EC2_PROVIDER;
-    private static final String REGION = AbstractJcloudsLiveTest.AWS_EC2_USEAST_REGION_NAME;
-    private static final String PRIVATE_IMAGE_ID = "us-east-1/ami-f95cf390";
-    
-    static BrooklynProperties globals = BrooklynProperties.Factory.newDefault();
-
-    String identity = globals.getFirst("brooklyn.location.jclouds.aws-ec2.identity");
-    String credential = globals.getFirst("brooklyn.location.jclouds.aws-ec2.credential");
-    
-    @Test(enabled=false, groups={"WIP","Live"})
-    public void createVm() {
-        String groupId = "mygroup-"+System.getProperty("user.name")+"-"+UUID.randomUUID().toString();
- 
-        Properties properties = new Properties();
-        properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
-        properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
-        // handy to list all images... but very slow!
-//        properties.setProperty(AWSEC2Constants.PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine");
-
-        ComputeServiceContext computeServiceContext = ContextBuilder.newBuilder(PROVIDER).
-                modules(Arrays.asList(new SshjSshClientModule(), new SLF4JLoggingModule())).
-                credentials(identity, credential).
-                overrides(properties).
-                build(ComputeServiceContext.class);
-        
-        final ComputeService computeService = computeServiceContext.getComputeService();
-        
-        NodeMetadata node = null;
-        try {
-            LOG.info("Creating VM for "+identity);
-
-            TemplateBuilder templateBuilder = computeService.templateBuilder();
-            templateBuilder.locationId(REGION);
-            
-            Template template = templateBuilder.build();
-            Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(groupId, 1, template);
-            node = Iterables.getOnlyElement(nodes, null);
-            if (node == null) throw new IllegalStateException("No nodes returned");
-
-            assertNotNull(node.getOperatingSystem());
-
-            Credentials nodeCredentials = node.getCredentials();
-            final LoginCredentials expectedCredentials = LoginCredentials.fromCredentials(nodeCredentials);
-            
-            LOG.info("Started VM, waiting for it to be sshable");
-            boolean reachable = false;
-            for (int i=0; i<120; i++) {
-                try {
-                    Statement statement = Statements.newStatementList(Statements.exec("date"));
-                    ExecResponse response = computeService.runScriptOnNode(node.getId(), statement,
-                            RunScriptOptions.Builder.overrideLoginCredentials(expectedCredentials));
-                    if (response.getExitStatus() == 0) {
-                        LOG.info("ssh 'date' succeeded");
-                        reachable = true;
-                        break;
-                    }
-                    LOG.info("ssh 'date' failed, exit "+response.getExitStatus()+", but still in retry loop");
-                } catch (Exception e) {
-                    if (i<120)
-                        LOG.info("ssh 'date' failed, but still in retry loop: "+e);
-                    else {
-                        LOG.error("ssh 'date' failed after timeout: "+e, e);
-                        Throwables.propagate(e);
-                    }
-                }
-                Thread.sleep(1000);
-            }
-        
-            if (!reachable) {
-                throw new IllegalStateException("SSH failed, never reachable");
-            }
-
-        } catch (RunNodesException e) {
-            if (e.getNodeErrors().size() > 0) {
-                node = Iterables.get(e.getNodeErrors().keySet(), 0);
-            }
-            LOG.error("Failed to start VM: "+e, e);
-            throw Throwables.propagate(e);
-        } catch (Exception e) {
-            LOG.error("Failed to start VM: "+e, e);
-            throw Throwables.propagate(e);
-        } finally {
-            LOG.info("Now destroying VM: "+node);
-            computeService.destroyNode( node.getId() );
-
-            computeService.getContext().close();
-        }
-        
-    }
-    
-    @Test(enabled=false, groups={"WIP","Live"})
-    public void createVmWithAdminUser() {
-        String groupId = "mygroup-"+System.getProperty("user.name")+"-"+UUID.randomUUID().toString();
- 
-        Properties properties = new Properties();
-        properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
-        properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
-
-        ComputeServiceContext computeServiceContext = ContextBuilder.newBuilder(PROVIDER).
-                modules(Arrays.asList(new SshjSshClientModule(), new SLF4JLoggingModule())).
-                credentials(identity, credential).
-                overrides(properties).
-                build(ComputeServiceContext.class);
-        
-        final ComputeService computeService = computeServiceContext.getComputeService();
-        
-        NodeMetadata node = null;
-        try {
-            LOG.info("Creating VM for "+identity);
-            String myPubKey = Files.toString(new File(System.getProperty("user.home")+"/.ssh/aws-id_rsa.pub"), Charset.defaultCharset());
-            String myPrivKey = Files.toString(new File(System.getProperty("user.home")+"/.ssh/aws-id_rsa"), Charset.defaultCharset());
-
-            TemplateBuilder templateBuilder = computeService.templateBuilder();
-            templateBuilder.locationId(REGION);
-            TemplateOptions opts = new TemplateOptions();
-            
-//            templateBuilder.imageId("us-east-1/ami-2342a94a");  //rightscale
-            // either use above, or below
-            templateBuilder.imageId(PRIVATE_IMAGE_ID);  //private one (to test when user isn't autodetected)
-            opts.overrideLoginUser("ec2-user");
-            
-            AdminAccess.Builder adminBuilder = AdminAccess.builder().
-                    adminUsername("bob").
-                    grantSudoToAdminUser(true).
-                    authorizeAdminPublicKey(true).adminPublicKey(myPubKey).
-                    // items below aren't wanted but values for some are required otherwise AdminAccess uses all defaults
-                    lockSsh(true).adminPassword(Identifiers.makeRandomId(12)).
-                    resetLoginPassword(false).loginPassword(Identifiers.makeRandomId(12)).
-                    installAdminPrivateKey(false).adminPrivateKey("ignored");
-            opts.runScript(adminBuilder.build());
-            
-            templateBuilder.options(opts);
-            
-            Template template = templateBuilder.build();
-            Set<? extends NodeMetadata> nodes = computeService.createNodesInGroup(groupId, 1, template);
-            node = Iterables.getOnlyElement(nodes, null);
-            if (node == null) throw new IllegalStateException("No nodes returned");
-
-            LOG.info("Started VM, waiting for it to be sshable on "+node.getPublicAddresses());
-            final LoginCredentials crds =
-//                    node.getCredentials();
-                    LoginCredentials.builder().user("bob").privateKey(myPrivKey).build();
-            boolean reachable = false;
-            for (int i=0; i<120; i++) {
-                try {
-                    Statement statement = Statements.newStatementList(Statements.exec("date"));
-                    ExecResponse response = computeService.runScriptOnNode(node.getId(), statement,
-                            RunScriptOptions.Builder.overrideLoginCredentials(crds));
-                    if (response.getExitStatus() == 0) {
-                        LOG.info("ssh 'date' succeeded");
-                        reachable = true;
-                        break;
-                    }
-                    LOG.info("ssh 'date' failed, exit "+response.getExitStatus()+", but still in retry loop");
-                } catch (Exception e) {
-                    if (i<120)
-                        LOG.info("ssh 'date' failed, but still in retry loop: "+e);
-                    else {
-                        LOG.error("ssh 'date' failed after timeout: "+e, e); 
-                        Throwables.propagate(e);
-                    }
-                }
-                Thread.sleep(1000);
-            }
-        
-            if (!reachable) {
-                throw new IllegalStateException("SSH failed, never reachable");
-            }
-            
-        } catch (RunNodesException e) {
-            if (e.getNodeErrors().size() > 0) {
-                node = Iterables.get(e.getNodeErrors().keySet(), 0);
-            }
-            LOG.error("Failed to start VM: "+e, e);
-            throw Throwables.propagate(e);
-        } catch (Exception e) {
-            LOG.error("Failed to start VM: "+e, e);
-            throw Throwables.propagate(e);
-        } finally {
-            LOG.info("Now destroying VM: "+node);
-            computeService.destroyNode( node.getId() );
-
-            computeService.getContext().close();
-        }
-        
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
deleted file mode 100644
index 69d962f..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizerTest.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.networking;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.net.URI;
-import java.util.Collections;
-
-import org.jclouds.aws.AWSResponseException;
-import org.jclouds.aws.domain.AWSError;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.SecurityGroup;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.extensions.SecurityGroupExtension;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.domain.Location;
-import org.jclouds.net.domain.IpPermission;
-import org.jclouds.net.domain.IpProtocol;
-import org.mockito.Answers;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Cidr;
-
-public class JcloudsLocationSecurityGroupCustomizerTest {
-
-    JcloudsLocationSecurityGroupCustomizer customizer;
-    ComputeService computeService;
-    Location location;
-    SecurityGroupExtension securityApi;
-
-    /** Used to skip external checks in unit tests. */
-    private static class TestCidrSupplier implements Supplier<Cidr> {
-        @Override public Cidr get() {
-            return new Cidr("192.168.10.10/32");
-        }
-    }
-
-    @BeforeMethod
-    public void setUp() {
-        customizer = new JcloudsLocationSecurityGroupCustomizer("testapp", new TestCidrSupplier());
-        location = mock(Location.class);
-        securityApi = mock(SecurityGroupExtension.class);
-        computeService = mock(ComputeService.class, Answers.RETURNS_DEEP_STUBS.get());
-        when(computeService.getSecurityGroupExtension()).thenReturn(Optional.of(securityApi));
-    }
-
-    @Test
-    public void testSameInstanceReturnedForSameApplication() {
-        assertEquals(JcloudsLocationSecurityGroupCustomizer.getInstance("a"),
-                JcloudsLocationSecurityGroupCustomizer.getInstance("a"));
-        assertNotEquals(JcloudsLocationSecurityGroupCustomizer.getInstance("a"),
-                JcloudsLocationSecurityGroupCustomizer.getInstance("b"));
-    }
-
-    @Test
-    public void testSecurityGroupAddedWhenJcloudsLocationCustomised() {
-        Template template = mock(Template.class);
-        TemplateOptions templateOptions = mock(TemplateOptions.class);
-        when(template.getLocation()).thenReturn(location);
-        when(template.getOptions()).thenReturn(templateOptions);
-        SecurityGroup group = newGroup("id");
-        when(securityApi.createSecurityGroup(anyString(), eq(location))).thenReturn(group);
-
-        // Two Brooklyn.JcloudsLocations added to same Jclouds.Location
-        JcloudsLocation jcloudsLocationA = new JcloudsLocation(MutableMap.of("deferConstruction", true));
-        JcloudsLocation jcloudsLocationB = new JcloudsLocation(MutableMap.of("deferConstruction", true));
-        customizer.customize(jcloudsLocationA, computeService, template);
-        customizer.customize(jcloudsLocationB, computeService, template);
-
-        // One group with three permissions shared by both locations.
-        // Expect TCP, UDP and ICMP between members of group and SSH to Brooklyn
-        verify(securityApi).createSecurityGroup(anyString(), eq(location));
-        verify(securityApi, times(4)).addIpPermission(any(IpPermission.class), eq(group));
-        // New groups set on options
-        verify(templateOptions, times(2)).securityGroups(anyString());
-    }
-
-    @Test
-    public void testSharedGroupLoadedWhenItExistsButIsNotCached() {
-        Template template = mock(Template.class);
-        TemplateOptions templateOptions = mock(TemplateOptions.class);
-        when(template.getLocation()).thenReturn(location);
-        when(template.getOptions()).thenReturn(templateOptions);
-        JcloudsLocation jcloudsLocation = new JcloudsLocation(MutableMap.of("deferConstruction", true));
-        SecurityGroup shared = newGroup(customizer.getNameForSharedSecurityGroup());
-        SecurityGroup irrelevant = newGroup("irrelevant");
-        when(securityApi.listSecurityGroupsInLocation(location)).thenReturn(ImmutableSet.of(irrelevant, shared));
-
-        customizer.customize(jcloudsLocation, computeService, template);
-
-        verify(securityApi).listSecurityGroupsInLocation(location);
-        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
-    }
-
-    @Test
-    public void testAddPermissionsToNode() {
-        IpPermission ssh = newPermission(22);
-        IpPermission jmx = newPermission(31001);
-        String nodeId = "node";
-        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
-        SecurityGroup group = newGroup("id");
-        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, group));
-        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
-
-        customizer.addPermissionsToLocation(ImmutableList.of(ssh, jmx), nodeId, computeService);
-
-        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
-        verify(securityApi, times(1)).addIpPermission(ssh, group);
-        verify(securityApi, times(1)).addIpPermission(jmx, group);
-    }
-
-    @Test
-    public void testAddPermissionsToNodeUsesUncachedSecurityGroup() {
-        JcloudsLocation jcloudsLocation = new JcloudsLocation(MutableMap.of("deferConstruction", true));
-        IpPermission ssh = newPermission(22);
-        String nodeId = "nodeId";
-        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
-        SecurityGroup uniqueGroup = newGroup("unique");
-
-        Template template = mock(Template.class);
-        TemplateOptions templateOptions = mock(TemplateOptions.class);
-        when(template.getLocation()).thenReturn(location);
-        when(template.getOptions()).thenReturn(templateOptions);
-        when(securityApi.createSecurityGroup(anyString(), eq(location))).thenReturn(sharedGroup);
-        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
-
-        // Call customize to cache the shared group
-        customizer.customize(jcloudsLocation, computeService, template);
-        reset(securityApi);
-        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(uniqueGroup, sharedGroup));
-        customizer.addPermissionsToLocation(ImmutableSet.of(ssh), nodeId, computeService);
-
-        // Expect the per-machine group to have been altered, not the shared group
-        verify(securityApi).addIpPermission(ssh, uniqueGroup);
-        verify(securityApi, never()).addIpPermission(any(IpPermission.class), eq(sharedGroup));
-    }
-
-    @Test
-    public void testSecurityGroupsLoadedWhenAddingPermissionsToUncachedNode() {
-        IpPermission ssh = newPermission(22);
-        String nodeId = "nodeId";
-        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
-        SecurityGroup uniqueGroup = newGroup("unique");
-
-        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
-        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
-
-        // Expect first call to list security groups on nodeId, second to use cached version
-        customizer.addPermissionsToLocation(ImmutableSet.of(ssh), nodeId, computeService);
-        customizer.addPermissionsToLocation(ImmutableSet.of(ssh), nodeId, computeService);
-
-        verify(securityApi, times(1)).listSecurityGroupsForNode(nodeId);
-        verify(securityApi, times(2)).addIpPermission(ssh, uniqueGroup);
-        verify(securityApi, never()).addIpPermission(any(IpPermission.class), eq(sharedGroup));
-    }
-
-    @Test
-    public void testAddRuleNotRetriedByDefault() {
-        IpPermission ssh = newPermission(22);
-        String nodeId = "node";
-        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
-        SecurityGroup uniqueGroup = newGroup("unique");
-        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
-        when(securityApi.addIpPermission(eq(ssh), eq(uniqueGroup)))
-                .thenThrow(new RuntimeException("exception creating " + ssh));
-        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
-
-        try {
-            customizer.addPermissionsToLocation(ImmutableList.of(ssh), nodeId, computeService);
-        } catch (Exception e) {
-            assertTrue(e.getMessage().contains("repeated errors from provider"), "message=" + e.getMessage());
-        }
-        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
-        verify(securityApi, times(1)).addIpPermission(ssh, uniqueGroup);
-    }
-
-    @Test
-    public void testCustomExceptionRetryablePredicate() {
-        final String message = "testCustomExceptionRetryablePredicate";
-        Predicate<Exception> messageChecker = new Predicate<Exception>() {
-            @Override
-            public boolean apply(Exception input) {
-                Throwable t = input;
-                while (t != null) {
-                    if (t.getMessage().contains(message)) {
-                        return true;
-                    } else {
-                        t = t.getCause();
-                    }
-                }
-                return false;
-            }
-        };
-        customizer.setRetryExceptionPredicate(messageChecker);
-        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
-
-        IpPermission ssh = newPermission(22);
-        String nodeId = "node";
-        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
-        SecurityGroup uniqueGroup = newGroup("unique");
-        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
-        when(securityApi.addIpPermission(eq(ssh), eq(uniqueGroup)))
-                .thenThrow(new RuntimeException(new Exception(message)))
-                .thenThrow(new RuntimeException(new Exception(message)))
-                .thenReturn(sharedGroup);
-
-        customizer.addPermissionsToLocation(ImmutableList.of(ssh), nodeId, computeService);
-
-        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
-        verify(securityApi, times(3)).addIpPermission(ssh, uniqueGroup);
-    }
-
-    @Test
-    public void testAddRuleRetriedOnAwsFailure() {
-        IpPermission ssh = newPermission(22);
-        String nodeId = "nodeId";
-        SecurityGroup sharedGroup = newGroup(customizer.getNameForSharedSecurityGroup());
-        SecurityGroup uniqueGroup = newGroup("unique");
-        customizer.setRetryExceptionPredicate(JcloudsLocationSecurityGroupCustomizer.newAwsExceptionRetryPredicate());
-        when(securityApi.listSecurityGroupsForNode(nodeId)).thenReturn(ImmutableSet.of(sharedGroup, uniqueGroup));
-        when(securityApi.addIpPermission(any(IpPermission.class), eq(uniqueGroup)))
-                .thenThrow(newAwsResponseExceptionWithCode("InvalidGroup.InUse"))
-                .thenThrow(newAwsResponseExceptionWithCode("DependencyViolation"))
-                .thenThrow(newAwsResponseExceptionWithCode("RequestLimitExceeded"))
-                .thenThrow(newAwsResponseExceptionWithCode("Blocked"))
-                .thenReturn(sharedGroup);
-        when(computeService.getContext().unwrap().getId()).thenReturn("aws-ec2");
-
-        try {
-            customizer.addPermissionsToLocation(ImmutableList.of(ssh), nodeId, computeService);
-        } catch (Exception e) {
-            String expected = "repeated errors from provider";
-            assertTrue(e.getMessage().contains(expected), "expected exception message to contain " + expected + ", was: " + e.getMessage());
-        }
-
-        verify(securityApi, never()).createSecurityGroup(anyString(), any(Location.class));
-        verify(securityApi, times(4)).addIpPermission(ssh, uniqueGroup);
-    }
-
-    private SecurityGroup newGroup(String id) {
-        URI uri = null;
-        String ownerId = null;
-        return new SecurityGroup(
-                "providerId",
-                id,
-                id,
-                location,
-                uri,
-                Collections.<String, String>emptyMap(),
-                ImmutableSet.<String>of(),
-                ImmutableSet.<IpPermission>of(),
-                ownerId);
-    }
-
-    private IpPermission newPermission(int port) {
-        return IpPermission.builder()
-                .ipProtocol(IpProtocol.TCP)
-                .fromPort(port)
-                .toPort(port)
-                .cidrBlock("0.0.0.0/0")
-                .build();
-    }
-
-    private AWSError newAwsErrorWithCode(String code) {
-        AWSError e = new AWSError();
-        e.setCode(code);
-        return e;
-    }
-
-    private Exception newAwsResponseExceptionWithCode(String code) {
-        AWSResponseException e = new AWSResponseException("irrelevant message", null, null, newAwsErrorWithCode(code));
-        return new RuntimeException(e);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsPortForwardingStubbedLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsPortForwardingStubbedLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsPortForwardingStubbedLiveTest.java
deleted file mode 100644
index fa1cb90..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/JcloudsPortForwardingStubbedLiveTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.networking;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-
-import java.util.List;
-
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.NodeMetadata.Status;
-import org.jclouds.compute.domain.NodeMetadataBuilder;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.domain.LoginCredentials;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.location.access.PortForwardManager;
-import brooklyn.location.access.PortForwardManagerImpl;
-import brooklyn.location.jclouds.AbstractJcloudsStubbedLiveTest;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsSshMachineLocation;
-import brooklyn.util.net.Cidr;
-import brooklyn.util.net.Protocol;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.net.HostAndPort;
-
-/**
- * The VM creation is stubbed out, but it still requires live access (i.e. real account credentials)
- * to generate the template etc.
- * 
- * We supply a ComputeServiceRegistry that delegates to the real instance for everything except
- * VM creation and deletion. For those operations, it delegates to a NodeCreator that 
- * returns a dummy NodeMetadata, recording all calls made to it.
- */
-public class JcloudsPortForwardingStubbedLiveTest extends AbstractJcloudsStubbedLiveTest {
-
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsPortForwardingStubbedLiveTest.class);
-
-    static class RecordingJcloudsPortForwarderExtension implements JcloudsPortForwarderExtension {
-        final PortForwardManager pfm;
-        final List<List<Object>> opens = Lists.newCopyOnWriteArrayList();
-        final List<List<Object>> closes = Lists.newCopyOnWriteArrayList();
-        int nextPublicPort = 12345;
-        
-        RecordingJcloudsPortForwarderExtension(PortForwardManager pfm) {
-            this.pfm = pfm;
-        }
-        @Override public HostAndPort openPortForwarding(NodeMetadata node, int targetPort, Optional<Integer> optionalPublicPort, Protocol protocol, Cidr accessingCidr) {
-            opens.add(ImmutableList.of(node, targetPort, optionalPublicPort, protocol, accessingCidr));
-            HostAndPort result = HostAndPort.fromParts("1.2.3.4", nextPublicPort++);
-            pfm.associate(node.getId(), result, targetPort);
-            return result;
-        }
-        @Override public void closePortForwarding(NodeMetadata node, int targetPort, HostAndPort publicHostAndPort, Protocol protocol) {
-            closes.add(ImmutableList.of(node, targetPort, publicHostAndPort, protocol));
-            pfm.forgetPortMapping(node.getId(), publicHostAndPort.getPort());
-        }
-    }
-
-    @Override
-    protected NodeCreator newNodeCreator() {
-        return new NodeCreator() {
-            int nextIpSuffix = 2;
-            @Override
-            protected NodeMetadata newNode(String group, Template template) {
-                int ipSuffix = nextIpSuffix++;
-                NodeMetadata result = new NodeMetadataBuilder()
-                        .id("myid-"+ipSuffix)
-                        .credentials(LoginCredentials.builder().identity("myuser").credential("mypassword").build())
-                        .loginPort(22)
-                        .status(Status.RUNNING)
-                        .publicAddresses(ImmutableList.of("173.194.32."+ipSuffix))
-                        .privateAddresses(ImmutableList.of("172.168.10."+ipSuffix))
-                        .build();
-                return result;
-            }
-        };
-    }
-
-    @Test(groups = {"Live", "Live-sanity"})
-    protected void testPortForwardingCallsForwarder() throws Exception {
-        PortForwardManager pfm = new PortForwardManagerImpl();
-        RecordingJcloudsPortForwarderExtension portForwarder = new RecordingJcloudsPortForwarderExtension(pfm);
-        
-        JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.<ConfigKey<?>,Object>of(
-                JcloudsLocation.USE_PORT_FORWARDING, true,
-                JcloudsLocation.PORT_FORWARDER, portForwarder));
-        
-        NodeMetadata created = nodeCreator.created.get(0);
-        assertEquals(nodeCreator.created.size(), 1, "created="+nodeCreator.created+"; machine="+machine);
-        assertEquals(machine.getNode(), created);
-        assertEquals(portForwarder.opens.size(), 1, "opens="+portForwarder.opens+"; machine="+machine);
-        assertEquals(portForwarder.opens.get(0).get(0), created);
-        assertEquals(portForwarder.opens.get(0).get(1), 22);
-        assertEquals(portForwarder.opens.get(0).get(3), Protocol.TCP);
-        assertEquals(portForwarder.opens.get(0).get(4), Cidr.UNIVERSAL);
-        assertEquals(machine.getSshHostAndPort(), HostAndPort.fromParts("1.2.3.4", 12345));
-        
-        releaseMachine(machine);
-        String destroyed = nodeCreator.destroyed.get(0);
-        assertEquals(nodeCreator.destroyed.size(), 1, "destroyed="+nodeCreator.destroyed+"; machine="+machine);
-        assertEquals(destroyed, created.getId());
-        assertEquals(portForwarder.closes.size(), 1, "closes="+portForwarder.closes+"; machine="+machine);
-        assertEquals(portForwarder.closes.get(0).get(0), created);
-        assertEquals(portForwarder.closes.get(0).get(1), 22);
-        assertEquals(portForwarder.closes.get(0).get(2), HostAndPort.fromParts("1.2.3.4", 12345));
-        assertEquals(portForwarder.closes.get(0).get(3), Protocol.TCP);
-    }
-    
-    @Test(groups = {"Live", "Live-sanity"})
-    protected void testDeregistersWithPortForwardManagerOnRelease() throws Exception {
-        PortForwardManager pfm = new PortForwardManagerImpl();
-        RecordingJcloudsPortForwarderExtension portForwarder = new RecordingJcloudsPortForwarderExtension(pfm);
-        
-        JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.<ConfigKey<?>,Object>of(
-                JcloudsLocation.PORT_FORWARDER, portForwarder,
-                JcloudsLocation.PORT_FORWARDING_MANAGER, pfm));
-        
-        // Add an association for this machine - expect that to be deleted when the machine is released.
-        HostAndPort publicHostAndPort = HostAndPort.fromParts("1.2.3.4", 1234);
-        pfm.associate("mypublicip", publicHostAndPort, machine, 80);
-        assertEquals(pfm.lookup(machine, 80), publicHostAndPort);
-        assertEquals(pfm.lookup("mypublicip", 80), publicHostAndPort);
-
-        // Release
-        releaseMachine(machine);
-        
-        // Expect to have been cleared from PortForwardManager's records
-        assertNull(pfm.lookup(machine, 80));
-        assertNull(pfm.lookup("mypublicip", 80));
-        
-        // And for port-forwarding to have been closed
-        assertEquals(portForwarder.closes.size(), 1, "closes="+portForwarder.closes+"; machine="+machine);
-        assertEquals(portForwarder.closes.get(0).get(1), 80);
-        assertEquals(portForwarder.closes.get(0).get(2), HostAndPort.fromParts("1.2.3.4", 1234));
-        assertEquals(portForwarder.closes.get(0).get(3), Protocol.TCP);
-    }
-    
-    @Test(groups = {"Live", "Live-sanity"})
-    protected void testReleaseVmDoesNotImpactOtherVms() throws Exception {
-        PortForwardManager pfm = new PortForwardManagerImpl();
-        RecordingJcloudsPortForwarderExtension portForwarder = new RecordingJcloudsPortForwarderExtension(pfm);
-        
-        JcloudsSshMachineLocation machine1 = obtainMachine(ImmutableMap.<ConfigKey<?>,Object>of(
-                JcloudsLocation.USE_PORT_FORWARDING, true,
-                JcloudsLocation.PORT_FORWARDER, portForwarder,
-                JcloudsLocation.PORT_FORWARDING_MANAGER, pfm));
-        
-        JcloudsSshMachineLocation machine2 = obtainMachine(ImmutableMap.<ConfigKey<?>,Object>of(
-                JcloudsLocation.USE_PORT_FORWARDING, true,
-                JcloudsLocation.PORT_FORWARDER, portForwarder,
-                JcloudsLocation.PORT_FORWARDING_MANAGER, pfm));
-        
-        NodeMetadata node1 = nodeCreator.created.get(0);
-
-        // Add an association for machine2 - expect that not to be touched when machine1 is released.
-        HostAndPort publicHostAndPort = HostAndPort.fromParts("1.2.3.4", 1234);
-        pfm.associate("mypublicip", publicHostAndPort, machine2, 80);
-
-        // Release machine1
-        releaseMachine(machine1);
-        
-        // Expect machine2 to still be registered
-        assertEquals(pfm.lookup(machine2, 80), publicHostAndPort);
-        assertEquals(pfm.lookup("mypublicip", 80), publicHostAndPort);
-        
-        // And no calls to "close" for machine2; just for machine1's port 22
-        assertEquals(portForwarder.closes.size(), 1, "closes="+portForwarder.closes+"; machine1="+machine1);
-        assertEquals(portForwarder.closes.get(0).get(0), node1);
-        assertEquals(portForwarder.closes.get(0).get(1), 22);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/SecurityGroupLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/SecurityGroupLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/SecurityGroupLiveTest.java
deleted file mode 100644
index f0d5d7c..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/networking/SecurityGroupLiveTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.networking;
-
-import org.testng.annotations.Test;
-
-@Test(groups = {"Live", "WIP"})
-public class SecurityGroupLiveTest {
-
-    public void testCreateEc2WithSecurityGroup() {
-        SecurityGroupDefinition sgDef = new SecurityGroupDefinition()
-            .allowingInternalPorts(8097, 8098).allowingInternalPortRange(6000, 7999)
-            .allowingPublicPort(8099);
-        // TODO create machine and test
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/pool/JcloudsMachinePoolLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/pool/JcloudsMachinePoolLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/pool/JcloudsMachinePoolLiveTest.java
deleted file mode 100644
index 4a08217..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/pool/JcloudsMachinePoolLiveTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.pool;
-
-import java.util.Arrays;
-
-import org.jclouds.ContextBuilder;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
-import org.jclouds.sshj.config.SshjSshClientModule;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.location.jclouds.AbstractJcloudsLiveTest;
-import brooklyn.location.jclouds.JcloudsLocation;
-
-public class JcloudsMachinePoolLiveTest extends AbstractJcloudsLiveTest {
-
-    public static final Logger log = LoggerFactory.getLogger(JcloudsMachinePoolLiveTest.class);
-    
-    private static final String PROVIDER = AWS_EC2_PROVIDER;
-    private static final String LOCATION_SPEC = PROVIDER + ":" + AWS_EC2_EUWEST_REGION_NAME;
-    
-    public static class SamplePool extends MachinePool {
-        public SamplePool(ComputeService svc) {
-            super(svc);
-        }
-
-        public final static ReusableMachineTemplate 
-            USUAL_VM = 
-                new ReusableMachineTemplate("usual").templateOwnedByMe().
-                tagOptional("tagForUsualVm").
-                metadataOptional("metadataForUsualVm", "12345").
-                minRam(1024).minCores(2);
-
-        public final static ReusableMachineTemplate 
-            ANYONE_NOT_TINY_VM = 
-                new ReusableMachineTemplate("anyone").
-                minRam(512).minCores(1).strict(false);
-
-        public static final ReusableMachineTemplate 
-            VM_LARGE1 = 
-                new ReusableMachineTemplate("vm.large1").templateOwnedByMe().
-                minRam(16384).minCores(4),
-            VM_SMALL1 = 
-                new ReusableMachineTemplate("vm.small1").templateOwnedByMe().smallest();
-        
-        { registerTemplates(USUAL_VM, ANYONE_NOT_TINY_VM, VM_LARGE1, VM_SMALL1); }
-    }
-    
-    private ComputeServiceContext context;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(LOCATION_SPEC);
-        
-        context = ContextBuilder.newBuilder(PROVIDER)
-                .modules(Arrays.asList(new SshjSshClientModule(), new SLF4JLoggingModule()))
-                .credentials(jcloudsLocation.getIdentity(), jcloudsLocation.getCredential())
-                .build(ComputeServiceContext.class);
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    @Override
-    public void tearDown() throws Exception {
-        try {
-            super.tearDown();
-        } finally {
-            if (context != null) context.close();
-        }
-    }
-    
-    @Test(groups={"Live","WIP"})
-    public void buildClaimAndDestroy() {
-        ComputeService svc = context.getComputeService();
-        SamplePool p = new SamplePool(svc);
-        log.info("buildClaimAndDestroy: created pool");
-        p.refresh();
-        log.info("buildClaimAndDestroy: refreshed pool");
-        p.ensureExists(2, SamplePool.USUAL_VM);
-        log.info("buildClaimAndDestroy: ensure have 2");
-        MachineSet l = p.claim(1, SamplePool.USUAL_VM);
-        Assert.assertEquals(l.size(), 1);
-        log.info("buildClaimAndDestroy: claimed 1");
-        MachineSet unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM));
-        log.info("buildClaimAndDestroy: unclaimed now "+unclaimedUsual);
-        Assert.assertTrue(!unclaimedUsual.isEmpty());
-        p.destroy(unclaimedUsual);
-        unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM));
-        log.info("buildClaimAndDestroy: destroyed, unclaimed now "+unclaimedUsual);
-        log.info("end");
-    }
-    
-
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
deleted file mode 100644
index 703b2f9..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.provider;
-
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-import org.testng.collections.Lists;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-public abstract class AbstractJcloudsLocationTest {
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractJcloudsLocationTest.class);
-
-    private final String provider;
-
-    protected JcloudsLocation loc;
-    protected List<SshMachineLocation> machines = MutableList.of();
-    protected ManagementContext ctx;
-
-    protected AbstractJcloudsLocationTest(String provider) {
-        this.provider = provider;
-    }
-
-    /**
-     * The location and image id tuplets to test.
-     */
-    @DataProvider(name = "fromImageId")
-    public abstract Object[][] cloudAndImageIds();
-
-    /**
-     * A single location and image id tuplet to test.
-     */
-    @DataProvider(name = "fromFirstImageId")
-    public Object[][] cloudAndImageFirstId() {
-        Object[][] all = cloudAndImageIds();
-        return (all != null) ? new Object[][] { all[0] } : new Object[][] { };
-    }
-
-    /**
-     * The location and image name pattern tuplets to test.
-     */
-    @DataProvider(name = "fromImageNamePattern")
-    public abstract Object[][] cloudAndImageNamePatterns();
-
-    /**
-     * The location, image pattern and image owner tuplets to test.
-     */
-    @DataProvider(name = "fromImageDescriptionPattern")
-    public abstract Object[][] cloudAndImageDescriptionPatterns();
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        BrooklynProperties props = BrooklynProperties.Factory.newDefault().addFromMap(ImmutableMap.of("provider", provider));
-        ctx = Entities.newManagementContext(props.asMapWithStringKeys());
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        List<Exception> exceptions = Lists.newArrayList();
-        for (SshMachineLocation machine : machines) {
-            try {
-                loc.release(machine);
-            } catch (Exception e) {
-                LOG.warn("Error releasing {}: {}; continuing...", machine, e.getMessage());
-                exceptions.add(e);
-            }
-        }
-        if (!exceptions.isEmpty()) {
-            LOG.info("Exception during tearDown: {}", Exceptions.collapseText(exceptions.get(0)));
-        }
-        machines.clear();
-        
-        if (ctx != null) Entities.destroyAllCatching(ctx);
-    }
-
-    @Test(dataProvider="fromImageId")
-    public void testTagMapping(String regionName, String imageId, String imageOwner) {
-        Map<String, Object> dummy = ImmutableMap.<String, Object>of("identity", "DUMMY", "credential", "DUMMY");
-        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(provider + (regionName == null ? "" : ":" + regionName), dummy);
-        ImmutableMap.Builder<String, Object> builder = ImmutableMap.<String, Object>builder().put("imageId", imageId);
-        if (imageOwner != null) builder.put("imageOwner", imageOwner);
-        Map<String, Object> tagMapping = builder.build();
-        loc.setTagMapping(ImmutableMap.<String, Map<String, ? extends Object>>of("MyEntityType", tagMapping));
-
-        Map<String, Object> flags = loc.getProvisioningFlags(ImmutableList.of("MyEntityType"));
-        assertTrue(Maps.<String, Object>difference(flags, tagMapping).entriesOnlyOnRight().isEmpty(), "flags="+flags);
-    }
-
-    @Test(groups = "Live", dataProvider="fromImageId")
-    public void testProvisionVmUsingImageId(String regionName, String imageId, String imageOwner) {
-        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(provider + (regionName == null ? "" : ":" + regionName));
-        SshMachineLocation machine = obtainMachine(MutableMap.of("imageId", imageId, "imageOwner", imageOwner, JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 2));
-
-        LOG.info("Provisioned {} vm {}; checking if ssh'able", provider, machine);
-        assertTrue(machine.isSshable());
-    }
-    
-    @Test(groups = "Live", dataProvider="fromImageNamePattern")
-    public void testProvisionVmUsingImageNamePattern(String regionName, String imageNamePattern, String imageOwner) {
-        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(provider + (regionName == null ? "" : ":" + regionName));
-        SshMachineLocation machine = obtainMachine(MutableMap.of("imageNameRegex", imageNamePattern, "imageOwner", imageOwner, JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 2));
-        
-        LOG.info("Provisioned {} vm {}; checking if ssh'able", provider, machine);
-        assertTrue(machine.isSshable());
-    }
-    
-    @Test(groups = "Live", dataProvider="fromImageDescriptionPattern")
-    public void testProvisionVmUsingImageDescriptionPattern(String regionName, String imageDescriptionPattern, String imageOwner) {
-        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(provider + (regionName == null ? "" : ":" + regionName));
-        SshMachineLocation machine = obtainMachine(MutableMap.of("imageDescriptionRegex", imageDescriptionPattern, "imageOwner", imageOwner, JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 2));
-        
-        LOG.info("Provisioned {} vm {}; checking if ssh'able", provider, machine);
-        assertTrue(machine.isSshable());
-    }
-
-    // Use this utility method to ensure machines are released on tearDown
-    protected SshMachineLocation obtainMachine(Map flags) {
-        try {
-            SshMachineLocation result = (SshMachineLocation)loc.obtain(flags);
-            machines.add(result);
-            return result;
-        } catch (NoMachinesAvailableException nmae) {
-            LOG.warn("No machines available", nmae);
-            throw Exceptions.propagate(nmae);
-        }
-    }
-    
-    protected SshMachineLocation release(SshMachineLocation machine) {
-        machines.remove(machine);
-        loc.release(machine);
-        return machine;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AwsEc2LocationLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AwsEc2LocationLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AwsEc2LocationLiveTest.java
deleted file mode 100644
index 141f32b..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AwsEc2LocationLiveTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.provider;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-public class AwsEc2LocationLiveTest extends AbstractJcloudsLocationTest {
-
-    private static final String PROVIDER = "aws-ec2";
-    private static final String EUWEST_REGION_NAME = "eu-west-1";
-    private static final String USEAST_REGION_NAME = "us-east-1";
-    private static final String EUWEST_IMAGE_ID = EUWEST_REGION_NAME+"/"+"ami-89def4fd"; // RightImage_CentOS_5.4_i386_v5.5.9_EBS
-    private static final String USEAST_IMAGE_ID = USEAST_REGION_NAME+"/"+"ami-2342a94a"; // RightImage_CentOS_5.4_i386_v5.5.9_EBS
-    private static final String IMAGE_OWNER = "411009282317";
-    private static final String IMAGE_PATTERN = "RightImage_CentOS_5.4_i386_v5.5.9_EBS";
-
-    public AwsEc2LocationLiveTest() {
-        super(PROVIDER);
-    }
-
-    @Override
-    @DataProvider(name = "fromImageId")
-    public Object[][] cloudAndImageIds() {
-        return new Object[][] {
-                new Object[] { EUWEST_REGION_NAME, EUWEST_IMAGE_ID, IMAGE_OWNER },
-                new Object[] { USEAST_REGION_NAME, USEAST_IMAGE_ID, IMAGE_OWNER }
-            };
-    }
-
-    @Override
-    @DataProvider(name = "fromImageDescriptionPattern")
-    public Object[][] cloudAndImageDescriptionPatterns() {
-        return new Object[][] {
-                new Object[] { EUWEST_REGION_NAME, IMAGE_PATTERN, IMAGE_OWNER },
-                new Object[] { USEAST_REGION_NAME, IMAGE_PATTERN, IMAGE_OWNER }
-            };
-    }
-
-    @Override
-    @DataProvider(name = "fromImageNamePattern")
-    public Object[][] cloudAndImageNamePatterns() {
-        return new Object[][] {
-                new Object[] { USEAST_REGION_NAME, IMAGE_PATTERN, IMAGE_OWNER }
-            };
-    }
-
-    @Test(enabled = false)
-    public void noop() { } /* just exists to let testNG IDE run the test */
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.groovy
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.groovy b/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.groovy
deleted file mode 100644
index f19b61b..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.groovy
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.provider;
-
-import static org.testng.Assert.*
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.AfterMethod
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-import brooklyn.entity.basic.Entities
-import brooklyn.location.basic.SshMachineLocation
-import brooklyn.location.jclouds.JcloudsLocation
-import brooklyn.location.jclouds.JcloudsSshMachineLocation
-import org.apache.brooklyn.api.management.ManagementContext
-
-import com.google.common.collect.ImmutableMap
-
-public class AwsEc2LocationWindowsLiveTest {
-    private static final Logger LOG = LoggerFactory.getLogger(AwsEc2LocationWindowsLiveTest.class)
-    
-    private static final String PROVIDER = "aws-ec2"
-    private static final String EUWEST_REGION_NAME = "eu-west-1" 
-    private static final String EUWEST_IMAGE_ID = EUWEST_REGION_NAME+"/"+"ami-7f0c260b";//"ami-41d3d635"
-    private static final String LOCATION_ID = "jclouds:"+PROVIDER+":"+EUWEST_REGION_NAME;
-    
-    protected JcloudsLocation loc;
-    protected Collection<SshMachineLocation> machines = []
-    protected ManagementContext ctx;
-    
-    @BeforeMethod(groups = "Live")
-    public void setUp() {
-        ctx = Entities.newManagementContext(ImmutableMap.of("provider", PROVIDER));
-
-        loc = ctx.locationRegistry.resolve LOCATION_ID
-    }
-
-    @AfterMethod(groups = "Live")
-    public void tearDown() {
-        List<Exception> exceptions = []
-        machines.each {
-            try {
-                loc?.release(it)
-            } catch (Exception e) {
-                LOG.warn("Error releasing machine $it; continuing...", e)
-                exceptions.add(e)
-            }
-        }
-        if (exceptions) {
-            throw exceptions.get(0)
-        }
-        machines.clear()
-    }
-    
-    // TODO Note careful choice of image due to jclouds 1.4 issue 886
-    // TODO Blocks for long time, waiting for IP:22 to be reachable, before falling back to using public IP
-    //      10*2 minutes per attempt in jclouds 1.4 because done sequentially, and done twice by us so test takes 40 minutes!
-    @Test(enabled=true, groups = [ "Live" ])
-    public void testProvisionWindowsVm() {
-        JcloudsSshMachineLocation machine = obtainMachine([ imageId:EUWEST_IMAGE_ID ]);
-
-        LOG.info("Provisioned Windows VM {}; checking if has password", machine)
-        assertNotNull(machine.waitForPassword())
-    }
-    
-    // Use this utility method to ensure machines are released on tearDown
-    protected SshMachineLocation obtainMachine(Map flags) {
-        SshMachineLocation result = loc.obtain(flags)
-        machines.add(result)
-        return result
-    }
-    
-    protected SshMachineLocation release(SshMachineLocation machine) {
-        machines.remove(machine)
-        loc.release(machine)
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/CarrenzaLocationLiveTest.groovy
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/CarrenzaLocationLiveTest.groovy b/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/CarrenzaLocationLiveTest.groovy
deleted file mode 100644
index 3a06a66..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/CarrenzaLocationLiveTest.groovy
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.provider;
-
-import static org.testng.Assert.*
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.AfterMethod
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-import brooklyn.config.BrooklynProperties
-import brooklyn.location.basic.SshMachineLocation
-import brooklyn.location.jclouds.JcloudsLocation
-import brooklyn.location.jclouds.JcloudsSshMachineLocation
-import brooklyn.management.internal.LocalManagementContext
-import brooklyn.util.collections.MutableMap
-
-import com.google.common.collect.ImmutableList
-
-/**
- * Tests vcloud, with Carrenza. Uses the cloudsoft test account (hard-coding its NAT Mapping, 
- * and one of its private vApp templates). Note that the template is for a Windows 2008 
- * machine with winsshd installed.
- * 
- * TODO Will only work with >= jclouds 1.5, due to jclouds issues 994 and 995. Therefore it 
- * will not work in brooklyn 0.4.0-M2 etc.
- */
-class CarrenzaLocationLiveTest {
-    private static final Logger LOG = LoggerFactory.getLogger(CarrenzaLocationLiveTest.class)
-    
-    private static final String PROVIDER = "vcloud"
-    private static final String ENDPOINT = "https://myvdc.carrenza.net/api"
-    private static final String LOCATION_ID = "jclouds:"+PROVIDER+":"+ENDPOINT;
-    private static final String WINDOWS_IMAGE_ID = "https://myvdc.carrenza.net/api/v1.0/vAppTemplate/vappTemplate-2bd5b0ff-ecd9-405e-8306-2f4f6c092a1b"
-    
-    private BrooklynProperties brooklynProperties;
-    private LocalManagementContext managementContext;
-    private JcloudsLocation loc;
-    private Collection<SshMachineLocation> machines = []
-    
-    // TODO Has not been tested since updating ot remove use of deleted LocationRegistry!
-    @BeforeMethod(groups = "Live")
-    public void setUp() {
-        System.out.println("classpath="+System.getProperty("java.class.path"));
-        
-        brooklynProperties = BrooklynProperties.Factory.newDefault();
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-description-regex");
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-name-regex");
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-id");
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".inboundPorts");
-        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".hardware-id");
-
-        // Also removes scriptHeader (e.g. if doing `. ~/.bashrc` and `. ~/.profile`, then that can cause "stdin: is not a tty")
-        brooklynProperties.remove("brooklyn.ssh.config.scriptHeader");
-        
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".jclouds.endpoint", ENDPOINT)
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".imageId", WINDOWS_IMAGE_ID)
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".noDefaultSshKeys", true)
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".userName", "Administrator")
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".dontCreateUser", true)
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".overrideLoginUser", "Administrator")
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".waitForSshable", false)
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".runAsRoot", false)
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".inboundPorts", [22, 3389])
-        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".natMapping", [("192.168.0.100"):"195.3.186.200", ("192.168.0.101"):"195.3.186.42"])
-
-        managementContext = new LocalManagementContext(brooklynProperties);
-        loc = (JcloudsLocation) managementContext.getLocationRegistry().resolve(LOCATION_ID);
-    }
-    
-    @AfterMethod(groups = "Live")
-    public void tearDown() {
-        List<Exception> exceptions = []
-        machines.each {
-            try {
-                loc?.release(it)
-            } catch (Exception e) {
-                LOG.warn("Error releasing machine $it; continuing...", e)
-                exceptions.add(e)
-            }
-        }
-        if (exceptions) {
-            throw exceptions.get(0)
-        }
-        machines.clear()
-    }
-    
-    // FIXME Disabled because of jclouds issues #994 and #995 (fixed in jclouds 1.5, so not in brooklyn 0.4.0-M2 etc)
-    // Note the careful settings in setUp (e.g. so don't try to install ssh-keys etc
-    // Also, the windows image used has winsshd installed
-    @Test(enabled=false, groups = [ "Live" ])
-    public void testProvisionWindowsVm() {
-        JcloudsSshMachineLocation machine = obtainMachine(MutableMap.of(
-                "imageId", WINDOWS_IMAGE_ID));
-        
-        LOG.info("Provisioned Windows VM {}; checking if has password", machine)
-        String password = machine.waitForPassword();
-        assertNotNull(password);
-        
-        LOG.info("Checking can ssh to windows machine {} using password {}", machine, password);
-        assertEquals(machine.execCommands(MutableMap.of("password", password), "check-reachable", ImmutableList.of("hostname")), 0);
-    }
-    
-    // Use this utility method to ensure machines are released on tearDown
-    protected SshMachineLocation obtainMachine(Map flags) {
-        SshMachineLocation result = loc.obtain(flags)
-        machines.add(result)
-        return result
-    }
-    
-    protected SshMachineLocation release(SshMachineLocation machine) {
-        machines.remove(machine)
-        loc.release(machine)
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/GoGridLocationLiveTest.groovy
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/GoGridLocationLiveTest.groovy b/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/GoGridLocationLiveTest.groovy
deleted file mode 100644
index 6e718c8..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/GoGridLocationLiveTest.groovy
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.provider;
-
-import static org.testng.Assert.*
-
-import org.testng.annotations.DataProvider
-
-public class GoGridLocationLiveTest extends AbstractJcloudsLocationTest {
-    
-    private static final String PROVIDER = "gogrid"
-    private static final String USWEST_REGION_NAME = "1"//"us-west-1"
-    private static final String USWEST_IMAGE_ID = "1532"
-    private static final String IMAGE_NAME_PATTERN = "CentOS 5.3 (64-bit) w/ None"
-    private static final String IMAGE_OWNER = null
-    
-    public GoGridLocationLiveTest() {
-        super(PROVIDER)
-    }
-    
-    @Override
-    @DataProvider(name = "fromImageId")
-    public Object[][] cloudAndImageIds() {
-        return [ [USWEST_REGION_NAME, USWEST_IMAGE_ID, IMAGE_OWNER] ]
-    }
-
-    @Override
-    @DataProvider(name = "fromImageNamePattern")
-    public Object[][] cloudAndImageNamePatterns() {
-        return [ [USWEST_REGION_NAME, IMAGE_NAME_PATTERN, IMAGE_OWNER] ]
-    }
-    
-    @Override
-    @DataProvider(name = "fromImageDescriptionPattern")
-    public Object[][] cloudAndImageDescriptionPatterns() {
-        return []
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/RackspaceLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/RackspaceLocationLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/RackspaceLocationLiveTest.java
deleted file mode 100644
index 129b4f5..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/provider/RackspaceLocationLiveTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.provider;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsSshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-
-public class RackspaceLocationLiveTest extends AbstractJcloudsLocationTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(RackspaceLocationLiveTest.class);
-
-    private static final String PROVIDER = "rackspace-cloudservers-uk";
-    private static final String REGION_NAME = null;
-    private static final String IMAGE_ID = "LON/f70ed7c7-b42e-4d77-83d8-40fa29825b85"; // CentOS 6.4
-    private static final String IMAGE_NAME_PATTERN = "CentOS 6.4";
-    private static final String IMAGE_OWNER = null;
-
-    public RackspaceLocationLiveTest() {
-        super(PROVIDER);
-    }
-
-    @Override
-    @DataProvider(name = "fromImageId")
-    public Object[][] cloudAndImageIds() {
-        return new Object[][] {
-            new Object[] { REGION_NAME, IMAGE_ID, IMAGE_OWNER }
-        };
-    }
-
-    @Override
-    @DataProvider(name = "fromImageNamePattern")
-    public Object[][] cloudAndImageNamePatterns() {
-        return new Object[][] {
-            new Object[] { REGION_NAME, IMAGE_NAME_PATTERN, IMAGE_OWNER }
-        };
-    }
-
-    @Override
-    @DataProvider(name = "fromImageDescriptionPattern")
-    public Object[][] cloudAndImageDescriptionPatterns() {
-        return new Object[0][0];
-    }
-
-    @Test(groups = "Live")
-    public void testVmMetadata() {
-        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(PROVIDER + (REGION_NAME == null ? "" : ":" + REGION_NAME));
-        SshMachineLocation machine = obtainMachine(MutableMap.of("imageId", IMAGE_ID, "userMetadata", MutableMap.of("mykey", "myval"), JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 2));
-
-        LOG.info("Provisioned {} vm {}; checking metadata and if ssh'able", PROVIDER, machine);
-
-        Map<String,String> userMetadata = ((JcloudsSshMachineLocation)machine).getNode().getUserMetadata();
-        assertEquals(userMetadata.get("mykey"), "myval", "metadata="+userMetadata);
-        assertTrue(machine.isSshable());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
deleted file mode 100644
index cf5bece..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.zone;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-
-import org.jclouds.domain.LocationScope;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.jclouds.AbstractJcloudsLiveTest;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsSshMachineLocation;
-import brooklyn.management.internal.LocalManagementContext;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-public class AwsAvailabilityZoneExtensionTest {
-
-    public static final String PROVIDER = AbstractJcloudsLiveTest.AWS_EC2_PROVIDER;
-    public static final String REGION_NAME = AbstractJcloudsLiveTest.AWS_EC2_USEAST_REGION_NAME;
-    public static final String LOCATION_SPEC = PROVIDER + (REGION_NAME == null ? "" : ":" + REGION_NAME);
-    public static final String SMALL_HARDWARE_ID = AbstractJcloudsLiveTest.AWS_EC2_SMALL_HARDWARE_ID;
-    
-    public static final String US_EAST_IMAGE_ID = "us-east-1/ami-7d7bfc14"; // centos 6.3
-    
-    private LocalManagementContext mgmt;
-    private JcloudsLocation loc;
-    private AwsAvailabilityZoneExtension zoneExtension;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        mgmt = new LocalManagementContext();
-        loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve(LOCATION_SPEC);
-        zoneExtension = new AwsAvailabilityZoneExtension(mgmt, loc);
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (mgmt != null) Entities.destroyAll(mgmt);
-    }
-    
-    @Test(groups={"Live", "Sanity"})
-    public void testFindsZones() throws Exception {
-        List<Location> subLocations = zoneExtension.getSubLocations(Integer.MAX_VALUE);
-        List<String> zoneNames = getRegionsOf(subLocations);
-        assertTrue(subLocations.size() >= 3, "zones="+subLocations);
-        assertTrue(zoneNames.containsAll(ImmutableList.of(REGION_NAME+"a", REGION_NAME+"b", REGION_NAME+"c")), "zoneNames="+zoneNames);
-    }
-    
-    @Test(groups={"Live", "Sanity"})
-    public void testFiltersZones() throws Exception {
-        List<Location> subLocations = zoneExtension.getSubLocationsByName(Predicates.containsPattern(REGION_NAME+"[ab]"), Integer.MAX_VALUE);
-        List<String> zoneNames = getRegionsOf(subLocations);
-        assertTrue(subLocations.size() == 2, "zones="+subLocations);
-        assertTrue(zoneNames.containsAll(ImmutableList.of(REGION_NAME+"a", REGION_NAME+"b")), "zoneNames="+zoneNames);
-    }
-    
-    // TODO choosing a specific availability zone looks dangerous!
-    // TODO report this on brooklyn issues
-    //      org.jclouds.aws.AWSResponseException: request POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1 failed with code 400, 
-    //      error: AWSError{requestId='5d360cc7-9c43-4683-8093-de3b081de87d', requestToken='null', code='Unsupported', 
-    //      message='The requested Availability Zone is currently constrained and we are no longer accepting new customer requests for t1/m1/c1/m2/m3 instance types. 
-    //              Please retry your request by not specifying an Availability Zone or choosing us-east-1e, us-east-1b, us-east-1c.', context='{Response=, Errors=}'}
-    @Test(groups={"Live"})
-    public void testSubLocationIsUsable() throws Exception {
-        String zoneName = REGION_NAME+"b";
-        List<Location> subLocations = zoneExtension.getSubLocationsByName(Predicates.equalTo(zoneName), Integer.MAX_VALUE);
-        JcloudsLocation subLocation = (JcloudsLocation) Iterables.getOnlyElement(subLocations);
-        JcloudsSshMachineLocation machine = null;
-        try {
-            machine = (JcloudsSshMachineLocation)subLocation.obtain(ImmutableMap.builder()
-                    .put(JcloudsLocation.IMAGE_ID, US_EAST_IMAGE_ID)
-                    .put(JcloudsLocation.HARDWARE_ID, SMALL_HARDWARE_ID)
-                    .put(JcloudsLocation.INBOUND_PORTS, ImmutableList.of(22))
-                    .build());
-            
-            org.jclouds.domain.Location machineLoc = machine.getNode().getLocation();
-            assertEquals(machineLoc.getScope(), LocationScope.ZONE, "machineLoc="+machineLoc);
-            assertEquals(machineLoc.getId(), zoneName, "machineLoc="+machineLoc);
-        } finally {
-            if (machine != null) {
-                subLocation.release(machine);
-            }
-        }
-    }
-    
-    protected List<String> getRegionsOf(List<Location> locs) {
-        List<String> result = Lists.newArrayList();
-        for (Location loc : locs) {
-            result.add(((JcloudsLocation)loc).getRegion());
-        }
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java b/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java
index ef38050..3973ade 100644
--- a/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java
@@ -25,8 +25,8 @@ import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 
 import com.google.common.collect.ImmutableList;
 



[13/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java
new file mode 100644
index 0000000..ea93685
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java
@@ -0,0 +1,182 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.pool;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.location.jclouds.templates.PortableTemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * A facility for having a template we can declare without knowing the provider,
+ * then find matching instances, create instances, and generally manipulate them.
+ * <p>
+ * NB: to be sure of matching a specific template, you should provide a unique id in the constructor.
+ * (this will force 'strict' mode.)
+ */
+// TODO tags/metadata semantics are not quite right, as they could apply to the server _image_ or _instance_
+
+// TODO we could use a hashcode over the values of template-builder and template-options fields, as a tag/usermetadata, 
+// to guarantee (virtually) matching only machines created from this template (instead of asking for unique id)
+public class ReusableMachineTemplate extends PortableTemplateBuilder<ReusableMachineTemplate> {
+
+    public static final String PREFIX = "brooklyn:template.";
+    public static final String NAME_METADATA_KEY = PREFIX+"name";
+    public static final String DESCRIPTION_METADATA_KEY = PREFIX+"name";
+    public static final String HASH_METADATA_KEY = PREFIX+"hash";
+    public static final String TEMPLATE_OWNER_METADATA_KEY = PREFIX+"owner";
+    
+    private String name = null;
+    private String templateOwner = null;
+    private String description = null;
+    private boolean strict;
+    
+    public ReusableMachineTemplate() { strict = false; }
+    public ReusableMachineTemplate(String name) { name(name); }
+    
+    /** see #getName() */
+    public ReusableMachineTemplate name(String name) {
+        this.name = name;
+        strict = true;
+        return this;
+    }
+    
+    /** see #getDescription() */
+    public ReusableMachineTemplate description(String description) {
+        this.description = description;
+        return this;
+    }
+
+    /** whether this template only matches machines instances created from this template; 
+     * defaults true if a name is set, otherwise false.
+     * if false, it will ignore name, owner, and hashcode */
+    public ReusableMachineTemplate strict(boolean strict) {
+        this.strict = strict;
+        return this;
+    }
+
+    /** no owner, means anyone can pick this up (default) */
+    public ReusableMachineTemplate templateUnowned() {
+        return templateOwner(null);
+    }
+    /** adds user.name as owner of this template */
+    public ReusableMachineTemplate templateOwnedByMe() {
+        return templateOwner(System.getProperty("user.name"));
+    }
+    /** adds an owner tag to this template */
+    public ReusableMachineTemplate templateOwner(String owner) {
+        this.templateOwner = owner;
+        return this;
+    }
+    
+    /** human-friendly name for this template. should normally be unique, it is the primary differentiator for strict matching. */
+    public String getName() {
+        return name;
+    }
+    
+    /** a description for this template; this is set on created machines but _not_ used to filter them 
+     * (so you can change description freely).  */
+    public String getDescription() {
+        return description;
+    }
+    
+    public String getOwner() {
+        return templateOwner;
+    }
+    
+    public boolean isStrict() {
+        return strict;
+    }
+
+    @Override
+    public List<TemplateOptions> getAdditionalOptions() {
+        List<TemplateOptions> result = new ArrayList<TemplateOptions>();
+        result.addAll(super.getAdditionalOptions());
+        if (isStrict()) addStrictOptions(result);
+        return result;
+    }
+
+    @Override
+    public List<TemplateOptions> getAdditionalOptionalOptions() {
+        List<TemplateOptions> result = new ArrayList<TemplateOptions>();
+        result.addAll(super.getAdditionalOptions());
+        addStrictOptions(result);
+        return result;
+    }
+    
+    protected void addStrictOptions(List<TemplateOptions> result) {
+        if (name!=null) result.add(TemplateOptions.Builder.userMetadata(NAME_METADATA_KEY, name));
+        if (templateOwner!=null) result.add(TemplateOptions.Builder.userMetadata(TEMPLATE_OWNER_METADATA_KEY, templateOwner));
+        // this is too strict -- the hash code seems to change from run to run (would be nice to fix that)
+//        result.add(TemplateOptions.Builder.userMetadata(HASH_METADATA_KEY, ""+hashCode()));
+    }
+    
+    /** computes the user metadata that this template will set (argument true) or required to match (argument false) */
+    public Map<String,String> getUserMetadata(boolean includeOptional) {
+        return ImmutableMap.copyOf(computeAggregatedOptions(includeOptional).getUserMetadata());
+    }
+
+    /** computes the tags that this template will set (argument true) or require to match (argument false) */
+    public Set<String> getTags(boolean includeOptional) {
+        return ImmutableSet.copyOf(computeAggregatedOptions(includeOptional).getTags());
+    }
+    
+    public ReusableMachineTemplate tag(String tag) {
+        return tags(tag);
+    }
+    public ReusableMachineTemplate tags(String ...tags) {
+        return addOptions(TemplateOptions.Builder.tags(Arrays.asList(tags)));
+    }
+
+    public ReusableMachineTemplate metadata(String key, String value) {
+        return addOptions(TemplateOptions.Builder.userMetadata(key, value));
+    }
+    public ReusableMachineTemplate metadata(Map<String,String> m) {
+        return addOptions(TemplateOptions.Builder.userMetadata(m));
+    }
+
+    public ReusableMachineTemplate tagOptional(String tag) {
+        return tagsOptional(tag);
+    }
+    public ReusableMachineTemplate tagsOptional(String ...tags) {
+        return addOptionalOptions(TemplateOptions.Builder.tags(Arrays.asList(tags)));
+    }
+
+    public ReusableMachineTemplate metadataOptional(String key, String value) {
+        return addOptionalOptions(TemplateOptions.Builder.userMetadata(key, value));
+    }
+    public ReusableMachineTemplate metadataOptional(Map<String,String> m) {
+        return addOptionalOptions(TemplateOptions.Builder.userMetadata(m));
+    }
+
+    @Override
+    public String toString() {
+        String s = makeNonTrivialArgumentsString();
+        return (name!=null ? name : "Template") + " [ " + s + " ]";
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java
new file mode 100644
index 0000000..b73e7ec
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java
@@ -0,0 +1,527 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.templates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+
+public abstract class AbstractPortableTemplateBuilder<T extends AbstractPortableTemplateBuilder<?>> implements TemplateBuilder {
+
+    /** list of commands supplied by user, excluding options */
+    protected List<Function<TemplateBuilder,TemplateBuilder>> commands = new ArrayList<Function<TemplateBuilder,TemplateBuilder>>();
+    
+    private Hardware hardware;
+    private Image image;
+    private Template template;
+    private String locationId;
+    private String imageId;
+    private String hardwareId;
+    private OsFamily os;
+    private String osNameRegex;
+    private String osDescriptionRegex;
+    private String osVersionRegex;
+    private String osArchitectureRegex;
+    private String hypervisorRegex;
+    private Boolean is64bit;
+    private String imageNameRegex;
+    private String imageDescriptionRegex;
+    private String imageVersionRegex;
+    private Double minCores;
+    private Integer minRam;
+    private Double minDisk;
+    private Predicate<Image> imageCondition;
+    private Function<Iterable<? extends Image>, Image> imageChooserFunction;
+    /** this is the last options instance set by a call to options(TemplateOptions) */
+    private TemplateOptions options;
+    /** these are extra options that we want _added_, in order, on top of the last options set */
+    private List<TemplateOptions> additionalOptions = new ArrayList<TemplateOptions>();
+    
+    @Override
+    public T any() {
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.any(); }});
+        return (T)this;
+    }
+
+    @Override
+    public T fromHardware(final Hardware hardware) {
+        this.hardware = hardware;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.fromHardware(hardware); }});
+        return (T)this;
+    }
+
+    public Hardware getHardware() {
+        return hardware;
+    }
+
+    @Override
+    public T fromImage(final Image image) {
+        this.image = image;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.fromImage(image); }});
+        return (T)this;
+    }
+    
+    public Image getImage() {
+        return image;
+    }
+
+    @Override
+    public T fromTemplate(final Template template) {
+        this.template = template;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.fromTemplate(template); }});
+        return (T)this;
+    }
+    
+    public Template getTemplate() {
+        return template;
+    }
+
+    @Override
+    public T smallest() {
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.smallest(); }});
+        return (T)this;
+    }
+
+    @Override
+    public T fastest() {
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.fastest(); }});
+        return (T)this;
+    }
+
+    @Override
+    public T biggest() {
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.biggest(); }});
+        return (T)this;
+    }
+
+    @Override
+    public T locationId(final String locationId) {
+        this.locationId = locationId;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.locationId(locationId); }});
+        return (T)this;
+    }
+    
+    public String getLocationId() {
+        return locationId;
+    }
+
+    @Override
+    public T imageId(final String imageId) {
+        this.imageId = imageId;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.imageId(imageId); }});
+        return (T)this;
+    }
+    
+    public String getImageId() {
+        return imageId;
+    }
+
+    @Override
+    public T hardwareId(final String hardwareId) {
+        this.hardwareId = hardwareId;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.hardwareId(hardwareId); }});
+        return (T)this;
+    }
+    
+    public String getHardwareId() {
+        return hardwareId;
+    }
+
+    @Override
+    public T osNameMatches(final String osNameRegex) {
+        this.osNameRegex = osNameRegex;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.osNameMatches(osNameRegex); }});
+        return (T)this;
+    }
+    
+    public String getOsNameMatchesRegex() {
+        return osNameRegex;
+    }
+
+    @Override
+    public T osDescriptionMatches(final String osDescriptionRegex) {
+        this.osDescriptionRegex = osDescriptionRegex;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.osDescriptionMatches(osDescriptionRegex); }});
+        return (T)this;
+    }
+    
+    public String getOsDescriptionMatchesRegex() {
+        return osDescriptionRegex;
+    }
+
+    @Override
+    public T osVersionMatches(final String osVersionRegex) {
+        this.osVersionRegex = osVersionRegex;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.osVersionMatches(osVersionRegex); }});
+        return (T)this;
+    }
+    
+    public String getOsVersionMatchesRegex() {
+        return osVersionRegex;
+    }
+
+    @Override
+    public T osArchMatches(final String osArchitectureRegex) {
+        this.osArchitectureRegex = osArchitectureRegex;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.osArchMatches(osArchitectureRegex); }});
+        return (T)this;
+    }
+    
+    public String getOsArchitectureMatchesRegex() {
+        return osArchitectureRegex;
+    }
+
+    @Override
+    public T os64Bit(final boolean is64bit) {
+        this.is64bit = is64bit;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.os64Bit(is64bit); }});
+        return (T)this;
+    }
+    
+    public Boolean getIs64bit() {
+        return is64bit;
+    }
+
+    @Override
+    public T osFamily(final OsFamily os) {
+        this.os = os;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.osFamily(os); }});
+        return (T)this;
+    }
+    
+    public OsFamily getOsFamily() {
+        return os;
+    }
+
+    @Override
+    public T hypervisorMatches(final String hypervisorRegex) {
+        this.hypervisorRegex = hypervisorRegex;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.hypervisorMatches(hypervisorRegex); }});
+        return (T)this;
+    }
+    
+    public String getHypervisorMatchesRegex() {
+        return hypervisorRegex;
+    }
+
+    @Override
+    public T imageNameMatches(final String imageNameRegex) {
+        this.imageNameRegex = imageNameRegex;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.imageNameMatches(imageNameRegex); }});
+        return (T)this;
+    }
+    
+    public String getImageNameMatchesRegex() {
+        return imageNameRegex;
+    }
+
+    @Override
+    public T imageDescriptionMatches(final String imageDescriptionRegex) {
+        this.imageDescriptionRegex = imageDescriptionRegex;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.imageDescriptionMatches(imageDescriptionRegex); }});
+        return (T)this;
+    }
+    
+    public String getImageDescriptionMatchesRegex() {
+        return imageDescriptionRegex;
+    }
+
+    @Override
+    public T imageVersionMatches(final String imageVersionRegex) {
+        this.imageVersionRegex = imageVersionRegex;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.imageVersionMatches(imageVersionRegex); }});
+        return (T)this;
+    }
+    
+    public String getImageVersionMatchesRegex() {
+        return imageVersionRegex;
+    }
+    
+    @Override
+    public T imageMatches(final Predicate<Image> condition) {
+        this.imageCondition = condition;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.imageMatches(condition); }});
+        return (T)this;
+    }
+    
+    public Predicate<Image> getImageMatchesCondition() {
+        return imageCondition;
+    }
+
+    @Override
+    public T minCores(final double minCores) {
+        this.minCores = minCores;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.minCores(minCores); }});
+        return (T)this;
+    }
+    
+    public Double getMinCores() {
+        return minCores;
+    }
+
+    @Override
+    public T minRam(final int megabytes) {
+        this.minRam = megabytes;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.minRam(megabytes); }});
+        return (T)this;
+    }
+    
+    /** megabytes */
+    public Integer getMinRam() {
+        return minRam;
+    }
+    
+    @Override
+    public T minDisk(final double gigabytes) {
+        this.minDisk = gigabytes;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.minDisk(gigabytes); }});
+        return (T)this;
+    }
+
+    /** megabytes */
+    public Double getMinDisk() {
+        return minDisk;
+    }
+
+    public T imageChooser(final Function<Iterable<? extends Image>, Image> imageChooserFunction) {
+        this.imageChooserFunction = imageChooserFunction;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.imageChooser(imageChooserFunction); }});
+        return (T)this;
+    }
+    
+    public Function<Iterable<? extends Image>, Image> imageChooser() {
+        return imageChooserFunction;
+    }
+
+    /** clears everything set in this template, including any default from the compute service */
+    // not sure this is that useful, as the default is only applied if there are no changes
+    public T blank() {
+        hardware = null;
+        image = null;
+        template = null;
+        hypervisorRegex = null;
+        os = null;
+        locationId = null;
+        imageId = null;
+        hardwareId = null;
+        osNameRegex = null;
+        osDescriptionRegex = null;
+        osVersionRegex = null;
+        osArchitectureRegex = null;
+        is64bit = null;
+        imageNameRegex = null;
+        imageDescriptionRegex = null;
+        imageVersionRegex = null;
+        imageCondition = null;
+        minCores = null;
+        minRam = null;
+        options = null;
+        additionalOptions.clear();
+
+        // clear all fields, and commands
+        commands.clear();
+        // then add a command to clear osName + Version + 64bit
+        osFamily(null);
+        osVersionMatches(null);
+        // no way to turn off 64-bitness, but it won't usually be turned on
+//        os64bit(null);
+        // set _something_ to prevent the default from applying
+        minRam(1);
+
+        return (T)this;
+    }
+    
+    /** true if the templateBuilder spec is blank (ignoring customization options e.g. tags for the resulting instance) */
+    public boolean isBlank() {
+        if (commands.isEmpty()) return true;
+        //also "blank" if we've blanked it
+        if (commands.size()==1 && (minRam!=null && minRam==1)) return true;
+        return false;
+    }
+    
+    @Override
+    public T options(final TemplateOptions options) {
+        this.options = options;
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.options(options); }});
+        return (T)this;
+    }
+
+    /** sets customization options; may be null if not set. use addOptions(new TemplateOptions()) to set new ones. */
+    public TemplateOptions getOptions() {
+        return options;
+    }
+    
+    /** adds customization options; if options have already been set, this will additively set selected options
+     * (but not all, see addTemplateOptions for more info)
+     */
+    public T addOptions(final TemplateOptions options) {
+        this.additionalOptions.add(options);
+        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
+            public TemplateBuilder apply(TemplateBuilder b) { return b.options(options); }});
+        return (T)this;
+    }
+
+    public List<TemplateOptions> getAdditionalOptions() {
+        return ImmutableList.copyOf(additionalOptions);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(
+                hypervisorRegex,
+                os,
+                locationId,
+                hardwareId,
+                imageId,
+                imageDescriptionRegex,
+                imageNameRegex,
+                imageVersionRegex,
+                // might not be implement hashCode, so ignore
+//                imageCondition,
+//                imageChooserFunction,
+                is64bit,
+                locationId,
+                osArchitectureRegex,
+                osDescriptionRegex,
+                osNameRegex,
+                osVersionRegex,
+                minCores,
+                minRam,
+                minDisk,
+                options,
+                additionalOptions,
+                // might not implement hashCode, so ignore
+//                template,
+                0);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        AbstractPortableTemplateBuilder other = (AbstractPortableTemplateBuilder) obj;
+        if (!Objects.equal(additionalOptions, other.additionalOptions)) return false;
+        if (!Objects.equal(commands, other.commands)) return false;
+        if (!Objects.equal(locationId, other.locationId)) return false;
+        if (!Objects.equal(hardware, other.hardware)) return false;
+        if (!Objects.equal(hardwareId, other.hardwareId)) return false;
+        if (!Objects.equal(image, other.image)) return false;
+        if (!Objects.equal(imageId, other.imageId)) return false;
+        if (!Objects.equal(imageDescriptionRegex, other.imageDescriptionRegex)) return false;
+        if (!Objects.equal(imageNameRegex, other.imageNameRegex)) return false;
+        if (!Objects.equal(imageVersionRegex, other.imageVersionRegex)) return false;
+        if (!Objects.equal(imageCondition, other.imageCondition)) return false;
+        if (!Objects.equal(imageChooserFunction, other.imageChooserFunction)) return false;
+        if (!Objects.equal(os, other.os)) return false;
+        if (!Objects.equal(osArchitectureRegex, other.osArchitectureRegex)) return false;
+        if (!Objects.equal(osDescriptionRegex, other.osDescriptionRegex)) return false;
+        if (!Objects.equal(osNameRegex, other.osNameRegex)) return false;
+        if (!Objects.equal(osVersionRegex, other.osVersionRegex)) return false;
+        if (!Objects.equal(is64bit, other.is64bit)) return false;
+        if (!Objects.equal(hypervisorRegex, other.hypervisorRegex)) return false;
+        if (!Objects.equal(minCores, other.minCores)) return false;
+        if (!Objects.equal(minRam, other.minRam)) return false;
+        if (!Objects.equal(minDisk, other.minDisk)) return false;
+        if (!Objects.equal(options, other.options)) return false;
+        if (!Objects.equal(template, other.template)) return false;
+        return true;
+    }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName()+"["+makeNonTrivialArgumentsString()+"]";
+    }
+
+    protected String makeNonTrivialArgumentsString() {
+        String s =
+                  (hardware != null ? "hardware=" + hardware + ", " : "")
+                + (image != null ? "image=" + image + ", " : "")
+                + (template != null ? "template=" + template + ", " : "")
+                + (hypervisorRegex != null ? "hypervisorRegex="
+                        + hypervisorRegex + ", " : "")
+                + (os != null ? "os=" + os + ", " : "")
+                + (locationId != null ? "locationId=" + locationId + ", " : "")
+                + (imageId != null ? "imageId=" + imageId + ", " : "")
+                + (hardwareId != null ? "hardwareId=" + hardwareId + ", " : "")
+                + (osNameRegex != null ? "osNameRegex=" + osNameRegex + ", "
+                        : "")
+                + (osDescriptionRegex != null ? "osDescriptionRegex="
+                        + osDescriptionRegex + ", " : "")
+                + (osVersionRegex != null ? "osVersionRegex=" + osVersionRegex
+                        + ", " : "")
+                + (osArchitectureRegex != null ? "osArchictectureRegex="
+                        + osArchitectureRegex + ", " : "")
+                + (is64bit != null ? "is64bit=" + is64bit + ", " : "")
+                + (imageNameRegex != null ? "imageNameRegex=" + imageNameRegex
+                        + ", " : "")
+                + (imageDescriptionRegex != null ? "imageDescriptionRegex="
+                        + imageDescriptionRegex + ", " : "")
+                + (imageVersionRegex != null ? "imageVersionRegex="
+                        + imageVersionRegex + ", " : "")
+                + (imageCondition != null ? "imageCondition=" + imageCondition
+                        + ", " : "")
+                + (imageChooserFunction != null ? "imageChooserFunction=" + imageChooserFunction
+                        + ", " : "")
+                + (minCores != null ? "minCores=" + minCores + ", " : "")
+                + (minRam != null ? "minRam=" + minRam + ", " : "")
+                + (minDisk != null ? "minDisk=" + minDisk + ", " : "");
+        if (s.endsWith(", ")) s = s.substring(0, s.length()-2);
+        return s;
+    }    
+
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java
new file mode 100644
index 0000000..eaea03b
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java
@@ -0,0 +1,145 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.templates;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.domain.TemplateBuilderSpec;
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.primitives.Ints;
+
+
+public class PortableTemplateBuilder<T extends PortableTemplateBuilder<?>> extends AbstractPortableTemplateBuilder<T> {
+    
+    ComputeService svc;
+    List<TemplateOptions> additionalOptionalOptions = new ArrayList<TemplateOptions>();
+
+    @Override
+    public synchronized Template build() {
+        if (svc!=null) return newJcloudsTemplate(svc);
+        throw new IllegalStateException("Cannot build a portable template until a compute service is attached");
+    }
+    
+    public synchronized ComputeService attachComputeService(ComputeService svc) {
+        ComputeService old = this.svc;
+        this.svc = svc;
+        return old;
+    }
+
+    public TemplateBuilder newJcloudsTemplateBuilder(ComputeService svc) {
+        TemplateBuilder tb = svc.templateBuilder();
+        for (Function<TemplateBuilder,TemplateBuilder> c: commands) {
+            tb = c.apply(tb);
+        }
+        
+        tb.options(computeAggregatedOptions(true));
+        
+        return tb;
+    }
+
+    public Template newJcloudsTemplate(ComputeService svc) {
+        return newJcloudsTemplateBuilder(svc).build();
+    }
+
+    /** Adds template options which are used for building, but not for matching/filtering. 
+     * (eg tags added here will be set on any machine created by this template,
+     * but will not be required when matching this template to existing machines) */
+    @SuppressWarnings("unchecked")
+    public T addOptionalOptions(TemplateOptions options) {
+        additionalOptionalOptions.add(options);
+        return (T)this;
+    }
+    
+    protected TemplateOptions computeAggregatedOptions(boolean includeOptional) {
+        TemplateOptions result;
+        if (getOptions()!=null) result = getOptions().clone();
+        else result = new TemplateOptions();
+        if (includeOptional)
+            for (TemplateOptions moreOptions: getAdditionalOptionalOptions()) result = addTemplateOptions(result, moreOptions);
+        for (TemplateOptions moreOptions: getAdditionalOptions()) result = addTemplateOptions(result, moreOptions);
+        return result;
+    }
+    
+    public List<TemplateOptions> getAdditionalOptionalOptions() {
+        return ImmutableList.copyOf(additionalOptionalOptions);
+    }
+    
+    /** like TemplateOptions.copyTo but additive wrt arrays, collections, and maps,
+     * putting moreOptions in on top of / at the end of options.
+     * currently applies to inboundPorts, tags, and userMetadata. */
+    public static TemplateOptions addTemplateOptions(TemplateOptions options, TemplateOptions moreOptions) {
+        TemplateOptions result = options.clone();
+        moreOptions.copyTo(result);
+        
+        Set<String> tags = new LinkedHashSet<String>(options.getTags());
+        tags.addAll(moreOptions.getTags());
+        result.tags(tags);
+
+        Map<String,String> userMetadata = new LinkedHashMap<String,String>(options.getUserMetadata());
+        userMetadata.putAll(moreOptions.getUserMetadata());
+        result.userMetadata(userMetadata);
+        
+        Set<Integer> inboundPorts = new TreeSet<Integer>();
+        for (int port: options.getInboundPorts()) inboundPorts.add(port);
+        for (int port: moreOptions.getInboundPorts()) inboundPorts.add(port);
+        int[] inboundPortsArray = new int[inboundPorts.size()];
+        int i=0;
+        for (Iterator<Integer> portI=inboundPorts.iterator(); portI.hasNext();) {
+            inboundPortsArray[i++] = portI.next();
+        }
+        result.inboundPorts(inboundPortsArray);
+        
+        return result;
+    }
+
+    protected String makeNonTrivialArgumentsString() {
+        String s = super.makeNonTrivialArgumentsString();
+        TemplateOptions aggr = computeAggregatedOptions(false);
+        if (aggr.getInboundPorts().length>0) s = "ports="+Ints.asList(aggr.getInboundPorts())+(s!=null && s.length()>0 ? ", "+s : "");
+        if (!aggr.getUserMetadata().isEmpty()) s = "metadata="+aggr.getUserMetadata()+(s!=null && s.length()>0 ? ", "+s : "");
+        if (!aggr.getTags().isEmpty()) s = "tags="+aggr.getTags()+(s!=null && s.length()>0 ? ", "+s : "");
+        return s;
+    }
+    
+    @Override
+    public TemplateBuilder from(TemplateBuilderSpec spec) {
+        TemplateOptions options = new TemplateOptions();
+        addOptionalOptions(options);
+        TemplateBuilder result = spec.copyTo(this, options);
+        return result;
+    }
+
+    @Override
+    public TemplateBuilder from(String spec) {
+        return from(TemplateBuilderSpec.parse(spec));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
new file mode 100644
index 0000000..dcb6b4c
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
@@ -0,0 +1,74 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.zone;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.ec2.domain.AvailabilityZoneInfo;
+
+import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+public class AwsAvailabilityZoneExtension extends AbstractAvailabilityZoneExtension implements AvailabilityZoneExtension {
+
+    private final JcloudsLocation loc;
+    
+    public AwsAvailabilityZoneExtension(ManagementContext managementContext, JcloudsLocation loc) {
+        super(managementContext);
+        this.loc = checkNotNull(loc, "loc");
+        checkArgument(loc.getProvider().equals("aws-ec2"), "provider not aws-ec2 (%s)", loc.getProvider());
+    }
+
+    @Override
+    protected List<Location> doGetAllSubLocations() {
+        List<Location> result = Lists.newArrayList();
+        Set<AvailabilityZoneInfo> zones = getAvailabilityZones();
+        for (AvailabilityZoneInfo zone : zones) {
+            result.add(newSubLocation(loc, zone));
+        }
+        return result;
+    }
+    
+    @Override
+    protected boolean isNameMatch(Location loc, Predicate<? super String> namePredicate) {
+        return namePredicate.apply(((JcloudsLocation)loc).getRegion());
+    }
+    
+    protected Set<AvailabilityZoneInfo> getAvailabilityZones() {
+        String regionName = loc.getRegion();
+        AWSEC2Api ec2Client = loc.getComputeService().getContext().unwrapApi(AWSEC2Api.class);
+        return ec2Client.getAvailabilityZoneAndRegionApi().get().describeAvailabilityZonesInRegion(regionName);
+    }
+    
+    protected JcloudsLocation newSubLocation(Location parent, AvailabilityZoneInfo zone) {
+        return loc.newSubLocation(ImmutableMap.of(JcloudsLocation.CLOUD_REGION_ID, zone.getZone()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/resources/META-INF/services/brooklyn.location.LocationResolver b/locations/jclouds/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
deleted file mode 100644
index 5b1c084..0000000
--- a/locations/jclouds/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
+++ /dev/null
@@ -1,2 +0,0 @@
-brooklyn.location.jclouds.JcloudsLocationResolver
-brooklyn.location.jclouds.JcloudsByonLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver b/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
new file mode 100644
index 0000000..e29b717
--- /dev/null
+++ b/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
@@ -0,0 +1,2 @@
+org.apache.brooklyn.location.jclouds.JcloudsLocationResolver
+org.apache.brooklyn.location.jclouds.JcloudsByonLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreCleaner.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreCleaner.java b/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreCleaner.java
index dcce68a..eb1654e 100644
--- a/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreCleaner.java
+++ b/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreCleaner.java
@@ -29,9 +29,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.BrooklynProperties;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 
 /** Utility for cleaning up after test leaks. Most should not leak of course, but if they do... */
 public class BlobStoreCleaner {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreExpiryTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreExpiryTest.java b/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreExpiryTest.java
index c29bf79..6260a8c 100644
--- a/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreExpiryTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreExpiryTest.java
@@ -44,10 +44,10 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsUtil;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsUtil;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreTest.java b/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreTest.java
index f9ba3a9..0553fd0 100644
--- a/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/BlobStoreTest.java
@@ -36,10 +36,10 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsUtil;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsUtil;
 import brooklyn.util.stream.Streams;
 import brooklyn.util.text.Identifiers;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/JcloudsExpect100ContinueTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/JcloudsExpect100ContinueTest.java b/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/JcloudsExpect100ContinueTest.java
index eaaf0f8..556c3c3 100644
--- a/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/JcloudsExpect100ContinueTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/entity/rebind/persister/jclouds/JcloudsExpect100ContinueTest.java
@@ -30,8 +30,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsUtil;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsUtil;
 import brooklyn.util.text.Identifiers;
 import ch.qos.logback.classic.Level;
 import ch.qos.logback.classic.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
deleted file mode 100644
index d84ce5c..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.exceptions.CompoundRuntimeException;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-
-public class AbstractJcloudsLiveTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractJcloudsLiveTest.class);
-
-    public static final String BROOKLYN_PROPERTIES_PREFIX = "brooklyn.location.jclouds.";
-    public static final String BROOKLYN_PROPERTIES_LEGACY_PREFIX = "brooklyn.jclouds.";
-    
-    public static final String AWS_EC2_PROVIDER = "aws-ec2";
-    public static final String AWS_EC2_MICRO_HARDWARE_ID = "t1.micro";
-    public static final String AWS_EC2_SMALL_HARDWARE_ID = "m1.small";
-    public static final String AWS_EC2_EUWEST_REGION_NAME = "eu-west-1";
-    public static final String AWS_EC2_USEAST_REGION_NAME = "us-east-1";
-
-    public static final String RACKSPACE_PROVIDER = "rackspace-cloudservers-uk";
-    
-    public static final String SOFTLAYER_PROVIDER = "softlayer";
-    public static final String SOFTLAYER_AMS01_REGION_NAME = "ams01";
-    
-    protected BrooklynProperties brooklynProperties;
-    protected LocalManagementContext managementContext;
-    
-    protected List<JcloudsSshMachineLocation> machines;
-    protected JcloudsLocation jcloudsLocation;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        machines = Lists.newCopyOnWriteArrayList();
-        managementContext = newManagementContext();
-        
-        // Don't let any defaults from brooklyn.properties (except credentials) interfere with test
-        brooklynProperties = managementContext.getBrooklynProperties();
-        stripBrooklynProperties(brooklynProperties);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        List<Exception> exceptions = Lists.newArrayList();
-        try {
-            if (machines != null) {
-                for (JcloudsSshMachineLocation machine : machines) {
-                    try {
-                        releaseMachine(machine);
-                    } catch (Exception e) {
-                        LOG.warn("Error releasing machine "+machine+"; continuing...", e);
-                        exceptions.add(e);
-                    }
-                }
-                machines.clear();
-            }
-        } finally {
-            try {
-                if (managementContext != null) Entities.destroyAll(managementContext);
-            } catch (Exception e) {
-                LOG.warn("Error destroying management context", e);
-                exceptions.add(e);
-            }
-        }
-        
-        // TODO Debate about whether to:
-        //  - use destroyAllCatching (i.e. not propagating exception)
-        //    Benefit is that other tests in class will subsequently be run, rather than bailing out.
-        //  - propagate exceptions from tearDown
-        //    Benefit is that we don't hide errors; release(...) etc should not be throwing exceptions.
-        if (exceptions.size() > 0) {
-            throw new CompoundRuntimeException("Error in tearDown of "+getClass(), exceptions);
-        }
-    }
-
-    protected LocalManagementContext newManagementContext() {
-        // loads properties, by default, but not OSGi or anything else
-        return LocalManagementContextForTests.builder(true).useDefaultProperties().build();
-    }
-    
-    protected void stripBrooklynProperties(BrooklynProperties props) {
-        // remove all location properties except for identity and credential
-        // (so key, scripts, etc settings don't interfere with tests) 
-        for (String key : ImmutableSet.copyOf(props.asMapWithStringKeys().keySet())) {
-            if (key.startsWith(BROOKLYN_PROPERTIES_PREFIX) && !(key.endsWith("identity") || key.endsWith("credential"))) {
-                props.remove(key);
-            }
-            if (key.startsWith(BROOKLYN_PROPERTIES_LEGACY_PREFIX) && !(key.endsWith("identity") || key.endsWith("credential"))) {
-                props.remove(key);
-            }
-            
-            // Also removes scriptHeader (e.g. if doing `. ~/.bashrc` and `. ~/.profile`, then that can cause "stdin: is not a tty")
-            if (key.startsWith("brooklyn.ssh")) {
-                props.remove(key);
-            }
-        }
-    }
-    
-    protected void assertSshable(SshMachineLocation machine) {
-        int result = machine.execScript("simplecommand", ImmutableList.of("true"));
-        assertEquals(result, 0);
-    }
-
-    // Use this utility method to ensure machines are released on tearDown
-    protected JcloudsSshMachineLocation obtainMachine(Map<?, ?> conf) throws Exception {
-        assertNotNull(jcloudsLocation);
-        JcloudsSshMachineLocation result = (JcloudsSshMachineLocation)jcloudsLocation.obtain(conf);
-        machines.add(checkNotNull(result, "result"));
-        return result;
-    }
-
-    protected JcloudsSshMachineLocation obtainMachine() throws Exception {
-        return obtainMachine(ImmutableMap.of());
-    }
-    
-    protected void releaseMachine(JcloudsSshMachineLocation machine) {
-        assertNotNull(jcloudsLocation);
-        machines.remove(machine);
-        jcloudsLocation.release(machine);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/AbstractJcloudsStubbedLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/AbstractJcloudsStubbedLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/AbstractJcloudsStubbedLiveTest.java
deleted file mode 100644
index 3b8a4f4..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/AbstractJcloudsStubbedLiveTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.List;
-import java.util.Set;
-
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.RunNodesException;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.NodeMetadata.Status;
-import org.jclouds.compute.domain.NodeMetadataBuilder;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.domain.LoginCredentials;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-
-import brooklyn.location.jclouds.ComputeServiceRegistry;
-import brooklyn.location.jclouds.ComputeServiceRegistryImpl;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsLocationConfig;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-/**
- * The VM creation is stubbed out, but it still requires live access (i.e. real account credentials)
- * to generate the template etc.
- * 
- * We supply a ComputeServiceRegistry that delegates to the real instance for everything except
- * VM creation and deletion. For those operations, it delegates to a NodeCreator that 
- * returns a dummy NodeMetadata, recording all calls made to it.
- */
-public abstract class AbstractJcloudsStubbedLiveTest extends AbstractJcloudsLiveTest {
-
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(AbstractJcloudsStubbedLiveTest.class);
-
-    public static final String LOCATION_SPEC = "jclouds:" + SOFTLAYER_PROVIDER + ":" + SOFTLAYER_AMS01_REGION_NAME;
-    
-    public static abstract class NodeCreator {
-        public final List<NodeMetadata> created = Lists.newCopyOnWriteArrayList();
-        public final List<String> destroyed = Lists.newCopyOnWriteArrayList();
-        
-        public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template) throws RunNodesException {
-            Set<NodeMetadata> result = Sets.newLinkedHashSet();
-            for (int i = 0; i < count; i++) {
-                NodeMetadata node = newNode(group, template);
-                created.add(node);
-                result.add(node);
-            }
-            return result;
-        }
-        public void destroyNode(String id) {
-            destroyed.add(id);
-        }
-        protected abstract NodeMetadata newNode(String group, Template template);
-    }
-    
-    public static class StubbedComputeService extends DelegatingComputeService {
-        private final NodeCreator nodeCreator;
-        
-        public StubbedComputeService(ComputeService delegate, NodeCreator nodeCreator) {
-            super(delegate);
-            this.nodeCreator = nodeCreator;
-        }
-        @Override
-        public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template) throws RunNodesException {
-            return nodeCreator.createNodesInGroup(group, count, template);
-        }
-        @Override
-        public void destroyNode(String id) {
-            nodeCreator.destroyNode(id);
-        }
-        @Override
-        public Set<? extends NodeMetadata> createNodesInGroup(String group, int count) {
-            throw new UnsupportedOperationException();
-        }
-        @Override
-        public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, TemplateOptions templateOptions) {
-            throw new UnsupportedOperationException();
-        }
-        @Override
-        public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
-            throw new UnsupportedOperationException();
-        }
-    }
-    
-    protected NodeCreator nodeCreator;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        nodeCreator = newNodeCreator();
-        ComputeServiceRegistry computeServiceRegistry = new ComputeServiceRegistry() {
-            @Override
-            public ComputeService findComputeService(ConfigBag conf, boolean allowReuse) {
-                ComputeService delegate = ComputeServiceRegistryImpl.INSTANCE.findComputeService(conf, allowReuse);
-                return new StubbedComputeService(delegate, nodeCreator);
-            }
-        };
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(
-                LOCATION_SPEC, 
-                ImmutableMap.of(
-                        JcloudsLocationConfig.COMPUTE_SERVICE_REGISTRY, computeServiceRegistry,
-                        JcloudsLocationConfig.WAIT_FOR_SSHABLE, "false"));
-    }
-    
-    protected abstract NodeCreator newNodeCreator();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/BailOutJcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/BailOutJcloudsLocation.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/BailOutJcloudsLocation.java
deleted file mode 100644
index d952c5b..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/BailOutJcloudsLocation.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Collections;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.Template;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.reflect.TypeToken;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.LocationSpec;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.CompoundRuntimeException;
-import brooklyn.util.exceptions.Exceptions;
-
-public class BailOutJcloudsLocation extends JcloudsLocation {
-
-    // Don't care which image; not actually provisioning
-    private static final String US_EAST_IMAGE_ID = "us-east-1/ami-7d7bfc14";
-    public static final RuntimeException BAIL_OUT_FOR_TESTING = new RuntimeException("early termination for test");
-
-    public static final ConfigKey<Function<ConfigBag, Void>> BUILD_TEMPLATE_INTERCEPTOR = ConfigKeys.newConfigKey(
-            new TypeToken<Function<ConfigBag, Void>>() {},
-            "buildtemplateinterceptor");
-
-    public static final ConfigKey<Boolean> BUILD_TEMPLATE = ConfigKeys.newBooleanConfigKey(
-            "buildtemplate");
-
-    private static final long serialVersionUID = -3373789512935057842L;
-
-    ConfigBag lastConfigBag;
-    Template template;
-
-    public BailOutJcloudsLocation() {
-        super();
-    }
-
-    public BailOutJcloudsLocation(Map<?, ?> conf) {
-        super(conf);
-    }
-
-    @Override
-    public Template buildTemplate(ComputeService computeService, ConfigBag config) {
-        lastConfigBag = config;
-        if (getConfig(BUILD_TEMPLATE_INTERCEPTOR) != null) {
-            getConfig(BUILD_TEMPLATE_INTERCEPTOR).apply(config);
-        }
-        if (Boolean.TRUE.equals(getConfig(BUILD_TEMPLATE))) {
-            template = super.buildTemplate(computeService, config);
-        }
-        throw BAIL_OUT_FOR_TESTING;
-    }
-
-    public Template getTemplate() {
-        return template;
-    }
-
-    public void tryObtain() {
-        tryObtain(Collections.emptyMap());
-    }
-
-    public void tryObtain(Map<?, ?> flags) {
-        tryObtainAndCheck(flags, Predicates.alwaysTrue());
-    }
-
-    public void tryObtainAndCheck(Map<?, ?> flags, Predicate<? super ConfigBag> test) {
-        try {
-            obtain(flags);
-        } catch (Exception e) {
-            if (e == BAIL_OUT_FOR_TESTING || e.getCause() == BAIL_OUT_FOR_TESTING
-                    || (e instanceof CompoundRuntimeException && ((CompoundRuntimeException) e).getAllCauses().contains(BAIL_OUT_FOR_TESTING))) {
-                test.apply(lastConfigBag);
-            } else {
-                throw Exceptions.propagate(e);
-            }
-        }
-    }
-
-    @Override
-    @VisibleForTesting
-    public UserCreation createUserStatements(@Nullable Image image, ConfigBag config) {
-        return super.createUserStatements(image, config);
-    }
-
-
-    public static BailOutJcloudsLocation newBailOutJcloudsLocation(ManagementContext mgmt) {
-        return newBailOutJcloudsLocation(mgmt, Collections.<ConfigKey<?>, Object>emptyMap());
-    }
-
-    public static BailOutJcloudsLocation newBailOutJcloudsLocation(ManagementContext mgmt, Map<ConfigKey<?>, ?> config) {
-        Map<ConfigKey<?>, ?> allConfig = MutableMap.<ConfigKey<?>, Object>builder()
-                .put(IMAGE_ID, "bogus")
-                .put(CLOUD_PROVIDER, "aws-ec2")
-                .put(ACCESS_IDENTITY, "bogus")
-                .put(CLOUD_REGION_ID, "bogus")
-                .put(ACCESS_CREDENTIAL, "bogus")
-                .put(USER, "fred")
-                .put(MIN_RAM, 16)
-                .put(JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 1)
-                .putAll(config)
-                .build();
-        return mgmt.getLocationManager().createLocation(
-                LocationSpec.create(BailOutJcloudsLocation.class).configure(allConfig));
-    }
-
-
-    // todo better name
-
-    /** As {@link BailOutJcloudsLocation}, counting the number of {@link #buildTemplate} calls. */
-    public static class CountingBailOutJcloudsLocation extends BailOutJcloudsLocation {
-        private static final long serialVersionUID = 2433684033045735773L;
-        int buildTemplateCount = 0;
-        @Override
-        public Template buildTemplate(ComputeService computeService, ConfigBag config) {
-            buildTemplateCount++;
-            return super.buildTemplate(computeService, config);
-        }
-    }
-
-    public static CountingBailOutJcloudsLocation newCountingBailOutJcloudsLocation(ManagementContext mgmt, Map flags) {
-        LocationSpec<CountingBailOutJcloudsLocation> spec = LocationSpec.create(CountingBailOutJcloudsLocation.class)
-                .configure(flags);
-        return mgmt.getLocationManager().createLocation(spec);
-    }
-
-    /** @see #newBailOutJcloudsLocationForLiveTest(LocalManagementContext, Map)} */
-    public static BailOutJcloudsLocation newBailOutJcloudsLocationForLiveTest(LocalManagementContext mgmt) {
-        return newBailOutJcloudsLocationForLiveTest(mgmt, Collections.<ConfigKey<?>, Object>emptyMap());
-    }
-
-    /**
-     * Takes identity and access credential from management context's Brooklyn properties and sets
-     * inbound ports to [22, 80, 9999].
-     */
-    public static BailOutJcloudsLocation newBailOutJcloudsLocationForLiveTest(LocalManagementContext mgmt, Map<ConfigKey<?>, ?> config) {
-        BrooklynProperties brooklynProperties = mgmt.getBrooklynProperties();
-        String identity = (String) brooklynProperties.get("brooklyn.location.jclouds.aws-ec2.identity");
-        if (identity == null) identity = (String) brooklynProperties.get("brooklyn.jclouds.aws-ec2.identity");
-        String credential = (String) brooklynProperties.get("brooklyn.location.jclouds.aws-ec2.credential");
-        if (credential == null) credential = (String) brooklynProperties.get("brooklyn.jclouds.aws-ec2.credential");
-
-        Map<ConfigKey<?>, ?> allConfig = MutableMap.<ConfigKey<?>, Object>builder()
-                .put(CLOUD_PROVIDER, AbstractJcloudsLiveTest.AWS_EC2_PROVIDER)
-                .put(CLOUD_REGION_ID, AbstractJcloudsLiveTest.AWS_EC2_USEAST_REGION_NAME)
-                .put(IMAGE_ID, US_EAST_IMAGE_ID) // so Brooklyn does not attempt to load all EC2 images
-                .put(ACCESS_IDENTITY, identity)
-                .put(ACCESS_CREDENTIAL, credential)
-                .put(INBOUND_PORTS, "[22, 80, 9999]")
-                .put(BUILD_TEMPLATE, true)
-                .putAll(config)
-                .build();
-
-        return newBailOutJcloudsLocation(mgmt, allConfig);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/BrooklynMachinePoolLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/BrooklynMachinePoolLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/BrooklynMachinePoolLiveTest.java
deleted file mode 100644
index 7a52f04..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/BrooklynMachinePoolLiveTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.jclouds.pool.MachinePoolPredicates;
-import brooklyn.location.jclouds.pool.MachineSet;
-import brooklyn.location.jclouds.pool.ReusableMachineTemplate;
-import brooklyn.management.internal.LocalManagementContext;
-
-public class BrooklynMachinePoolLiveTest {
-
-    public static final Logger log = LoggerFactory.getLogger(BrooklynMachinePoolLiveTest.class);
-    
-    public static class SamplePool extends BrooklynMachinePool {
-        public SamplePool(JcloudsLocation l) {
-            super(l);
-        }
-
-        public final static ReusableMachineTemplate 
-            USUAL_VM = 
-                new ReusableMachineTemplate("usual").templateOwnedByMe().
-                tagOptional("tagForUsualVm").
-                metadataOptional("metadataForUsualVm", "12345").
-                minRam(1024).minCores(2);
-
-        public final static ReusableMachineTemplate 
-            ANYONE_NOT_TINY_VM = 
-                new ReusableMachineTemplate("anyone").
-                minRam(512).minCores(1).strict(false);
-
-        public static final ReusableMachineTemplate 
-            VM_LARGE1 = 
-                new ReusableMachineTemplate("vm.large1").templateOwnedByMe().
-                minRam(16384).minCores(4),
-            VM_SMALL1 = 
-                new ReusableMachineTemplate("vm.small1").templateOwnedByMe().smallest();
-        
-        { registerTemplates(USUAL_VM, ANYONE_NOT_TINY_VM, VM_LARGE1, VM_SMALL1); }
-    }
-
-
-    private LocalManagementContext managementContext;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = new LocalManagementContext();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) managementContext.terminate();
-    }
-    
-    @Test(groups="Live")
-    public void buildClaimAndDestroy() {
-        SamplePool p = new SamplePool(resolve("aws-ec2:us-west-1"));
-        log.info("buildClaimAndDestroy: created pool");
-        p.refresh();
-        log.info("buildClaimAndDestroy: refreshed pool");
-        p.ensureExists(2, SamplePool.USUAL_VM);
-        log.info("buildClaimAndDestroy: ensure have 2");
-        SshMachineLocation l = p.obtain(SamplePool.USUAL_VM);
-        Assert.assertNotNull(l);
-        log.info("buildClaimAndDestroy: claimed 1");
-        MachineSet unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM));
-        log.info("buildClaimAndDestroy: unclaimed now "+unclaimedUsual);
-        Assert.assertTrue(!unclaimedUsual.isEmpty(), "should have been unclaimed machines (can fail if there are some we cannot connect to, ie blacklisted)");
-        p.destroy(unclaimedUsual);
-        p.destroy(l);
-        unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM));
-        log.info("buildClaimAndDestroy: destroyed, unclaimed now "+unclaimedUsual);
-        log.info("end");
-    }
-    
-
-    private JcloudsLocation resolve(String spec) {
-        return (JcloudsLocation) managementContext.getLocationRegistry().resolve(new JcloudsLocationResolver().getPrefix() + ":" + spec);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/DelegatingComputeService.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/DelegatingComputeService.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/DelegatingComputeService.java
deleted file mode 100644
index 62f621e..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/DelegatingComputeService.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.RunNodesException;
-import org.jclouds.compute.RunScriptOnNodesException;
-import org.jclouds.compute.domain.ComputeMetadata;
-import org.jclouds.compute.domain.ExecResponse;
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.extensions.ImageExtension;
-import org.jclouds.compute.extensions.SecurityGroupExtension;
-import org.jclouds.compute.options.RunScriptOptions;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.domain.Location;
-import org.jclouds.scriptbuilder.domain.Statement;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.util.concurrent.ListenableFuture;
-
-public class DelegatingComputeService implements ComputeService {
-
-    private final ComputeService delegate;
-    
-    public DelegatingComputeService(ComputeService delegate) {
-        this.delegate = delegate;
-    }
-    
-    @Override
-    public ComputeServiceContext getContext() {
-        return delegate.getContext();
-    }
-
-    @Override
-    public TemplateBuilder templateBuilder() {
-        return delegate.templateBuilder();
-    }
-
-    @Override
-    public TemplateOptions templateOptions() {
-        return delegate.templateOptions();
-    }
-
-    @Override
-    public Set<? extends Hardware> listHardwareProfiles() {
-        return delegate.listHardwareProfiles();
-    }
-
-    @Override
-    public Set<? extends Image> listImages() {
-        return delegate.listImages();
-    }
-
-    @Override
-    public Image getImage(String id) {
-        return delegate.getImage(id);
-    }
-
-    @Override
-    public Set<? extends ComputeMetadata> listNodes() {
-        return delegate.listNodes();
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> listNodesByIds(Iterable<String> ids) {
-        return delegate.listNodesByIds(ids);
-    }
-
-    @Override
-    public Set<? extends Location> listAssignableLocations() {
-        return delegate.listAssignableLocations();
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template) throws RunNodesException {
-        return delegate.createNodesInGroup(group, count, template);
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, TemplateOptions templateOptions)
-            throws RunNodesException {
-        return delegate.createNodesInGroup(group, count, templateOptions);
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> createNodesInGroup(String group, int count) throws RunNodesException {
-        return delegate.createNodesInGroup(group, count);
-    }
-
-    @Override
-    public void resumeNode(String id) {
-        delegate.resumeNode(id);
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> resumeNodesMatching(Predicate<NodeMetadata> filter) {
-        return delegate.resumeNodesMatching(filter);
-    }
-
-    @Override
-    public void suspendNode(String id) {
-        delegate.suspendNode(id);
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> suspendNodesMatching(Predicate<NodeMetadata> filter) {
-        return delegate.suspendNodesMatching(filter);
-    }
-
-    @Override
-    public void destroyNode(String id) {
-        delegate.destroyNode(id);
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
-        return delegate.destroyNodesMatching(filter);
-    }
-
-    @Override
-    public void rebootNode(String id) {
-        delegate.rebootNode(id);
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> rebootNodesMatching(Predicate<NodeMetadata> filter) {
-        return delegate.rebootNodesMatching(filter);
-    }
-
-    @Override
-    public NodeMetadata getNodeMetadata(String id) {
-        return delegate.getNodeMetadata(id);
-    }
-
-    @Override
-    public Set<? extends NodeMetadata> listNodesDetailsMatching(Predicate<ComputeMetadata> filter) {
-        return delegate.listNodesDetailsMatching(filter);
-    }
-
-    @Override
-    public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, String runScript)
-            throws RunScriptOnNodesException {
-        return delegate.runScriptOnNodesMatching(filter, runScript);
-    }
-
-    @Override
-    public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Statement runScript)
-            throws RunScriptOnNodesException {
-        return delegate.runScriptOnNodesMatching(filter, runScript);
-    }
-
-    @Override
-    public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
-            String runScript, RunScriptOptions options) throws RunScriptOnNodesException {
-        return delegate.runScriptOnNodesMatching(filter, runScript, options);
-    }
-
-    @Override
-    public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
-            Statement runScript, RunScriptOptions options) throws RunScriptOnNodesException {
-        return delegate.runScriptOnNodesMatching(filter, runScript, options);
-    }
-
-    @Override
-    public ExecResponse runScriptOnNode(String id, Statement runScript, RunScriptOptions options) {
-        return delegate.runScriptOnNode(id, runScript, options);
-    }
-
-    @Override
-    public ListenableFuture<ExecResponse> submitScriptOnNode(String id, String runScript, RunScriptOptions options) {
-        return delegate.submitScriptOnNode(id, runScript, options);
-    }
-
-    @Override
-    public ListenableFuture<ExecResponse> submitScriptOnNode(String id, Statement runScript, RunScriptOptions options) {
-        return delegate.submitScriptOnNode(id, runScript, options);
-    }
-
-    @Override
-    public ExecResponse runScriptOnNode(String id, Statement runScript) {
-        return delegate.runScriptOnNode(id, runScript);
-    }
-
-    @Override
-    public ExecResponse runScriptOnNode(String id, String runScript, RunScriptOptions options) {
-        return delegate.runScriptOnNode(id, runScript, options);
-    }
-
-    @Override
-    public ExecResponse runScriptOnNode(String id, String runScript) {
-        return delegate.runScriptOnNode(id, runScript);
-    }
-
-    @Override
-    public Optional<ImageExtension> getImageExtension() {
-        return delegate.getImageExtension();
-    }
-
-    @Override
-    public Optional<SecurityGroupExtension> getSecurityGroupExtension() {
-        return delegate.getSecurityGroupExtension();
-    }
-
-}


[45/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
[BROOKLYN-162] Renaming package brooklyn.location


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/e2c57058
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/e2c57058
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/e2c57058

Branch: refs/heads/master
Commit: e2c57058a3c0783c38d5095e8f42b69b3692d658
Parents: e5289b8
Author: Valentin Aitken <va...@cloudsoftcorp.com>
Authored: Thu Aug 13 07:48:56 2015 +0300
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Thu Aug 13 22:41:47 2015 -0400

----------------------------------------------------------------------
 .../brooklyn/location/AddressableLocation.java  |   43 -
 .../BasicMachineLocationCustomizer.java         |   41 -
 .../java/brooklyn/location/HardwareDetails.java |   40 -
 .../main/java/brooklyn/location/Location.java   |  146 -
 .../brooklyn/location/LocationDefinition.java   |   42 -
 .../location/LocationNotAvailableException.java |   35 -
 .../brooklyn/location/LocationRegistry.java     |  128 -
 .../brooklyn/location/LocationResolver.java     |   57 -
 .../java/brooklyn/location/LocationSpec.java    |  229 --
 .../java/brooklyn/location/LocationType.java    |   32 -
 .../java/brooklyn/location/MachineDetails.java  |   34 -
 .../java/brooklyn/location/MachineLocation.java |   46 -
 .../location/MachineLocationCustomizer.java     |   42 -
 .../location/MachineManagementMixins.java       |   92 -
 .../location/MachineProvisioningLocation.java   |   72 -
 .../location/NoMachinesAvailableException.java  |   35 -
 .../main/java/brooklyn/location/OsDetails.java  |   46 -
 .../main/java/brooklyn/location/PortRange.java  |   48 -
 .../java/brooklyn/location/PortSupplier.java    |   50 -
 .../brooklyn/location/ProvisioningLocation.java |   44 -
 .../org/apache/brooklyn/api/entity/Entity.java  |    2 +-
 .../api/entity/drivers/EntityDriver.java        |    2 +-
 .../api/entity/drivers/EntityDriverManager.java |    2 +-
 .../api/entity/proxying/EntitySpec.java         |    2 +-
 .../api/entity/proxying/EntityTypeRegistry.java |    2 +-
 .../api/entity/rebind/BrooklynObjectType.java   |    2 +-
 .../entity/rebind/RebindExceptionHandler.java   |    2 +-
 .../api/management/AccessController.java        |    2 +-
 .../api/management/LocationManager.java         |    4 +-
 .../api/management/ManagementContext.java       |    2 +-
 .../brooklyn/location/AddressableLocation.java  |   43 +
 .../BasicMachineLocationCustomizer.java         |   41 +
 .../brooklyn/location/HardwareDetails.java      |   40 +
 .../org/apache/brooklyn/location/Location.java  |  146 +
 .../brooklyn/location/LocationDefinition.java   |   42 +
 .../location/LocationNotAvailableException.java |   35 +
 .../brooklyn/location/LocationRegistry.java     |  128 +
 .../brooklyn/location/LocationResolver.java     |   57 +
 .../apache/brooklyn/location/LocationSpec.java  |  229 ++
 .../apache/brooklyn/location/LocationType.java  |   32 +
 .../brooklyn/location/MachineDetails.java       |   34 +
 .../brooklyn/location/MachineLocation.java      |   46 +
 .../location/MachineLocationCustomizer.java     |   42 +
 .../location/MachineManagementMixins.java       |   92 +
 .../location/MachineProvisioningLocation.java   |   72 +
 .../location/NoMachinesAvailableException.java  |   35 +
 .../org/apache/brooklyn/location/OsDetails.java |   46 +
 .../org/apache/brooklyn/location/PortRange.java |   48 +
 .../apache/brooklyn/location/PortSupplier.java  |   50 +
 .../brooklyn/location/ProvisioningLocation.java |   44 +
 .../mementos/BrooklynMementoPersister.java      |    2 +-
 .../main/java/brooklyn/basic/BrooklynTypes.java |    2 +-
 .../brooklyn/catalog/CatalogPredicates.java     |    4 +-
 .../catalog/internal/BasicBrooklynCatalog.java  |    6 +-
 .../catalog/internal/CatalogClasspathDo.java    |    2 +-
 .../internal/CatalogLocationItemDto.java        |    4 +-
 .../entity/basic/AbstractApplication.java       |    2 +-
 .../brooklyn/entity/basic/AbstractEntity.java   |    4 +-
 .../brooklyn/entity/basic/BasicStartable.java   |    6 +-
 .../entity/basic/BasicStartableImpl.java        |    5 +-
 .../entity/basic/BrooklynConfigKeys.java        |    2 +-
 .../brooklyn/entity/basic/DataEntityImpl.java   |    2 +-
 .../entity/basic/EffectorStartableImpl.java     |    2 +-
 .../java/brooklyn/entity/basic/Entities.java    |    8 +-
 .../entity/basic/EntityFactoryForLocation.java  |    2 +-
 .../brooklyn/entity/basic/EntityFunctions.java  |    2 +-
 .../brooklyn/entity/basic/EntityInternal.java   |    2 +-
 .../brooklyn/entity/basic/EntityPredicates.java |    2 +-
 .../brooklyn/entity/basic/EntitySuppliers.java  |    4 +-
 .../basic/EntityTransientCopyInternal.java      |    4 +-
 .../java/brooklyn/entity/basic/Lifecycle.java   |    3 +-
 .../drivers/BasicEntityDriverManager.java       |    2 +-
 .../drivers/ReflectiveEntityDriverFactory.java  |    8 +-
 .../drivers/RegistryEntityDriverFactory.java    |    2 +-
 .../brooklyn/entity/effector/EffectorTasks.java |    6 +-
 .../brooklyn/entity/group/DynamicCluster.java   |    2 +-
 .../entity/group/DynamicClusterImpl.java        |    8 +-
 .../entity/group/DynamicFabricImpl.java         |    2 +-
 .../entity/group/DynamicRegionsFabricImpl.java  |    2 +-
 .../zoneaware/AbstractZoneFailureDetector.java  |    2 +-
 .../BalancingNodePlacementStrategy.java         |    2 +-
 .../zoneaware/CombiningZoneFailureDetector.java |    2 +-
 .../CriticalCauseZoneFailureDetector.java       |    2 +-
 .../ProportionalZoneFailureDetector.java        |    2 +-
 .../proxying/InternalLocationFactory.java       |    9 +-
 .../entity/rebind/BasicEntityRebindSupport.java |    2 +-
 .../rebind/BasicLocationRebindSupport.java      |    4 +-
 .../rebind/ImmediateDeltaChangeListener.java    |    4 +-
 .../rebind/PeriodicDeltaChangeListener.java     |    2 +-
 .../entity/rebind/RebindContextImpl.java        |    2 +-
 .../rebind/RebindContextLookupContext.java      |    2 +-
 .../rebind/RebindExceptionHandlerImpl.java      |    2 +-
 .../brooklyn/entity/rebind/RebindIteration.java |    6 +-
 .../java/brooklyn/entity/rebind/TreeUtils.java  |    2 +-
 .../entity/rebind/dto/MementosGenerators.java   |    4 +-
 .../persister/BrooklynPersistenceUtils.java     |    6 +-
 .../rebind/persister/XmlMementoSerializer.java  |    2 +-
 .../java/brooklyn/entity/trait/Startable.java   |    2 +-
 .../brooklyn/entity/trait/StartableMethods.java |    2 +-
 .../basic/PortAttributeSensorAndConfigKey.java  |   10 +-
 .../java/brooklyn/event/feed/ssh/SshFeed.java   |    6 +-
 .../brooklyn/event/feed/ssh/SshPollValue.java   |    2 +-
 .../windows/WindowsPerformanceCounterFeed.java  |    2 +-
 .../internal/BrooklynInitialization.java        |    2 +-
 .../location/access/BrooklynAccessUtils.java    |  143 -
 .../location/access/PortForwardManager.java     |  327 --
 .../access/PortForwardManagerAuthority.java     |   47 -
 .../access/PortForwardManagerClient.java        |  406 ---
 .../location/access/PortForwardManagerImpl.java |  506 ----
 .../PortForwardManagerLocationResolver.java     |   89 -
 .../brooklyn/location/access/PortMapping.java   |  101 -
 .../location/basic/AbstractLocation.java        |  708 -----
 .../basic/AbstractLocationResolver.java         |  189 --
 .../AggregatingMachineProvisioningLocation.java |  139 -
 .../location/basic/BasicHardwareDetails.java    |   56 -
 .../location/basic/BasicLocationDefinition.java |   85 -
 .../location/basic/BasicLocationRegistry.java   |  481 ---
 .../location/basic/BasicMachineDetails.java     |  181 --
 .../location/basic/BasicMachineMetadata.java    |   84 -
 .../brooklyn/location/basic/BasicOsDetails.java |  122 -
 .../location/basic/ByonLocationResolver.java    |  250 --
 .../location/basic/CatalogLocationResolver.java |   80 -
 .../basic/DefinedLocationByIdResolver.java      |   75 -
 .../basic/DeprecatedKeysMappingBuilder.java     |   67 -
 .../FixedListMachineProvisioningLocation.java   |  474 ---
 .../location/basic/HasSubnetHostname.java       |   32 -
 .../location/basic/HostLocationResolver.java    |   90 -
 .../basic/LocalhostLocationResolver.java        |   73 -
 .../LocalhostMachineProvisioningLocation.java   |  346 ---
 ...calhostPropertiesFromBrooklynProperties.java |   57 -
 .../location/basic/LocationConfigKeys.java      |   79 -
 .../location/basic/LocationConfigUtils.java     |  559 ----
 .../location/basic/LocationDynamicType.java     |   39 -
 .../location/basic/LocationInternal.java        |   94 -
 .../location/basic/LocationPredicates.java      |  108 -
 ...ocationPropertiesFromBrooklynProperties.java |  224 --
 .../location/basic/LocationTypeSnapshot.java    |   41 -
 .../java/brooklyn/location/basic/Locations.java |  159 -
 .../java/brooklyn/location/basic/Machines.java  |  188 --
 .../brooklyn/location/basic/MultiLocation.java  |  167 -
 .../location/basic/MultiLocationResolver.java   |  146 -
 .../location/basic/NamedLocationResolver.java   |   97 -
 .../brooklyn/location/basic/PortRanges.java     |  257 --
 .../basic/RegistryLocationResolver.java         |   41 -
 .../basic/SingleMachineLocationResolver.java    |   77 -
 .../SingleMachineProvisioningLocation.java      |   92 -
 .../location/basic/SshMachineLocation.java      | 1031 -------
 .../location/basic/SupportsPortForwarding.java  |   39 -
 .../location/basic/WinRmMachineLocation.java    |  360 ---
 .../AbstractAvailabilityZoneExtension.java      |   83 -
 ...bstractCloudMachineProvisioningLocation.java |   98 -
 .../cloud/AvailabilityZoneExtension.java        |   54 -
 .../location/cloud/CloudLocationConfig.java     |  116 -
 .../cloud/names/AbstractCloudMachineNamer.java  |  151 -
 .../cloud/names/BasicCloudMachineNamer.java     |   92 -
 .../location/cloud/names/CloudMachineNamer.java |   62 -
 .../cloud/names/CustomMachineNamer.java         |   73 -
 .../location/dynamic/DynamicLocation.java       |   51 -
 .../location/dynamic/LocationOwner.java         |   86 -
 .../location/geo/GeoBytesHostGeoLookup.java     |  105 -
 .../brooklyn/location/geo/HasHostGeoInfo.java   |   25 -
 .../java/brooklyn/location/geo/HostGeoInfo.java |  206 --
 .../brooklyn/location/geo/HostGeoLookup.java    |   27 -
 .../location/geo/LocalhostExternalIpLoader.java |  179 --
 .../location/geo/MaxMind2HostGeoLookup.java     |  115 -
 .../location/geo/UtraceHostGeoLookup.java       |  210 --
 .../brooklyn/location/paas/PaasLocation.java    |   30 -
 .../ha/HighAvailabilityManagerImpl.java         |    2 +-
 .../internal/AbstractManagementContext.java     |    4 +-
 .../internal/BrooklynGarbageCollector.java      |    2 +-
 .../management/internal/LocalAccessManager.java |    2 +-
 .../internal/LocalLocationManager.java          |   10 +-
 .../internal/LocalManagementContext.java        |    2 +-
 .../management/internal/LocalUsageManager.java  |    8 +-
 .../internal/LocationManagerInternal.java       |    2 +-
 .../internal/ManagementContextInternal.java     |    2 +-
 .../internal/NonDeploymentLocationManager.java  |    4 +-
 .../NonDeploymentManagementContext.java         |    4 +-
 .../internal/NonDeploymentUsageManager.java     |    2 +-
 .../management/internal/UsageListener.java      |    2 +-
 .../management/internal/UsageManager.java       |    2 +-
 .../brooklyn/util/BrooklynNetworkUtils.java     |    2 +-
 .../main/java/brooklyn/util/ResourceUtils.java  |    2 +-
 .../java/brooklyn/util/file/ArchiveTasks.java   |    2 +-
 .../java/brooklyn/util/file/ArchiveUtils.java   |    2 +-
 .../util/task/ssh/SshFetchTaskFactory.java      |    2 +-
 .../util/task/ssh/SshFetchTaskWrapper.java      |    2 +-
 .../util/task/ssh/SshPutTaskFactory.java        |    2 +-
 .../brooklyn/util/task/ssh/SshPutTaskStub.java  |    2 +-
 .../java/brooklyn/util/task/ssh/SshTasks.java   |    8 +-
 .../internal/AbstractSshExecTaskFactory.java    |    2 +-
 .../ssh/internal/PlainSshExecTaskFactory.java   |    3 +-
 .../util/task/system/ProcessTaskFactory.java    |    2 +-
 .../util/task/system/ProcessTaskStub.java       |    2 +-
 .../internal/AbstractProcessTaskFactory.java    |    2 +-
 .../system/internal/ExecWithLoggingHelpers.java |    2 +-
 .../internal/SystemProcessTaskFactory.java      |    2 +-
 .../brooklyn/util/text/TemplateProcessor.java   |    2 +-
 .../location/access/BrooklynAccessUtils.java    |  143 +
 .../location/access/PortForwardManager.java     |  327 ++
 .../access/PortForwardManagerAuthority.java     |   47 +
 .../access/PortForwardManagerClient.java        |  406 +++
 .../location/access/PortForwardManagerImpl.java |  506 ++++
 .../PortForwardManagerLocationResolver.java     |   90 +
 .../brooklyn/location/access/PortMapping.java   |  101 +
 .../location/basic/AbstractLocation.java        |  708 +++++
 .../basic/AbstractLocationResolver.java         |  189 ++
 .../AggregatingMachineProvisioningLocation.java |  139 +
 .../location/basic/BasicHardwareDetails.java    |   56 +
 .../location/basic/BasicLocationDefinition.java |   85 +
 .../location/basic/BasicLocationRegistry.java   |  480 +++
 .../location/basic/BasicMachineDetails.java     |  181 ++
 .../location/basic/BasicMachineMetadata.java    |   83 +
 .../brooklyn/location/basic/BasicOsDetails.java |  122 +
 .../location/basic/ByonLocationResolver.java    |  251 ++
 .../location/basic/CatalogLocationResolver.java |   80 +
 .../basic/DefinedLocationByIdResolver.java      |   74 +
 .../basic/DeprecatedKeysMappingBuilder.java     |   67 +
 .../FixedListMachineProvisioningLocation.java   |  474 +++
 .../location/basic/HasSubnetHostname.java       |   32 +
 .../location/basic/HostLocationResolver.java    |   90 +
 .../basic/LocalhostLocationResolver.java        |   74 +
 .../LocalhostMachineProvisioningLocation.java   |  347 +++
 ...calhostPropertiesFromBrooklynProperties.java |   57 +
 .../location/basic/LocationConfigKeys.java      |   79 +
 .../location/basic/LocationConfigUtils.java     |  559 ++++
 .../location/basic/LocationDynamicType.java     |   39 +
 .../location/basic/LocationInternal.java        |   94 +
 .../location/basic/LocationPredicates.java      |  108 +
 ...ocationPropertiesFromBrooklynProperties.java |  224 ++
 .../location/basic/LocationTypeSnapshot.java    |   41 +
 .../brooklyn/location/basic/Locations.java      |  159 +
 .../brooklyn/location/basic/Machines.java       |  188 ++
 .../brooklyn/location/basic/MultiLocation.java  |  167 +
 .../location/basic/MultiLocationResolver.java   |  146 +
 .../location/basic/NamedLocationResolver.java   |   97 +
 .../brooklyn/location/basic/PortRanges.java     |  257 ++
 .../basic/RegistryLocationResolver.java         |   42 +
 .../basic/SingleMachineLocationResolver.java    |   77 +
 .../SingleMachineProvisioningLocation.java      |   92 +
 .../location/basic/SshMachineLocation.java      | 1031 +++++++
 .../location/basic/SupportsPortForwarding.java  |   39 +
 .../location/basic/WinRmMachineLocation.java    |  360 +++
 .../AbstractAvailabilityZoneExtension.java      |   83 +
 ...bstractCloudMachineProvisioningLocation.java |   97 +
 .../cloud/AvailabilityZoneExtension.java        |   54 +
 .../location/cloud/CloudLocationConfig.java     |  116 +
 .../cloud/names/AbstractCloudMachineNamer.java  |  151 +
 .../cloud/names/BasicCloudMachineNamer.java     |   92 +
 .../location/cloud/names/CloudMachineNamer.java |   62 +
 .../cloud/names/CustomMachineNamer.java         |   73 +
 .../location/dynamic/DynamicLocation.java       |   51 +
 .../location/dynamic/LocationOwner.java         |   86 +
 .../location/geo/GeoBytesHostGeoLookup.java     |  105 +
 .../brooklyn/location/geo/HasHostGeoInfo.java   |   25 +
 .../brooklyn/location/geo/HostGeoInfo.java      |  206 ++
 .../brooklyn/location/geo/HostGeoLookup.java    |   27 +
 .../location/geo/LocalhostExternalIpLoader.java |  178 ++
 .../location/geo/MaxMind2HostGeoLookup.java     |  115 +
 .../location/geo/UtraceHostGeoLookup.java       |  210 ++
 .../brooklyn/location/paas/PaasLocation.java    |   30 +
 .../services/brooklyn.location.LocationResolver |    9 -
 ...rg.apache.brooklyn.location.LocationResolver |    9 +
 .../brooklyn/location/basic/os-details.sh       |   93 -
 .../geo/external-ip-address-resolvers.txt       |   25 -
 .../brooklyn/location/basic/os-details.sh       |   93 +
 .../geo/external-ip-address-resolvers.txt       |   25 +
 ...stomAggregatingEnricherDeprecatedTest.groovy |    5 +-
 .../enricher/CustomAggregatingEnricherTest.java |    4 +-
 .../TransformingEnricherDeprecatedTest.groovy   |    3 +-
 .../enricher/TransformingEnricherTest.java      |    2 +-
 .../brooklyn/entity/EffectorMetadataTest.java   |    2 +-
 .../java/brooklyn/entity/SetFromFlagTest.java   |    4 +-
 .../basic/AbstractApplicationLegacyTest.java    |    4 +-
 .../entity/basic/AbstractEntityLegacyTest.java  |    3 +-
 .../entity/basic/BasicStartableTest.java        |    8 +-
 .../brooklyn/entity/basic/DataEntityTest.java   |    4 +-
 .../brooklyn/entity/basic/EntitiesTest.java     |    4 +-
 .../basic/EntityConfigMapUsageLegacyTest.java   |    2 +-
 .../entity/basic/EntityConfigMapUsageTest.java  |    2 +-
 .../entity/basic/EntityFunctionsTest.java       |    2 +-
 .../entity/basic/EntityLocationsTest.java       |    2 +-
 .../entity/basic/EntityPredicatesTest.java      |    2 +-
 .../brooklyn/entity/basic/EntitySpecTest.java   |    2 +-
 .../entity/basic/EntitySubscriptionTest.java    |    2 +-
 .../entity/basic/EntitySuppliersTest.java       |    6 +-
 ...apListAndOtherStructuredConfigKeyTest.groovy |    2 +-
 .../entity/basic/ServiceStateLogicTest.java     |    2 +-
 .../drivers/BasicEntityDriverManagerTest.java   |    4 +-
 .../drivers/EntityDriverRegistryTest.java       |    2 +-
 .../ReflectiveEntityDriverFactoryTest.java      |    6 +-
 .../RegistryEntityDriverFactoryTest.java        |    6 +-
 .../downloads/BasicDownloadsRegistryTest.java   |    4 +-
 .../DownloadProducerFromLocalRepoTest.java      |    4 +-
 .../DownloadProducerFromPropertiesTest.java     |    4 +-
 .../downloads/DownloadSubstitutersTest.java     |    4 +-
 .../drivers/downloads/MyEntityDriver.java       |    2 +-
 .../entity/effector/EffectorBasicTest.java      |    2 +-
 .../entity/group/DynamicClusterTest.java        |    4 +-
 ...DynamicClusterWithAvailabilityZonesTest.java |   12 +-
 .../entity/group/DynamicFabricTest.java         |    6 +-
 .../entity/group/DynamicMultiGroupTest.java     |    3 +-
 .../entity/group/DynamicRegionsFabricTest.java  |    4 +-
 .../java/brooklyn/entity/group/GroupTest.java   |    4 +-
 .../group/MembershipTrackingPolicyTest.java     |    4 +-
 .../entity/group/QuarantineGroupTest.java       |    4 +-
 .../BalancingNodePlacementStrategyTest.java     |    6 +-
 .../ProportionalZoneFailureDetectorTest.java    |    4 +-
 .../entity/hello/LocalEntitiesTest.java         |    2 +-
 .../entity/rebind/RebindCatalogItemTest.java    |    2 +-
 .../entity/rebind/RebindEnricherTest.java       |    4 +-
 .../entity/rebind/RebindEntityTest.java         |    6 +-
 .../brooklyn/entity/rebind/RebindFeedTest.java  |    6 +-
 .../rebind/RebindLocalhostLocationTest.java     |    6 +-
 .../entity/rebind/RebindLocationTest.java       |    7 +-
 .../entity/rebind/RebindPolicyTest.java         |    4 +-
 .../rebind/RebindSshMachineLocationTest.java    |    6 +-
 .../brooklyn/entity/rebind/RebindTestUtils.java |    2 +-
 .../rebind/RecordingRebindExceptionHandler.java |    2 +-
 .../BrooklynMementoPersisterTestFixture.java    |    6 +-
 .../persister/XmlMementoSerializerTest.java     |    8 +-
 .../entity/trait/FailingEntityImpl.java         |    2 +-
 .../entity/trait/StartableMethodsTest.java      |    2 +-
 .../event/feed/function/FunctionFeedTest.java   |    4 +-
 .../feed/http/HttpFeedIntegrationTest.java      |    6 +-
 .../brooklyn/event/feed/http/HttpFeedTest.java  |    2 +-
 .../feed/shell/ShellFeedIntegrationTest.java    |    2 +-
 .../event/feed/ssh/SshFeedIntegrationTest.java  |    4 +-
 .../WindowsPerformanceCounterFeedLiveTest.java  |    6 +-
 .../WindowsPerformanceCounterFeedTest.java      |    4 +-
 .../PortForwardManagerLocationResolverTest.java |   83 -
 .../access/PortForwardManagerRebindTest.java    |  195 --
 .../location/access/PortForwardManagerTest.java |  194 --
 .../location/basic/AbstractLocationTest.java    |  184 --
 ...regatingMachineProvisioningLocationTest.java |  116 -
 .../basic/ByonLocationResolverTest.java         |  423 ---
 ...stMachineProvisioningLocationRebindTest.java |  129 -
 ...ixedListMachineProvisioningLocationTest.java |  576 ----
 .../basic/HostLocationResolverTest.java         |  126 -
 .../basic/LegacyAbstractLocationTest.java       |  151 -
 .../basic/LocalhostLocationResolverTest.java    |  265 --
 ...ocalhostMachineProvisioningLocationTest.java |  213 --
 .../LocalhostProvisioningAndAccessTest.java     |   58 -
 .../location/basic/LocationConfigTest.java      |  202 --
 .../location/basic/LocationConfigUtilsTest.java |  156 -
 .../location/basic/LocationExtensionsTest.java  |  186 --
 .../location/basic/LocationManagementTest.java  |   81 -
 .../location/basic/LocationPredicatesTest.java  |   99 -
 ...ionPropertiesFromBrooklynPropertiesTest.java |  121 -
 .../location/basic/LocationRegistryTest.java    |  159 -
 .../location/basic/MachineDetailsTest.java      |   81 -
 .../location/basic/MultiLocationRebindTest.java |  120 -
 .../basic/MultiLocationResolverTest.java        |  199 --
 .../location/basic/MultiLocationTest.java       |  119 -
 .../location/basic/PaasLocationTest.java        |   35 -
 .../brooklyn/location/basic/PortRangesTest.java |  131 -
 .../RecordingMachineLocationCustomizer.java     |   71 -
 .../location/basic/SimulatedLocation.java       |  136 -
 .../SingleMachineLocationResolverTest.java      |  131 -
 .../SingleMachineProvisioningLocationTest.java  |   64 -
 .../SshMachineLocationIntegrationTest.java      |  141 -
 .../SshMachineLocationPerformanceTest.java      |  172 --
 .../SshMachineLocationReuseIntegrationTest.java |  172 --
 .../location/basic/SshMachineLocationTest.java  |  340 ---
 .../basic/TestPortSupplierLocation.java         |   90 -
 .../location/cloud/CloudMachineNamerTest.java   |  161 -
 .../location/cloud/CustomMachineNamerTest.java  |   79 -
 .../brooklyn/location/geo/HostGeoInfoTest.java  |   52 -
 .../geo/HostGeoLookupIntegrationTest.java       |   84 -
 ...ocalhostExternalIpLoaderIntegrationTest.java |   53 -
 .../AcmeEntitlementManagerTestFixture.java      |    5 +-
 .../entitlement/EntityEntitlementTest.java      |    2 +-
 .../ha/HighAvailabilityManagerInMemoryTest.java |    8 +-
 .../HighAvailabilityManagerSplitBrainTest.java  |    2 +-
 .../brooklyn/management/ha/HotStandbyTest.java  |    6 +-
 .../brooklyn/management/ha/WarmStandbyTest.java |    2 +-
 .../management/internal/AccessManagerTest.java  |    6 +-
 .../internal/LocalManagementContextTest.java    |    2 +-
 .../policy/basic/PolicySubscriptionTest.java    |    2 +-
 .../longevity/EntityCleanupLongevityTest.java   |    4 +-
 .../EntityCleanupLongevityTestFixture.java      |    4 +-
 .../qa/longevity/EntityCleanupTest.java         |    4 +-
 .../qa/performance/AbstractPerformanceTest.java |    2 +-
 .../EntityPersistencePerformanceTest.java       |    4 +-
 .../test/java/brooklyn/test/HttpService.java    |    4 +-
 .../test/location/TestPaasLocation.java         |    6 +-
 .../brooklyn/util/file/ArchiveUtilsTest.java    |    2 +-
 .../util/http/HttpToolIntegrationTest.java      |    2 +-
 .../util/ssh/BashCommandsIntegrationTest.java   |    4 +-
 .../brooklyn/util/task/ssh/SshTasksTest.java    |    6 +-
 .../PortForwardManagerLocationResolverTest.java |   83 +
 .../access/PortForwardManagerRebindTest.java    |  195 ++
 .../location/access/PortForwardManagerTest.java |  193 ++
 .../location/basic/AbstractLocationTest.java    |  184 ++
 ...regatingMachineProvisioningLocationTest.java |  116 +
 .../basic/ByonLocationResolverTest.java         |  423 +++
 ...stMachineProvisioningLocationRebindTest.java |  129 +
 ...ixedListMachineProvisioningLocationTest.java |  575 ++++
 .../basic/HostLocationResolverTest.java         |  126 +
 .../basic/LegacyAbstractLocationTest.java       |  151 +
 .../basic/LocalhostLocationResolverTest.java    |  265 ++
 ...ocalhostMachineProvisioningLocationTest.java |  213 ++
 .../LocalhostProvisioningAndAccessTest.java     |   58 +
 .../location/basic/LocationConfigTest.java      |  203 ++
 .../location/basic/LocationConfigUtilsTest.java |  155 +
 .../location/basic/LocationExtensionsTest.java  |  186 ++
 .../location/basic/LocationManagementTest.java  |   81 +
 .../location/basic/LocationPredicatesTest.java  |   99 +
 ...ionPropertiesFromBrooklynPropertiesTest.java |  121 +
 .../location/basic/LocationRegistryTest.java    |  159 +
 .../location/basic/MachineDetailsTest.java      |   81 +
 .../location/basic/MultiLocationRebindTest.java |  120 +
 .../basic/MultiLocationResolverTest.java        |  199 ++
 .../location/basic/MultiLocationTest.java       |  119 +
 .../location/basic/PaasLocationTest.java        |   35 +
 .../brooklyn/location/basic/PortRangesTest.java |  130 +
 .../RecordingMachineLocationCustomizer.java     |   71 +
 .../location/basic/SimulatedLocation.java       |  136 +
 .../SingleMachineLocationResolverTest.java      |  131 +
 .../SingleMachineProvisioningLocationTest.java  |   64 +
 .../SshMachineLocationIntegrationTest.java      |  141 +
 .../SshMachineLocationPerformanceTest.java      |  172 ++
 .../SshMachineLocationReuseIntegrationTest.java |  172 ++
 .../location/basic/SshMachineLocationTest.java  |  340 +++
 .../basic/TestPortSupplierLocation.java         |   90 +
 .../location/cloud/CloudMachineNamerTest.java   |  161 +
 .../location/cloud/CustomMachineNamerTest.java  |   79 +
 .../brooklyn/location/geo/HostGeoInfoTest.java  |   52 +
 .../geo/HostGeoLookupIntegrationTest.java       |   84 +
 ...ocalhostExternalIpLoaderIntegrationTest.java |   53 +
 .../test/entity/BlockingEntityImpl.java         |    2 +-
 .../brooklyn/test/entity/TestApplication.java   |    4 +-
 .../test/entity/TestApplicationImpl.java        |    6 +-
 .../brooklyn/test/entity/TestEntityImpl.java    |    2 +-
 .../brooklyn/location/basic/sample_id_rsa       |   27 -
 .../brooklyn/location/basic/sample_id_rsa.pub   |    1 -
 .../brooklyn/location/basic/sample_id_rsa       |   27 +
 .../brooklyn/location/basic/sample_id_rsa.pub   |    1 +
 .../big_examples/global-web-fabric/index.md     |    4 +-
 docs/guide/ops/locations/index.md               |    4 +-
 .../brooklyn.location.AddressableLocation.html  |    6 +-
 .../brooklyn.location.MachineLocation.html      |    6 +-
 ...tMixins$RichMachineProvisioningLocation.html |    6 +-
 ...yn.location.MachineProvisioningLocation.html |    6 +-
 ...rooklyn.location.basic.AbstractLocation.html |    6 +-
 ....AggregatingMachineProvisioningLocation.html |    6 +-
 ...ic.FixedListMachineProvisioningLocation.html |    6 +-
 ...neProvisioningLocation$LocalhostMachine.html |    6 +-
 ...ic.LocalhostMachineProvisioningLocation.html |    6 +-
 ...rooklyn.location.basic.LocationInternal.html |    6 +-
 .../brooklyn.location.basic.MultiLocation.html  |    6 +-
 ...ooklyn.location.basic.SimulatedLocation.html |    6 +-
 ...basic.SingleMachineProvisioningLocation.html |    6 +-
 ...oklyn.location.basic.SshMachineLocation.html |    6 +-
 ...bstractCloudMachineProvisioningLocation.html |    6 +-
 ...AbstractJcloudsSubnetSshMachineLocation.html |    6 +-
 ...ooklyn.location.jclouds.JcloudsLocation.html |    6 +-
 ...ation.jclouds.JcloudsSshMachineLocation.html |    6 +-
 .../brooklyn/demo/GlobalWebFabricExample.java   |    2 +-
 .../brooklyn/demo/CumulusRDFApplication.java    |    4 +-
 .../brooklyn/demo/SingleWebServerExample.java   |    2 +-
 .../demo/WebClusterDatabaseExample.java         |    2 +-
 .../demo/WebClusterDatabaseExampleApp.java      |    2 +-
 ...lusterDatabaseExampleAppIntegrationTest.java |    3 +-
 .../JcloudsBlobStoreBasedObjectStore.java       |    8 +-
 ...AbstractJcloudsSubnetSshMachineLocation.java |   38 -
 .../jclouds/BasicJcloudsLocationCustomizer.java |   99 -
 .../location/jclouds/BrooklynImageChooser.java  |  367 ---
 .../location/jclouds/BrooklynMachinePool.java   |  220 --
 .../jclouds/ComputeServiceRegistry.java         |   28 -
 .../jclouds/ComputeServiceRegistryImpl.java     |  182 --
 .../jclouds/JcloudsByonLocationResolver.java    |  183 --
 .../location/jclouds/JcloudsLocation.java       | 2863 ------------------
 .../location/jclouds/JcloudsLocationConfig.java |  280 --
 .../jclouds/JcloudsLocationCustomizer.java      |  105 -
 .../jclouds/JcloudsLocationResolver.java        |  227 --
 .../jclouds/JcloudsMachineLocation.java         |   45 -
 .../location/jclouds/JcloudsMachineNamer.java   |   44 -
 .../location/jclouds/JcloudsPredicates.java     |   53 -
 ...JcloudsPropertiesFromBrooklynProperties.java |  159 -
 .../jclouds/JcloudsSshMachineLocation.java      |  340 ---
 .../brooklyn/location/jclouds/JcloudsUtil.java  |  448 ---
 .../jclouds/JcloudsWinRmMachineLocation.java    |  154 -
 .../jclouds/SudoTtyFixingCustomizer.java        |   58 -
 .../JcloudsLocationSecurityGroupCustomizer.java |  561 ----
 .../JcloudsPortForwarderExtension.java          |   45 -
 .../networking/SecurityGroupDefinition.java     |  103 -
 .../jclouds/networking/SecurityGroupTool.java   |  167 -
 .../location/jclouds/pool/MachinePool.java      |  395 ---
 .../jclouds/pool/MachinePoolPredicates.java     |  149 -
 .../location/jclouds/pool/MachineSet.java       |   98 -
 .../jclouds/pool/ReusableMachineTemplate.java   |  183 --
 .../AbstractPortableTemplateBuilder.java        |  527 ----
 .../templates/PortableTemplateBuilder.java      |  145 -
 .../zone/AwsAvailabilityZoneExtension.java      |   74 -
 .../policy/os/AdvertiseWinrmLoginPolicy.java    |    4 +-
 .../brooklyn/policy/os/CreateUserPolicy.java    |    4 +-
 ...AbstractJcloudsSubnetSshMachineLocation.java |   38 +
 .../jclouds/BasicJcloudsLocationCustomizer.java |   99 +
 .../location/jclouds/BrooklynImageChooser.java  |  367 +++
 .../location/jclouds/BrooklynMachinePool.java   |  219 ++
 .../jclouds/ComputeServiceRegistry.java         |   28 +
 .../jclouds/ComputeServiceRegistryImpl.java     |  183 ++
 .../jclouds/JcloudsByonLocationResolver.java    |  184 ++
 .../location/jclouds/JcloudsLocation.java       | 2861 +++++++++++++++++
 .../location/jclouds/JcloudsLocationConfig.java |  280 ++
 .../jclouds/JcloudsLocationCustomizer.java      |  105 +
 .../jclouds/JcloudsLocationResolver.java        |  227 ++
 .../jclouds/JcloudsMachineLocation.java         |   45 +
 .../location/jclouds/JcloudsMachineNamer.java   |   44 +
 .../location/jclouds/JcloudsPredicates.java     |   53 +
 ...JcloudsPropertiesFromBrooklynProperties.java |  159 +
 .../jclouds/JcloudsSshMachineLocation.java      |  338 +++
 .../brooklyn/location/jclouds/JcloudsUtil.java  |  448 +++
 .../jclouds/JcloudsWinRmMachineLocation.java    |  154 +
 .../jclouds/SudoTtyFixingCustomizer.java        |   58 +
 .../JcloudsLocationSecurityGroupCustomizer.java |  563 ++++
 .../JcloudsPortForwarderExtension.java          |   45 +
 .../networking/SecurityGroupDefinition.java     |  103 +
 .../jclouds/networking/SecurityGroupTool.java   |  167 +
 .../location/jclouds/pool/MachinePool.java      |  395 +++
 .../jclouds/pool/MachinePoolPredicates.java     |  149 +
 .../location/jclouds/pool/MachineSet.java       |   98 +
 .../jclouds/pool/ReusableMachineTemplate.java   |  182 ++
 .../AbstractPortableTemplateBuilder.java        |  527 ++++
 .../templates/PortableTemplateBuilder.java      |  145 +
 .../zone/AwsAvailabilityZoneExtension.java      |   74 +
 .../services/brooklyn.location.LocationResolver |    2 -
 ...rg.apache.brooklyn.location.LocationResolver |    2 +
 .../persister/jclouds/BlobStoreCleaner.java     |    6 +-
 .../persister/jclouds/BlobStoreExpiryTest.java  |    8 +-
 .../rebind/persister/jclouds/BlobStoreTest.java |    8 +-
 .../jclouds/JcloudsExpect100ContinueTest.java   |    4 +-
 .../jclouds/AbstractJcloudsLiveTest.java        |  158 -
 .../jclouds/AbstractJcloudsStubbedLiveTest.java |  133 -
 .../jclouds/BailOutJcloudsLocation.java         |  188 --
 .../jclouds/BrooklynMachinePoolLiveTest.java    |  103 -
 .../jclouds/DelegatingComputeService.java       |  229 --
 .../jclouds/JcloudsAddressesLiveTest.java       |  228 --
 .../JcloudsByonLocationResolverAwsLiveTest.java |  178 --
 ...dsByonLocationResolverSoftlayerLiveTest.java |  105 -
 .../JcloudsByonLocationResolverTest.java        |   81 -
 .../JcloudsHardwareProfilesStubbedLiveTest.java |   78 -
 .../jclouds/JcloudsLocationMetadataTest.java    |   72 -
 .../JcloudsLocationRebindMachineLiveTest.java   |  139 -
 .../jclouds/JcloudsLocationResolverTest.java    |  357 ---
 ...ationTemplateOptionsCustomisersLiveTest.java |  119 -
 .../location/jclouds/JcloudsLocationTest.java   |  510 ----
 .../location/jclouds/JcloudsLoginLiveTest.java  |  408 ---
 .../jclouds/JcloudsMachineNamerTest.java        |   52 -
 ...udsPropertiesFromBrooklynPropertiesTest.java |   99 -
 .../location/jclouds/JcloudsSshingLiveTest.java |   61 -
 .../location/jclouds/LiveTestEntity.java        |   90 -
 .../jclouds/RebindJcloudsLocationLiveTest.java  |  150 -
 .../jclouds/RebindJcloudsLocationTest.java      |   66 -
 ...loudsLocationUserLoginAndConfigLiveTest.java |  249 --
 ...hineProvisioningLocationJcloudsLiveTest.java |  124 -
 .../jclouds/StandaloneJcloudsLiveTest.java      |  254 --
 ...oudsLocationSecurityGroupCustomizerTest.java |  311 --
 .../JcloudsPortForwardingStubbedLiveTest.java   |  197 --
 .../networking/SecurityGroupLiveTest.java       |   32 -
 .../pool/JcloudsMachinePoolLiveTest.java        |  120 -
 .../provider/AbstractJcloudsLocationTest.java   |  170 --
 .../provider/AwsEc2LocationLiveTest.java        |   66 -
 .../AwsEc2LocationWindowsLiveTest.groovy        |   95 -
 .../provider/CarrenzaLocationLiveTest.groovy    |  133 -
 .../provider/GoGridLocationLiveTest.groovy      |   54 -
 .../provider/RackspaceLocationLiveTest.java     |   83 -
 .../zone/AwsAvailabilityZoneExtensionTest.java  |  121 -
 .../os/AdvertiseWinrmLoginPolicyTest.java       |    4 +-
 .../policy/os/CreateUserPolicyLiveTest.java     |   11 +-
 .../policy/os/CreateUserPolicyTest.java         |    5 +-
 .../jclouds/AbstractJcloudsLiveTest.java        |  158 +
 .../jclouds/AbstractJcloudsStubbedLiveTest.java |  125 +
 .../jclouds/BailOutJcloudsLocation.java         |  188 ++
 .../jclouds/BrooklynMachinePoolLiveTest.java    |  103 +
 .../jclouds/DelegatingComputeService.java       |  229 ++
 .../jclouds/JcloudsAddressesLiveTest.java       |  228 ++
 .../JcloudsByonLocationResolverAwsLiveTest.java |  178 ++
 ...dsByonLocationResolverSoftlayerLiveTest.java |  105 +
 .../JcloudsByonLocationResolverTest.java        |   81 +
 .../JcloudsHardwareProfilesStubbedLiveTest.java |   78 +
 .../jclouds/JcloudsLocationMetadataTest.java    |   72 +
 .../JcloudsLocationRebindMachineLiveTest.java   |  138 +
 .../jclouds/JcloudsLocationResolverTest.java    |  357 +++
 ...ationTemplateOptionsCustomisersLiveTest.java |  107 +
 .../location/jclouds/JcloudsLocationTest.java   |  510 ++++
 .../location/jclouds/JcloudsLoginLiveTest.java  |  407 +++
 .../jclouds/JcloudsMachineNamerTest.java        |   52 +
 ...udsPropertiesFromBrooklynPropertiesTest.java |   99 +
 .../location/jclouds/JcloudsSshingLiveTest.java |   61 +
 .../location/jclouds/LiveTestEntity.java        |   90 +
 .../jclouds/RebindJcloudsLocationLiveTest.java  |  150 +
 .../jclouds/RebindJcloudsLocationTest.java      |   66 +
 ...loudsLocationUserLoginAndConfigLiveTest.java |  249 ++
 ...hineProvisioningLocationJcloudsLiveTest.java |  124 +
 .../jclouds/StandaloneJcloudsLiveTest.java      |  254 ++
 ...oudsLocationSecurityGroupCustomizerTest.java |  311 ++
 .../JcloudsPortForwardingStubbedLiveTest.java   |  196 ++
 .../networking/SecurityGroupLiveTest.java       |   32 +
 .../pool/JcloudsMachinePoolLiveTest.java        |  120 +
 .../provider/AbstractJcloudsLocationTest.java   |  170 ++
 .../provider/AwsEc2LocationLiveTest.java        |   66 +
 .../AwsEc2LocationWindowsLiveTest.groovy        |   95 +
 .../provider/CarrenzaLocationLiveTest.groovy    |  133 +
 .../provider/GoGridLocationLiveTest.groovy      |   52 +
 .../provider/RackspaceLocationLiveTest.java     |   83 +
 .../zone/AwsAvailabilityZoneExtensionTest.java  |  121 +
 ...location-test-various-login-credentials.yaml |   67 -
 ...location-test-various-login-credentials.yaml |   67 +
 parent/pom.xml                                  |    2 +-
 .../followthesun/DefaultFollowTheSunModel.java  |    4 +-
 .../policy/followthesun/FollowTheSunModel.java  |    2 +-
 .../followthesun/FollowTheSunParameters.java    |    2 +-
 .../policy/followthesun/FollowTheSunPolicy.java |    4 +-
 .../followthesun/FollowTheSunStrategy.java      |    2 +-
 .../policy/ha/SshMachineFailureDetector.java    |    4 +-
 .../loadbalancing/BalanceablePoolModel.java     |    2 +-
 .../policy/loadbalancing/BalancingStrategy.java |    2 +-
 .../DefaultBalanceablePoolModel.java            |    2 +-
 .../loadbalancing/LocationConstraint.java       |    2 +-
 .../enricher/HttpLatencyDetectorTest.java       |    3 +-
 .../entity/brooklyn/BrooklynMetricsTest.java    |    3 +-
 .../autoscaling/AutoScalerPolicyRebindTest.java |    4 +-
 .../AbstractFollowTheSunPolicyTest.java         |    6 +-
 .../followthesun/FollowTheSunModelTest.java     |    5 +-
 .../FollowTheSunPolicySoakTest.java             |    4 +-
 .../followthesun/FollowTheSunPolicyTest.java    |    4 +-
 .../brooklyn/policy/ha/HaPolicyRebindTest.java  |    6 +-
 .../brooklyn/policy/ha/ServiceReplacerTest.java |    6 +-
 .../AbstractLoadBalancingPolicyTest.java        |    3 +-
 .../BalanceableWorkerPoolTest.java              |    2 +-
 .../ItemsInContainersGroupTest.java             |    2 +-
 .../loadbalancing/MockContainerEntityImpl.java  |    2 +-
 .../basic/AbstractSoftwareProcessDriver.java    |    2 +-
 .../basic/AbstractSoftwareProcessSshDriver.java |    2 +-
 .../AbstractSoftwareProcessWinRmDriver.java     |    2 +-
 .../basic/EmptySoftwareProcessSshDriver.java    |    2 +-
 .../SameServerDriverLifecycleEffectorTasks.java |    8 +-
 .../brooklyn/entity/basic/SameServerEntity.java |    2 +-
 .../entity/basic/SameServerEntityImpl.java      |    2 +-
 .../brooklyn/entity/basic/SoftwareProcess.java  |    2 +-
 ...wareProcessDriverLifecycleEffectorTasks.java |    4 +-
 .../entity/basic/SoftwareProcessImpl.java       |   14 +-
 .../basic/VanillaSoftwareProcessSshDriver.java  |    2 +-
 .../basic/VanillaWindowsProcessWinRmDriver.java |    2 +-
 .../entity/basic/lifecycle/ScriptHelper.java    |    2 +-
 .../entity/brooklynnode/BrooklynNodeImpl.java   |    4 +-
 .../brooklynnode/BrooklynNodeSshDriver.java     |    2 +-
 .../entity/chef/ChefLifecycleEffectorTasks.java |    4 +-
 .../brooklyn/entity/chef/ChefServerTasks.java   |    2 +-
 .../brooklyn/entity/chef/ChefSoloDriver.java    |    2 +-
 .../entity/chef/KnifeConvergeTaskFactory.java   |    2 +-
 .../java/JavaSoftwareProcessSshDriver.java      |    2 +-
 .../java/brooklyn/entity/java/JmxSupport.java   |    6 +-
 .../main/java/brooklyn/entity/java/UsesJmx.java |    4 +-
 .../entity/java/VanillaJavaAppSshDriver.java    |    2 +-
 .../entity/machine/MachineEntityImpl.java       |    5 +-
 .../java/brooklyn/entity/pool/ServerPool.java   |    9 +-
 .../brooklyn/entity/pool/ServerPoolImpl.java    |   14 +-
 .../entity/pool/ServerPoolLocation.java         |   10 +-
 .../entity/pool/ServerPoolLocationResolver.java |   16 +-
 .../entity/service/InitdServiceInstaller.java   |    4 +-
 .../entity/service/SystemServiceEnricher.java   |    2 +-
 .../entity/software/MachineInitTasks.java       |    2 +-
 .../software/MachineLifecycleEffectorTasks.java |   25 +-
 .../software/ProvidesProvisioningFlags.java     |    2 +-
 .../entity/software/SshEffectorTasks.java       |    6 +-
 .../services/brooklyn.location.LocationResolver |    1 -
 ...rg.apache.brooklyn.location.LocationResolver |    1 +
 .../brooklyn/entity/AbstractEc2LiveTest.java    |    6 +-
 .../entity/AbstractGoogleComputeLiveTest.java   |    2 +-
 .../entity/AbstractSoftlayerLiveTest.java       |    2 +-
 ...ctSoftwareProcessRestartIntegrationTest.java |    2 +-
 .../basic/DoNothingSoftwareProcessDriver.java   |    2 +-
 .../entity/basic/SameServerEntityTest.java      |    6 +-
 .../basic/SoftwareProcessEntityLatchTest.java   |    6 +-
 .../basic/SoftwareProcessEntityRebindTest.java  |   10 +-
 .../entity/basic/SoftwareProcessEntityTest.java |   14 +-
 ...SoftwareProcessSshDriverIntegrationTest.java |    8 +-
 .../basic/SoftwareProcessSubclassTest.java      |    2 +-
 ...ftwareProcessAndChildrenIntegrationTest.java |    2 +-
 .../entity/basic/lifecycle/MyEntityImpl.java    |    2 +-
 .../basic/lifecycle/NaiveScriptRunnerTest.java  |    4 +-
 .../basic/lifecycle/ScriptHelperTest.java       |    6 +-
 .../basic/lifecycle/StartStopSshDriverTest.java |    2 +-
 .../BrooklynClusterIntegrationTest.java         |    2 +-
 .../BrooklynNodeIntegrationTest.java            |   10 +-
 .../entity/brooklynnode/BrooklynNodeTest.java   |    4 +-
 .../entity/brooklynnode/MockBrooklynNode.java   |    2 +-
 .../brooklynnode/SameBrooklynNodeImpl.java      |    2 +-
 .../entity/chef/ChefLiveTestSupport.java        |    7 +-
 .../AbstractChefToyMySqlEntityLiveTest.java     |    4 +-
 .../brooklyn/entity/driver/MockSshDriver.java   |    4 +-
 ...rWithAvailabilityZonesMultiLocationTest.java |   12 +-
 .../brooklyn/entity/java/EntityPollingTest.java |    4 +-
 .../java/brooklyn/entity/java/JavaOptsTest.java |    6 +-
 ...SoftwareProcessSshDriverIntegrationTest.java |    6 +-
 .../entity/java/VanillaJavaAppRebindTest.java   |    2 +-
 .../entity/java/VanillaJavaAppTest.java         |    4 +-
 .../machine/MachineEntityEc2LiveTest.java       |    2 +-
 .../entity/pool/AbstractServerPoolTest.java     |    8 +-
 .../entity/pool/ServerPoolLiveTest.java         |    2 +-
 .../pool/ServerPoolLocationResolverTest.java    |    8 +-
 .../brooklyn/entity/pool/ServerPoolTest.java    |    4 +-
 .../service/SystemServiceEnricherTest.java      |    4 +-
 .../entity/software/AbstractDockerLiveTest.java |    2 +-
 .../MachineLifecycleEffectorTasksTest.java      |    2 +-
 .../entity/software/SoftwareEffectorTest.java   |    6 +-
 .../entity/software/SshEffectorTasksTest.java   |    7 +-
 .../software/http/HttpRequestSensorTest.java    |    2 +-
 .../mysql/AbstractToyMySqlEntityTest.java       |    8 +-
 .../mysql/DynamicToyMySqlEntityBuilder.java     |   10 +-
 .../mysql/DynamicToyMySqlEntityTest.java        |    2 +-
 .../software/ssh/SshCommandIntegrationTest.java |    4 +-
 .../PortAttributeSensorAndConfigKeyTest.java    |    6 +-
 .../brooklyn/event/feed/jmx/JmxFeedTest.java    |    7 +-
 .../event/feed/jmx/RebindJmxFeedTest.java       |    6 +-
 .../basic/MachineDetailsEc2LiveTest.java        |   68 -
 .../MachineDetailsGoogleComputeLiveTest.java    |   66 -
 .../basic/WinRmMachineLocationLiveTest.java     |   93 -
 .../basic/WinRmMachineLocationTest.java         |   44 -
 .../usage/ApplicationUsageTrackingTest.java     |    2 +-
 .../usage/LocationUsageTrackingTest.java        |   10 +-
 .../management/usage/UsageListenerTest.java     |    2 +-
 .../basic/MachineDetailsEc2LiveTest.java        |   68 +
 .../MachineDetailsGoogleComputeLiveTest.java    |   65 +
 .../basic/WinRmMachineLocationLiveTest.java     |   93 +
 .../basic/WinRmMachineLocationTest.java         |   44 +
 .../entity/database/crate/CrateNode.java        |    2 +-
 .../database/crate/CrateNodeSshDriver.java      |    2 +-
 .../entity/database/mariadb/MariaDbNode.java    |    2 +-
 .../database/mariadb/MariaDbNodeImpl.java       |    4 +-
 .../database/mariadb/MariaDbSshDriver.java      |    4 +-
 .../entity/database/mysql/MySqlClusterImpl.java |    2 +-
 .../entity/database/mysql/MySqlNode.java        |    2 +-
 .../entity/database/mysql/MySqlNodeImpl.java    |    4 +-
 .../entity/database/mysql/MySqlSshDriver.java   |    6 +-
 .../database/postgresql/PostgreSqlNode.java     |    2 +-
 .../PostgreSqlNodeChefImplFromScratch.java      |    4 +-
 .../postgresql/PostgreSqlSshDriver.java         |    4 +-
 .../database/rubyrep/RubyRepSshDriver.java      |    2 +-
 .../crate/CrateNodeIntegrationTest.java         |    2 +-
 .../mariadb/MariaDbIntegrationTest.java         |    2 +-
 .../database/mariadb/MariaDbLiveEc2Test.java    |    4 +-
 .../mariadb/MariaDbLiveRackspaceTest.java       |    4 +-
 .../database/mysql/MySqlClusterLiveEc2Test.java |    2 +-
 .../mysql/MySqlClusterLiveSoftlayerTest.java    |    2 +-
 .../database/mysql/MySqlClusterTestHelper.java  |    2 +-
 .../database/mysql/MySqlIntegrationTest.java    |    2 +-
 .../entity/database/mysql/MySqlLiveEc2Test.java |    2 +-
 .../entity/database/mysql/MySqlLiveGceTest.java |    2 +-
 .../database/mysql/MySqlLiveRackspaceTest.java  |    4 +-
 .../database/mysql/MysqlDockerLiveTest.java     |    4 +-
 .../postgresql/PostgreSqDockerLiveTest.java     |    2 +-
 .../database/postgresql/PostgreSqlChefTest.java |    6 +-
 .../postgresql/PostgreSqlEc2LiveTest.java       |    2 +-
 .../postgresql/PostgreSqlGceLiveTest.java       |    2 +-
 .../postgresql/PostgreSqlIntegrationTest.java   |    2 +-
 .../postgresql/PostgreSqlRackspaceLiveTest.java |    6 +-
 .../PostgreSqlRebindIntegrationTest.java        |    2 +-
 .../database/rubyrep/RubyRepEc2LiveTest.java    |    4 +-
 .../rubyrep/RubyRepIntegrationTest.java         |    6 +-
 .../rubyrep/RubyRepRackspaceLiveTest.java       |    6 +-
 .../messaging/activemq/ActiveMQSshDriver.java   |    2 +-
 .../kafka/AbstractfKafkaSshDriver.java          |    2 +-
 .../entity/messaging/kafka/KafkaBroker.java     |    2 +-
 .../messaging/kafka/KafkaBrokerSshDriver.java   |    2 +-
 .../messaging/kafka/KafkaClusterImpl.java       |    2 +-
 .../kafka/KafkaZooKeeperSshDriver.java          |    2 +-
 .../entity/messaging/qpid/QpidSshDriver.java    |    2 +-
 .../messaging/rabbit/RabbitDestination.java     |    2 +-
 .../messaging/rabbit/RabbitSshDriver.java       |    2 +-
 .../entity/messaging/storm/StormSshDriver.java  |    4 +-
 .../entity/zookeeper/ZooKeeperEnsembleImpl.java |    3 +-
 .../entity/zookeeper/ZooKeeperSshDriver.java    |    2 +-
 .../messaging/activemq/ActiveMQEc2LiveTest.java |    2 +-
 .../activemq/ActiveMQGoogleComputeLiveTest.java |    2 +-
 .../activemq/ActiveMQIntegrationTest.java       |    2 +-
 .../messaging/kafka/KafkaIntegrationTest.java   |    6 +-
 .../entity/messaging/kafka/KafkaLiveTest.java   |    2 +-
 .../entity/messaging/qpid/QpidEc2LiveTest.java  |    2 +-
 .../messaging/qpid/QpidIntegrationTest.java     |    2 +-
 .../messaging/rabbit/RabbitEc2LiveTest.java     |    2 +-
 .../messaging/rabbit/RabbitIntegrationTest.java |    4 +-
 .../storm/StormAbstractCloudLiveTest.java       |    2 +-
 .../messaging/storm/StormEc2LiveTest.java       |    2 +-
 .../zookeeper/ZooKeeperEc2LiveTest.java         |    2 +-
 .../zookeeper/ZooKeeperEnsembleLiveTest.java    |    2 +-
 .../entity/monitoring/monit/MonitNodeImpl.java  |    4 +-
 .../entity/monitoring/monit/MonitSshDriver.java |    4 +-
 .../monitoring/monit/MonitIntegrationTest.java  |    4 +-
 .../entity/network/bind/BindDnsServer.java      |    2 +-
 .../entity/network/bind/BindDnsServerImpl.java  |    4 +-
 .../network/bind/BindDnsServerSshDriver.java    |    2 +-
 .../network/bind/BindDnsServerByonLiveTest.java |    2 +-
 .../network/bind/BindDnsServerEc2LiveTest.java  |    2 +-
 .../network/bind/BindDnsServerLiveTest.java     |    2 +-
 .../bind/BindDnsServerSoftlayerLiveTest.java    |    2 +-
 .../bind/DoNothingSoftwareProcessDriver.java    |    2 +-
 .../network/bind/TestBindDnsServerImpl.java     |    2 +-
 .../cassandra/CassandraDatacenterImpl.java      |    4 +-
 .../entity/nosql/cassandra/CassandraFabric.java |    2 +-
 .../nosql/cassandra/CassandraFabricImpl.java    |    2 +-
 .../entity/nosql/cassandra/CassandraNode.java   |    2 +-
 .../nosql/cassandra/CassandraNodeImpl.java      |    8 +-
 .../nosql/cassandra/CassandraNodeSshDriver.java |    8 +-
 .../nosql/couchbase/CouchbaseClusterImpl.java   |    2 +-
 .../nosql/couchbase/CouchbaseNodeImpl.java      |    6 +-
 .../nosql/couchbase/CouchbaseNodeSshDriver.java |    6 +-
 .../couchbase/CouchbaseSyncGatewayImpl.java     |    2 +-
 .../CouchbaseSyncGatewaySshDriver.java          |    4 +-
 .../nosql/couchdb/CouchDBNodeSshDriver.java     |    4 +-
 .../nosql/elasticsearch/ElasticSearchNode.java  |    2 +-
 .../elasticsearch/ElasticSearchNodeImpl.java    |    2 +-
 .../ElasticSearchNodeSshDriver.java             |    2 +-
 .../nosql/mongodb/AbstractMongoDBSshDriver.java |    4 +-
 .../nosql/mongodb/MongoDBClientSshDriver.java   |    2 +-
 .../nosql/mongodb/MongoDBClientSupport.java     |    3 +-
 .../nosql/mongodb/MongoDBReplicaSetImpl.java    |    2 +-
 .../entity/nosql/mongodb/MongoDBServerImpl.java |    2 +-
 .../entity/nosql/mongodb/MongoDBSshDriver.java  |    2 +-
 .../entity/nosql/mongodb/ReplicaSetConfig.java  |    2 +-
 .../sharding/CoLocatedMongoDBRouterImpl.java    |    2 +-
 .../MongoDBConfigServerClusterImpl.java         |    4 +-
 .../sharding/MongoDBConfigServerSshDriver.java  |    2 +-
 .../sharding/MongoDBRouterClusterImpl.java      |    2 +-
 .../sharding/MongoDBRouterSshDriver.java        |    2 +-
 .../sharding/MongoDBShardClusterImpl.java       |    3 +-
 .../sharding/MongoDBShardedDeploymentImpl.java  |    2 +-
 .../entity/nosql/redis/RedisClusterImpl.java    |    2 +-
 .../entity/nosql/redis/RedisStoreImpl.java      |    6 +-
 .../entity/nosql/redis/RedisStoreSshDriver.java |    4 +-
 .../entity/nosql/riak/RiakNodeImpl.java         |    6 +-
 .../entity/nosql/riak/RiakNodeSshDriver.java    |    4 +-
 .../brooklyn/entity/nosql/solr/SolrServer.java  |    2 +-
 .../entity/nosql/solr/SolrServerImpl.java       |    2 +-
 .../entity/nosql/solr/SolrServerSshDriver.java  |    5 +-
 .../cassandra/AbstractCassandraNodeTest.java    |    3 +-
 .../CassandraDatacenterIntegrationTest.java     |    4 +-
 .../cassandra/CassandraDatacenterLiveTest.java  |    4 +-
 ...assandraDatacenterRebindIntegrationTest.java |    4 +-
 .../cassandra/CassandraDatacenterTest.java      |    6 +-
 .../nosql/cassandra/CassandraFabricTest.java    |    8 +-
 .../cassandra/CassandraNodeEc2LiveTest.java     |    3 +-
 .../nosql/couchbase/CouchbaseOfflineTest.java   |    5 +-
 .../CouchbaseSyncGatewayEc2LiveTest.java        |    5 +-
 .../nosql/couchdb/AbstractCouchDBNodeTest.java  |    5 +-
 .../nosql/couchdb/CouchDBClusterLiveTest.java   |    4 +-
 .../nosql/couchdb/CouchDBNodeEc2LiveTest.java   |    3 +-
 .../ElasticSearchClusterIntegrationTest.java    |    4 +-
 .../ElasticSearchNodeIntegrationTest.java       |    5 +-
 .../nosql/mongodb/MongoDBEc2LiveTest.java       |    3 +-
 .../nosql/mongodb/MongoDBIntegrationTest.java   |    3 +-
 .../mongodb/MongoDBRebindIntegrationTest.java   |    3 +-
 .../mongodb/MongoDBReplicaSetEc2LiveTest.java   |    4 +-
 .../MongoDBReplicaSetIntegrationTest.java       |    4 +-
 .../nosql/mongodb/MongoDBSoftLayerLiveTest.java |    3 +-
 .../entity/nosql/mongodb/MongoDBTestHelper.java |    4 +-
 .../MongoDBConfigServerIntegrationTest.java     |    3 +-
 .../MongoDBShardedDeploymentEc2LiveTest.java    |    5 +-
 ...MongoDBShardedDeploymentIntegrationTest.java |    8 +-
 .../redis/RedisClusterIntegrationTest.java      |    7 +-
 .../entity/nosql/redis/RedisEc2LiveTest.java    |    3 +-
 .../nosql/redis/RedisIntegrationTest.java       |    5 +-
 .../nosql/riak/RiakClusterEc2LiveTest.java      |    4 +-
 .../entity/nosql/riak/RiakNodeEc2LiveTest.java  |    3 +-
 .../riak/RiakNodeGoogleComputeLiveTest.java     |    4 +-
 .../nosql/riak/RiakNodeIntegrationTest.java     |    3 +-
 .../nosql/riak/RiakNodeSoftlayerLiveTest.java   |    3 +-
 .../nosql/solr/AbstractSolrServerTest.java      |    3 +-
 .../nosql/solr/SolrServerEc2LiveTest.java       |    3 +-
 .../entity/osgi/karaf/KarafSshDriver.java       |    2 +-
 .../osgi/karaf/KarafContainerEc2LiveTest.java   |    2 +-
 .../entity/osgi/karaf/KarafContainerTest.java   |    4 +-
 .../entity/dns/AbstractGeoDnsService.java       |    2 +-
 .../entity/dns/AbstractGeoDnsServiceImpl.java   |    2 +-
 .../geoscaling/GeoscalingDnsServiceImpl.java    |    2 +-
 .../geoscaling/GeoscalingScriptGenerator.java   |    2 +-
 .../entity/proxy/AbstractControllerImpl.java    |    4 +-
 .../AbstractNonProvisionedControllerImpl.java   |    2 +-
 .../entity/proxy/nginx/NginxSshDriver.java      |    7 +-
 .../ControlledDynamicWebAppClusterImpl.java     |    2 +-
 .../entity/webapp/ElasticJavaWebAppService.java |    4 +-
 .../entity/webapp/JavaWebAppSshDriver.java      |    2 +-
 .../entity/webapp/WebAppServiceMethods.java     |    2 +-
 .../entity/webapp/jboss/JBoss6SshDriver.java    |    2 +-
 .../entity/webapp/jboss/JBoss7ServerImpl.java   |    2 +-
 .../entity/webapp/jboss/JBoss7SshDriver.java    |    2 +-
 .../entity/webapp/jetty/Jetty6SshDriver.java    |    2 +-
 .../webapp/nodejs/NodeJsWebAppService.java      |    4 +-
 .../webapp/nodejs/NodeJsWebAppServiceImpl.java  |    2 +-
 .../webapp/nodejs/NodeJsWebAppSshDriver.java    |    2 +-
 .../entity/webapp/tomcat/Tomcat7SshDriver.java  |    2 +-
 .../entity/webapp/tomcat/TomcatServer.java      |    2 +-
 .../entity/webapp/tomcat/TomcatSshDriver.java   |    2 +-
 .../entity/dns/AbstractGeoDnsServiceTest.java   |   22 +-
 .../geoscaling/GeoscalingIntegrationTest.java   |   12 +-
 .../GeoscalingScriptGeneratorTest.java          |    3 +-
 .../entity/proxy/AbstractControllerTest.java    |   14 +-
 .../brooklyn/entity/proxy/StubAppServer.java    |    8 +-
 .../brooklyn/entity/proxy/UrlMappingTest.java   |    4 +-
 .../nginx/NginxClusterIntegrationTest.java      |    6 +-
 .../entity/proxy/nginx/NginxEc2LiveTest.java    |    3 +-
 .../nginx/NginxHttpsSslIntegrationTest.java     |    5 +-
 .../proxy/nginx/NginxIntegrationTest.java       |    3 +-
 .../proxy/nginx/NginxLightIntegrationTest.java  |    4 +-
 .../proxy/nginx/NginxRebindIntegrationTest.java |    4 +-
 .../nginx/NginxRebindWithHaIntegrationTest.java |    7 +-
 .../nginx/NginxUrlMappingIntegrationTest.java   |    4 +-
 .../proxy/nginx/NginxWebClusterEc2LiveTest.java |    6 +-
 .../AbstractWebAppFixtureIntegrationTest.java   |    4 +-
 ...lledDynamicWebAppClusterIntegrationTest.java |    4 +-
 .../ControlledDynamicWebAppClusterTest.java     |    4 +-
 .../entity/webapp/DynamicWebAppClusterTest.java |    4 +-
 .../entity/webapp/DynamicWebAppFabricTest.java  |    5 +-
 .../webapp/ElasticCustomLocationTest.java       |    3 +-
 ...ElasticJavaWebAppServiceIntegrationTest.java |    3 +-
 .../webapp/TomcatAutoScalerPolicyTest.java      |    4 +-
 .../webapp/WebAppConcurrentDeployTest.java      |    6 +-
 .../webapp/WebAppLiveIntegrationTest.groovy     |    8 +-
 ...namicWebAppClusterRebindIntegrationTest.java |    3 +-
 ...namicWebAppClusterRebindIntegrationTest.java |    5 +-
 .../jboss/JBoss6ServerAwsEc2LiveTest.java       |    5 +-
 ...Boss6ServerNonInheritingIntegrationTest.java |    5 +-
 .../jboss/JBoss7ServerAwsEc2LiveTest.java       |    5 +-
 .../jboss/JBoss7ServerDockerLiveTest.java       |    5 +-
 ...Boss7ServerNonInheritingIntegrationTest.java |    4 +-
 .../JBoss7ServerRebindingIntegrationTest.java   |    3 +-
 ...ultiVersionWebAppFixtureIntegrationTest.java |    4 +-
 .../Jboss7ServerGoogleComputeLiveTest.java      |    5 +-
 .../JettyWebAppFixtureIntegrationTest.java      |    4 +-
 .../webapp/nodejs/NodeJsWebAppEc2LiveTest.java  |    3 +-
 .../NodeJsWebAppFixtureIntegrationTest.java     |    4 +-
 .../NodeJsWebAppSimpleIntegrationTest.java      |    8 +-
 .../nodejs/NodeJsWebAppSoftlayerLiveTest.java   |    3 +-
 .../webapp/tomcat/Tomcat8ServerEc2LiveTest.java |    3 +-
 .../tomcat/Tomcat8ServerSoftlayerLiveTest.java  |    3 +-
 ...mcat8ServerWebAppFixtureIntegrationTest.java |    3 +-
 ...ableRetrieveUsageMetricsIntegrationTest.java |    3 +-
 .../webapp/tomcat/TomcatServerEc2LiveTest.java  |    5 +-
 .../tomcat/TomcatServerSoftlayerLiveTest.java   |    5 +-
 ...omcatServerWebAppFixtureIntegrationTest.java |    3 +-
 .../test/entity/TestJavaWebAppEntity.java       |    2 +-
 .../app/ClusterWebServerDatabaseSample.java     |    2 +-
 .../sample/app/SingleWebServerSample.java       |    2 +-
 .../BrooklynComponentTemplateResolver.java      |    2 +-
 .../creation/BrooklynYamlLocationResolver.java  |    4 +-
 .../camp/brooklyn/ByonLocationsYamlTest.java    |   16 +-
 .../brooklyn/EmptySoftwareProcessYamlTest.java  |    4 +-
 .../camp/brooklyn/EntitiesYamlTest.java         |    2 +-
 .../camp/brooklyn/LocationsYamlTest.java        |   12 +-
 .../brooklyn/TestEntityWithInitConfigImpl.java  |    2 +-
 .../CatalogOsgiVersionMoreEntityTest.java       |    2 +-
 .../catalog/CatalogYamlLocationTest.java        |    8 +-
 .../org/apache/brooklyn/cli/CloudExplorer.java  |   12 +-
 .../org/apache/brooklyn/cli/ItemLister.java     |    4 +-
 .../brooklyn/cli/lister/ItemDescriptors.java    |    2 +-
 .../java/org/apache/brooklyn/cli/CliTest.java   |   11 +-
 .../brooklyn/launcher/BrooklynLauncher.java     |   10 +-
 .../brooklyn/launcher/BrooklynWebServer.java    |    6 +-
 .../launcher/config/BrooklynGlobalConfig.java   |    2 +-
 .../brooklynnode/BrooklynNodeRestTest.java      |    2 +-
 .../BrooklynLauncherRebindTestFixture.java      |    2 +-
 .../brooklyn/launcher/BrooklynLauncherTest.java |    4 +-
 .../qa/load/SimulatedJBoss7ServerImpl.java      |    4 +-
 .../qa/load/SimulatedMySqlNodeImpl.java         |    2 +-
 .../qa/load/SimulatedNginxControllerImpl.java   |    2 +-
 .../brooklyn/qa/load/SimulatedTheeTierApp.java  |    2 +-
 .../SoftlayerObtainPrivateLiveTest.java         |    4 +-
 .../org/apache/brooklyn/qa/load/LoadTest.java   |    3 +-
 .../brooklyn/rest/domain/LocationSpec.java      |    2 +-
 .../ApplicationResourceIntegrationTest.java     |    2 +-
 .../rest/client/BrooklynApiRestClientTest.java  |    3 +-
 .../apache/brooklyn/rest/BrooklynWebConfig.java |    2 +-
 .../rest/resources/ApplicationResource.java     |    2 +-
 .../rest/resources/CatalogResource.java         |    4 +-
 .../brooklyn/rest/resources/EntityResource.java |    2 +-
 .../rest/resources/LocationResource.java        |    6 +-
 .../rest/transform/ApplicationTransformer.java  |    2 +-
 .../rest/transform/CatalogTransformer.java      |    4 +-
 .../rest/transform/LocationTransformer.java     |   10 +-
 .../rest/util/BrooklynRestResourceUtils.java    |    4 +-
 .../brooklyn/rest/util/EntityLocationUtils.java |    4 +-
 .../rest/util/json/BidiSerialization.java       |    2 +-
 .../rest/resources/ApplicationResourceTest.java |    8 +-
 .../rest/resources/LocationResourceTest.java    |    6 +-
 .../rest/resources/ScriptResourceTest.java      |    2 +-
 .../rest/resources/UsageResourceTest.java       |   10 +-
 .../rest/testing/BrooklynRestApiTest.java       |    4 +-
 .../testing/mocks/RestMockSimpleEntity.java     |    2 +-
 .../rest/util/EntityLocationUtilsTest.java      |    8 +-
 .../brooklyn/osgi/tests/SimpleLocation.java     |    2 +-
 .../brooklyn/osgi/tests/more/MoreLocation.java  |    2 +-
 .../brooklyn/osgi/tests/more/MoreLocation.java  |    2 +-
 995 files changed, 33714 insertions(+), 33908 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/AddressableLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/AddressableLocation.java b/api/src/main/java/brooklyn/location/AddressableLocation.java
deleted file mode 100644
index 172c478..0000000
--- a/api/src/main/java/brooklyn/location/AddressableLocation.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.net.InetAddress;
-
-/** A location that has an IP address.
- * <p>
- * This IP address may be a machine (usually the MachineLocation sub-interface), 
- * or often an entry point for a service.
- */
-public interface AddressableLocation extends Location {
-
-    /**
-     * Return the single most appropriate address for this location.
-     * (An implementation or sub-interface definition may supply more information
-     * on the precise semantics of the address.)
-     * 
-     * Should not return null, but in some "special cases" (e.g. CloudFoundryLocation it
-     * may return null if the location is not configured correctly). Users should expect
-     * a non-null result and treat null as a programming error or misconfiguration. 
-     * Implementors of this interface should strive to not return null (and then we'll
-     * remove this caveat from the javadoc!).
-     */
-    InetAddress getAddress();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/BasicMachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/BasicMachineLocationCustomizer.java b/api/src/main/java/brooklyn/location/BasicMachineLocationCustomizer.java
deleted file mode 100644
index a05dd44..0000000
--- a/api/src/main/java/brooklyn/location/BasicMachineLocationCustomizer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import com.google.common.annotations.Beta;
-
-/**
- * A default no-op implementation, which can be extended to override the appropriate methods.
- * 
- * Sub-classing will give the user some protection against future API changes - note that 
- * {@link MachineLocationCustomizer} is marked {@link Beta}.
- */
-@Beta
-public class BasicMachineLocationCustomizer implements MachineLocationCustomizer {
-
-    @Override
-    public void customize(MachineLocation machine) {
-        // no-op
-    }
-    
-    @Override
-    public void preRelease(MachineLocation machine) {
-        // no-op
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/HardwareDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/HardwareDetails.java b/api/src/main/java/brooklyn/location/HardwareDetails.java
deleted file mode 100644
index e0a90a9..0000000
--- a/api/src/main/java/brooklyn/location/HardwareDetails.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import javax.annotation.Nullable;
-
-/**
- * @since 0.7.0
- */
-public interface HardwareDetails {
-
-    /**
-     * The number of CPUs on the machine
-     */
-    @Nullable
-    Integer getCpuCount();
-
-    /**
-     * Amount of RAM in megabytes
-     */
-    @Nullable
-    Integer getRam();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/Location.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/Location.java b/api/src/main/java/brooklyn/location/Location.java
deleted file mode 100644
index 791ca7a..0000000
--- a/api/src/main/java/brooklyn/location/Location.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.brooklyn.api.basic.BrooklynObject;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-
-/**
- * A location that an entity can be in. Examples of locations include a single machine
- * or a pool of machines, or a region within a given cloud. 
- * 
- * See {@link brooklyn.entity.trait.Startable#start(Collection)}.
- * 
- * Locations may not be {@link Serializable} in subsequent releases!
- */
-public interface Location extends Serializable, BrooklynObject {
-
-    /**
-     * A unique id for this location.
-     */
-    @Override
-    String getId();
-
-    /**
-     * Get the name assigned to this location.
-     *
-     * @return the name assigned to the location.
-     * @since 0.6 (previously getName())
-     */
-    @Override
-    String getDisplayName();
-
-    /**
-     * Get the 'parent' of this location. Locations are organized into a tree hierarchy, and this method will return a reference
-     * to the parent of this location, or {@code null} if this location is the tree root.
-     *
-     * @return a reference to the parent of this location, or {@code null} if this location is the tree root.
-     * @since 0.6 (previously getParentLocation())
-     */
-    Location getParent();
-
-    /**
-     * Get the 'children' of this location. Locations are organized into a tree hierarchy, and this method will return a
-     * collection containing the children of this location. This collection is an unmodifiable view of the data.
-     *
-     * @return a collection containing the children of this location.
-     * @since 0.6 (previously getChildLocations())
-     */
-    Collection<Location> getChildren();
-
-    /**
-     * Set the 'parent' of this location. If this location was previously a child of a different location, it is removed from
-     * the other location first. It is valid to pass in {@code null} to indicate that the location should be disconnected
-     * from its parent.
-     * 
-     * Adds this location as a child of the new parent (see {@code getChildLocations()}).
-     *
-     * @param newParent the new parent location object, or {@code null} to clear the parent reference.
-     * @since 0.6 (previously setParentLocation(Location))
-     */
-    void setParent(Location newParent);
-
-    /**
-     * @return meta-data about the location (usually a long line, or a small number of lines).
-     * 
-     * @since 0.6
-     */
-    String toVerboseString();
-    
-    /**
-     * Answers true if this location equals or is an ancestor of the given location.
-     */
-    boolean containsLocation(Location potentialDescendent);
-
-    /** 
-     * Returns configuration set at this location or inherited or default.
-     * 
-     * Convenience method for {@code config().get(key)}
-     */
-    <T> T getConfig(ConfigKey<T> key);
-
-    /**
-     * Convenience method for {@code config().get(key)}
-     * 
-     * @see {@link #getConfig(ConfigKey)}
-     */
-    <T> T getConfig(HasConfigKey<T> key);
-
-    /** 
-     * True iff the indication config key is set, either inherited (second argument true) or locally-only (second argument false).
-     * 
-     * @deprecated since 0.7.0; use {@link #config()}, such as {@code ((LocationInternal)location).config().getRaw(key).isPresent()}
-     */
-    @Deprecated
-    boolean hasConfig(ConfigKey<?> key, boolean includeInherited);
-
-    /** 
-     * Returns all config set, either inherited (argument true) or locally-only (argument false).
-     * 
-     * @deprecated since 0.7.0; use {@link #config()}, such as {@code policy.config().getBag()}
-     */
-    @Deprecated
-    public Map<String,Object> getAllConfig(boolean includeInherited);
-    
-    /**
-     * Whether this location has support for the given extension type.
-     * See additional comments in {@link #getExtension(Class)}.
-     * 
-     * @throws NullPointerException if extensionType is null
-     */
-    boolean hasExtension(Class<?> extensionType);
-
-    /**
-     * Returns an extension of the given type. Note that the type must be an exact match for
-     * how the extension was registered (e.g. {@code getExtension(Object.class)} will not match
-     * anything, even though registered extension extend {@link Object}.
-     * <p>
-     * This will not look at extensions of {@link #getParent()}.
-     * 
-     * @throws IllegalArgumentException if this location does not support the given extension type
-     * @throws NullPointerException if extensionType is null
-     */
-    <T> T getExtension(Class<T> extensionType);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/LocationDefinition.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationDefinition.java b/api/src/main/java/brooklyn/location/LocationDefinition.java
deleted file mode 100644
index 3a20a24..0000000
--- a/api/src/main/java/brooklyn/location/LocationDefinition.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-
-/**
- * Defines a location, where the {@link #getSpec()} is like a serialized representation
- * of the location so that Brooklyn can create a corresponding location.
- * 
- * Examples include a complete description (e.g. giving a list of machines in a pool), or
- * a name that matches a named location defined in the brooklyn poperties.
- * 
- * Users are not expected to implement this, or to use the interface directly. See
- * {@link LocationRegistry#resolve(String)} and {@link ManagementContext#getLocationRegistry()}.
- */
-public interface LocationDefinition {
-
-    public String getId();
-    public String getName();
-    public String getSpec();
-    public Map<String,Object> getConfig();
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/LocationNotAvailableException.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationNotAvailableException.java b/api/src/main/java/brooklyn/location/LocationNotAvailableException.java
deleted file mode 100644
index 561d625..0000000
--- a/api/src/main/java/brooklyn/location/LocationNotAvailableException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-
-/**
- * Indicates that a {@link ProvisioningLocation} is not able to provision a requested location
- */
-public class LocationNotAvailableException extends Exception {
-    private static final long serialVersionUID = 1079817235289265761L;
-    
-    public LocationNotAvailableException(String s) {
-        super(s);
-    }
-
-    public LocationNotAvailableException(String s, Throwable throwable) {
-        super(s, throwable);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/LocationRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationRegistry.java b/api/src/main/java/brooklyn/location/LocationRegistry.java
deleted file mode 100644
index cc2c251..0000000
--- a/api/src/main/java/brooklyn/location/LocationRegistry.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.annotation.Nullable;
-
-import brooklyn.util.guava.Maybe;
-
-import com.google.common.annotations.Beta;
-
-/**
- * The registry of the sorts of locations that brooklyn knows about. Given a
- * {@LocationDefinition} or a {@link String} representation of a spec, this can
- * be used to create a {@link Location} instance.
- */
-@SuppressWarnings("rawtypes")
-public interface LocationRegistry {
-
-    /** map of ID (possibly randomly generated) to the definition (spec, name, id, and props; 
-     * where spec is the spec as defined, for instance possibly another named:xxx location) */
-    public Map<String,LocationDefinition> getDefinedLocations();
-    
-    /** returns a LocationDefinition given its ID (usually a random string), or null if none */
-    public LocationDefinition getDefinedLocationById(String id);
-    
-    /** returns a LocationDefinition given its name (e.g. for named locations, supply the bit after the "named:" prefix), 
-     * or null if none */
-    public LocationDefinition getDefinedLocationByName(String name);
-
-    /** adds or updates the given defined location */
-    public void updateDefinedLocation(LocationDefinition l);
-
-    /** removes the defined location from the registry (applications running there are unaffected) */
-    public void removeDefinedLocation(String id);
-
-    /** Returns a fully populated (config etc) location from the given definition, with optional add'l flags.
-     * the location will be managed by default, unless the manage parameter is false, 
-     * or the manage parameter is null and the CREATE_UNMANAGED flag is set.
-     * <p>
-     * The manage parameter is {@link Boolean} so that null can be used to say rely on anything in the flags.
-     * 
-     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
-    @Beta
-    public Maybe<Location> resolve(LocationDefinition ld, Boolean manage, Map locationFlags);
-    
-    /** As {@link #resolve(LocationDefinition, Boolean, Map), with the location managed, and no additional flags,
-     * unwrapping the result (throwing if not resolvable) */
-    public Location resolve(LocationDefinition l);
-
-    /** Returns a location created from the given spec, which might correspond to a definition, or created on-the-fly.
-     * Optional flags can be passed through to underlying the location. 
-     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
-    @Beta
-    public Maybe<Location> resolve(String spec, Boolean manage, Map locationFlags);
-    
-    /** efficiently returns for inspection only a fully populated (config etc) location from the given definition; 
-     * the value might be unmanaged so it is not meant for any use other than inspection,
-     * but callers should prefer this when they don't wish to create a new location which will be managed in perpetuity!
-     * 
-     * @deprecated since 0.7.0, use {@link #resolve(LocationDefinition, Boolean, Map)} */
-    @Deprecated
-    public Location resolveForPeeking(LocationDefinition l);
-
-    /** returns fully populated (config etc) location from the given definition, with overrides;
-     * @deprecated since 0.7.0, use {@link #resolve(LocationDefinition, Boolean, Map)} */
-    @Deprecated
-    public Location resolve(LocationDefinition l, Map<?,?> locationFlags);
-    
-    /** See {@link #resolve(String, Boolean, Map)}; asks for the location to be managed, and supplies no additional flags,
-     * and unwraps the result (throwing if the spec cannot be resolve) */
-    public Location resolve(String spec);
-    
-    /** Returns true/false depending whether spec seems like a valid location,
-     * that is it has a chance of being resolved (depending on the spec) but NOT guaranteed,
-     * as it is not passed to the spec;
-     * see {@link #resolve(String, Boolean, Map)} which has stronger guarantees 
-     * @deprecated since 0.7.0, not really needed, and semantics are weak; use {@link #resolve(String, Boolean, Map)} */
-    @Deprecated
-    public boolean canMaybeResolve(String spec);
-    
-    /** As {@link #resolve(String, Boolean, Map)}, but unwrapped
-     * @throws NoSuchElementException if the spec cannot be resolved */
-    public Location resolve(String spec, @Nullable Map locationFlags);
-    
-    /** as {@link #resolve(String)} but returning null (never throwing)
-     * @deprecated since 0.7.0 use {@link #resolve(String, Boolean, Map)} */
-    @Deprecated
-    public Location resolveIfPossible(String spec);
-
-    /**
-     * As {@link #resolve(String)} but takes collections (of strings or locations)
-     * <p>
-     * Expects a collection of elements being individual location spec strings or locations, 
-     * and returns a list of resolved (newly created and managed) locations.
-     * <p>
-     * From 0.7.0 this no longer flattens lists (nested lists are disallowed) 
-     * or parses comma-separated elements (they are resolved as-is)
-     */
-    public List<Location> resolve(Iterable<?> spec);
-    
-    /** Takes a string, interpreted as a comma-separated (or JSON style, when you need internal double quotes or commas) list;
-     * or a list, passed to {@link #resolve(Iterable)}; or null/empty (empty list),
-     * and returns a list of resolved (created and managed) locations */
-    public List<Location> resolveList(Object specList);
-    
-    public Map getProperties();
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/LocationResolver.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationResolver.java b/api/src/main/java/brooklyn/location/LocationResolver.java
deleted file mode 100644
index bcd32b6..0000000
--- a/api/src/main/java/brooklyn/location/LocationResolver.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Provides a way of creating location instances of a particular type.
- */
-public interface LocationResolver {
-
-    void init(ManagementContext managementContext);
-    
-    /** the prefix that this resolver will attend to */
-    String getPrefix();
-    
-    /** whether the spec is something which should be passed to this resolver */
-    boolean accepts(String spec, brooklyn.location.LocationRegistry registry);
-
-    /**
-     * Similar to {@link #newLocationFromString(Map, String)} 
-     * but passing in a reference to the registry itself (from which the base properties are discovered)
-     * and including flags (e.g. user, key, cloud credential) which are known to be for this location.
-     * <p>
-     * introduced to support locations which refer to other locations, e.g. NamedLocationResolver  
-     **/ 
-    @SuppressWarnings("rawtypes")
-    Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry);
-
-    /** @since 0.7.0 exploring this as a mechanism to disable locations */
-    @Beta
-    public interface EnableableLocationResolver extends LocationResolver {
-        /** whether the location is enabled */
-        boolean isEnabled();
-    }
-    
-}


[39/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocationPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocationPredicates.java b/core/src/main/java/brooklyn/location/basic/LocationPredicates.java
deleted file mode 100644
index 45783e7..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocationPredicates.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import javax.annotation.Nullable;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.location.Location;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-
-public class LocationPredicates {
-
-    public static <T> Predicate<Location> idEqualTo(final T val) {
-        return new Predicate<Location>() {
-            @Override
-            public boolean apply(@Nullable Location input) {
-                return (input != null) && Objects.equal(input.getId(), val);
-            }
-        };
-    }
-    
-    public static <T> Predicate<Location> displayNameEqualTo(final T val) {
-        return new Predicate<Location>() {
-            @Override
-            public boolean apply(@Nullable Location input) {
-                return (input != null) && Objects.equal(input.getDisplayName(), val);
-            }
-        };
-    }
-    
-    public static <T> Predicate<Location> configEqualTo(final ConfigKey<T> configKey, final T val) {
-        return new Predicate<Location>() {
-            @Override
-            public boolean apply(@Nullable Location input) {
-                return (input != null) && Objects.equal(input.getConfig(configKey), val);
-            }
-        };
-    }
-
-    public static <T> Predicate<Location> configEqualTo(final HasConfigKey<T> configKey, final T val) {
-        return new Predicate<Location>() {
-            @Override
-            public boolean apply(@Nullable Location input) {
-                return (input != null) && Objects.equal(input.getConfig(configKey), val);
-            }
-        };
-    }
-
-    /**
-     * Returns a predicate that determines if a given location is a direct child of this {@code parent}.
-     */
-    public static <T> Predicate<Location> isChildOf(final Location parent) {
-        return new Predicate<Location>() {
-            @Override
-            public boolean apply(@Nullable Location input) {
-                return (input != null) && Objects.equal(input.getParent(), parent);
-            }
-        };
-    }
-
-    /**
-     * Returns a predicate that determines if a given location is a descendant of this {@code ancestor}.
-     */
-    public static <T> Predicate<Location> isDescendantOf(final Location ancestor) {
-        return new Predicate<Location>() {
-            @Override
-            public boolean apply(@Nullable Location input) {
-                // assumes impossible to have cycles in location-hierarchy
-                Location contenderAncestor = (input == null) ? input : input.getParent();
-                while (contenderAncestor != null) {
-                    if (Objects.equal(contenderAncestor, ancestor)) {
-                        return true;
-                    }
-                    contenderAncestor = contenderAncestor.getParent();
-                }
-                return false;
-            }
-        };
-    }
-
-    public static <T> Predicate<Location> managed() {
-        return new Predicate<Location>() {
-            @Override
-            public boolean apply(@Nullable Location input) {
-                return (input != null) && Locations.isManaged(input);
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocationPropertiesFromBrooklynProperties.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocationPropertiesFromBrooklynProperties.java b/core/src/main/java/brooklyn/location/basic/LocationPropertiesFromBrooklynProperties.java
deleted file mode 100644
index 8693b5e..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocationPropertiesFromBrooklynProperties.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.io.File;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.config.BrooklynServerConfig;
-import brooklyn.config.ConfigUtils;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.os.Os;
-
-import com.google.common.base.Predicates;
-import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
-
-/**
- * The properties to use for locations, loaded from brooklyn.properties file.
- * 
- * @author aledsage
- **/
-public class LocationPropertiesFromBrooklynProperties {
-
-    private static final Logger LOG = LoggerFactory.getLogger(LocationPropertiesFromBrooklynProperties.class);
-
-    @SuppressWarnings("deprecation")
-    protected static final Map<String, String> DEPRECATED_KEYS_MAPPING = new DeprecatedKeysMappingBuilder(LOG)
-            .camelToHyphen(LocationConfigKeys.DISPLAY_NAME)
-            .camelToHyphen(LocationConfigKeys.PRIVATE_KEY_FILE)
-            .camelToHyphen(LocationConfigKeys.PRIVATE_KEY_DATA)
-            .camelToHyphen(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE)
-            .camelToHyphen(LocationConfigKeys.PUBLIC_KEY_FILE)
-            .camelToHyphen(LocationConfigKeys.PUBLIC_KEY_DATA)
-            .camelToHyphen(LocationConfigKeys.CALLER_CONTEXT)
-            .build();
-    
-    /**
-     * Finds the properties that apply to location, stripping off the prefixes.
-     * 
-     * Order of preference (in ascending order) is:
-     * <ol>
-     * <li>brooklyn.location.*
-     * <li>brooklyn.location.provider.*
-     * <li>brooklyn.location.named.namedlocation.*
-     * </ol>
-     * <p>
-     * Converts deprecated hyphenated properties to the non-deprecated camelCase format. 
-     */
-    public Map<String, Object> getLocationProperties(String provider, String namedLocation, Map<String, ?> properties) {
-        ConfigBag result = ConfigBag.newInstance();
-        
-        if (!Strings.isNullOrEmpty(provider)) 
-            result.put(LocationConfigKeys.CLOUD_PROVIDER, provider);
-        // named properties are preferred over providerOrApi properties
-        result.putAll(transformDeprecated(getGenericLocationSingleWordProperties(properties)));
-        if (!Strings.isNullOrEmpty(provider)) result.putAll(transformDeprecated(getScopedLocationProperties(provider, properties)));
-        if (!Strings.isNullOrEmpty(namedLocation)) result.putAll(transformDeprecated(getNamedLocationProperties(namedLocation, properties)));
-        
-        setLocalTempDir(properties, result);
-        
-        return result.getAllConfigRaw();
-    }
-
-    /** allow the temp dir where ssh temporary files on the brooklyn server side are placed */
-    public static void setLocalTempDir(Map<String,?> source, ConfigBag target) {
-        // TODO better would be to use BrooklynServerConfig, requiring management passed in
-        String brooklynDataDir = (String) source.get(BrooklynServerConfig.getMgmtBaseDir(source));
-        if (brooklynDataDir != null && brooklynDataDir.length() > 0) {
-            String tempDir = Os.mergePaths(brooklynDataDir, "tmp", "ssh");
-            target.putIfAbsentAndNotNull(SshTool.PROP_LOCAL_TEMP_DIR, tempDir);
-            Os.deleteOnExitEmptyParentsUpTo(new File(tempDir), new File(brooklynDataDir));
-        }
-    }
-    
-    /**
-     * Gets the named provider (e.g. if using a property like {@code brooklyn.location.named.myfavourite=localhost}, then
-     * {@code getNamedProvider("myfavourite", properties)} will return {@code "localhost"}).
-     */
-    protected String getNamedProvider(String namedLocation, Map<String, ?> properties) {
-        String key = String.format("brooklyn.location.named.%s", namedLocation);
-        return (String) properties.get(key);
-    }
-    
-    /**
-     * Returns those properties in the form "brooklyn.location.xyz", where "xyz" is any
-     * key that does not contain dots. We do this special (sub-optimal!) filtering
-     * because we want to exclude brooklyn.location.named.*, brooklyn.location.jclouds.*, etc.
-     * We only want those properties that are to be generic for all locations.
-     * 
-     * Strips off the prefix in the returned map.
-     */
-    protected Map<String, Object> getGenericLocationSingleWordProperties(Map<String, ?> properties) {
-        return getMatchingSingleWordProperties("brooklyn.location.", properties);
-    }
-
-    /**
-     * Gets all properties that start with {@code "brooklyn.location."+scopeSuffix+"."}, stripping off
-     * the prefix in the returned map.
-     */
-    protected Map<String, Object> getScopedLocationProperties(String scopeSuffix, Map<String, ?> properties) {
-        checkArgument(!scopeSuffix.startsWith("."), "scopeSuffix \"%s\" should not start with \".\"", scopeSuffix);
-        checkArgument(!scopeSuffix.endsWith("."), "scopeSuffix \"%s\" should not end with \".\"", scopeSuffix);
-        String prefix = String.format("brooklyn.location.%s.", scopeSuffix);
-        return ConfigUtils.filterForPrefixAndStrip(properties, prefix).asMapWithStringKeys();
-    }
-
-    /**
-     * Gets all properties that start with the given {@code fullPrefix}, stripping off
-     * the prefix in the returned map.
-     */
-    protected Map<String, Object> getMatchingProperties(String fullPrefix, Map<String, ?> properties) {
-        return ConfigUtils.filterForPrefixAndStrip(properties, fullPrefix).asMapWithStringKeys();
-    }
-
-    /**
-     * Gets all properties that start with either of the given prefixes. The {@code fullPreferredPrefix} 
-     * properties will override any duplicates in {@code fullDeprecatedPrefix}. If there are any
-     * properties that match the {@code fullDeprecatedPrefix}, then a warning will be logged.
-     * 
-     * @see #getMatchingProperties(String, Map)
-     */
-    protected Map<String, Object> getMatchingProperties(String fullPreferredPrefix, String fullDeprecatedPrefix, Map<String, ?> properties) {
-        Map<String, Object> deprecatedResults = getMatchingProperties(fullDeprecatedPrefix, properties);
-        Map<String, Object> results = getMatchingProperties(fullPreferredPrefix, properties);
-        
-        if (deprecatedResults.size() > 0) {
-            LOG.warn("Deprecated use of properties prefix "+fullDeprecatedPrefix+"; instead use "+fullPreferredPrefix);
-            return MutableMap.<String, Object>builder()
-                    .putAll(deprecatedResults)
-                    .putAll(results)
-                    .build();
-        } else {
-            return results;
-        }
-    }
-
-    /**
-     * Gets all properties that start with the given {@code fullPrefix}, stripping off
-     * the prefix in the returned map.
-     * 
-     * Returns only those properties whose key suffix is a single word (i.e. contains no dots).
-     * We do this special (sub-optimal!) filtering because we want sub-scoped things 
-     * (e.g. could want brooklyn.location.privateKeyFile, but not brooklyn.location.named.*). 
-     */
-    protected Map<String, Object> getMatchingSingleWordProperties(String fullPrefix, Map<String, ?> properties) {
-        BrooklynProperties filteredProperties = ConfigUtils.filterForPrefixAndStrip(properties, fullPrefix);
-        return ConfigUtils.filterFor(filteredProperties, Predicates.not(Predicates.containsPattern("\\."))).asMapWithStringKeys();
-    }
-
-    /**
-     * Gets all single-word properties that start with either of the given prefixes. The {@code fullPreferredPrefix} 
-     * properties will override any duplicates in {@code fullDeprecatedPrefix}. If there are any
-     * properties that match the {@code fullDeprecatedPrefix}, then a warning will be logged.
-     * 
-     * @see #getMatchingSingleWordProperties(String, Map)
-     */
-    protected Map<String, Object> getMatchingSingleWordProperties(String fullPreferredPrefix, String fullDeprecatedPrefix, Map<String, ?> properties) {
-        Map<String, Object> deprecatedResults = getMatchingSingleWordProperties(fullDeprecatedPrefix, properties);
-        Map<String, Object> results = getMatchingSingleWordProperties(fullPreferredPrefix, properties);
-        
-        if (deprecatedResults.size() > 0) {
-            LOG.warn("Deprecated use of properties prefix "+fullDeprecatedPrefix+"; instead use "+fullPreferredPrefix);
-            return MutableMap.<String, Object>builder()
-                    .putAll(deprecatedResults)
-                    .putAll(results)
-                    .build();
-        } else {
-            return results;
-        }
-    }
-
-    protected Map<String, Object> getNamedLocationProperties(String locationName, Map<String, ?> properties) {
-        checkArgument(!Strings.isNullOrEmpty(locationName), "locationName should not be blank");
-        String prefix = String.format("brooklyn.location.named.%s.", locationName);
-        return ConfigUtils.filterForPrefixAndStrip(properties, prefix).asMapWithStringKeys();
-    }
-
-    protected Map<String, Object> transformDeprecated(Map<String, ?> properties) {
-        Map<String,Object> result = Maps.newLinkedHashMap();
-        Map<String, String> deprecatedKeysMapping = getDeprecatedKeysMapping();
-        
-        for (Map.Entry<String,?> entry : properties.entrySet()) {
-            String key = entry.getKey();
-            Object value = entry.getValue();
-            if (deprecatedKeysMapping.containsKey(key)) {
-                String transformedKey = deprecatedKeysMapping.get(key);
-                LOG.warn("Deprecated key {}, transformed to {}; will not be supported in future versions", new Object[] {key, transformedKey});
-                result.put(transformedKey, value);
-            } else {
-                result.put(key, value);
-            }
-        }
-        
-        return result;
-    }
-    
-    protected Map<String,String> getDeprecatedKeysMapping() {
-        return DEPRECATED_KEYS_MAPPING;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocationTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocationTypeSnapshot.java b/core/src/main/java/brooklyn/location/basic/LocationTypeSnapshot.java
deleted file mode 100644
index aac7dc8..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocationTypeSnapshot.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import org.apache.brooklyn.policy.EnricherType;
-
-import brooklyn.basic.BrooklynTypeSnapshot;
-import brooklyn.config.ConfigKey;
-
-public class LocationTypeSnapshot extends BrooklynTypeSnapshot implements EnricherType {
-    
-    private static final long serialVersionUID = 9150132836104748237L;
-
-    LocationTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
-        super(name, configKeys);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        return (obj instanceof LocationTypeSnapshot) && super.equals(obj);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/Locations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/Locations.java b/core/src/main/java/brooklyn/location/basic/Locations.java
deleted file mode 100644
index 73221ca..0000000
--- a/core/src/main/java/brooklyn/location/basic/Locations.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.management.LocationManager;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.yaml.Yamls;
-
-import com.google.common.collect.ImmutableList;
-
-public class Locations {
-
-    private static final Logger log = LoggerFactory.getLogger(Locations.class);
-
-    public static final LocationsFilter USE_FIRST_LOCATION = new LocationsFilter() {
-        private static final long serialVersionUID = 3100091615409115890L;
-
-        @Override
-        public List<Location> filterForContext(List<Location> locations, Object context) {
-            if (locations.size()<=1) return locations;
-            return ImmutableList.of(locations.get(0));
-        }
-    };
-
-    public interface LocationsFilter extends Serializable {
-        public List<Location> filterForContext(List<Location> locations, Object context);
-    }
-    
-    /** as {@link Machines#findUniqueMachineLocation(Iterable)} */
-    public static Maybe<MachineLocation> findUniqueMachineLocation(Iterable<? extends Location> locations) {
-        return Machines.findUniqueMachineLocation(locations);
-    }
-    
-    /** as {@link Machines#findUniqueSshMachineLocation(Iterable)} */
-    public static Maybe<SshMachineLocation> findUniqueSshMachineLocation(Iterable<? extends Location> locations) {
-        return Machines.findUniqueSshMachineLocation(locations);
-    }
-
-    /** if no locations are supplied, returns locations on the entity, or in the ancestors, until it finds a non-empty set,
-     * or ultimately the empty set if no locations are anywhere */ 
-    public static Collection<? extends Location> getLocationsCheckingAncestors(Collection<? extends Location> locations, Entity entity) {
-        // look in ancestors if location not set here
-        Entity ancestor = entity;
-        while ((locations==null || locations.isEmpty()) && ancestor!=null) {
-            locations = ancestor.getLocations();
-            ancestor = ancestor.getParent();
-        }
-        return locations;
-    }
-    
-    public static boolean isManaged(Location loc) {
-        ManagementContext mgmt = ((LocationInternal)loc).getManagementContext();
-        return (mgmt != null) && mgmt.isRunning() && mgmt.getLocationManager().isManaged(loc);
-    }
-
-    public static void unmanage(Location loc) {
-        if (isManaged(loc)) {
-            ManagementContext mgmt = ((LocationInternal)loc).getManagementContext();
-            mgmt.getLocationManager().unmanage(loc);
-        }
-    }
-    
-    /**
-     * Registers the given location (and all its children) with the management context. 
-     * @throws IllegalStateException if the parent location is not already managed
-     * 
-     * @since 0.6.0 (added only for backwards compatibility, where locations are being created directly; previously in {@link Entities}).
-     * @deprecated in 0.6.0; use {@link LocationManager#createLocation(LocationSpec)} instead.
-     */
-    public static void manage(Location loc, ManagementContext managementContext) {
-        if (!managementContext.getLocationManager().isManaged(loc)) {
-            log.warn("Deprecated use of unmanaged location ("+loc+"); will be managed automatically now but not supported in future versions");
-            // FIXME this occurs MOST OF THE TIME e.g. including BrooklynLauncher.location(locationString)
-            // not sure what is the recommend way to convert from locationString to locationSpec, or the API we want to expose;
-            // deprecating some of the LocationRegistry methods seems sensible?
-            log.debug("Stack trace for location of: Deprecated use of unmanaged location; will be managed automatically now but not supported in future versions", new Exception("TRACE for: Deprecated use of unmanaged location"));
-            managementContext.getLocationManager().manage(loc);
-        }
-    }
-
-    public static Location coerce(ManagementContext mgmt, Object rawO) {
-        if (rawO==null)
-            return null;
-        if (rawO instanceof Location)
-            return (Location)rawO;
-        
-        Object raw = rawO;
-        if (raw instanceof String)
-            raw = Yamls.parseAll((String)raw).iterator().next();
-        
-        String name;
-        Map<?, ?> flags = null;
-        if (raw instanceof Map) {
-            // for yaml, take the key, and merge with locationFlags
-            Map<?,?> tm = ((Map<?,?>)raw);
-            if (tm.size()!=1) {
-                throw new IllegalArgumentException("Location "+rawO+" is invalid; maps must have only one key, being the location spec string");
-            }
-            name = (String) tm.keySet().iterator().next();
-            flags = (Map<?, ?>) tm.values().iterator().next();
-            
-        } else if (raw instanceof String) {
-            name = (String)raw;
-            
-        } else {
-            throw new IllegalArgumentException("Location "+rawO+" is invalid; can only parse strings or maps");
-        }
-        return mgmt.getLocationRegistry().resolve(name, flags);
-    }
-    
-    public static Collection<? extends Location> coerceToCollection(ManagementContext mgmt, Object rawO) {
-        if (rawO==null) return null;
-        Object raw = rawO;
-        if (raw instanceof Collection) {
-            List<Location> result = MutableList.<Location>of();
-            for (Object o: (Collection<?>)raw)
-                result.add(coerce(mgmt, o));
-            return result;
-        }
-        if (raw instanceof String) {
-            raw = Yamls.parseAll((String)raw).iterator().next();
-            if (raw instanceof Collection)
-                return coerceToCollection(mgmt, raw);
-        }
-        return Collections.singletonList( coerce(mgmt, raw) );
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/Machines.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/Machines.java b/core/src/main/java/brooklyn/location/basic/Machines.java
deleted file mode 100644
index 8c6115a..0000000
--- a/core/src/main/java/brooklyn/location/basic/Machines.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.net.InetAddress;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Iterables;
-
-import brooklyn.entity.basic.Attributes;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.net.HasNetworkAddresses;
-
-/** utilities for working with MachineLocations */
-public class Machines {
-
-    private static final Logger log = LoggerFactory.getLogger(Machines.class);
-    
-    public static Maybe<String> getSubnetHostname(Location where) {
-        // TODO Should we look at HasNetworkAddresses? But that's not a hostname.
-        String hostname = null;
-        if (where instanceof HasSubnetHostname) {
-            hostname = ((HasSubnetHostname) where).getSubnetHostname();
-        }
-        if (hostname == null && where instanceof MachineLocation) {
-            InetAddress addr = ((MachineLocation) where).getAddress();
-            if (addr != null) hostname = addr.getHostAddress();
-        }
-        log.debug("computed subnet hostname {} for {}", hostname, where);
-        // TODO if Maybe.absent(message) appears, could/should use that
-        // TODO If no machine available, should we throw new IllegalStateException("Cannot find hostname for "+where);
-        return Maybe.fromNullable(hostname);
-    }
-
-    public static Maybe<String> getSubnetIp(Location where) {
-        // TODO Too much duplication between the ip and hostname methods
-        String result = null;
-        if (where instanceof HasSubnetHostname) {
-            result = ((HasSubnetHostname) where).getSubnetIp();
-        }
-        if (where instanceof HasNetworkAddresses) {
-            Set<String> privateAddrs = ((HasNetworkAddresses) where).getPrivateAddresses();
-            if (privateAddrs.size() > 0) {
-                result = Iterables.get(privateAddrs, 0);
-            }
-        }
-        if (result == null && where instanceof MachineLocation) {
-            InetAddress addr = ((MachineLocation) where).getAddress();
-            if (addr != null) result = addr.getHostAddress();
-        }
-        log.debug("computed subnet host ip {} for {}", result, where);
-        return Maybe.fromNullable(result);
-    }
-
-    @SuppressWarnings("unchecked")
-    public static <T> Maybe<T> findUniqueElement(Iterable<?> items, Class<T> type) {
-        if (items==null) return null;
-        Iterator<?> i = items.iterator();
-        T result = null;
-        while (i.hasNext()) {
-            Object candidate = i.next();
-            if (type.isInstance(candidate)) {
-                if (result==null) result = (T)candidate;
-                else {
-                    if (log.isTraceEnabled())
-                        log.trace("Multiple instances of "+type+" in "+items+"; ignoring");
-                    return Maybe.absent(new IllegalStateException("Multiple instances of "+type+" in "+items+"; expected a single one"));
-                }
-            }
-        }
-        if (result==null) 
-            return Maybe.absent(new IllegalStateException("No instances of "+type+" available (in "+items+")"));
-        return Maybe.of(result);
-    }
-    
-    public static Maybe<MachineLocation> findUniqueMachineLocation(Iterable<? extends Location> locations) {
-        return findUniqueElement(locations, MachineLocation.class);
-    }
-
-    public static Maybe<SshMachineLocation> findUniqueSshMachineLocation(Iterable<? extends Location> locations) {
-        return findUniqueElement(locations, SshMachineLocation.class);
-    }
-
-    public static Maybe<WinRmMachineLocation> findUniqueWinRmMachineLocation(Iterable<? extends Location> locations) {
-        return findUniqueElement(locations, WinRmMachineLocation.class);
-    }
-
-    public static Maybe<String> findSubnetHostname(Iterable<? extends Location> ll) {
-        Maybe<MachineLocation> l = findUniqueMachineLocation(ll);
-        if (!l.isPresent()) {
-            return Maybe.absent();
-//            throw new IllegalStateException("Cannot find hostname for among "+ll);
-        }
-        return Machines.getSubnetHostname(l.get());
-    }
-
-    public static Maybe<String> findSubnetHostname(Entity entity) {
-        String sh = entity.getAttribute(Attributes.SUBNET_HOSTNAME);
-        if (sh!=null) return Maybe.of(sh);
-        return findSubnetHostname(entity.getLocations());
-    }
-    
-    public static Maybe<String> findSubnetOrPublicHostname(Entity entity) {
-        String hn = entity.getAttribute(Attributes.HOSTNAME);
-        if (hn!=null) {
-            // attributes already set, see if there was a SUBNET_HOSTNAME set
-            // note we rely on (public) hostname being set _after_ subnet_hostname,
-            // to prevent tiny possibility of races resulting in hostname being returned
-            // becasue subnet is still being looked up -- see MachineLifecycleEffectorTasks
-            Maybe<String> sn = findSubnetHostname(entity);
-            if (sn.isPresent()) return sn;
-            // short-circuit discovery if attributes have been set already
-            return Maybe.of(hn);
-        }
-        
-        Maybe<MachineLocation> l = findUniqueMachineLocation(entity.getLocations());
-        if (!l.isPresent()) return Maybe.absent();
-        InetAddress addr = l.get().getAddress();
-        if (addr==null) return Maybe.absent();
-        return Maybe.fromNullable(addr.getHostName());
-    }
-
-    public static Maybe<String> findSubnetOrPrivateIp(Entity entity) {
-        // see comments in findSubnetOrPrivateHostname
-        String hn = entity.getAttribute(Attributes.ADDRESS);
-        if (hn!=null) {
-            Maybe<String> sn = findSubnetIp(entity);
-            if (sn.isPresent()) return sn;
-            return Maybe.of(hn);
-        }
-        
-        Maybe<MachineLocation> l = findUniqueMachineLocation(entity.getLocations());
-        if (!l.isPresent()) return Maybe.absent();
-        InetAddress addr = l.get().getAddress();
-        if (addr==null) return Maybe.absent();
-        return Maybe.fromNullable(addr.getHostAddress());
-    }
-
-    public static Maybe<String> findSubnetIp(Entity entity) {
-        String sh = entity.getAttribute(Attributes.SUBNET_ADDRESS);
-        if (sh!=null) return Maybe.of(sh);
-        return findSubnetIp(entity.getLocations());
-    }
-    
-    public static Maybe<String> findSubnetIp(Iterable<? extends Location> ll) {
-        // TODO Or if can't find MachineLocation, should we throw new IllegalStateException("Cannot find hostname for among "+ll);
-        Maybe<MachineLocation> l = findUniqueMachineLocation(ll);
-        return (l.isPresent()) ? Machines.getSubnetIp(l.get()) : Maybe.<String>absent();
-    }
-
-    /** returns whether it is localhost (and has warned) */
-    public static boolean warnIfLocalhost(Collection<? extends Location> locations, String message) {
-        if (locations.size()==1) {
-            Location l = locations.iterator().next();
-            if (l instanceof LocalhostMachineProvisioningLocation || l instanceof LocalhostMachine) {
-                log.warn(message);
-                return true;
-            }
-        }
-        return false;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/MultiLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/MultiLocation.java b/core/src/main/java/brooklyn/location/basic/MultiLocation.java
deleted file mode 100644
index 8804e48..0000000
--- a/core/src/main/java/brooklyn/location/basic/MultiLocation.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
-import brooklyn.location.cloud.AvailabilityZoneExtension;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.CompoundRuntimeException;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.reflect.TypeToken;
-
-/** A location which consists of multiple locations stitched together to form availability zones.
- * The first location will be used by default, but if an {@link AvailabilityZoneExtension}-aware entity
- * is used, it may stripe across each of the locations.  See notes at {@link AvailabilityZoneExtension}. */
-public class MultiLocation<T extends MachineLocation> extends AbstractLocation implements MachineProvisioningLocation<T> {
-
-    private static final long serialVersionUID = 7993091317970457862L;
-    
-    @SuppressWarnings("serial")
-    @SetFromFlag("subLocations")
-    public static final ConfigKey<List<MachineProvisioningLocation<?>>> SUB_LOCATIONS = ConfigKeys.newConfigKey(
-            new TypeToken<List<MachineProvisioningLocation<?>>>() {},
-            "subLocations", 
-            "The sub-machines that this location can delegate to");
-    
-    @Override
-    public void init() {
-        super.init();
-        List<MachineProvisioningLocation<?>> subLocs = getSubLocations();
-        checkState(subLocs.size() >= 1, "sub-locations must not be empty");
-        AvailabilityZoneExtension azExtension = new AvailabilityZoneExtensionImpl(getManagementContext(), subLocs);
-        addExtension(AvailabilityZoneExtension.class, azExtension);
-    }
-
-    public T obtain() throws NoMachinesAvailableException {
-        return obtain(MutableMap.of());
-    }
-    
-    /** finds (creates) and returns a {@link MachineLocation}; 
-     * this always tries the first sub-location, moving on the second and subsequent if the first throws {@link NoMachinesAvailableException}.
-     * (if you want striping across locations, see notes in {@link AvailabilityZoneExtension}.) */
-    @SuppressWarnings("unchecked")
-    @Override
-    public T obtain(Map<?, ?> flags) throws NoMachinesAvailableException {
-        List<MachineProvisioningLocation<?>> sublocsList = getSubLocations();
-        Iterator<MachineProvisioningLocation<?>> sublocs = sublocsList.iterator();
-        List<NoMachinesAvailableException> errors = MutableList.of();
-        while (sublocs.hasNext()) {
-            try {
-                return (T) sublocs.next().obtain(flags);
-            } catch (NoMachinesAvailableException e) {
-                errors.add(e);
-            }
-        }
-        Exception wrapped;
-        String msg;
-        if (errors.size()>1) {
-            wrapped = new CompoundRuntimeException(errors.size()+" sublocation exceptions, including: "+
-                Exceptions.collapseText(errors.get(0)), errors);
-            msg = Exceptions.collapseText(wrapped);
-        } else if (errors.size()==1) {
-            wrapped = errors.get(0);
-            msg = wrapped.getMessage();
-            if (Strings.isBlank(msg)) msg = wrapped.toString();
-        } else {
-            msg = "no sub-locations set for this multi-location";
-            wrapped = null;
-        }
-        throw new NoMachinesAvailableException("No machines available in any of the "+sublocsList.size()+" location"+Strings.s(sublocsList.size())+
-            " configured here: "+msg, wrapped);
-    }
-
-    public List<MachineProvisioningLocation<?>> getSubLocations() {
-        return getRequiredConfig(SUB_LOCATIONS);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public MachineProvisioningLocation<T> newSubLocation(Map<?, ?> newFlags) {
-        // TODO shouldn't have to copy config bag as it should be inherited (but currently it is not used inherited everywhere; just most places)
-        return getManagementContext().getLocationManager().createLocation(LocationSpec.create(getClass())
-                .parent(this)
-                .configure(config().getLocalBag().getAllConfig())  // FIXME Should this just be inherited?
-                .configure(newFlags));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public void release(T machine) {
-        ((MachineProvisioningLocation<T>)machine.getParent()).release(machine);
-    }
-
-    @Override
-    public Map<String, Object> getProvisioningFlags(Collection<String> tags) {
-        return Maps.<String,Object>newLinkedHashMap();
-    }
-
-    @SuppressWarnings("unchecked")
-    protected MachineProvisioningLocation<T> firstSubLoc() {
-        return (MachineProvisioningLocation<T>) Iterables.get(getSubLocations(), 0);
-    }
-
-    protected <K> K getRequiredConfig(ConfigKey<K> key) {
-        return checkNotNull(getConfig(key), key.getName());
-    }
-
-    public static class AvailabilityZoneExtensionImpl extends AbstractAvailabilityZoneExtension implements AvailabilityZoneExtension {
-
-        private final List<MachineProvisioningLocation<?>> subLocations;
-        
-        public AvailabilityZoneExtensionImpl(ManagementContext managementContext, List<MachineProvisioningLocation<?>> subLocations) {
-            super(managementContext);
-            this.subLocations = ImmutableList.copyOf(subLocations);
-        }
-        
-        @Override
-        protected List<Location> doGetAllSubLocations() {
-            return ImmutableList.<Location>copyOf(subLocations);
-        }
-        
-        @Override
-        protected boolean isNameMatch(Location loc, Predicate<? super String> namePredicate) {
-            return namePredicate.apply(loc.getDisplayName());
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/MultiLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/MultiLocationResolver.java b/core/src/main/java/brooklyn/location/basic/MultiLocationResolver.java
deleted file mode 100644
index 87219b5..0000000
--- a/core/src/main/java/brooklyn/location/basic/MultiLocationResolver.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-import brooklyn.location.LocationSpec;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.text.KeyValueParser;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-
-import com.google.common.collect.Lists;
-
-public class MultiLocationResolver implements LocationResolver {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MultiLocationResolver.class);
-
-    private static final String MULTI = "multi";
-    
-    private static final Pattern PATTERN = Pattern.compile("(" + MULTI + "|" + MULTI.toUpperCase() + ")" + ":" + "\\((.*)\\)$");
-    
-    private volatile ManagementContext managementContext;
-
-    @Override
-    public void init(ManagementContext managementContext) {
-        this.managementContext = checkNotNull(managementContext, "managementContext");
-    }
-
-    @Override
-    public Location newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        // FIXME pass all flags into the location
-        
-        Map globalProperties = registry.getProperties();
-        Map<String,?> locationArgs;
-        if (spec.equalsIgnoreCase(MULTI)) {
-            locationArgs = MutableMap.copyOf(locationFlags);
-        } else {
-            Matcher matcher = PATTERN.matcher(spec);
-            if (!matcher.matches()) {
-                throw new IllegalArgumentException("Invalid location '" + spec + "'; must specify something like multi(targets=named:foo)");
-            }
-            String args = matcher.group(2);
-            // TODO we are ignoring locationFlags after this (apart from named), looking only at these args
-            locationArgs = KeyValueParser.parseMap(args);
-        }
-        String namedLocation = (String) locationFlags.get("named");
-
-        Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties().getLocationProperties(null, namedLocation, globalProperties);
-        MutableMap<String, Object> flags = MutableMap.<String, Object>builder()
-                .putAll(filteredProperties)
-                .putAll(locationFlags)
-                .removeAll("named")
-                .putAll(locationArgs).build();
-        
-        if (locationArgs.get("targets") == null) {
-            throw new IllegalArgumentException("target must be specified in single-machine spec");
-        }
-        
-        // TODO do we need to pass location flags etc into the children to ensure they are inherited?
-        List<Location> targets = Lists.newArrayList();
-        Object targetSpecs = locationArgs.remove("targets");
-        try {
-            if (targetSpecs instanceof String) {
-                for (String targetSpec : JavaStringEscapes.unwrapJsonishListIfPossible((String)targetSpecs)) {
-                    targets.add(managementContext.getLocationRegistry().resolve(targetSpec));
-                }
-            } else if (targetSpecs instanceof Iterable) {
-                for (Object targetSpec: (Iterable<?>)targetSpecs) {
-                    if (targetSpec instanceof String) {
-                        targets.add(managementContext.getLocationRegistry().resolve((String)targetSpec));
-                    } else {
-                        Set<?> keys = ((Map<?,?>)targetSpec).keySet();
-                        if (keys.size()!=1) 
-                            throw new IllegalArgumentException("targets supplied to MultiLocation must be a list of single-entry maps (got map of size "+keys.size()+": "+targetSpec+")");
-                        Object key = keys.iterator().next();
-                        Object flagsS = ((Map<?,?>)targetSpec).get(key);
-                        targets.add(managementContext.getLocationRegistry().resolve((String)key, (Map<?,?>)flagsS));
-                    }
-                }
-            } else throw new IllegalArgumentException("targets must be supplied to MultiLocation, either as string spec or list of single-entry maps each being a location spec");
-            
-            MultiLocation result = managementContext.getLocationManager().createLocation(LocationSpec.create(MultiLocation.class)
-                    .configure(flags)
-                    .configure("subLocations", targets)
-                    .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
-
-            // TODO Important workaround for BasicLocationRegistry.resolveForPeeking.
-            // That creates a location (from the resolver) and immediately unmanages it.
-            // The unmanage *must* remove all the targets created here; otherwise we have a leak.
-            // Adding the targets as children achieves this.
-            for (Location target : targets) {
-                target.setParent(result);
-            }
-            return result;
-
-        } catch (Exception e) {
-            // Must clean up after ourselves: don't leak sub-locations on error
-            if (LOG.isDebugEnabled()) LOG.debug("Problem resolving MultiLocation; cleaning up any sub-locations and rethrowing: "+e);
-            for (Location target : targets) {
-                Locations.unmanage(target);
-            }
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    @Override
-    public String getPrefix() {
-        return MULTI;
-    }
-
-    @Override
-    public boolean accepts(String spec, LocationRegistry registry) {
-        return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/NamedLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/NamedLocationResolver.java b/core/src/main/java/brooklyn/location/basic/NamedLocationResolver.java
deleted file mode 100644
index b936c93..0000000
--- a/core/src/main/java/brooklyn/location/basic/NamedLocationResolver.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.text.Strings;
-
-/**
- * Allows you to say, in your brooklyn.properties:
- * 
- * brooklyn.location.named.foo=localhost
- * brooklyn.location.named.foo.user=bob
- * brooklyn.location.named.foo.privateKeyFile=~/.ssh/custom-key-for-bob
- * brooklyn.location.named.foo.privateKeyPassphrase=WithAPassphrase
- * <p>
- * or
- * <p>
- * brooklyn.location.named.bob-aws-east=jclouds:aws-ec2:us-east-1
- * brooklyn.location.named.bob-aws-east.identity=BobId
- * brooklyn.location.named.bob-aws-east.credential=BobCred
- * <p>
- * then you can simply refer to:   foo   or   named:foo   (or bob-aws-east or named:bob-aws-east)   in any location spec
- */
-public class NamedLocationResolver implements LocationResolver {
-
-    public static final Logger log = LoggerFactory.getLogger(NamedLocationResolver.class);
-
-    public static final String NAMED = "named";
-    
-    @SuppressWarnings("unused")
-    private ManagementContext managementContext;
-
-    @Override
-    public void init(ManagementContext managementContext) {
-        this.managementContext = checkNotNull(managementContext, "managementContext");
-    }
-    
-    @Override
-    @SuppressWarnings({ "rawtypes" })
-    public Location newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        String name = spec;
-        ConfigBag lfBag = ConfigBag.newInstance(locationFlags).putIfAbsent(LocationInternal.ORIGINAL_SPEC, name);
-        name = Strings.removeFromStart(spec, getPrefix()+":");
-        if (name.toLowerCase().startsWith(NAMED+":")) {
-            // since 0.7.0
-            log.warn("Deprecated use of 'named:' prefix with wrong case ("+spec+"); support may be removed in future versions");
-            name = spec.substring( (NAMED+":").length() );
-        }
-        
-        LocationDefinition ld = registry.getDefinedLocationByName(name);
-        if (ld==null) throw new NoSuchElementException("No named location defined matching '"+name+"'");
-        return ((BasicLocationRegistry)registry).resolveLocationDefinition(ld, lfBag.getAllConfig(), name);
-    }
-
-    @Override
-    public String getPrefix() {
-        return NAMED;
-    }
-    
-    /** accepts anything starting  named:xxx  or  xxx where xxx is a defined location name */
-    @Override
-    public boolean accepts(String spec, LocationRegistry registry) {
-        if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true;
-        if (registry.getDefinedLocationByName(spec)!=null) return true;
-        return false;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/PortRanges.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/PortRanges.java b/core/src/main/java/brooklyn/location/basic/PortRanges.java
deleted file mode 100644
index 75cd5a5..0000000
--- a/core/src/main/java/brooklyn/location/basic/PortRanges.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import brooklyn.location.PortRange;
-import brooklyn.util.flags.TypeCoercions;
-
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-public class PortRanges {
-
-    public static final int MAX_PORT = 65535;
-    public static final PortRange ANY_HIGH_PORT = new LinearPortRange(1024, MAX_PORT);
-    
-    public static class SinglePort implements PortRange, Serializable {
-        private static final long serialVersionUID = 7446781416534230401L;
-        
-        final int port;
-        private SinglePort(int port) { this.port = port; }
-        
-        @Override
-        public Iterator<Integer> iterator() {
-            return Collections.singletonList(port).iterator();
-        }
-        @Override
-        public boolean isEmpty() {
-            return false;
-        }
-        @Override
-        public boolean asBoolean() {
-            return true;
-        }
-        @Override
-        public String toString() {
-            return //getClass().getName()+"["+
-                    ""+port; //+"]";
-        }
-        public int hashCode() {
-            return Objects.hashCode(port);
-        }
-        @Override
-        public boolean equals(Object obj) {
-            return (obj instanceof SinglePort) && port == ((SinglePort)obj).port;
-        }
-    }
-
-    public static class LinearPortRange implements PortRange, Serializable {
-        private static final long serialVersionUID = -9165280509363743508L;
-        
-        final int start, end, delta;
-        private LinearPortRange(int start, int end, int delta) {
-            this.start = start;
-            this.end = end;
-            this.delta = delta;
-            checkArgument(start > 0 && start <= MAX_PORT, "start port %s out of range", start);
-            checkArgument(end > 0 && end <= MAX_PORT, "end port %s out of range", end);
-            checkArgument(delta > 0 ? start <= end : start >= end, "start and end out of order: %s to %s, delta %s", start, end, delta);
-            checkArgument(delta != 0, "delta must be non-zero");
-        }
-        public LinearPortRange(int start, int end) {
-            this(start, end, (start<=end?1:-1));
-        }
-        
-        @Override
-        public Iterator<Integer> iterator() {
-            return new Iterator<Integer>() {
-                int next = start;
-                boolean hasNext = true;
-                
-                @Override
-                public boolean hasNext() {
-                    return hasNext;
-                }
-
-                @Override
-                public Integer next() {
-                    if (!hasNext)
-                        throw new NoSuchElementException("Exhausted available ports");
-                    int result = next;
-                    next += delta;
-                    if ((delta>0 && next>end) || (delta<0 && next<end)) hasNext = false;
-                    return result;
-                }
-                
-                @Override
-                public void remove() {
-                    throw new UnsupportedOperationException();
-                }
-            };
-        }
-        
-        @Override
-        public boolean isEmpty() {
-            return false;
-        }
-        @Override
-        public boolean asBoolean() {
-            return true;
-        }
-        @Override
-        public String toString() {
-            return //getClass().getName()+"["+
-                    start+"-"+end; //+"]";
-        }
-        @Override
-        public int hashCode() {
-            return Objects.hashCode(start, end, delta);
-        }
-        @Override
-        public boolean equals(Object obj) {
-            if (!(obj instanceof LinearPortRange)) return false;
-            LinearPortRange o = (LinearPortRange) obj;
-            return start == o.start && end == o.end && delta == o.delta;
-        }
-    }
-    
-    public static class AggregatePortRange implements PortRange, Serializable {
-        private static final long serialVersionUID = 7332682500816739660L;
-        
-        final List<PortRange> ranges;
-        private AggregatePortRange(List<PortRange> ranges) {
-            this.ranges = ImmutableList.copyOf(ranges);
-        }
-        @Override
-        public Iterator<Integer> iterator() {
-            return Iterables.concat(ranges).iterator();
-        }
-        @Override
-        public boolean isEmpty() {
-            for (PortRange r: ranges)
-                if (!r.isEmpty()) return false;
-            return true;
-        }
-        @Override
-        public boolean asBoolean() {
-            return !isEmpty();
-        }
-        @Override
-        public String toString() {
-            String s = "";
-            for (PortRange r: ranges) {
-                if (s.length()>0) s+=",";
-                s += r;
-            }
-            return //getClass().getName()+"["+
-                s; //+"]";
-        }
-        public int hashCode() {
-            return Objects.hashCode(ranges);
-        }
-        @Override
-        public boolean equals(Object obj) {
-            return (obj instanceof AggregatePortRange) && ranges.equals(((AggregatePortRange)obj).ranges);
-        }
-    }
-
-    public static PortRange fromInteger(int x) {
-        return new SinglePort(x);
-    }
-    
-    public static PortRange fromCollection(Collection<?> c) {
-        List<PortRange> l = new ArrayList<PortRange>();
-        for (Object o: c) {
-            if (o instanceof Integer) l.add(fromInteger((Integer)o));
-            else if (o instanceof String) l.add(fromString((String)o));
-            else if (o instanceof Collection) l.add(fromCollection((Collection<?>)o));
-            else l.add(TypeCoercions.coerce(o, PortRange.class));
-        }
-        return new AggregatePortRange(l);
-    }
-
-    /** parses a string representation of ports, as "80,8080,8000,8080-8099" */
-    public static PortRange fromString(String s) {
-        List<PortRange> l = new ArrayList<PortRange>();
-        for (String si: s.split(",")) {
-            si = si.trim();
-            int start, end;
-            if (si.endsWith("+")) {
-                String si2 = si.substring(0, si.length()-1).trim();
-                start = Integer.parseInt(si2);
-                end = MAX_PORT;
-            } else if (si.indexOf('-')>0) {
-                int v = si.indexOf('-');
-                start = Integer.parseInt(si.substring(0, v).trim());
-                end = Integer.parseInt(si.substring(v+1).trim());
-            } else if (si.length()==0) {
-                //nothing, ie empty range, just continue
-                continue;
-            } else {
-                //should be number on its own
-                l.add(new SinglePort(Integer.parseInt(si)));
-                continue;
-            }
-            l.add(new LinearPortRange(start, end));
-        }
-        if (l.size() == 1) {
-            return l.get(0);
-        } else {
-            return new AggregatePortRange(l);
-        }
-    }
-
-    private static AtomicBoolean initialized = new AtomicBoolean(false); 
-    /** performs the language extensions required for this project */
-    @SuppressWarnings("rawtypes")
-    public static void init() {
-        if (initialized.get()) return;
-        synchronized (initialized) {
-            if (initialized.get()) return;
-            TypeCoercions.registerAdapter(Integer.class, PortRange.class, new Function<Integer,PortRange>() {
-                public PortRange apply(Integer x) { return fromInteger(x); }
-            });
-            TypeCoercions.registerAdapter(String.class, PortRange.class, new Function<String,PortRange>() {
-                public PortRange apply(String x) { return fromString(x); }
-            });
-            TypeCoercions.registerAdapter(Collection.class, PortRange.class, new Function<Collection,PortRange>() {
-                public PortRange apply(Collection x) { return fromCollection(x); }
-            });
-            initialized.set(true);
-        }
-    }
-    
-    static {
-        init();
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/RegistryLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/RegistryLocationResolver.java b/core/src/main/java/brooklyn/location/basic/RegistryLocationResolver.java
deleted file mode 100644
index 480ff4d..0000000
--- a/core/src/main/java/brooklyn/location/basic/RegistryLocationResolver.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationResolver;
-
-/**
- * Extension to LocationResolver which can take a registry.
- * 
- * @deprecated since 0.6; the LocationResolver always takes the LocationRegistry now
- */
-@Deprecated
-public interface RegistryLocationResolver extends LocationResolver {
-
-    @Override
-    @SuppressWarnings("rawtypes")
-    Location newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry);
-
-    @Override
-    boolean accepts(String spec, brooklyn.location.LocationRegistry registry);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/SingleMachineLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/SingleMachineLocationResolver.java b/core/src/main/java/brooklyn/location/basic/SingleMachineLocationResolver.java
deleted file mode 100644
index 7b2dc25..0000000
--- a/core/src/main/java/brooklyn/location/basic/SingleMachineLocationResolver.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationSpec;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.guava.Maybe.Absent;
-
-public class SingleMachineLocationResolver extends AbstractLocationResolver {
-    
-    private static final String SINGLE = "single";
-    
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Override
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
-        ConfigBag config = extractConfig(locationFlags, spec, registry);
-        Map globalProperties = registry.getProperties();
-        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
-        
-        if (registry != null) {
-            LocationPropertiesFromBrooklynProperties.setLocalTempDir(globalProperties, config);
-        }
-
-        if (config.getStringKey("target") == null) {
-            throw new IllegalArgumentException("target must be specified in single-machine spec");
-        }
-        String target = config.getStringKey("target").toString();
-        config.remove("target");
-        Maybe<Location> testResolve = managementContext.getLocationRegistry().resolve(target, false, null);
-        if (!testResolve.isPresent()) {
-            throw new IllegalArgumentException("Invalid target location '" + target + "' for location '"+SINGLE+"': "+
-                Exceptions.collapseText( ((Absent<?>)testResolve).getException() ));
-        }
-        
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(SingleMachineProvisioningLocation.class)
-                .configure("location", target)
-                .configure("locationFlags", config.getAllConfig())
-                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
-    }
-    
-    @Override
-    public String getPrefix() {
-        return SINGLE;
-    }
-    
-    @Override
-    protected Class<? extends Location> getLocationType() {
-        return SingleMachineProvisioningLocation.class;
-    }
-
-    @Override
-    protected SpecParser getSpecParser() {
-        return new SpecParser(getPrefix()).setExampleUsage("\"single(target=jclouds:aws-ec2:us-east-1)\"");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/SingleMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/SingleMachineProvisioningLocation.java b/core/src/main/java/brooklyn/location/basic/SingleMachineProvisioningLocation.java
deleted file mode 100644
index 5b9f30a..0000000
--- a/core/src/main/java/brooklyn/location/basic/SingleMachineProvisioningLocation.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.collect.ImmutableMap;
-
-public class SingleMachineProvisioningLocation<T extends MachineLocation> extends FixedListMachineProvisioningLocation<T> {
-    private static final long serialVersionUID = -4216528515792151062L;
-
-    private static final Logger log = LoggerFactory.getLogger(SingleMachineProvisioningLocation.class);
-    
-    @SetFromFlag(nullable=false)
-    private String location;
-    
-    @SetFromFlag(nullable=false)
-    private Map<?,?> locationFlags;
-    
-    private T singleLocation;
-    private int referenceCount;
-    private MachineProvisioningLocation<T> provisioningLocation;
-
-
-    public SingleMachineProvisioningLocation() {
-    }
-
-    @SuppressWarnings("rawtypes")
-    public SingleMachineProvisioningLocation(String location, Map locationFlags) {
-        this.locationFlags = locationFlags;
-        this.location = location;
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Override
-    public synchronized T obtain(Map flags) throws NoMachinesAvailableException {
-        log.info("Flags {} passed to newLocationFromString will be ignored, using {}", flags, locationFlags);
-        return obtain();
-    }
-
-    @Override
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public synchronized T obtain() throws NoMachinesAvailableException {
-        if (singleLocation == null) {
-            if (provisioningLocation == null) {
-                provisioningLocation = (MachineProvisioningLocation) getManagementContext().getLocationRegistry().resolve(
-                    location, locationFlags);
-            }
-            singleLocation = provisioningLocation.obtain(ImmutableMap.of());
-            inUse.add(singleLocation);
-        }
-        referenceCount++;
-        return singleLocation;
-    }
-
-    @Override
-    public synchronized void release(T machine) {
-        if (!machine.equals(singleLocation)) {
-            throw new IllegalArgumentException("Invalid machine " + machine + " passed to release, expecting: " + singleLocation);
-        }
-        if (--referenceCount == 0) {
-            provisioningLocation.release(machine);
-            singleLocation = null;
-        }
-        inUse.remove(machine);
-    };
-
-}


[02/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java
index df1cdb8..249cfc9 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java
@@ -19,14 +19,13 @@
 package org.apache.brooklyn.entity.nosql.riak;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.riak.RiakNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.BeforeMethod;
 
 import com.google.common.collect.ImmutableList;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class RiakNodeSoftlayerLiveTest extends AbstractSoftlayerLiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java
index 381a78d..3e144e2 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java
@@ -18,11 +18,10 @@
  */
 package org.apache.brooklyn.entity.nosql.solr;
 
-import org.apache.brooklyn.entity.nosql.solr.SolrServer;
 import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * Solr test framework for integration and live tests.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java
index 46057ab..5196ede 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java
@@ -22,7 +22,6 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.solr.SolrServer;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.solr.common.SolrDocument;
 import org.slf4j.Logger;
@@ -30,7 +29,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafSshDriver.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafSshDriver.java b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafSshDriver.java
index 3d8281a..135994d 100644
--- a/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafSshDriver.java
+++ b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafSshDriver.java
@@ -26,7 +26,7 @@ import java.util.Map;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java
index 67dc76a..ad39164 100644
--- a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java
+++ b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java
@@ -25,7 +25,7 @@ import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.text.Identifiers;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
index 65a39ca..bd2d46a 100644
--- a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
+++ b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
@@ -35,8 +35,8 @@ import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
index c815eba..6d2eeb0 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
@@ -30,7 +30,7 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
 
 import com.google.common.reflect.TypeToken;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
index 4bc72c7..0e7c8d1 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceImpl.java
@@ -47,7 +47,7 @@ import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
-import brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.flags.SetFromFlag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
index 5779ec2..c71c00a 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsServiceImpl.java
@@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
-import brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGenerator.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGenerator.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGenerator.java
index ae3883f..e8def56 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGenerator.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGenerator.java
@@ -24,7 +24,7 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.TimeZone;
 
-import brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java
index 485b3e3..9bd0928 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java
@@ -45,8 +45,8 @@ import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.Cluster;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.basic.Machines;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
index 0db2cba..3c0421b 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
@@ -37,7 +37,7 @@ import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.Cluster;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.guava.Maybe;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java
index ef83c73..6c7b093 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java
@@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.proxy.AbstractController;
+import org.apache.brooklyn.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -35,8 +36,8 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.net.Networking;
@@ -54,7 +55,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 
 /**
- * Start a {@link NginxController} in a {@link brooklyn.location.Location} accessible over ssh.
+ * Start a {@link NginxController} in a {@link Location} accessible over ssh.
  */
 public class NginxSshDriver extends AbstractSoftwareProcessSshDriver implements NginxDriver {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
index 51ac064..9b80173 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
@@ -45,7 +45,7 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.QuorumCheck.QuorumChecks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java
index 66160a4..8a6b133 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java
@@ -27,8 +27,8 @@ import brooklyn.entity.basic.AbstractConfigurableEntityFactory;
 import brooklyn.entity.basic.ConfigurableEntityFactory;
 import brooklyn.entity.basic.EntityFactoryForLocation;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
 
 public interface ElasticJavaWebAppService extends JavaWebAppService, Startable {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppSshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppSshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppSshDriver.java
index 0f2df03..f7c3e04 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppSshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppSshDriver.java
@@ -26,7 +26,7 @@ import java.util.Set;
 
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.task.Tasks;
 import brooklyn.util.task.ssh.SshTasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMethods.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMethods.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMethods.java
index e9f0eee..34d3d7c 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMethods.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMethods.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import brooklyn.enricher.RollingTimeWindowMeanEnricher;
 import brooklyn.enricher.TimeFractionDeltaEnricher;
 import brooklyn.enricher.TimeWeightedDeltaEnricher;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import brooklyn.util.time.Duration;
 
 import com.google.common.net.HostAndPort;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6SshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6SshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6SshDriver.java
index 10caeab..3d55002 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6SshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6SshDriver.java
@@ -33,7 +33,7 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.UsesJmx;
 import brooklyn.entity.java.UsesJmx.JmxAgentModes;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
index 61f9dd7..f834d8c 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
@@ -31,7 +31,7 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import brooklyn.util.guava.Functionals;
 
 import com.google.common.base.Functions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7SshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7SshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7SshDriver.java
index e9db6ba..bb51ddf 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7SshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7SshDriver.java
@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6SshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6SshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6SshDriver.java
index 49f1f15..7f2d3c5 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6SshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6SshDriver.java
@@ -27,7 +27,7 @@ import java.util.Map;
 import org.apache.brooklyn.entity.webapp.JavaWebAppSshDriver;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java
index e2829cf..5935940 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java
@@ -28,8 +28,8 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java
index 74eb500..ec69b9c 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java
@@ -28,7 +28,7 @@ import brooklyn.event.feed.ConfigToAttributes;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 
 import com.google.common.base.Predicates;
 import com.google.common.net.HostAndPort;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSshDriver.java
index cd72263..e336a93 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSshDriver.java
@@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.file.ArchiveUtils;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat7SshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat7SshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat7SshDriver.java
index 584054b..203096f 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat7SshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat7SshDriver.java
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.entity.webapp.tomcat;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 @Deprecated
 public class Tomcat7SshDriver extends TomcatSshDriver implements Tomcat7Driver {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java
index c975ac7..d9327cd 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java
@@ -31,7 +31,7 @@ import brooklyn.entity.java.UsesJmx;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatSshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatSshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatSshDriver.java
index 45d9bb9..24fb1c3 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatSshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatSshDriver.java
@@ -28,7 +28,7 @@ import java.util.Map;
 import org.apache.brooklyn.entity.webapp.JavaWebAppSshDriver;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
index 273d308..2bf6067 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
@@ -50,17 +50,17 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.group.DynamicFabric;
 import brooklyn.entity.group.DynamicRegionsFabric;
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.BasicLocationRegistry;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SimulatedLocation;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
index 54dec72..c6df429 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
@@ -38,12 +38,12 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.geo.HostGeoInfo;
-import brooklyn.location.geo.HostGeoLookup;
-import brooklyn.location.geo.MaxMind2HostGeoLookup;
-import brooklyn.location.geo.UtraceHostGeoLookup;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.geo.HostGeoLookup;
+import org.apache.brooklyn.location.geo.MaxMind2HostGeoLookup;
+import org.apache.brooklyn.location.geo.UtraceHostGeoLookup;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGeneratorTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGeneratorTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGeneratorTest.java
index fe45121..f5c3f41 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGeneratorTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingScriptGeneratorTest.java
@@ -25,10 +25,9 @@ import java.util.Date;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
-import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingScriptGenerator;
 import org.testng.annotations.Test;
 
-import brooklyn.location.geo.HostGeoInfo;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
 import brooklyn.util.ResourceUtils;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java
index a0ee5d0..a024cb1 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java
@@ -47,13 +47,13 @@ import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.group.Cluster;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
index d09185c..3e1ee85 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
@@ -29,10 +29,10 @@ import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.base.Throwables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java
index bdd1ce6..1c43f95 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java
@@ -44,8 +44,8 @@ import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
index 3037393..7212424 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
@@ -28,8 +28,6 @@ import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.management.EntityManager;
 import org.apache.brooklyn.entity.proxy.LoadBalancerCluster;
-import org.apache.brooklyn.entity.proxy.nginx.NginxController;
-import org.apache.brooklyn.entity.proxy.nginx.UrlMapping;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.EntityTestUtils;
@@ -45,8 +43,8 @@ import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java
index 396ec9c..dc97eb5 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java
@@ -19,7 +19,6 @@
 package org.apache.brooklyn.entity.proxy.nginx;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.HttpTestUtils;
@@ -29,7 +28,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
index 1f5675e..044d7e0 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
@@ -27,7 +27,6 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.proxy.LoadBalancer;
 import org.apache.brooklyn.entity.proxy.ProxySslConfig;
-import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
 import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
@@ -44,8 +43,8 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.test.Asserts;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
index 01e4f44..b3327e7 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
@@ -29,7 +29,6 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
 import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
@@ -45,7 +44,7 @@ import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.group.DynamicCluster;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.time.Duration;
 import brooklyn.util.time.Time;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java
index 1e0ed21..164d0ab 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxLightIntegrationTest.java
@@ -20,13 +20,11 @@ package org.apache.brooklyn.entity.proxy.nginx;
 
 import static org.testng.Assert.assertEquals;
 
-import java.net.URL;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.proxy.StubAppServer;
-import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
@@ -34,7 +32,7 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.BasicConfigurableEntityFactory;
 import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.group.DynamicCluster;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
index c025f47..863280d 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
@@ -53,8 +53,8 @@ import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindOptions;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.base.Predicates;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java
index d0fcf2f..d1ea99b 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.brooklyn.entity.proxy.nginx;
 
-import java.net.URL;
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.Callable;
@@ -51,9 +50,9 @@ import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
 import brooklyn.entity.rebind.RebindTestUtils;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocationReuseIntegrationTest.RecordingSshjTool;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocationReuseIntegrationTest.RecordingSshjTool;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxUrlMappingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxUrlMappingIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxUrlMappingIntegrationTest.java
index fb43555..6733181 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxUrlMappingIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxUrlMappingIntegrationTest.java
@@ -39,9 +39,7 @@ import org.apache.brooklyn.entity.proxy.nginx.UrlMapping;
 import org.apache.brooklyn.entity.proxy.nginx.UrlRewriteRule;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
 import org.apache.brooklyn.entity.webapp.WebAppService;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server;
-import org.apache.brooklyn.entity.webapp.tomcat.Tomcat8ServerImpl;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.slf4j.Logger;
@@ -55,7 +53,7 @@ import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.group.DynamicCluster;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java
index 8d3a26b..9f62577 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java
@@ -41,9 +41,9 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java
index 09d69b0..74e8bb2 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java
@@ -53,8 +53,8 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.Application;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterIntegrationTest.java
index 9e7834b..ca402b1 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterIntegrationTest.java
@@ -34,8 +34,6 @@ import org.apache.brooklyn.entity.basic.RecordingSensorEventListener;
 import org.apache.brooklyn.entity.proxy.AbstractController;
 import org.apache.brooklyn.entity.proxy.LoadBalancer;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
-import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
 import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -45,7 +43,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Lifecycle;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java
index 8c39097..ee82eb6 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterTest.java
@@ -27,8 +27,6 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.proxy.AbstractController;
 import org.apache.brooklyn.entity.proxy.LoadBalancer;
 import org.apache.brooklyn.entity.proxy.TrackingAbstractController;
-import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
@@ -44,7 +42,7 @@ import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterTest.java
index 29a7123..726c53d 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterTest.java
@@ -23,8 +23,6 @@ import static org.testng.Assert.assertEquals;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestJavaWebAppEntity;
@@ -35,7 +33,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricTest.java
index f9fb84d..2dba5d1 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricTest.java
@@ -23,9 +23,6 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.DynamicWebAppFabric;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestJavaWebAppEntity;
@@ -39,7 +36,7 @@ import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.trait.Changeable;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticCustomLocationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticCustomLocationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticCustomLocationTest.java
index d41934f..8f15948 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticCustomLocationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticCustomLocationTest.java
@@ -21,7 +21,6 @@ package org.apache.brooklyn.entity.webapp;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.entity.webapp.ElasticJavaWebAppService;
 import org.apache.brooklyn.entity.webapp.ElasticJavaWebAppService.ElasticJavaWebAppServiceAwareLocation;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntityImpl;
@@ -34,7 +33,7 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BasicConfigurableEntityFactory;
 import brooklyn.entity.basic.ConfigurableEntityFactory;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppServiceIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppServiceIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppServiceIntegrationTest.java
index 17dacc7..aeddfb1 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppServiceIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppServiceIntegrationTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.brooklyn.entity.webapp;
 
-import org.apache.brooklyn.entity.webapp.ElasticJavaWebAppService;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -28,7 +27,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java
index fe324e2..dd27b6b 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java
@@ -35,8 +35,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.policy.autoscaling.AutoScalerPolicy;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
index b0f4f4e..af21126 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
@@ -31,9 +31,9 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
index bcd8597..d8b7457 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
@@ -18,14 +18,10 @@
  */
 package org.apache.brooklyn.entity.webapp
 
-import static brooklyn.entity.basic.ConfigKeys.*
-import static org.apache.brooklyn.entity.webapp.jboss.JBoss6Server.*
 import static org.apache.brooklyn.test.TestUtils.*
 import static java.util.concurrent.TimeUnit.*
 import static org.testng.Assert.*
 
-import java.util.concurrent.TimeUnit
-
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 import org.testng.annotations.AfterMethod
@@ -44,8 +40,8 @@ import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7ServerImpl
 import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
 import org.apache.brooklyn.entity.webapp.tomcat.TomcatServerImpl
-import brooklyn.location.Location
-import brooklyn.location.basic.BasicLocationRegistry
+import org.apache.brooklyn.location.Location
+import org.apache.brooklyn.location.basic.BasicLocationRegistry
 import org.apache.brooklyn.test.TestUtils
 import org.apache.brooklyn.test.entity.TestApplicationImpl
 import brooklyn.util.internal.TimeExtras

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
index ea03941..fc3b0b4 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
@@ -33,7 +33,6 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.apache.brooklyn.test.WebAppMonitor;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -47,7 +46,7 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.internal.TimeExtras;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java
index 34cad0d..8a3ab2e3 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/DynamicWebAppClusterRebindIntegrationTest.java
@@ -24,7 +24,6 @@ import static org.apache.brooklyn.test.HttpTestUtils.assertUrlUnreachableEventua
 import static org.testng.Assert.assertEquals;
 
 import java.io.File;
-import java.net.URL;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ExecutorService;
@@ -33,7 +32,6 @@ import java.util.concurrent.Executors;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.apache.brooklyn.test.WebAppMonitor;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -46,9 +44,8 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.collections.MutableMap;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java
index ccffd2a..1fe7088 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java
@@ -21,16 +21,13 @@ package org.apache.brooklyn.entity.webapp.jboss;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
-import java.net.URL;
-
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss6Server;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerNonInheritingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerNonInheritingIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerNonInheritingIntegrationTest.java
index 0551b18..19ffba6 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerNonInheritingIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerNonInheritingIntegrationTest.java
@@ -21,10 +21,7 @@ package org.apache.brooklyn.entity.webapp.jboss;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
-import java.net.URL;
-
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss6Server;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.BeforeMethod;
@@ -32,7 +29,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.java.UsesJmx;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java
index a76d5ba..212ab31 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java
@@ -21,16 +21,13 @@ package org.apache.brooklyn.entity.webapp.jboss;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
-import java.net.URL;
-
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java
index 1642ae0..be1f08b 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java
@@ -19,11 +19,10 @@
 package org.apache.brooklyn.entity.webapp.jboss;
 
 import brooklyn.entity.software.AbstractDockerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 
@@ -31,8 +30,6 @@ import com.google.common.collect.ImmutableList;
 
 import org.testng.annotations.Test;
 
-import java.net.URL;
-
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerNonInheritingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerNonInheritingIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerNonInheritingIntegrationTest.java
index 6408425..d0987cc 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerNonInheritingIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerNonInheritingIntegrationTest.java
@@ -30,16 +30,14 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.webapp.AbstractWebAppFixtureIntegrationTest;
 import org.apache.brooklyn.entity.webapp.HttpsSslConfig;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
-import org.apache.brooklyn.test.entity.TestApplication;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerRebindingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerRebindingIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerRebindingIntegrationTest.java
index 73363c6..ece595e 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerRebindingIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerRebindingIntegrationTest.java
@@ -26,7 +26,6 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
@@ -41,7 +40,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.rebind.RebindOptions;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBossServersMultiVersionWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBossServersMultiVersionWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBossServersMultiVersionWebAppFixtureIntegrationTest.java
index 82b126d..74530e9 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBossServersMultiVersionWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBossServersMultiVersionWebAppFixtureIntegrationTest.java
@@ -21,14 +21,12 @@ package org.apache.brooklyn.entity.webapp.jboss;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.webapp.AbstractWebAppFixtureIntegrationTest;
 import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss6Server;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 
 public class JBossServersMultiVersionWebAppFixtureIntegrationTest extends AbstractWebAppFixtureIntegrationTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java
index 7a73178..d111aff 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java
@@ -21,16 +21,13 @@ package org.apache.brooklyn.entity.webapp.jboss;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
-import java.net.URL;
-
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jetty/JettyWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jetty/JettyWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jetty/JettyWebAppFixtureIntegrationTest.java
index b42333e..1bbe111 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jetty/JettyWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jetty/JettyWebAppFixtureIntegrationTest.java
@@ -21,14 +21,12 @@ package org.apache.brooklyn.entity.webapp.jetty;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.webapp.AbstractWebAppFixtureIntegrationTest;
 import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.entity.webapp.jetty.Jetty6Server;
-import org.apache.brooklyn.entity.webapp.jetty.JettyWebAppFixtureIntegrationTest;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 
 public class JettyWebAppFixtureIntegrationTest extends AbstractWebAppFixtureIntegrationTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java
index badf0d3..29081bb 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java
@@ -23,12 +23,11 @@ import static org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppFixtureIntegr
 import static org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppFixtureIntegrationTest.GIT_REPO_URL;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppService;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
index c3f1a10..0f82d5d 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.entity.webapp.nodejs;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcessDriver;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Urls;



[21/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocationInternal.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocationInternal.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocationInternal.html
index 009a41d..1a71db3 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocationInternal.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocationInternal.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.LocationInternal</title>
+    <title>Brooklyn Location - LocationInternal</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.LocationInternal</h1>
+        <h1>LocationInternal</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.LocationInternal";
+            return entity.type == "LocationInternal";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.MultiLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.MultiLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.MultiLocation.html
index cefe218..cf5a497 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.MultiLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.MultiLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.MultiLocation</title>
+    <title>Brooklyn Location - MultiLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.MultiLocation</h1>
+        <h1>MultiLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.MultiLocation";
+            return entity.type == "MultiLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SimulatedLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SimulatedLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SimulatedLocation.html
index 5fe7a58..b08d8a7 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SimulatedLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SimulatedLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.SimulatedLocation</title>
+    <title>Brooklyn Location - SimulatedLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.SimulatedLocation</h1>
+        <h1>SimulatedLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.SimulatedLocation";
+            return entity.type == "SimulatedLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SingleMachineProvisioningLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SingleMachineProvisioningLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SingleMachineProvisioningLocation.html
index 29abdf8..168929f 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SingleMachineProvisioningLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SingleMachineProvisioningLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.SingleMachineProvisioningLocation</title>
+    <title>Brooklyn Location - SingleMachineProvisioningLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.SingleMachineProvisioningLocation</h1>
+        <h1>SingleMachineProvisioningLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.SingleMachineProvisioningLocation";
+            return entity.type == "SingleMachineProvisioningLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SshMachineLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SshMachineLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SshMachineLocation.html
index 3ee27ab..b6edac1 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SshMachineLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.SshMachineLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.SshMachineLocation</title>
+    <title>Brooklyn Location - SshMachineLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.SshMachineLocation</h1>
+        <h1>SshMachineLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.SshMachineLocation";
+            return entity.type == "SshMachineLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation.html
index 6a41d3f..958594e 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation</title>
+    <title>Brooklyn Location - AbstractCloudMachineProvisioningLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation</h1>
+        <h1>AbstractCloudMachineProvisioningLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation";
+            return entity.type == "AbstractCloudMachineProvisioningLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.AbstractJcloudsSubnetSshMachineLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.AbstractJcloudsSubnetSshMachineLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.AbstractJcloudsSubnetSshMachineLocation.html
index 7240131..c2de588 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.AbstractJcloudsSubnetSshMachineLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.AbstractJcloudsSubnetSshMachineLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.jclouds.AbstractJcloudsSubnetSshMachineLocation</title>
+    <title>Brooklyn Location - AbstractJcloudsSubnetSshMachineLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.jclouds.AbstractJcloudsSubnetSshMachineLocation</h1>
+        <h1>AbstractJcloudsSubnetSshMachineLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.jclouds.AbstractJcloudsSubnetSshMachineLocation";
+            return entity.type == "AbstractJcloudsSubnetSshMachineLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsLocation.html
index de80bcb..4491b02 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.jclouds.JcloudsLocation</title>
+    <title>Brooklyn Location - JcloudsLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.jclouds.JcloudsLocation</h1>
+        <h1>JcloudsLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.jclouds.JcloudsLocation";
+            return entity.type == "JcloudsLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsSshMachineLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsSshMachineLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsSshMachineLocation.html
index 6ae6cc0..c7fd198 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsSshMachineLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.jclouds.JcloudsSshMachineLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.jclouds.JcloudsSshMachineLocation</title>
+    <title>Brooklyn Location - JcloudsSshMachineLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.jclouds.JcloudsSshMachineLocation</h1>
+        <h1>JcloudsSshMachineLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.jclouds.JcloudsSshMachineLocation";
+            return entity.type == "JcloudsSshMachineLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
----------------------------------------------------------------------
diff --git a/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java b/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
index 4332ef5..d53cf44 100644
--- a/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
+++ b/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
@@ -44,7 +44,7 @@ import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
 
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.BrooklynMavenArtifacts;
 import brooklyn.util.CommandLineUtil;
 import brooklyn.util.ResourceUtils;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
index 23fb28a..9c3edad 100644
--- a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
@@ -57,8 +57,8 @@ import org.apache.brooklyn.launcher.BrooklynLauncher;
 import org.apache.brooklyn.policy.EnricherSpec;
 import org.apache.brooklyn.policy.PolicySpec;
 
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.policy.ha.ServiceFailureDetector;
 import brooklyn.policy.ha.ServiceReplacer;
 import brooklyn.policy.ha.ServiceRestarter;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java
index 27657f3..5523286 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/SingleWebServerExample.java
@@ -33,7 +33,7 @@ import org.apache.brooklyn.entity.webapp.JavaWebAppService;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.CommandLineUtil;
 
 import com.google.common.collect.Lists;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
index a013484..7084b74 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
@@ -45,7 +45,7 @@ import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.policy.autoscaling.AutoScalerPolicy;
 import brooklyn.util.CommandLineUtil;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
index 22672f5..5b72a58 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
@@ -50,7 +50,7 @@ import brooklyn.event.basic.Sensors;
 
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.policy.autoscaling.AutoScalerPolicy;
 import brooklyn.util.BrooklynMavenArtifacts;
 import brooklyn.util.CommandLineUtil;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java b/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
index 1e10164..900ba4a 100644
--- a/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
+++ b/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
@@ -20,7 +20,6 @@ package org.apache.brooklyn.demo;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.demo.WebClusterDatabaseExampleApp;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
 import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
@@ -56,7 +55,7 @@ import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.java.JavaEntityMethods;
 import brooklyn.entity.rebind.RebindOptions;
 import brooklyn.entity.rebind.RebindTestFixture;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.policy.autoscaling.AutoScalerPolicy;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/entity/rebind/persister/jclouds/JcloudsBlobStoreBasedObjectStore.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/entity/rebind/persister/jclouds/JcloudsBlobStoreBasedObjectStore.java b/locations/jclouds/src/main/java/brooklyn/entity/rebind/persister/jclouds/JcloudsBlobStoreBasedObjectStore.java
index b72dca2..ca6f757 100644
--- a/locations/jclouds/src/main/java/brooklyn/entity/rebind/persister/jclouds/JcloudsBlobStoreBasedObjectStore.java
+++ b/locations/jclouds/src/main/java/brooklyn/entity/rebind/persister/jclouds/JcloudsBlobStoreBasedObjectStore.java
@@ -35,10 +35,10 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.BrooklynServerConfig;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsUtil;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsUtil;
 import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
 import brooklyn.util.text.Strings;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/AbstractJcloudsSubnetSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/AbstractJcloudsSubnetSshMachineLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/AbstractJcloudsSubnetSshMachineLocation.java
deleted file mode 100644
index a528b6a..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/AbstractJcloudsSubnetSshMachineLocation.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Map;
-
-import org.jclouds.compute.domain.NodeMetadata;
-
-import brooklyn.location.basic.SupportsPortForwarding.RequiresPortForwarding;
-
-public abstract class AbstractJcloudsSubnetSshMachineLocation extends JcloudsSshMachineLocation implements RequiresPortForwarding {
-
-    public AbstractJcloudsSubnetSshMachineLocation() {
-    }
-
-    /** @deprecated since 0.6.0 use no-arg constructor, as per parent */
-    @Deprecated
-    public AbstractJcloudsSubnetSshMachineLocation(Map flags, JcloudsLocation parent, NodeMetadata node) {
-        super(flags, parent, node);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/BasicJcloudsLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/BasicJcloudsLocationCustomizer.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/BasicJcloudsLocationCustomizer.java
deleted file mode 100644
index 502c40c..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/BasicJcloudsLocationCustomizer.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.options.TemplateOptions;
-
-import com.google.common.annotations.Beta;
-
-
-/**
- * A default no-op implementation, which can be extended to override the appropriate methods.
- * 
- * Sub-classing will give the user some protection against future API changes - note that 
- * {@link JcloudsLocationCustomizer} is marked {@link Beta}.
- * 
- * @author aled
- */
-public class BasicJcloudsLocationCustomizer implements JcloudsLocationCustomizer {
-
-    @Override
-    public void customize(JcloudsLocation location, ComputeService computeService, TemplateBuilder templateBuilder) {
-        // no-op
-    }
-
-    @Override
-    public void customize(JcloudsLocation location, ComputeService computeService, Template template) {
-        // no-op
-    }
-
-    @Override
-    public void customize(JcloudsLocation location, ComputeService computeService, TemplateOptions templateOptions) {
-        // no-op
-    }
-
-    @Override
-    public void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine) {
-        if (machine instanceof JcloudsSshMachineLocation) {
-            customize(location, computeService, (JcloudsSshMachineLocation)machine);
-        } else {
-            // no-op
-        }
-    }
-    
-    @Override
-    public void preRelease(JcloudsMachineLocation machine) {
-        if (machine instanceof JcloudsSshMachineLocation) {
-            preRelease((JcloudsSshMachineLocation)machine);
-        } else {
-            // no-op
-        }
-    }
-
-    @Override
-    public void postRelease(JcloudsMachineLocation machine) {
-        if (machine instanceof JcloudsSshMachineLocation) {
-            postRelease((JcloudsSshMachineLocation)machine);
-        } else {
-            // no-op
-        }
-    }
-    
-    @Override
-    @Deprecated
-    public void customize(JcloudsLocation location, ComputeService computeService, JcloudsSshMachineLocation machine) {
-        // no-op
-    }
-
-    @Override
-    @Deprecated
-    public void preRelease(JcloudsSshMachineLocation machine) {
-        // no-op
-    }
-
-    @Override
-    @Deprecated
-    public void postRelease(JcloudsSshMachineLocation machine) {
-        // no-op
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/BrooklynImageChooser.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/BrooklynImageChooser.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/BrooklynImageChooser.java
deleted file mode 100644
index 75cd3a7..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/BrooklynImageChooser.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.List;
-
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.OperatingSystem;
-import org.jclouds.compute.domain.OsFamily;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.collections.MutableList;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.collect.ComparisonChain;
-import com.google.common.collect.Ordering;
-import com.google.common.math.DoubleMath;
-
-@Beta
-/** NB: subclasses must implement {@link #clone()} */
-public class BrooklynImageChooser implements Cloneable {
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynImageChooser.class);
-    
-    protected ComputeService computeService;
-    protected String cloudProviderName;
-    
-    protected static int compare(double left, double right) {
-        return DoubleMath.fuzzyCompare(left, right, 0.00000001);
-    }
-    
-    protected static boolean imageNameContains(Image img, String pattern) {
-        if (img.getName()==null) return false;
-        return img.getName().contains(pattern);
-    }
-    
-    protected static boolean imageNameContainsCaseInsensitive(Image img, String pattern) {
-        if (img.getName()==null) return false;
-        return img.getName().toLowerCase().contains(pattern.toLowerCase());
-    }
-    
-    protected static boolean imageNameContainsWordCaseInsensitive(Image img, String pattern) {
-        if (img.getName()==null) return false;
-        return img.getName().toLowerCase().matches("(.*[^a-z])?"+pattern.toLowerCase()+"([^a-z].*)?");
-    }
-    
-    public double punishmentForOldOsVersions(Image img, OsFamily family, double minVersion) {
-        OperatingSystem os = img.getOperatingSystem();
-        if (os!=null && family.equals(os.getFamily())) {
-            String v = os.getVersion();
-            if (v!=null) {
-                try {
-                    double vd = Double.parseDouble(v);
-                    // punish older versions, with a -log function (so 0.5 version behind is -log(1.5)=-0.5 and 2 versions behind is -log(3)=-1.2  
-                    if (vd < minVersion) return -Math.log(1+(minVersion - vd));
-                } catch (Exception e) {
-                    /* ignore unparseable versions */
-                }
-            }
-        }
-        return 0;
-    }
-    
-    public List<String> blackListedImageIds() {
-        return Arrays.asList(
-                // bad natty image - causes 403 on attempts to apt-get; https://bugs.launchpad.net/ubuntu/+bug/987182
-                "us-east-1/ami-1cb30875",
-                // wrong login user advertised, causes "Error Invalid packet: indicated length 1349281121 too large"
-                // from sshj due to message coming back "Plea"(se log in as another user), according to https://github.com/jclouds/legacy-jclouds/issues/748
-                "us-east-1/ami-08faa660"
-            );
-    }
-
-    public List<String> whilelistedImageIds() {
-        return Arrays.asList(
-        // these are the ones we recommend in brooklyn.properties, but now autodetection should be more reliable
-//                "us-east-1/ami-d0f89fb9",
-//                "us-west-1/ami-fe002cbb",
-//                "us-west-2/ami-70f96e40",
-//                "eu-west-1/ami-ce7b6fba",
-//                "sa-east-1/ami-a3da00be",
-//                "ap-southeast-1/ami-64084736",
-//                "ap-southeast-2/ami-04ea7a3e",
-//                "ap-northeast-1/ami-fe6ceeff"
-            );
-    }
-    
-    public double score(Image img) {
-        double score = 0;
-
-        if (blackListedImageIds().contains(img.getId()))
-            score -= 50;
-
-        if (whilelistedImageIds().contains(img.getId()))
-            // NB: this should be less than deprecated punishment to catch deprecation of whitelisted items
-            score += 20;
-
-        score += punishmentForDeprecation(img);
-
-    
-        // prefer these guys, in stock brooklyn provisioning
-        score += punishmentForOldOsVersions(img, OsFamily.UBUNTU, 11);
-        score += punishmentForOldOsVersions(img, OsFamily.CENTOS, 6);
-
-        OperatingSystem os = img.getOperatingSystem();
-        if (os!=null) {
-            if (os.getFamily()!=null) {
-                // preference for these open, popular OS (but only wrt versions above) 
-                if (os.getFamily().equals(OsFamily.CENTOS)) score += 2;
-                else if (os.getFamily().equals(OsFamily.UBUNTU)) {
-                    score += 2;
-
-                    // prefer these LTS releases slightly above others (including above CentOS)
-                    // (but note in AWS Virginia, at least, version is empty for the 14.04 images for some reason, as of Aug 2014)
-                    if ("14.04".equals(os.getVersion())) score += 0.2;
-                    else if ("12.04".equals(os.getVersion())) score += 0.1;
-
-                    // NB some 13.10 images take 20m+ before they are sshable on AWS
-                    // with "vesafb: module verification error" showing in the AWS system log
-                }
-
-                // slight preference for these 
-                else if (os.getFamily().equals(OsFamily.RHEL)) score += 1;
-                else if (os.getFamily().equals(OsFamily.AMZN_LINUX)) score += 1;
-                else if (os.getFamily().equals(OsFamily.DEBIAN)) score += 1;
-
-                // prefer to take our chances with unknown / unlabelled linux than something explicitly windows
-                else if (os.getFamily().equals(OsFamily.WINDOWS)) score -= 1;
-                
-                if ("softlayer".equals(cloudProviderName)) {
-                    // on softlayer, prefer images where family is part of the image id
-                    // (this is the only way to identiy official images; but in other clouds
-                    // it can cause not-so-good images to get selected!)
-                    if (img.getId().toLowerCase().indexOf(os.getFamily().toString().toLowerCase()) >= 0)
-                        score += 0.5;
-                }
-            }
-            // prefer 64-bit
-            if (os.is64Bit()) score += 0.5;
-        }
-
-        // TODO prefer known providerIds
-
-        if (log.isTraceEnabled())
-            log.trace("initial score "+score+" for "+img);
-        
-        return score;
-    }
-
-    protected double punishmentForDeprecation(Image img) {
-        // google deprecation strategy
-        //        userMetadata={deprecatedState=DEPRECATED}}
-        String deprecated = img.getUserMetadata().get("deprecatedState");
-        if (deprecated!=null) {
-            if ("deprecated".equalsIgnoreCase(deprecated))
-                return -30;
-            log.warn("Unrecognised 'deprecatedState' value '"+deprecated+"' when scoring "+img+"; ignoring that metadata");
-        }
-        
-        // common strategies
-        if (imageNameContainsWordCaseInsensitive(img, "deprecated")) return -30;
-        if (imageNameContainsWordCaseInsensitive(img, "alpha")) return -10;
-        if (imageNameContainsWordCaseInsensitive(img, "beta")) return -5;
-        if (imageNameContainsWordCaseInsensitive(img, "testing")) return -5;
-        if (imageNameContainsWordCaseInsensitive(img, "rc")) return -3;
-
-        // no indication this is deprecated
-        return 0;
-    }
-
-    public BrooklynImageChooser clone() {
-        return new BrooklynImageChooser();
-    }
-    
-    protected void use(ComputeService service) {
-        if (this.computeService!=null && !this.computeService.equals(service))
-            throw new IllegalStateException("ImageChooser must be cloned to set a compute service");
-        this.computeService = service;
-        if (computeService!=null) {
-            cloudProviderName = computeService.getContext().unwrap().getId();
-        }
-    }
-    
-    public BrooklynImageChooser cloneFor(ComputeService service) {
-        BrooklynImageChooser result = clone();
-        result.use(service);
-        return result;
-    }
-    
-    public static class OrderingScoredWithoutDefaults extends Ordering<Image> implements ComputeServiceAwareChooser<OrderingScoredWithoutDefaults> {
-        private BrooklynImageChooser chooser;
-        public OrderingScoredWithoutDefaults(BrooklynImageChooser chooser) {
-            this.chooser = chooser;
-        }
-        public int compare(Image left, Image right) {
-            return BrooklynImageChooser.compare(chooser.score(left), chooser.score(right));
-        }
-        @Override
-        public OrderingScoredWithoutDefaults cloneFor(ComputeService service) {
-            return new OrderingScoredWithoutDefaults(chooser.cloneFor(service));
-        }        
-    }
-    
-    public Ordering<Image> orderingScoredWithoutDefaults() {
-        return new OrderingScoredWithoutDefaults(this);
-    }
-    
-    /** @deprecated since 0.7.0 kept in case persisted */
-    @Deprecated
-    public Ordering<Image> orderingScoredWithoutDefaultsDeprecated() {
-        return new Ordering<Image>() {
-            @Override
-            public int compare(Image left, Image right) {
-                return BrooklynImageChooser.compare(score(left), score(right));
-            }
-        };
-    }
-    
-    public static class OrderingWithDefaults extends Ordering<Image> implements ComputeServiceAwareChooser<OrderingWithDefaults> {
-        Ordering<Image> primaryOrdering;
-        public OrderingWithDefaults(final Ordering<Image> primaryOrdering) {
-            this.primaryOrdering = primaryOrdering;
-        }
-        @Override
-        public int compare(Image left, Image right) {
-            return ComparisonChain.start()
-                .compare(left, right, primaryOrdering)
-                // fall back to default strategy otherwise, except preferring *non*-null values
-                // TODO use AlphaNum string comparator
-                .compare(left.getName(), right.getName(), Ordering.<String> natural().nullsFirst())
-                .compare(left.getVersion(), right.getVersion(), Ordering.<String> natural().nullsFirst())
-                .compare(left.getDescription(), right.getDescription(), Ordering.<String> natural().nullsFirst())
-                .compare(left.getOperatingSystem().getName(), right.getOperatingSystem().getName(), Ordering.<String> natural().nullsFirst())
-                .compare(left.getOperatingSystem().getVersion(), right.getOperatingSystem().getVersion(), Ordering.<String> natural().nullsFirst())
-                .compare(left.getOperatingSystem().getDescription(), right.getOperatingSystem().getDescription(), Ordering.<String> natural().nullsFirst())
-                .compare(left.getOperatingSystem().getArch(), right.getOperatingSystem().getArch(), Ordering.<String> natural().nullsFirst()).result();
-        }    
-        @Override
-        public OrderingWithDefaults cloneFor(ComputeService service) {
-            if (primaryOrdering instanceof ComputeServiceAwareChooser) {
-                return new OrderingWithDefaults( BrooklynImageChooser.cloneFor(primaryOrdering, service) );
-            }
-            return this;
-        }        
-    }
-    
-    public static Ordering<Image> orderingWithDefaults(final Ordering<Image> primaryOrdering) {
-        return new OrderingWithDefaults(primaryOrdering);
-    }
-    
-    /** @deprecated since 0.7.0 kept in case persisted */
-    @Deprecated
-    public static Ordering<Image> orderingWithDefaultsDeprecated(final Ordering<Image> primaryOrdering) {
-        return new Ordering<Image>() {
-            @Override
-            public int compare(Image left, Image right) {
-                return ComparisonChain.start()
-                    .compare(left, right, primaryOrdering)
-                    // fall back to default strategy otherwise, except preferring *non*-null values
-                    // TODO use AlphaNum string comparator
-                    .compare(left.getName(), right.getName(), Ordering.<String> natural().nullsFirst())
-                    .compare(left.getVersion(), right.getVersion(), Ordering.<String> natural().nullsFirst())
-                    .compare(left.getDescription(), right.getDescription(), Ordering.<String> natural().nullsFirst())
-                    .compare(left.getOperatingSystem().getName(), right.getOperatingSystem().getName(), Ordering.<String> natural().nullsFirst())
-                    .compare(left.getOperatingSystem().getVersion(), right.getOperatingSystem().getVersion(), Ordering.<String> natural().nullsFirst())
-                    .compare(left.getOperatingSystem().getDescription(), right.getOperatingSystem().getDescription(), Ordering.<String> natural().nullsFirst())
-                    .compare(left.getOperatingSystem().getArch(), right.getOperatingSystem().getArch(), Ordering.<String> natural().nullsFirst()).result();
-            }
-        };
-    }
-    
-    public static class ImageChooserFromOrdering implements Function<Iterable<? extends Image>, Image>, ComputeServiceAwareChooser<ImageChooserFromOrdering> {
-        final Ordering<Image> ordering;
-        public ImageChooserFromOrdering(final Ordering<Image> ordering) { this.ordering = ordering; }
-        @Override
-        public Image apply(Iterable<? extends Image> input) {
-            List<? extends Image> maxImages = multiMax(ordering, input);
-            return maxImages.get(maxImages.size() - 1);
-        }
-        @Override
-        public ImageChooserFromOrdering cloneFor(ComputeService service) {
-            if (ordering instanceof ComputeServiceAwareChooser) {
-                return new ImageChooserFromOrdering( BrooklynImageChooser.cloneFor(ordering, service) );
-            }
-            return this;
-        }        
-    }
-
-    public static Function<Iterable<? extends Image>, Image> imageChooserFromOrdering(final Ordering<Image> ordering) {
-        return new ImageChooserFromOrdering(ordering);
-    }
-    
-    /** @deprecated since 0.7.0 kept in case persisted */
-    @Deprecated
-    public static Function<Iterable<? extends Image>, Image> imageChooserFromOrderingDeprecated(final Ordering<Image> ordering) {
-        return new Function<Iterable<? extends Image>, Image>() {
-            @Override
-            public Image apply(Iterable<? extends Image> input) {
-                List<? extends Image> maxImages = multiMax(ordering, input);
-                return maxImages.get(maxImages.size() - 1);
-            }
-        };
-    }
-    
-    protected interface ComputeServiceAwareChooser<T> {
-        public T cloneFor(ComputeService service);
-    }
-
-    /** Attempts to clone the given item for use with the given {@link ComputeService}, if
-     * the item is {@link ComputeServiceAwareChooser}; otherwise it returns the item unchanged */
-    @SuppressWarnings("unchecked")
-    public static <T> T cloneFor(T item, ComputeService service) {
-        if (item instanceof ComputeServiceAwareChooser) {
-            return ((ComputeServiceAwareChooser<T>)item).cloneFor(service);
-        }
-        return item;
-    }
-    
-    // from jclouds
-    static <T, E extends T> List<E> multiMax(Comparator<T> ordering, Iterable<E> iterable) {
-        Iterator<E> iterator = iterable.iterator();
-        List<E> maxes = MutableList.of(iterator.next());
-        E maxSoFar = maxes.get(0);
-        while (iterator.hasNext()) {
-           E current = iterator.next();
-           int comparison = ordering.compare(maxSoFar, current);
-           if (comparison == 0) {
-              maxes.add(current);
-           } else if (comparison < 0) {
-              maxes = MutableList.of(current);
-              maxSoFar = current;
-           }
-        }
-        return maxes;
-     }
-    
-    public Ordering<Image> ordering() {
-        return orderingWithDefaults(orderingScoredWithoutDefaults());
-    }
-
-    public Function<Iterable<? extends Image>,Image> chooser() {
-        return imageChooserFromOrdering(ordering());
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/BrooklynMachinePool.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/BrooklynMachinePool.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/BrooklynMachinePool.java
deleted file mode 100644
index 6fc2076..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/BrooklynMachinePool.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static brooklyn.location.jclouds.pool.MachinePoolPredicates.matching;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.management.Task;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.trait.Startable;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.basic.WinRmMachineLocation;
-import brooklyn.location.jclouds.pool.MachinePool;
-import brooklyn.location.jclouds.pool.MachineSet;
-import brooklyn.location.jclouds.pool.ReusableMachineTemplate;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.task.BasicExecutionContext;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-
-/**
- * @deprecated since 0.6.0; never used in production setting, and thus of dubious value; best avoided as unlikely to be supported in future versions
- */
-@Deprecated
-public class BrooklynMachinePool extends MachinePool {
-
-    private static final Logger log = LoggerFactory.getLogger(BrooklynMachinePool.class);
-    
-    protected final JcloudsLocation location;
-    final List<Task<?>> activeTasks = new ArrayList<Task<?>>();
-    final String providerLocationId;
-    
-    public BrooklynMachinePool(JcloudsLocation l) {
-        super(l.getComputeService());
-        providerLocationId = l.getRegion();
-        this.location = l;
-    }
-    
-    /** claims a machine with the indicated spec, creating if necessary */
-    public SshMachineLocation obtain(ReusableMachineTemplate t) {
-        MachineSet previous = unclaimed(matching(t));
-        
-        while (true) {
-            NodeMetadata m = claim(1, t).iterator().next();
-            // TODO ideally shouldn't have to rebind
-            SshMachineLocation result = null;
-            try {
-                result = toSshMachineLocation( m );
-            } catch (Exception e) {
-                if (previous.contains(m)) {
-                    log.debug("attempt to bind to previous existing machine "+m+" failed (will blacklist and retry another): "+e);
-                } else {
-                    log.warn("attempt to bind to machine "+m+" failed: "+e);
-                    throw Throwables.propagate(e);
-                }
-            }
-            if (result!=null) return result;
-            if (previous.contains(m)) {
-                log.debug("could not bind to previous existing machine "+m+"; blacklisting and trying a new one");
-                addToBlacklist(new MachineSet(m));
-            } else {
-                throw new IllegalStateException("cannot bind/connect to newly created machine; error in configuration");
-            }
-        }
-    }
-    
-    protected MachineSet filterForAllowedMachines(MachineSet input) {
-        MachineSet result = super.filterForAllowedMachines(input);
-        if (providerLocationId!=null) {
-            result = result.filtered(matching( new ReusableMachineTemplate().locationId(providerLocationId).strict(false) ));
-        }
-        return result;
-    }
-
-    /** returns an SshMachineLocation, if one can be created and accessed; returns null if it cannot be created */
-    protected SshMachineLocation toSshMachineLocation(NodeMetadata m) {
-        try {
-            JcloudsSshMachineLocation sshM = location.rebindMachine(m);
-            if (sshM.execCommands("check-reachable", Arrays.asList("whoami")) != 0) {
-                log.warn("cannot bind to machine "+m);
-                return null;
-            }
-            return sshM;
-        } catch (Exception e) {
-            throw Throwables.propagate(e);
-        }
-    }
-    
-    @Override
-    public MachineSet create(int count, ReusableMachineTemplate template) {
-        List<NodeMetadata> nodes = new ArrayList<NodeMetadata>();
-        for (int i=0; i<count; i++) {
-            // TODO this in parallel
-            JcloudsSshMachineLocation m;
-            try {
-                MachineLocation machineLocation = location.obtain(MutableMap.of("callerContext", ""+this+"("+template+")"), template);
-                // Class has been deprecated since 0.6.0, and prior to that, obtain would have returned a JcloudsSshMachineLocation
-                if (machineLocation instanceof JcloudsSshMachineLocation) {
-                    m = (JcloudsSshMachineLocation) machineLocation;
-                } else {
-                    throw new UnsupportedOperationException("Cannot create WinRmMachineLocation");
-                }
-            } catch (Exception e) {
-                throw Throwables.propagate(e);
-            }
-            nodes.add(m.getNode());
-        }
-        MachineSet result = new MachineSet(nodes);
-        registerNewNodes(result, template);
-        return result;
-    }
-
-    public boolean unclaim(SshMachineLocation location) {
-        init();
-        if (location instanceof JcloudsSshMachineLocation)
-            return unclaim(new MachineSet( ((JcloudsSshMachineLocation)location).getNode()) ) > 0;
-        return false;
-    }
-    public boolean destroy(SshMachineLocation location) {
-        init();
-        if (location instanceof JcloudsSshMachineLocation)
-            return destroy(new MachineSet( ((JcloudsSshMachineLocation)location).getNode()) ) > 0;
-        return false;
-    }
-
-    // TODO we need to remove stale tasks somewhere
-    protected <T> Task<T> addTask(Task<T> t) {
-        synchronized (activeTasks) { activeTasks.add(t); }
-        return t;
-    }
-    
-    public List<Task<?>> getActiveTasks() {
-        List<Task<?>> result;
-        synchronized (activeTasks) { result = ImmutableList.<Task<?>>copyOf(activeTasks); }
-        return result;
-    }
-
-    public void blockUntilTasksEnded() {
-        while (true) {
-            boolean allDone = true;
-            List<Task<?>> tt = getActiveTasks();
-            for (Task<?> t: tt) {
-                if (!t.isDone()) {
-                    allDone = false;
-                    if (log.isDebugEnabled()) log.debug("Pool "+this+", blocking for completion of: "+t);
-                    t.blockUntilEnded();
-                }
-            }
-            synchronized (activeTasks) {
-                List<Task> newTT = new ArrayList<Task>(getActiveTasks());
-                newTT.removeAll(tt);
-                if (allDone && tt.isEmpty()) {
-                    //task list has stabilized, and there are no active tasks; clear and exit
-                    if (log.isDebugEnabled()) log.debug("Pool "+this+", all known tasks have completed, clearing list");
-                    activeTasks.clear();
-                    break;
-                }
-                if (log.isDebugEnabled()) log.debug("Pool "+this+", all previously known tasks have completed, but there are new tasks ("+newTT+") checking them");
-            }
-        }
-    }
-
-    /** starts the given template; for use only within a task (e.g. application's start effector).
-     * returns a child task of the current task.
-     * <p>
-     * throws exception if not in a task. (you will have to claim, then invoke the effectors manually.) */
-    public Task<?> start(final ReusableMachineTemplate template, final List<? extends Startable> entities) {
-        BasicExecutionContext ctx = BasicExecutionContext.getCurrentExecutionContext();
-        if (ctx==null) throw new IllegalStateException("Pool.start is only permitted within a task (effector)");
-        final AtomicReference<Task<?>> t = new AtomicReference<Task<?>>();
-        synchronized (t) {
-            t.set(ctx.submit(new Runnable() {
-                public void run() {
-                    synchronized (t) {
-                        if (log.isDebugEnabled()) log.debug("Pool "+this+", task "+t.get()+" claiming a "+template);
-                        SshMachineLocation m = obtain(template);
-                        if (log.isDebugEnabled()) log.debug("Pool "+this+", task "+t.get()+" got "+m+"; starting "+entities);
-                        for (Startable entity: entities)
-                            addTask( ((Entity)entity).invoke(Startable.START, MutableMap.of("locations", Arrays.asList(m))) );
-                    }
-                }
-            }));
-        }
-        addTask(t.get());
-        return t.get();
-    }
-
-    /** @see #start(ReusableMachineTemplate, List) */
-    public Task<?> start(ReusableMachineTemplate template, Startable ...entities) {
-        return start(template, Arrays.asList(entities));
-    }
-
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/ComputeServiceRegistry.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/ComputeServiceRegistry.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/ComputeServiceRegistry.java
deleted file mode 100644
index 519fa01..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/ComputeServiceRegistry.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import org.jclouds.compute.ComputeService;
-
-import brooklyn.util.config.ConfigBag;
-
-public interface ComputeServiceRegistry {
-    
-    public ComputeService findComputeService(ConfigBag conf, boolean allowReuse);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/ComputeServiceRegistryImpl.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/ComputeServiceRegistryImpl.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/ComputeServiceRegistryImpl.java
deleted file mode 100644
index a1786ec..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/ComputeServiceRegistryImpl.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_AMI_QUERY;
-import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMI_QUERY;
-
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.jclouds.Constants;
-import org.jclouds.ContextBuilder;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.ec2.reference.EC2Constants;
-import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
-import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
-import org.jclouds.sshj.config.SshjSshClientModule;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.Sanitizer;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.inject.Module;
-
-public class ComputeServiceRegistryImpl implements ComputeServiceRegistry, JcloudsLocationConfig {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(ComputeServiceRegistryImpl.class);
-
-    public static final ComputeServiceRegistryImpl INSTANCE = new ComputeServiceRegistryImpl();
-        
-    protected ComputeServiceRegistryImpl() {
-    }
-    
-    protected final Map<Map<?,?>,ComputeService> cachedComputeServices = new ConcurrentHashMap<Map<?,?>,ComputeService>();
-
-    protected final Object createComputeServicesMutex = new Object();
-
-    @Override
-    public ComputeService findComputeService(ConfigBag conf, boolean allowReuse) {
-        String provider = checkNotNull(conf.get(CLOUD_PROVIDER), "provider must not be null");
-        String identity = checkNotNull(conf.get(ACCESS_IDENTITY), "identity must not be null");
-        String credential = checkNotNull(conf.get(ACCESS_CREDENTIAL), "credential must not be null");
-        
-        Properties properties = new Properties();
-        properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
-        properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
-        properties.setProperty("jclouds.ssh.max-retries", conf.getStringKey("jclouds.ssh.max-retries") != null ? 
-                conf.getStringKey("jclouds.ssh.max-retries").toString() : "50");
-        // Enable aws-ec2 lazy image fetching, if given a specific imageId; otherwise customize for specific owners; or all as a last resort
-        // See https://issues.apache.org/jira/browse/WHIRR-416
-        if ("aws-ec2".equals(provider)) {
-            // TODO convert AWS-only flags to config keys
-            if (groovyTruth(conf.get(IMAGE_ID))) {
-                properties.setProperty(PROPERTY_EC2_AMI_QUERY, "");
-                properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, "");
-            } else if (groovyTruth(conf.getStringKey("imageOwner"))) {
-                properties.setProperty(PROPERTY_EC2_AMI_QUERY, "owner-id="+conf.getStringKey("imageOwner")+";state=available;image-type=machine");
-            } else if (groovyTruth(conf.getStringKey("anyOwner"))) {
-                // set `anyOwner: true` to override the default query (which is restricted to certain owners as per below), 
-                // allowing the AMI query to bind to any machine
-                // (note however, we sometimes pick defaults in JcloudsLocationFactory);
-                // (and be careful, this can give a LOT of data back, taking several minutes,
-                // and requiring extra memory allocated on the command-line)
-                properties.setProperty(PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine");
-                /*
-                 * by default the following filters are applied:
-                 * Filter.1.Name=owner-id&Filter.1.Value.1=137112412989&
-                 * Filter.1.Value.2=063491364108&
-                 * Filter.1.Value.3=099720109477&
-                 * Filter.1.Value.4=411009282317&
-                 * Filter.2.Name=state&Filter.2.Value.1=available&
-                 * Filter.3.Name=image-type&Filter.3.Value.1=machine&
-                 */
-            }
-            
-            // occasionally can get com.google.common.util.concurrent.UncheckedExecutionException: java.lang.RuntimeException: 
-            //     security group eu-central-1/jclouds#brooklyn-bxza-alex-eu-central-shoul-u2jy-nginx-ielm is not available after creating
-            // the default timeout was 500ms so let's raise it in case that helps
-            properties.setProperty(EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT, ""+Duration.seconds(30).toMilliseconds());
-        }
-
-        // FIXME Deprecated mechanism, should have a ConfigKey for overrides
-        Map<String, Object> extra = Maps.filterKeys(conf.getAllConfig(), Predicates.containsPattern("^jclouds\\."));
-        if (extra.size() > 0) {
-            LOG.warn("Jclouds using deprecated property overrides: "+Sanitizer.sanitize(extra));
-        }
-        properties.putAll(extra);
-
-        String endpoint = conf.get(CLOUD_ENDPOINT);
-        if (!groovyTruth(endpoint)) endpoint = getDeprecatedProperty(conf, Constants.PROPERTY_ENDPOINT);
-        if (groovyTruth(endpoint)) properties.setProperty(Constants.PROPERTY_ENDPOINT, endpoint);
-
-        Map<?,?> cacheKey = MutableMap.builder()
-                .putAll(properties)
-                .put("provider", provider)
-                .put("identity", identity)
-                .put("credential", credential)
-                .putIfNotNull("endpoint", endpoint)
-                .build()
-                .asUnmodifiable();
-
-        if (allowReuse) {
-            ComputeService result = cachedComputeServices.get(cacheKey);
-            if (result!=null) {
-                LOG.trace("jclouds ComputeService cache hit for compute service, for "+Sanitizer.sanitize(properties));
-                return result;
-            }
-            LOG.debug("jclouds ComputeService cache miss for compute service, creating, for "+Sanitizer.sanitize(properties));
-        }
-
-        Iterable<Module> modules = getCommonModules();
-
-        // Synchronizing to avoid deadlock from sun.reflect.annotation.AnnotationType.
-        // See https://github.com/brooklyncentral/brooklyn/issues/974
-        ComputeServiceContext computeServiceContext;
-        synchronized (createComputeServicesMutex) {
-            computeServiceContext = ContextBuilder.newBuilder(provider)
-                    .modules(modules)
-                    .credentials(identity, credential)
-                    .overrides(properties)
-                    .build(ComputeServiceContext.class);
-        }
-        final ComputeService computeService = computeServiceContext.getComputeService();
-        if (allowReuse) {
-            synchronized (cachedComputeServices) {
-                ComputeService result = cachedComputeServices.get(cacheKey);
-                if (result != null) {
-                    LOG.debug("jclouds ComputeService cache recovery for compute service, for "+Sanitizer.sanitize(cacheKey));
-                    //keep the old one, discard the new one
-                    computeService.getContext().close();
-                    return result;
-                }
-                LOG.debug("jclouds ComputeService created "+computeService+", adding to cache, for "+Sanitizer.sanitize(properties));
-                cachedComputeServices.put(cacheKey, computeService);
-            }
-        }
-        return computeService;
-     }
-
-    /** returns the jclouds modules we typically install */ 
-    protected ImmutableSet<Module> getCommonModules() {
-        return ImmutableSet.<Module> of(
-                new SshjSshClientModule(), 
-                new SLF4JLoggingModule(),
-                new BouncyCastleCryptoModule());
-    }
-     
-    protected String getDeprecatedProperty(ConfigBag conf, String key) {
-        if (conf.containsKey(key)) {
-            LOG.warn("Jclouds using deprecated brooklyn-jclouds property "+key+": "+Sanitizer.sanitize(conf.getAllConfig()));
-            return (String) conf.getStringKey(key);
-        } else {
-            return null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsByonLocationResolver.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
deleted file mode 100644
index a027907..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.BasicLocationRegistry;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.LocationConfigUtils;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.basic.LocationPropertiesFromBrooklynProperties;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.text.KeyValueParser;
-import brooklyn.util.text.Strings;
-import brooklyn.util.text.WildcardGlobs;
-import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-/**
- * Examples of valid specs:
- *   <ul>
- *     <li>byon:(hosts=myhost)
- *     <li>byon:(hosts="myhost, myhost2")
- *     <li>byon:(hosts="myhost, myhost2", name="my location name")
- *   </ul>
- * 
- * @author aled
- */
-@SuppressWarnings({"unchecked","rawtypes"})
-public class JcloudsByonLocationResolver implements LocationResolver {
-
-    public static final Logger log = LoggerFactory.getLogger(JcloudsByonLocationResolver.class);
-    
-    public static final String BYON = "jcloudsByon";
-
-    private static final Pattern PATTERN = Pattern.compile("("+BYON+"|"+BYON.toUpperCase()+")" + ":" + "\\((.*)\\)$");
-
-    private ManagementContext managementContext;
-
-    @Override
-    public void init(ManagementContext managementContext) {
-        this.managementContext = checkNotNull(managementContext, "managementContext");
-    }
-    
-    // TODO Remove some duplication from JcloudsResolver; needs more careful review
-    @Override
-    public FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        Map globalProperties = registry.getProperties();
-
-        Matcher matcher = PATTERN.matcher(spec);
-        if (!matcher.matches()) {
-            throw new IllegalArgumentException("Invalid location '"+spec+"'; must specify something like jcloudsByon(provider=\"aws-ec2\",region=\"us-east-1\",hosts=\"i-f2014593,i-d1234567\")");
-        }
-        
-        String argsPart = matcher.group(2);
-        Map<String, String> argsMap = KeyValueParser.parseMap(argsPart);
-        
-        // prefer args map over location flags
-        
-        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
-
-        String providerOrApi = argsMap.containsKey("provider") ? argsMap.get("provider") : (String)locationFlags.get("provider");
-
-        String regionName = argsMap.containsKey("region") ? argsMap.get("region") : (String)locationFlags.get("region");
-        
-        String endpoint = argsMap.containsKey("endpoint") ? argsMap.get("endpoint") : (String)locationFlags.get("endpoint");
-        
-        String name = argsMap.containsKey("name") ? argsMap.get("name") : (String)locationFlags.get("name");
-
-        String user = argsMap.containsKey("user") ? argsMap.get("user") : (String)locationFlags.get("user");
-
-        String privateKeyFile = argsMap.containsKey("privateKeyFile") ? argsMap.get("privateKeyFile") : (String)locationFlags.get("privateKeyFile");
-        
-        String hosts = argsMap.get("hosts");
-        
-        if (Strings.isEmpty(providerOrApi)) {
-            throw new IllegalArgumentException("Invalid location '"+spec+"'; provider must be defined");
-        }
-        if (hosts == null || hosts.isEmpty()) {
-            throw new IllegalArgumentException("Invalid location '"+spec+"'; at least one host must be defined");
-        }
-        if (argsMap.containsKey("name") && (Strings.isEmpty(name))) {
-            throw new IllegalArgumentException("Invalid location '"+spec+"'; if name supplied then value must be non-empty");
-        }
-
-        // For everything in brooklyn.properties, only use things with correct prefix (and remove that prefix).
-        // But for everything passed in via locationFlags, pass those as-is.
-        // TODO Should revisit the locationFlags: where are these actually used? Reason accepting properties without
-        //      full prefix is that the map's context is explicitly this location, rather than being generic properties.
-        Map allProperties = getAllProperties(registry, globalProperties);
-        Map jcloudsProperties = new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties(providerOrApi, regionName, namedLocation, allProperties);
-        jcloudsProperties.putAll(locationFlags);
-        jcloudsProperties.putAll(argsMap);
-        
-        String jcloudsSpec = "jclouds:"+providerOrApi + (regionName != null ? ":"+regionName : "") + (endpoint != null ? ":"+endpoint : "");
-        JcloudsLocation jcloudsLocation = (JcloudsLocation) registry.resolve(jcloudsSpec, jcloudsProperties);
-
-        List<String> hostIdentifiers = WildcardGlobs.getGlobsAfterBraceExpansion("{"+hosts+"}",
-                true /* numeric */, /* no quote support though */ PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR);
-        List<JcloudsSshMachineLocation> machines = Lists.newArrayList();
-        
-        for (String hostIdentifier : hostIdentifiers) {
-            Map<?, ?> machineFlags = MutableMap.builder()
-                    .put("id", hostIdentifier)
-                    .putIfNotNull("user", user)
-                    .putIfNotNull("privateKeyFile", privateKeyFile)
-                    .build();
-            try {
-                JcloudsSshMachineLocation machine = jcloudsLocation.rebindMachine(jcloudsLocation.config().getBag().putAll(machineFlags));
-                machines.add(machine);
-            } catch (NoMachinesAvailableException e) {
-                log.warn("Error rebinding to jclouds machine "+hostIdentifier+" in "+jcloudsLocation, e);
-                Exceptions.propagate(e);
-            }
-        }
-        
-        ConfigBag flags = ConfigBag.newInstance(jcloudsProperties);
-
-        flags.putStringKey("machines", machines);
-        flags.putIfNotNull(LocationConfigKeys.USER, user);
-        flags.putStringKeyIfNotNull("name", name);
-        
-        if (registry != null) 
-            LocationPropertiesFromBrooklynProperties.setLocalTempDir(registry.getProperties(), flags);
-
-        log.debug("Created Jclouds BYON location "+name+": "+machines);
-        
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .configure(flags.getAllConfig())
-                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
-    }
-    
-    private Map getAllProperties(brooklyn.location.LocationRegistry registry, Map<?,?> properties) {
-        Map<Object,Object> allProperties = Maps.newHashMap();
-        if (registry!=null) allProperties.putAll(registry.getProperties());
-        allProperties.putAll(properties);
-        return allProperties;
-    }
-    
-    @Override
-    public String getPrefix() {
-        return BYON;
-    }
-    
-    @Override
-    public boolean accepts(String spec, LocationRegistry registry) {
-        return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true);
-    }
-}
\ No newline at end of file


[40/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java b/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
deleted file mode 100644
index 73766c2..0000000
--- a/core/src/main/java/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static brooklyn.util.GroovyJavaMethods.truth;
-
-import java.io.Closeable;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.management.LocationManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineLocationCustomizer;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.util.collections.CollectionFunctionals;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.text.WildcardGlobs;
-import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
-
-/**
- * A provisioner of {@link MachineLocation}s which takes a list of machines it can connect to.
- * The collection of initial machines should be supplied in the 'machines' flag in the constructor,
- * for example a list of machines which can be SSH'd to. 
- * 
- * This can be extended to have a mechanism to make more machines to be available
- * (override provisionMore and canProvisionMore).
- */
-public class FixedListMachineProvisioningLocation<T extends MachineLocation> extends AbstractLocation 
-implements MachineProvisioningLocation<T>, Closeable {
-
-    // TODO Synchronization looks very wrong for accessing machines/inUse 
-    // e.g. removeChild doesn't synchronize when doing machines.remove(...),
-    // and getMachines() returns the real sets risking 
-    // ConcurrentModificationException in the caller if it iterates over them etc.
-    
-    private static final Logger log = LoggerFactory.getLogger(FixedListMachineProvisioningLocation.class);
-    
-    public static final ConfigKey<Function<Iterable<? extends MachineLocation>, MachineLocation>> MACHINE_CHOOSER =
-            ConfigKeys.newConfigKey(
-                    new TypeToken<Function<Iterable<? extends MachineLocation>, MachineLocation>>() {}, 
-                    "byon.machineChooser",
-                    "For choosing which of the possible machines is chosen and returned by obtain()",
-                    CollectionFunctionals.<MachineLocation>firstElement());
-
-    public static final ConfigKey<Collection<MachineLocationCustomizer>> MACHINE_LOCATION_CUSTOMIZERS = CloudLocationConfig.MACHINE_LOCATION_CUSTOMIZERS;
-    
-    private final Object lock = new Object();
-    
-    @SetFromFlag
-    protected Set<T> machines;
-    
-    @SetFromFlag
-    protected Set<T> inUse;
-
-    @SetFromFlag
-    protected Set<T> pendingRemoval;
-    
-    @SetFromFlag
-    protected Map<T, Map<String, Object>> origConfigs;
-
-    public FixedListMachineProvisioningLocation() {
-        this(Maps.newLinkedHashMap());
-    }
-    public FixedListMachineProvisioningLocation(Map properties) {
-        super(properties);
-
-        if (isLegacyConstruction()) {
-            init();
-        }
-    }
-
-    @Override
-    public void init() {
-        super.init();
-        
-        Set<T> machinesCopy = MutableSet.of();
-        for (T location: machines) {
-            if (location==null) {
-                log.warn(""+this+" initialized with null location, removing (may be due to rebind with reference to an unmanaged location)");
-            } else {
-                Location parent = location.getParent();
-                if (parent == null) {
-                    addChild(location);
-                }
-                machinesCopy.add(location);
-            }
-        }
-        if (!machinesCopy.equals(machines)) {
-            machines = machinesCopy;
-        }
-    }
-    
-    @Override
-    public String toVerboseString() {
-        return Objects.toStringHelper(this).omitNullValues()
-                .add("id", getId()).add("name", getDisplayName())
-                .add("machinesAvailable", getAvailable()).add("machinesInUse", getInUse())
-                .toString();
-    }
-
-    @Override
-    public AbstractLocation configure(Map<?,?> properties) {
-        if (machines == null) machines = Sets.newLinkedHashSet();
-        if (inUse == null) inUse = Sets.newLinkedHashSet();
-        if (pendingRemoval == null) pendingRemoval = Sets.newLinkedHashSet();
-        if (origConfigs == null) origConfigs = Maps.newLinkedHashMap();
-        return super.configure(properties);
-    }
-    
-    @SuppressWarnings("unchecked")
-    public FixedListMachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags) {
-        // TODO shouldn't have to copy config bag as it should be inherited (but currently it is not used inherited everywhere; just most places)
-        return getManagementContext().getLocationManager().createLocation(LocationSpec.create(getClass())
-                .parent(this)
-                .configure(config().getLocalBag().getAllConfig())  // FIXME Should this just be inherited?
-                .configure(newFlags));
-    }
-
-    @Override
-    public void close() {
-        for (T machine : machines) {
-            if (machine instanceof Closeable) Streams.closeQuietly((Closeable)machine);
-        }
-    }
-    
-    public void addMachine(T machine) {
-        synchronized (lock) {
-            if (machines.contains(machine)) {
-                throw new IllegalArgumentException("Cannot add "+machine+" to "+toString()+", because already contained");
-            }
-            
-            Location existingParent = ((Location)machine).getParent();
-            if (existingParent == null) {
-                addChild(machine);
-            }
-            
-            machines.add(machine);
-        }
-    }
-    
-    public void removeMachine(T machine) {
-        synchronized (lock) {
-            if (inUse.contains(machine)) {
-                pendingRemoval.add(machine);
-            } else {
-                machines.remove(machine);
-                pendingRemoval.remove(machine);
-                if (this.equals(machine.getParent())) {
-                    removeChild((Location)machine);
-                }
-            }
-        }
-    }
-    
-    protected Set<T> getMachines() {
-        return machines;
-    }
-    
-    public Set<T> getAvailable() {
-        Set<T> a = Sets.newLinkedHashSet(machines);
-        a.removeAll(inUse);
-        return a;
-    }   
-     
-    public Set<T> getInUse() {
-        return Sets.newLinkedHashSet(inUse);
-    }   
-     
-    public Set<T> getAllMachines() {
-        return ImmutableSet.copyOf(machines);
-    }   
-     
-    @Override
-    public void addChild(Location child) {
-        super.addChild(child);
-        machines.add((T)child);
-    }
-
-    @Override
-    public boolean removeChild(Location child) {
-        if (inUse.contains(child)) {
-            throw new IllegalStateException("Child location "+child+" is in use; cannot remove from "+this);
-        }
-        machines.remove(child);
-        return super.removeChild(child);
-    }
-
-    protected boolean canProvisionMore() {
-        return false;
-    }
-    
-    protected void provisionMore(int size) {
-        provisionMore(size, ImmutableMap.of());
-    }
-
-    protected void provisionMore(int size, Map<?,?> flags) {
-        throw new IllegalStateException("more not permitted");
-    }
-
-    public T obtain() throws NoMachinesAvailableException {
-        return obtain(Maps.<String,Object>newLinkedHashMap());
-    }
-    
-    @Override
-    public T obtain(Map<?,?> flags) throws NoMachinesAvailableException {
-        T machine;
-        T desiredMachine = (T) flags.get("desiredMachine");
-        ConfigBag allflags = ConfigBag.newInstanceExtending(config().getBag()).putAll(flags);
-        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = allflags.get(MACHINE_CHOOSER);
-        
-        synchronized (lock) {
-            Set<T> a = getAvailable();
-            if (a.isEmpty()) {
-                if (canProvisionMore()) {
-                    provisionMore(1, allflags.getAllConfig());
-                    a = getAvailable();
-                }
-                if (a.isEmpty())
-                    throw new NoMachinesAvailableException("No machines available in "+toString());
-            }
-            if (desiredMachine != null) {
-                if (a.contains(desiredMachine)) {
-                    machine = desiredMachine;
-                } else {
-                    throw new IllegalStateException("Desired machine "+desiredMachine+" not available in "+toString()+"; "+
-                            (inUse.contains(desiredMachine) ? "machine in use" : "machine unknown"));
-                }
-            } else {
-                machine = (T) chooser.apply(a);
-                if (!a.contains(machine)) {
-                    throw new IllegalStateException("Machine chooser attempted to choose '"+machine+"' from outside the available set, in "+this);
-                }
-            }
-            inUse.add(machine);
-            updateMachineConfig(machine, flags);
-        }
-        
-        for (MachineLocationCustomizer customizer : getMachineCustomizers(allflags)) {
-            customizer.customize(machine);
-        }
-        
-        return machine;
-    }
-
-    @Override
-    public void release(T machine) {
-        ConfigBag machineConfig = ((ConfigurationSupportInternal)machine.config()).getBag();
-        for (MachineLocationCustomizer customizer : getMachineCustomizers(machineConfig)) {
-            customizer.preRelease(machine);
-        }
-
-        synchronized (lock) {
-            if (inUse.contains(machine) == false)
-                throw new IllegalStateException("Request to release machine "+machine+", but this machine is not currently allocated");
-            restoreMachineConfig(machine);
-            inUse.remove(machine);
-            
-            if (pendingRemoval.contains(machine)) {
-                removeMachine(machine);
-            }
-        }
-    }
-
-    @Override
-    public Map<String,Object> getProvisioningFlags(Collection<String> tags) {
-        return Maps.<String,Object>newLinkedHashMap();
-    }
-    
-    protected void updateMachineConfig(T machine, Map<?, ?> flags) {
-        if (origConfigs == null) {
-            // For backwards compatibility, where peristed state did not have this.
-            origConfigs = Maps.newLinkedHashMap();
-        }
-        Map<String, Object> strFlags = ConfigBag.newInstance(flags).getAllConfig();
-        Map<String, Object> origConfig = ((ConfigurationSupportInternal)machine.config()).getLocalBag().getAllConfig();
-        origConfigs.put(machine, origConfig);
-        requestPersist();
-        
-        ((ConfigurationSupportInternal)machine.config()).addToLocalBag(strFlags);
-    }
-    
-    protected void restoreMachineConfig(MachineLocation machine) {
-        if (origConfigs == null) {
-            // For backwards compatibility, where peristed state did not have this.
-            origConfigs = Maps.newLinkedHashMap();
-        }
-        Map<String, Object> origConfig = origConfigs.remove(machine);
-        if (origConfig == null) return;
-        requestPersist();
-        
-        Set<String> currentKeys = ((ConfigurationSupportInternal)machine.config()).getLocalBag().getAllConfig().keySet();
-        Set<String> newKeys = Sets.difference(currentKeys, origConfig.entrySet());
-        for (String key : newKeys) {
-            ((ConfigurationSupportInternal)machine.config()).removeFromLocalBag(key);
-        }
-        ((ConfigurationSupportInternal)machine.config()).addToLocalBag(origConfig);
-    }
-    
-    @SuppressWarnings("unchecked")
-    private <K> K getConfigPreferringOverridden(ConfigKey<K> key, Map<?,?> overrides) {
-        K result = (K) overrides.get(key);
-        if (result == null) result = (K) overrides.get(key.getName());
-        if (result == null) result = getConfig(key);
-        return result;
-    }
-
-    protected Collection<MachineLocationCustomizer> getMachineCustomizers(ConfigBag setup) {
-        Collection<MachineLocationCustomizer> customizers = setup.get(MACHINE_LOCATION_CUSTOMIZERS);
-        return (customizers == null ? ImmutableList.<MachineLocationCustomizer>of() : customizers);
-    }
-
-    /**
-     * Facilitates fluent/programmatic style for constructing a fixed pool of machines.
-     * <pre>
-     * {@code
-     *   new FixedListMachineProvisioningLocation.Builder()
-     *           .user("alex")
-     *           .keyFile("/Users/alex/.ssh/id_rsa")
-     *           .addAddress("10.0.0.1")
-     *           .addAddress("10.0.0.2")
-     *           .addAddress("10.0.0.3")
-     *           .addAddressMultipleTimes("me@127.0.0.1", 5)
-     *           .build();
-     * }
-     * </pre>
-     */
-    public static class Builder {
-        LocationManager lm;
-        String user;
-        String privateKeyPassphrase;
-        String privateKeyFile;
-        String privateKeyData;
-        File localTempDir;
-        List machines = Lists.newArrayList();
-
-        public Builder(LocationManager lm) {
-            this.lm = lm;
-        }
-        public Builder user(String user) {
-            this.user = user;
-            return this;
-        }
-        public Builder keyPassphrase(String keyPassphrase) {
-            this.privateKeyPassphrase = keyPassphrase;
-            return this; 
-        }
-        public Builder keyFile(String keyFile) {
-            this.privateKeyFile = keyFile;
-            return this; 
-        }
-        public Builder keyData(String keyData) {
-            this.privateKeyData = keyData;
-            return this;
-        }
-        public Builder localTempDir(File val) {
-            this.localTempDir = val;
-            return this;
-        }
-        /** adds the locations; user and keyfile set in the builder are _not_ applied to the machine
-         * (use add(String address) for that)
-         */
-        public Builder add(SshMachineLocation location) {
-            machines.add(location);
-            return this;
-        }
-        public Builder addAddress(String address) {
-            return addAddresses(address);
-        }
-        public Builder addAddressMultipleTimes(String address, int n) {
-            for (int i=0; i<n; i++)
-                addAddresses(address);
-            return this;
-        }
-        public Builder addAddresses(String address1, String ...others) {
-            List<String> addrs = new ArrayList<String>();
-            addrs.addAll(WildcardGlobs.getGlobsAfterBraceExpansion("{"+address1+"}",
-                    true /* numeric */, /* no quote support though */ PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR));
-            for (String address: others) 
-                addrs.addAll(WildcardGlobs.getGlobsAfterBraceExpansion("{"+address+"}",
-                        true /* numeric */, /* no quote support though */ PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR));
-            for (String addr: addrs)
-                add(createMachine(addr)); 
-            return this;
-        }
-        protected SshMachineLocation createMachine(String addr) {
-            if (lm==null)
-                return new SshMachineLocation(makeConfig(addr));
-            else
-                return lm.createLocation(makeConfig(addr), SshMachineLocation.class);
-        }
-        private Map makeConfig(String address) {
-            String user = this.user;
-            if (address.contains("@")) {
-                user = address.substring(0, address.indexOf("@"));
-                address = address.substring(address.indexOf("@")+1);
-            }
-            Map config = MutableMap.of("address", address);
-            if (truth(user)) {
-                config.put("user", user);
-                config.put("sshconfig.user", user);
-            }
-            if (truth(privateKeyPassphrase)) config.put("sshconfig.privateKeyPassphrase", privateKeyPassphrase);
-            if (truth(privateKeyFile)) config.put("sshconfig.privateKeyFile", privateKeyFile);
-            if (truth(privateKeyData)) config.put("sshconfig.privateKey", privateKeyData);
-            if (truth(localTempDir)) config.put("localTempDir", localTempDir);
-            return config;
-        }
-        @SuppressWarnings("unchecked")
-        public FixedListMachineProvisioningLocation<SshMachineLocation> build() {
-            if (lm==null)
-                return new FixedListMachineProvisioningLocation<SshMachineLocation>(MutableMap.builder()
-                    .putIfNotNull("machines", machines)
-                    .putIfNotNull("user", user)
-                    .putIfNotNull("privateKeyPassphrase", privateKeyPassphrase)
-                    .putIfNotNull("privateKeyFile", privateKeyFile)
-                    .putIfNotNull("privateKeyData", privateKeyData)
-                    .putIfNotNull("localTempDir", localTempDir)
-                    .build());
-            else
-                return lm.createLocation(MutableMap.builder()
-                    .putIfNotNull("machines", machines)
-                    .putIfNotNull("user", user)
-                    .putIfNotNull("privateKeyPassphrase", privateKeyPassphrase)
-                    .putIfNotNull("privateKeyFile", privateKeyFile)
-                    .putIfNotNull("privateKeyData", privateKeyData)
-                    .putIfNotNull("localTempDir", localTempDir)
-                    .build(), 
-                FixedListMachineProvisioningLocation.class);
-        }        
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/HasSubnetHostname.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/HasSubnetHostname.java b/core/src/main/java/brooklyn/location/basic/HasSubnetHostname.java
deleted file mode 100644
index 1ad8f1b..0000000
--- a/core/src/main/java/brooklyn/location/basic/HasSubnetHostname.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import com.google.common.annotations.Beta;
-
-@Beta
-public interface HasSubnetHostname {
-
-    /** returns a hostname for use internally within a subnet / VPC */
-    @Beta
-    String getSubnetHostname();
-
-    /** returns an IP for use internally within a subnet / VPC */
-    String getSubnetIp();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/HostLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/HostLocationResolver.java b/core/src/main/java/brooklyn/location/basic/HostLocationResolver.java
deleted file mode 100644
index 2bb5b4b..0000000
--- a/core/src/main/java/brooklyn/location/basic/HostLocationResolver.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.AbstractLocationResolver.SpecParser.ParsedSpec;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.guava.Maybe.Absent;
-import brooklyn.util.text.KeyValueParser;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public class HostLocationResolver extends AbstractLocationResolver {
-    
-    private static final String HOST = "host";
-    
-    @SuppressWarnings("rawtypes")
-    @Override
-    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
-        // Extract args from spec
-        ParsedSpec parsedSpec = specParser.parse(spec);
-        Map<String, String> argsMap = parsedSpec.argsMap;
-        if (argsMap.isEmpty()) {
-            throw new IllegalArgumentException("Invalid host spec (no host supplied): "+spec);
-        } else if (argsMap.size() == 1 && Iterables.get(argsMap.values(), 0) == null) {
-            // only given ip or hostname
-            argsMap = ImmutableMap.of("hosts", Iterables.get(argsMap.keySet(), 0));
-        } else if (!(argsMap.containsKey("host") || argsMap.containsKey("hosts"))) {
-            throw new IllegalArgumentException("Invalid host spec (no host supplied): "+spec);
-        }
-
-        // Find generic applicable properties
-        Map globalProperties = registry.getProperties();
-        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
-        Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties().getLocationProperties(null, namedLocation, globalProperties);
-        ConfigBag flags = ConfigBag.newInstance(locationFlags).putIfAbsent(filteredProperties);
-        flags.remove(LocationInternal.NAMED_SPEC_NAME);
-
-        // Generate target spec
-        String target = "byon("+KeyValueParser.toLine(argsMap)+")";
-        Maybe<Location> testResolve = managementContext.getLocationRegistry().resolve(target, false, null);
-        if (!testResolve.isPresent()) {
-            throw new IllegalArgumentException("Invalid target location '" + target + "' for location '"+HOST+"': "+
-                Exceptions.collapseText( ((Absent<?>)testResolve).getException() ), ((Absent<?>)testResolve).getException());
-        }
-        
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(SingleMachineProvisioningLocation.class)
-                .configure("location", target)
-                .configure("locationFlags", flags.getAllConfig())
-                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
-    }
-    
-    @Override
-    public String getPrefix() {
-        return HOST;
-    }
-    
-    @Override
-    protected Class<? extends Location> getLocationType() {
-        return SingleMachineProvisioningLocation.class;
-    }
-
-    @Override
-    protected SpecParser getSpecParser() {
-        return new SpecParser(getPrefix()).setExampleUsage("\"host(1.1.1.1)\" or \"host(host=1.1.1.1,name=myname)\"");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocalhostLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocalhostLocationResolver.java b/core/src/main/java/brooklyn/location/basic/LocalhostLocationResolver.java
deleted file mode 100644
index 6451ed1..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocalhostLocationResolver.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationResolver.EnableableLocationResolver;
-import brooklyn.util.config.ConfigBag;
-
-/**
- * Examples of valid specs:
- *   <ul>
- *     <li>localhost
- *     <li>localhost()
- *     <li>localhost(name=abc)
- *     <li>localhost(name="abc")
- *   </ul>
- * 
- * @author alex, aled
- */
-public class LocalhostLocationResolver extends AbstractLocationResolver implements EnableableLocationResolver {
-
-    public static final String LOCALHOST = "localhost";
-
-    @Override
-    public String getPrefix() {
-        return LOCALHOST;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return LocationConfigUtils.isEnabled(managementContext, "brooklyn.location.localhost");
-    }
-
-    @Override
-    protected Class<? extends Location> getLocationType() {
-        return LocalhostMachineProvisioningLocation.class;
-    }
-
-    @Override
-    protected SpecParser getSpecParser() {
-        return new AbstractLocationResolver.SpecParser(getPrefix()).setExampleUsage("\"localhost\" or \"localhost(displayName=abc)\"");
-    }
-
-    @Override
-    protected Map<String, Object> getFilteredLocationProperties(String provider, String namedLocation, Map<String, ?> globalProperties) {
-        return new LocalhostPropertiesFromBrooklynProperties().getLocationProperties("localhost", namedLocation, globalProperties);
-    }
-
-    @Override
-    protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        ConfigBag config = super.extractConfig(locationFlags, spec, registry);
-        config.putAsStringKeyIfAbsent("name", "localhost");
-        return config;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java b/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
deleted file mode 100644
index 64f31f9..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static brooklyn.util.GroovyJavaMethods.elvis;
-import static brooklyn.util.GroovyJavaMethods.truth;
-
-import java.io.File;
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.rebind.persister.FileBasedObjectStore;
-import brooklyn.entity.rebind.persister.LocationWithObjectStore;
-import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.location.AddressableLocation;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.OsDetails;
-import brooklyn.location.PortRange;
-import brooklyn.location.geo.HostGeoInfo;
-import brooklyn.util.BrooklynNetworkUtils;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.internal.ssh.process.ProcessTool;
-import brooklyn.util.mutex.MutexSupport;
-import brooklyn.util.mutex.WithMutexes;
-import brooklyn.util.net.Networking;
-import brooklyn.util.os.Os;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.time.Duration;
-import brooklyn.util.time.Time;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-/**
- * An implementation of {@link brooklyn.location.MachineProvisioningLocation} that can provision a {@link SshMachineLocation} for the
- * local host.
- *
- * By default you can only obtain a single SshMachineLocation for the localhost. Optionally, you can "overload"
- * and choose to allow localhost to be provisioned multiple times, which may be useful in some testing scenarios.
- */
-public class LocalhostMachineProvisioningLocation extends FixedListMachineProvisioningLocation<SshMachineLocation> implements AddressableLocation, LocationWithObjectStore {
-
-    public static final Logger LOG = LoggerFactory.getLogger(LocalhostMachineProvisioningLocation.class);
-    
-    public static final ConfigKey<Boolean> SKIP_ON_BOX_BASE_DIR_RESOLUTION = ConfigKeys.newConfigKeyWithDefault(
-            BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, 
-            true);
-    
-    @SetFromFlag("count")
-    int initialCount;
-
-    @SetFromFlag
-    Boolean canProvisionMore;
-    
-    @SetFromFlag
-    InetAddress address;
-
-    private static Set<Integer> portsInUse = Sets.newLinkedHashSet();
-
-    private static HostGeoInfo cachedHostGeoInfo;
-    
-    @VisibleForTesting
-    public static void clearStaticData() {
-        portsInUse.clear();
-        cachedHostGeoInfo = null;
-    }
-        
-    /**
-     * Construct a new instance.
-     *
-     * The constructor recognises the following properties:
-     * <ul>
-     * <li>count - number of localhost machines to make available
-     * </ul>
-     */
-    public LocalhostMachineProvisioningLocation() {
-        this(Maps.newLinkedHashMap());
-    }
-    /**
-     * @param properties the properties of the new instance.
-     * @deprecated since 0.6
-     * @see #LocalhostMachineProvisioningLocation()
-     */
-    public LocalhostMachineProvisioningLocation(Map properties) {
-        super(properties);
-    }
-    public LocalhostMachineProvisioningLocation(String name) {
-        this(name, 0);
-    }
-    public LocalhostMachineProvisioningLocation(String name, int count) {
-        this(MutableMap.of("name", name, "count", count));
-    }
-    
-    public static LocationSpec<LocalhostMachineProvisioningLocation> spec() {
-        return LocationSpec.create(LocalhostMachineProvisioningLocation.class);
-    }
-    
-    public LocalhostMachineProvisioningLocation configure(Map<?,?> flags) {
-        super.configure(flags);
-        
-        if (!truth(getDisplayName())) { setDisplayName("localhost"); }
-        if (!truth(address)) address = getLocalhostInetAddress();
-        // TODO should try to confirm this machine is accessible on the given address ... but there's no 
-        // immediate convenience in java so early-trapping of that particular error is deferred
-        
-        if (canProvisionMore==null) {
-            if (initialCount>0) canProvisionMore = false;
-            else canProvisionMore = true;
-        }
-        if (getHostGeoInfo()==null) {
-            if (cachedHostGeoInfo==null)
-                cachedHostGeoInfo = HostGeoInfo.fromLocation(this);
-            setHostGeoInfo(cachedHostGeoInfo);
-        }
-        if (initialCount > getMachines().size()) {
-            provisionMore(initialCount - getMachines().size());
-        }
-        
-        if (getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR)==null && (getManagementContext()==null || getManagementContext().getConfig().getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR)==null)) {
-            setConfig(BrooklynConfigKeys.ONBOX_BASE_DIR, "/tmp/brooklyn-"+Os.user());
-        }
-        
-        return this;
-    }
-    
-    public static InetAddress getLocalhostInetAddress() {
-        return BrooklynNetworkUtils.getLocalhostInetAddress();
-    }
-
-    @Override
-    public InetAddress getAddress() {
-        return address;
-    }
-    
-    @Override
-    public boolean canProvisionMore() {
-        return canProvisionMore;
-    }
-    
-    @Override
-    protected void provisionMore(int size, Map<?,?> flags) {
-        for (int i=0; i<size; i++) {
-            Map<Object,Object> flags2 = MutableMap.<Object,Object>builder()
-                    .putAll(flags)
-                    .put("address", elvis(address, Networking.getLocalHost()))
-                    .put("mutexSupport", LocalhostMachine.mutexSupport)
-                    .build();
-            
-            // copy inherited keys for ssh; 
-            // shouldn't be necessary but not sure that all contexts traverse the hierarchy
-            // NOTE: changed Nov 2013 to copy only those ssh config keys actually set, rather than all of them
-            // TODO should take the plunge and try removing this altogether!
-            // (or alternatively switch to copying all ancestor keys)
-            for (HasConfigKey<?> k: SshMachineLocation.ALL_SSH_CONFIG_KEYS) {
-                if (config().getRaw(k).isPresent())
-                    flags2.put(k, getConfig(k));
-            }
-            
-            if (isManaged()) {
-                addChild(LocationSpec.create(LocalhostMachine.class).configure(flags2));
-            } else {
-                addChild(new LocalhostMachine(flags2)); // TODO legacy way
-            }
-       }
-    }
-
-    public static synchronized boolean obtainSpecificPort(InetAddress localAddress, int portNumber) {
-        if (portsInUse.contains(portNumber)) {
-            return false;
-        } else {
-            //see if it is available?
-            if (!checkPortAvailable(localAddress, portNumber)) {
-                return false;
-            }
-            portsInUse.add(portNumber);
-            return true;
-        }
-    }
-    /** checks the actual availability of the port on localhost, ie by binding to it; cf {@link Networking#isPortAvailable(int)} */
-    public static boolean checkPortAvailable(InetAddress localAddress, int portNumber) {
-        if (portNumber<1024) {
-            if (LOG.isDebugEnabled()) LOG.debug("Skipping system availability check for privileged localhost port "+portNumber);
-            return true;
-        }
-        return Networking.isPortAvailable(localAddress, portNumber);
-    }
-    public static int obtainPort(PortRange range) {
-        return obtainPort(getLocalhostInetAddress(), range);
-    }
-    public static int obtainPort(InetAddress localAddress, PortRange range) {
-        for (int p: range)
-            if (obtainSpecificPort(localAddress, p)) return p;
-        if (LOG.isDebugEnabled()) LOG.debug("unable to find port in {} on {}; returning -1", range, localAddress);
-        return -1;
-    }
-
-    public static synchronized void releasePort(InetAddress localAddress, int portNumber) {
-        portsInUse.remove((Object) portNumber);
-    }
-
-    public void release(SshMachineLocation machine) {
-        LocalhostMachine localMachine = (LocalhostMachine) machine;
-        Set<Integer> portsObtained = Sets.newLinkedHashSet();
-        synchronized (localMachine.portsObtained) {
-            portsObtained.addAll(localMachine.portsObtained);
-        }
-        
-        super.release(machine);
-        
-        for (int p: portsObtained)
-            releasePort(null, p);
-    }
-    
-    public static class LocalhostMachine extends SshMachineLocation implements HasSubnetHostname {
-        // declaring this here (as well as on LocalhostMachineProvisioningLocation) because:
-        //  1. machine.getConfig(key) will not inherit default value of machine.getParent()'s key
-        //  2. things might instantiate a `LocalhostMachine` without going through LocalhostMachineProvisioningLocation
-        //     so not sufficient for LocalhostMachineProvisioningLocation to just push its config value into
-        //     the LocalhostMachine instance.
-        public static final ConfigKey<Boolean> SKIP_ON_BOX_BASE_DIR_RESOLUTION = ConfigKeys.newConfigKeyWithDefault(
-                BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, 
-                true);
-
-        private static final WithMutexes mutexSupport = new MutexSupport();
-        
-        private final Set<Integer> portsObtained = Sets.newLinkedHashSet();
-
-        public LocalhostMachine() {
-            super();
-        }
-        /** @deprecated since 0.6.0 use no-arg constructor (and spec) then configure */
-        public LocalhostMachine(Map properties) {
-            super(MutableMap.builder().putAll(properties).put("mutexSupport", mutexSupport).build());
-        }
-        
-        @Override
-        protected WithMutexes getMutexSupport() {
-            return mutexSupport;
-        }
-        
-        public boolean obtainSpecificPort(int portNumber) {
-            if (!isSudoAllowed() && portNumber <= 1024)
-                return false;
-            return LocalhostMachineProvisioningLocation.obtainSpecificPort(getAddress(), portNumber);
-        }
-        
-        public int obtainPort(PortRange range) {
-            int r = LocalhostMachineProvisioningLocation.obtainPort(getAddress(), range);
-            synchronized (portsObtained) {
-                if (r>0) portsObtained.add(r);
-            }
-            LOG.debug("localhost.obtainPort("+range+"), returning "+r);
-            return r;
-        }
-        
-        @Override
-        public void releasePort(int portNumber) {
-            synchronized (portsObtained) {
-                portsObtained.remove((Object)portNumber);
-            }
-            LocalhostMachineProvisioningLocation.releasePort(getAddress(), portNumber);
-        }
-        
-        @Override
-        public OsDetails getOsDetails() {
-            return BasicOsDetails.Factory.newLocalhostInstance();
-        }
-        
-        @Override
-        public LocalhostMachine configure(Map<?,?> properties) {
-            if (address==null || !properties.containsKey("address"))
-                address = Networking.getLocalHost();
-            super.configure(properties);
-            return this;
-        }
-        @Override
-        public String getSubnetHostname() {
-           return Networking.getLocalHost().getHostName();
-        }
-        @Override
-        public String getSubnetIp() {
-            return Networking.getLocalHost().getHostAddress();
-        }
-    }
-
-    private static class SudoChecker {
-        static volatile long lastSudoCheckTime = -1;
-        static boolean lastSudoResult = false;
-        public static boolean isSudoAllowed() {
-            if (Time.hasElapsedSince(lastSudoCheckTime, Duration.FIVE_MINUTES))
-                checkIfNeeded();                    
-            return lastSudoResult;
-        }
-        private static synchronized void checkIfNeeded() {
-            if (Time.hasElapsedSince(lastSudoCheckTime, Duration.FIVE_MINUTES)) {
-                try {
-                    lastSudoResult = new ProcessTool().execCommands(MutableMap.<String,Object>of(), Arrays.asList(
-                            BashCommands.sudo("date"))) == 0;
-                } catch (Exception e) {
-                    lastSudoResult = false;
-                    LOG.debug("Error checking sudo at localhost: "+e, e);
-                }
-                lastSudoCheckTime = System.currentTimeMillis();
-            }
-        }
-    }
-
-    public static boolean isSudoAllowed() {
-        return SudoChecker.isSudoAllowed();
-    }
-
-    @Override
-    public PersistenceObjectStore newPersistenceObjectStore(String container) {
-        File basedir = new File(container);
-        if (basedir.isFile()) throw new IllegalArgumentException("Destination directory must not be a file");
-        return new FileBasedObjectStore(basedir);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocalhostPropertiesFromBrooklynProperties.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocalhostPropertiesFromBrooklynProperties.java b/core/src/main/java/brooklyn/location/basic/LocalhostPropertiesFromBrooklynProperties.java
deleted file mode 100644
index c76fe96..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocalhostPropertiesFromBrooklynProperties.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.base.Strings;
-
-/**
- * @author aledsage
- **/
-public class LocalhostPropertiesFromBrooklynProperties extends LocationPropertiesFromBrooklynProperties {
-
-    // TODO Once delete support for deprecated "location.localhost.*" then can get rid of this class, and use
-    // LocationPropertiesFromBrooklynProperties directly
-    
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(LocalhostPropertiesFromBrooklynProperties.class);
-
-    @Override
-    public Map<String, Object> getLocationProperties(String provider, String namedLocation, Map<String, ?> properties) {
-        if (Strings.isNullOrEmpty(namedLocation) && Strings.isNullOrEmpty(provider)) {
-            throw new IllegalArgumentException("Neither cloud provider/API nor location name have been specified correctly");
-        }
-
-        ConfigBag result = ConfigBag.newInstance();
-        
-        result.putAll(transformDeprecated(getGenericLocationSingleWordProperties(properties)));
-        result.putAll(transformDeprecated(getMatchingSingleWordProperties("brooklyn.location.", properties)));
-        result.putAll(transformDeprecated(getMatchingProperties("brooklyn.location.localhost.", "brooklyn.localhost.", properties)));
-        if (!Strings.isNullOrEmpty(namedLocation)) result.putAll(transformDeprecated(getNamedLocationProperties(namedLocation, properties)));
-        setLocalTempDir(properties, result);
-        
-        return result.getAllConfigRaw();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocationConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocationConfigKeys.java b/core/src/main/java/brooklyn/location/basic/LocationConfigKeys.java
deleted file mode 100644
index 2d341b8..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocationConfigKeys.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.io.File;
-import java.util.Set;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.util.os.Os;
-
-import com.google.common.base.CaseFormat;
-import com.google.common.reflect.TypeToken;
-
-public class LocationConfigKeys {
-
-    public static final ConfigKey<String> LOCATION_ID = ConfigKeys.newStringConfigKey("id");
-    public static final ConfigKey<String> DISPLAY_NAME = ConfigKeys.newStringConfigKey("displayName");
-    public static final ConfigKey<Boolean> ENABLED = ConfigKeys.newBooleanConfigKey("enabled", "Whether the location is enabled for listing and use "
-        + "(only supported for selected locations)", true);
-    
-    public static final ConfigKey<String> ACCESS_IDENTITY = ConfigKeys.newStringConfigKey("identity"); 
-    public static final ConfigKey<String> ACCESS_CREDENTIAL = ConfigKeys.newStringConfigKey("credential"); 
-
-    public static final ConfigKey<Double> LATITUDE = new BasicConfigKey<Double>(Double.class, "latitude"); 
-    public static final ConfigKey<Double> LONGITUDE = new BasicConfigKey<Double>(Double.class, "longitude"); 
-
-    public static final ConfigKey<String> CLOUD_PROVIDER = ConfigKeys.newStringConfigKey("provider");
-    public static final ConfigKey<String> CLOUD_ENDPOINT = ConfigKeys.newStringConfigKey("endpoint");
-    public static final ConfigKey<String> CLOUD_REGION_ID = ConfigKeys.newStringConfigKey("region");
-    public static final ConfigKey<String> CLOUD_AVAILABILITY_ZONE_ID = ConfigKeys.newStringConfigKey("availabilityZone");
-
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Set<String>> ISO_3166 = ConfigKeys.newConfigKey(new TypeToken<Set<String>>() {}, "iso3166", "ISO-3166 or ISO-3166-2 location codes"); 
-
-    public static final ConfigKey<String> USER = ConfigKeys.newStringConfigKey("user", 
-            "user account for normal access to the remote machine, defaulting to local user", System.getProperty("user.name"));
-    
-    public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password", "password to use for ssh; note some images do not allow password-based ssh access");
-    public static final ConfigKey<String> PUBLIC_KEY_FILE = ConfigKeys.newStringConfigKey("publicKeyFile", "ssh public key file to use; if blank will infer from privateKeyFile by appending \".pub\"");
-    public static final ConfigKey<String> PUBLIC_KEY_DATA = ConfigKeys.newStringConfigKey("publicKeyData", "ssh public key string to use (takes precedence over publicKeyFile)");
-    public static final ConfigKey<String> PRIVATE_KEY_FILE = ConfigKeys.newStringConfigKey("privateKeyFile", "a '" + File.pathSeparator + "' separated list of ssh private key files; uses first in list that can be read",
-                                                                                           Os.fromHome(".ssh/id_rsa") + File.pathSeparator + Os.fromHome(".ssh/id_dsa"));
-    public static final ConfigKey<String> PRIVATE_KEY_DATA = ConfigKeys.newStringConfigKey("privateKeyData", "ssh private key string to use (takes precedence over privateKeyFile)");
-    public static final ConfigKey<String> PRIVATE_KEY_PASSPHRASE = ConfigKeys.newStringConfigKey("privateKeyPassphrase");
-
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PUBLIC_KEY_FILE = ConfigKeys.convert(PUBLIC_KEY_FILE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PUBLIC_KEY_DATA = ConfigKeys.convert(PUBLIC_KEY_DATA, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_FILE = ConfigKeys.convert(PRIVATE_KEY_FILE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_DATA = ConfigKeys.convert(PRIVATE_KEY_DATA, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_PASSPHRASE = ConfigKeys.convert(PRIVATE_KEY_PASSPHRASE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
-
-    public static final ConfigKey<Object> CALLER_CONTEXT = new BasicConfigKey<Object>(Object.class, "callerContext",
-            "An object whose toString is used for logging, to indicate wherefore a VM is being created");
-    public static final ConfigKey<String> CLOUD_MACHINE_NAMER_CLASS = ConfigKeys.newStringConfigKey("cloudMachineNamer", "fully qualified class name of a class that extends CloudMachineNamer and has a single-parameter constructor that takes a ConfigBag");
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocationConfigUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocationConfigUtils.java b/core/src/main/java/brooklyn/location/basic/LocationConfigUtils.java
deleted file mode 100644
index 9949947..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocationConfigUtils.java
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.security.KeyPair;
-import java.security.PublicKey;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.crypto.AuthorizedKeysParser;
-import brooklyn.util.crypto.SecureKeys;
-import brooklyn.util.crypto.SecureKeys.PassphraseProblem;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.os.Os;
-import brooklyn.util.text.StringFunctions;
-import brooklyn.util.text.Strings;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-public class LocationConfigUtils {
-
-    private static final Logger log = LoggerFactory.getLogger(LocationConfigUtils.class);
-
-    /** Creates an instance of {@link OsCredential} by inspecting {@link LocationConfigKeys#PASSWORD}; 
-     * {@link LocationConfigKeys#PRIVATE_KEY_DATA} and {@link LocationConfigKeys#PRIVATE_KEY_FILE};
-     * {@link LocationConfigKeys#PRIVATE_KEY_PASSPHRASE} if needed, and
-     * {@link LocationConfigKeys#PRIVATE_KEY_DATA} and {@link LocationConfigKeys#PRIVATE_KEY_FILE}
-     * (defaulting to the private key file + ".pub"). 
-     **/
-    public static OsCredential getOsCredential(ConfigBag config) {
-        return OsCredential.newInstance(config);
-    }
-    
-    /** Convenience class for holding private/public keys and passwords, inferring from config keys.
-     * See {@link LocationConfigUtils#getOsCredential(ConfigBag)}. */
-    @Beta // would be nice to replace with a builder pattern 
-    public static class OsCredential {
-        private final ConfigBag config;
-        private boolean preferPassword = false;
-        private boolean tryDefaultKeys = true;
-        private boolean requirePublicKey = true;
-        private boolean doKeyValidation = BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_VALIDATE_LOCATION_SSH_KEYS);
-        private boolean warnOnErrors = true;
-        private boolean throwOnErrors = false;
-        
-        private boolean dirty = true;;
-        
-        private String privateKeyData;
-        private String publicKeyData;
-        private String password;
-        
-        private OsCredential(ConfigBag config) {
-            this.config = config;
-        }
-
-        /** throws if there are any problems */
-        public OsCredential checkNotEmpty() {
-            checkNoErrors();
-            
-            if (!hasKey() && !hasPassword()) {
-                if (warningMessages.size()>0)
-                    throw new IllegalStateException("Could not find credentials: "+warningMessages);
-                else 
-                    throw new IllegalStateException("Could not find credentials");
-            }
-            return this;
-        }
-
-        /** throws if there were errors resolving (e.g. explicit keys, none of which were found/valid, or public key required and not found) 
-         * @return */
-        public OsCredential checkNoErrors() {
-            throwOnErrors(true);
-            dirty();
-            infer();
-            return this;
-        }
-        
-        public OsCredential logAnyWarnings() {
-            if (!warningMessages.isEmpty())
-                log.warn("When reading credentials: "+warningMessages);
-            return this;
-        }
-
-        public Set<String> getWarningMessages() {
-            return warningMessages;
-        }
-        
-        /** returns either the key or password or null; if both a key and a password this prefers the key unless otherwise set
-         * via {@link #preferPassword()} */
-        public synchronized String getPreferredCredential() {
-            infer();
-            
-            if (isUsingPassword()) return password;
-            if (hasKey()) return privateKeyData;
-            return null;
-        }
-
-        /** if there is no credential (ignores public key) */
-        public boolean isEmpty() {
-            return !hasKey() && !hasPassword();
-        }
-        public boolean hasKey() {
-            infer();
-            // key has stricter non-blank check than password
-            return Strings.isNonBlank(privateKeyData);
-        }
-        public boolean hasPassword() {
-            infer();
-            // blank, even empty passwords are allowed
-            return password!=null;
-        }
-        /** if a password is available, and either this is preferred over a key or there is no key */
-        public boolean isUsingPassword() {
-            return hasPassword() && (!hasKey() || preferPassword);
-        }
-        
-        public String getPrivateKeyData() {
-            infer();
-            return privateKeyData;
-        }
-        public String getPublicKeyData() {
-            infer();
-            return publicKeyData;
-        }
-        public String getPassword() {
-            infer();
-            return password;
-        }
-        
-        /** if both key and password supplied, prefer the key; the default */
-        public OsCredential preferKey() { preferPassword = false; return dirty(); }
-        /** if both key and password supplied, prefer the password; see {@link #preferKey()} */
-        public OsCredential preferPassword() { preferPassword = true; return dirty(); }
-        
-        /** if false, do not mind if there is no public key corresponding to any private key;
-         * defaults to true; only applies if a private key is set */
-        public OsCredential requirePublicKey(boolean requirePublicKey) {
-            this.requirePublicKey = requirePublicKey;
-            return dirty(); 
-        }
-        /** whether to check the private/public keys and passphrase are coherent; default true */
-        public OsCredential doKeyValidation(boolean doKeyValidation) {
-            this.doKeyValidation = doKeyValidation;
-            return dirty();
-        }
-        /** if true (the default) this will look at default locations set on keys */
-        public OsCredential useDefaultKeys(boolean tryDefaultKeys) {
-            this.tryDefaultKeys = tryDefaultKeys;
-            return dirty(); 
-        }
-        /** whether to log warnings on problems */
-        public OsCredential warnOnErrors(boolean warnOnErrors) {
-            this.warnOnErrors = warnOnErrors;
-            return dirty(); 
-        }
-        /** whether to throw on problems */
-        public OsCredential throwOnErrors(boolean throwOnErrors) {
-            this.throwOnErrors = throwOnErrors;
-            return dirty(); 
-        }
-        
-        private OsCredential dirty() { dirty = true; return this; }
-            
-        public static OsCredential newInstance(ConfigBag config) {
-            return new OsCredential(config);
-        }
-        
-        private synchronized void infer() {
-            if (!dirty) return;
-            warningMessages.clear(); 
-            
-            log.debug("Inferring OS credentials");
-            privateKeyData = config.get(LocationConfigKeys.PRIVATE_KEY_DATA);
-            password = config.get(LocationConfigKeys.PASSWORD);
-            publicKeyData = getKeyDataFromDataKeyOrFileKey(config, LocationConfigKeys.PUBLIC_KEY_DATA, LocationConfigKeys.PUBLIC_KEY_FILE);
-
-            KeyPair privateKey = null;
-            
-            if (Strings.isBlank(privateKeyData)) {
-                // look up private key files
-                String privateKeyFiles = null;
-                boolean privateKeyFilesExplicitlySet = config.containsKey(LocationConfigKeys.PRIVATE_KEY_FILE);
-                if (privateKeyFilesExplicitlySet || (tryDefaultKeys && password==null)) 
-                    privateKeyFiles = config.get(LocationConfigKeys.PRIVATE_KEY_FILE);
-                if (Strings.isNonBlank(privateKeyFiles)) {
-                    Iterator<String> fi = Arrays.asList(privateKeyFiles.split(File.pathSeparator)).iterator();
-                    while (fi.hasNext()) {
-                        String file = fi.next();
-                        if (Strings.isNonBlank(file)) {
-                            try {
-                                // real URL's won't actual work, due to use of path separator above 
-                                // not real important, but we get it for free if "files" is a list instead.
-                                // using ResourceUtils is useful for classpath resources
-                                if (file!=null)
-                                    privateKeyData = ResourceUtils.create().getResourceAsString(file);
-                                // else use data already set
-                                
-                                privateKey = getValidatedPrivateKey(file);
-                                
-                                if (privateKeyData==null) {
-                                    // was cleared due to validation error
-                                } else if (Strings.isNonBlank(publicKeyData)) {
-                                    log.debug("Loaded private key data from "+file+" (public key data explicitly set)");
-                                    break;
-                                } else {
-                                    String publicKeyFile = (file!=null ? file+".pub" : "(data)");
-                                    try {
-                                        publicKeyData = ResourceUtils.create().getResourceAsString(publicKeyFile);
-                                        
-                                        log.debug("Loaded private key data from "+file+
-                                            " and public key data from "+publicKeyFile);
-                                        break;
-                                    } catch (Exception e) {
-                                        Exceptions.propagateIfFatal(e);
-                                        log.debug("No public key file "+publicKeyFile+"; will try extracting from private key");
-                                        publicKeyData = AuthorizedKeysParser.encodePublicKey(privateKey.getPublic());
-                                        
-                                        if (publicKeyData==null) {
-                                            if (requirePublicKey) {
-                                                addWarning("Unable to find or extract public key for "+file, "skipping");
-                                            } else {
-                                                log.debug("Loaded private key data from "+file+" (public key data not found but not required)");
-                                                break;
-                                            }
-                                        } else {
-                                            log.debug("Loaded private key data from "+file+" (public key data extracted)");
-                                            break;
-                                        }
-                                        privateKeyData = null;
-                                    }
-                                }
-
-                            } catch (Exception e) {
-                                Exceptions.propagateIfFatal(e);
-                                String message = "Missing/invalid private key file "+file;
-                                if (privateKeyFilesExplicitlySet) addWarning(message, (!fi.hasNext() ? "no more files to try" : "trying next file")+": "+e);
-                            }
-                        }
-                    }
-                    if (privateKeyFilesExplicitlySet && Strings.isBlank(privateKeyData))
-                        error("No valid private keys found", ""+warningMessages);
-                }
-            } else {
-                privateKey = getValidatedPrivateKey("(data)");
-            }
-            
-            if (privateKeyData!=null) {
-                if (requirePublicKey && Strings.isBlank(publicKeyData)) {
-                    if (privateKey!=null) {
-                        publicKeyData = AuthorizedKeysParser.encodePublicKey(privateKey.getPublic());
-                    }
-                    if (Strings.isBlank(publicKeyData)) {
-                        error("If explicit "+LocationConfigKeys.PRIVATE_KEY_DATA.getName()+" is supplied, then "
-                            + "the corresponding "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" must also be supplied.", null);
-                    } else {
-                        log.debug("Public key data extracted");
-                    }
-                }
-                if (doKeyValidation && privateKey!=null && privateKey.getPublic()!=null && Strings.isNonBlank(publicKeyData)) {
-                    PublicKey decoded = null;
-                    try {
-                        decoded = AuthorizedKeysParser.decodePublicKey(publicKeyData);
-                    } catch (Exception e) {
-                        Exceptions.propagateIfFatal(e);
-                        addWarning("Invalid public key: "+decoded);
-                    }
-                    if (decoded!=null && !privateKey.getPublic().equals( decoded )) {
-                        error("Public key inferred from does not match public key extracted from private key", null);
-                    }
-                }
-            }
-
-            log.debug("OS credential inference: "+this);
-            dirty = false;
-        }
-
-        private KeyPair getValidatedPrivateKey(String label) {
-            KeyPair privateKey = null;
-            String passphrase = config.get(CloudLocationConfig.PRIVATE_KEY_PASSPHRASE);
-            try {
-                privateKey = SecureKeys.readPem(new ByteArrayInputStream(privateKeyData.getBytes()), passphrase);
-                if (passphrase!=null) {
-                    // get the unencrypted key data for our internal use (jclouds requires this)
-                    privateKeyData = SecureKeys.toPem(privateKey);
-                }
-            } catch (PassphraseProblem e) {
-                if (doKeyValidation) {
-                    log.debug("Encountered error handling key "+label+": "+e, e);
-                    if (Strings.isBlank(passphrase))
-                        addWarning("Passphrase required for key '"+label+"'");
-                    else
-                        addWarning("Invalid passphrase for key '"+label+"'");
-                    privateKeyData = null;
-                }
-            } catch (Exception e) {
-                Exceptions.propagateIfFatal(e);
-                if (doKeyValidation) {
-                    addWarning("Unable to parse private key from '"+label+"': unknown format");
-                    privateKeyData = null;
-                }
-            }
-            return privateKey;
-        }
-        
-        Set<String> warningMessages = MutableSet.of();
-        
-        private void error(String msg, String logExtension) {
-            addWarning(msg);
-            if (warnOnErrors) log.warn(msg+(logExtension==null ? "" : ": "+logExtension));
-            if (throwOnErrors) throw new IllegalStateException(msg+(logExtension==null ? "" : "; "+logExtension));
-        }
-
-        private void addWarning(String msg) {
-            addWarning(msg, null);
-        }
-        private void addWarning(String msg, String debugExtension) {
-            log.debug(msg+(debugExtension==null ? "" : "; "+debugExtension));
-            warningMessages.add(msg);
-        }
-
-        @Override
-        public String toString() {
-            return getClass().getSimpleName()+"["+
-                (Strings.isNonBlank(publicKeyData) ? publicKeyData : "no-public-key")+";"+
-                (Strings.isNonBlank(privateKeyData) ? "private-key-present" : "no-private-key")+","+
-                (password!=null ? "password(len="+password.length()+")" : "no-password")+"]";
-        }
-    }
-
-    /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated
-    public static String getPrivateKeyData(ConfigBag config) {
-        return getKeyData(config, LocationConfigKeys.PRIVATE_KEY_DATA, LocationConfigKeys.PRIVATE_KEY_FILE);
-    }
-    
-    /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated
-    public static String getPublicKeyData(ConfigBag config) {
-        String data = getKeyData(config, LocationConfigKeys.PUBLIC_KEY_DATA, LocationConfigKeys.PUBLIC_KEY_FILE);
-        if (groovyTruth(data)) return data;
-        
-        String privateKeyFile = config.get(LocationConfigKeys.PRIVATE_KEY_FILE);
-        if (groovyTruth(privateKeyFile)) {
-            List<String> privateKeyFiles = Arrays.asList(privateKeyFile.split(File.pathSeparator));
-            List<String> publicKeyFiles = ImmutableList.copyOf(Iterables.transform(privateKeyFiles, StringFunctions.append(".pub")));
-            List<String> publicKeyFilesTidied = tidyFilePaths(publicKeyFiles);
-            
-            String fileData = getFileContents(publicKeyFilesTidied);
-            if (groovyTruth(fileData)) {
-                if (log.isDebugEnabled()) log.debug("Loaded "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" from inferred files, based on "+LocationConfigKeys.PRIVATE_KEY_FILE.getName() + ": used " + publicKeyFilesTidied + " for "+config.getDescription());
-                config.put(LocationConfigKeys.PUBLIC_KEY_DATA, fileData);
-                return fileData;
-            } else {
-                log.info("Not able to load "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" from inferred files, based on "+LocationConfigKeys.PRIVATE_KEY_FILE.getName() + ": tried " + publicKeyFilesTidied + " for "+config.getDescription());
-            }
-        }
-        
-        return null;
-    }
-
-    /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated
-    public static String getKeyData(ConfigBag config, ConfigKey<String> dataKey, ConfigKey<String> fileKey) {
-        return getKeyDataFromDataKeyOrFileKey(config, dataKey, fileKey);
-    }
-    
-    private static String getKeyDataFromDataKeyOrFileKey(ConfigBag config, ConfigKey<String> dataKey, ConfigKey<String> fileKey) {
-        boolean unused = config.isUnused(dataKey);
-        String data = config.get(dataKey);
-        if (groovyTruth(data) && !unused) {
-            return data;
-        }
-        
-        String file = config.get(fileKey);
-        if (groovyTruth(file)) {
-            List<String> files = Arrays.asList(file.split(File.pathSeparator));
-            List<String> filesTidied = tidyFilePaths(files);
-            String fileData = getFileContents(filesTidied);
-            if (fileData == null) {
-                log.warn("Invalid file" + (files.size() > 1 ? "s" : "") + " for " + fileKey + " (given " + files + 
-                        (files.equals(filesTidied) ? "" : "; converted to " + filesTidied) + ") " +
-                        "may fail provisioning " + config.getDescription());
-            } else if (groovyTruth(data)) {
-                if (!fileData.trim().equals(data.trim()))
-                    log.warn(dataKey.getName()+" and "+fileKey.getName()+" both specified; preferring the former");
-            } else {
-                data = fileData;
-                config.put(dataKey, data);
-                config.get(dataKey);
-            }
-        }
-        
-        return data;
-    }
-    
-    /**
-     * Reads the given file(s) in-order, returning the contents of the first file that can be read.
-     * Returns the file contents, or null if none of the files can be read.
-     *  
-     * @param files             list of file paths
-     */
-    private static String getFileContents(Iterable<String> files) {
-        Iterator<String> fi = files.iterator();
-        while (fi.hasNext()) {
-            String file = fi.next();
-            if (groovyTruth(file)) {
-                try {
-                    // see comment above
-                    String result = ResourceUtils.create().getResourceAsString(file);
-                    if (result!=null) return result;
-                    log.debug("Invalid file "+file+" ; " + (!fi.hasNext() ? "no more files to try" : "trying next file")+" (null)");
-                } catch (Exception e) {
-                    Exceptions.propagateIfFatal(e);
-                    log.debug("Invalid file "+file+" ; " + (!fi.hasNext() ? "no more files to try" : "trying next file"), e);
-                }
-            }
-        }
-        return null;
-    }
-
-    private static List<String> tidyFilePaths(Iterable<String> files) {
-        List<String> result = Lists.newArrayList();
-        for (String file : files) {
-            result.add(Os.tidyPath(file));
-        }
-        return result;
-    }
-
-    /** @deprecated since 0.6.0 use configBag.getWithDeprecation */
-    @Deprecated
-    @SuppressWarnings("unchecked")
-    public static <T> T getConfigCheckingDeprecatedAlternatives(ConfigBag configBag, ConfigKey<T> preferredKey,
-            ConfigKey<?> ...deprecatedKeys) {
-        T value1 = (T) configBag.getWithDeprecation(preferredKey, deprecatedKeys);
-        T value2 = getConfigCheckingDeprecatedAlternativesInternal(configBag, preferredKey, deprecatedKeys);
-        if (!Objects.equal(value1, value2)) {
-            // points to a bug in one of the get-with-deprecation methods
-            log.warn("Deprecated getConfig with deprecated keys "+Arrays.toString(deprecatedKeys)+" gets different value with " +
-                    "new strategy "+preferredKey+" ("+value1+") and old ("+value2+"); preferring old value for now, but this behaviour will change");
-            return value2;
-        }
-        return value1;
-    }
-    
-    @SuppressWarnings("unchecked")
-    private static <T> T getConfigCheckingDeprecatedAlternativesInternal(ConfigBag configBag, ConfigKey<T> preferredKey,
-            ConfigKey<?> ...deprecatedKeys) {
-        ConfigKey<?> keyProvidingValue = null;
-        T value = null;
-        boolean found = false;
-        if (configBag.containsKey(preferredKey)) {
-            value = configBag.get(preferredKey);
-            found = true;
-            keyProvidingValue = preferredKey;
-        }
-        
-        for (ConfigKey<?> deprecatedKey: deprecatedKeys) {
-            T altValue = null;
-            boolean altFound = false;
-            if (configBag.containsKey(deprecatedKey)) {
-                altValue = (T) configBag.get(deprecatedKey);
-                altFound = true;
-                
-                if (altFound) {
-                    if (found) {
-                        if (Objects.equal(value, altValue)) {
-                            // fine -- nothing
-                        } else {
-                            log.warn("Detected deprecated key "+deprecatedKey+" with value "+altValue+" used in addition to "+keyProvidingValue+" " +
-                                    "with value "+value+" for "+configBag.getDescription()+"; ignoring");
-                            configBag.remove(deprecatedKey);
-                        }
-                    } else {
-                        log.warn("Detected deprecated key "+deprecatedKey+" with value "+altValue+" used instead of recommended "+preferredKey+"; " +
-                                "promoting to preferred key status; will not be supported in future versions");
-                        configBag.put(preferredKey, altValue);
-                        configBag.remove(deprecatedKey);
-                        value = altValue;
-                        found = true;
-                        keyProvidingValue = deprecatedKey;
-                    }
-                }
-            }
-        }
-        
-        if (found) {
-            return value;
-        } else {
-            return configBag.get(preferredKey); // get the default
-        }
-    }
-
-    public static Map<ConfigKey<String>,String> finalAndOriginalSpecs(String finalSpec, Object ...sourcesForOriginalSpec) {
-        // yuck!: TODO should clean up how these things get passed around
-        Map<ConfigKey<String>,String> result = MutableMap.of();
-        if (finalSpec!=null) 
-            result.put(LocationInternal.FINAL_SPEC, finalSpec);
-        
-        String originalSpec = null;
-        for (Object source: sourcesForOriginalSpec) {
-            if (source instanceof CharSequence) originalSpec = source.toString();
-            else if (source instanceof Map) {
-                if (originalSpec==null) originalSpec = Strings.toString( ((Map<?,?>)source).get(LocationInternal.ORIGINAL_SPEC) );
-                if (originalSpec==null) originalSpec = Strings.toString( ((Map<?,?>)source).get(LocationInternal.ORIGINAL_SPEC.getName()) );
-            }
-            if (originalSpec!=null) break; 
-        }
-        if (originalSpec==null) originalSpec = finalSpec;
-        if (originalSpec!=null)
-            result.put(LocationInternal.ORIGINAL_SPEC, originalSpec);
-        
-        return result;
-    }
-
-    public static boolean isEnabled(ManagementContext mgmt, String prefix) {
-        ConfigKey<Boolean> key = ConfigKeys.newConfigKeyWithPrefix(prefix+".", LocationConfigKeys.ENABLED);
-        Boolean enabled = mgmt.getConfig().getConfig(key);
-        if (enabled!=null) return enabled.booleanValue();
-        return true;
-    }
-    
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocationDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocationDynamicType.java b/core/src/main/java/brooklyn/location/basic/LocationDynamicType.java
deleted file mode 100644
index cc0b304..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocationDynamicType.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import brooklyn.basic.BrooklynDynamicType;
-import brooklyn.location.Location;
-import brooklyn.location.LocationType;
-
-public class LocationDynamicType extends BrooklynDynamicType<Location, AbstractLocation> {
-
-    public LocationDynamicType(AbstractLocation location) {
-        super(location);
-    }
-    
-    public LocationType getSnapshot() {
-        return (LocationType) super.getSnapshot();
-    }
-
-    @Override
-    protected LocationTypeSnapshot newSnapshot() {
-        return new LocationTypeSnapshot(name, value(configKeys));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/LocationInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/LocationInternal.java b/core/src/main/java/brooklyn/location/basic/LocationInternal.java
deleted file mode 100644
index e846cd3..0000000
--- a/core/src/main/java/brooklyn/location/basic/LocationInternal.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.rebind.RebindSupport;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.mementos.LocationMemento;
-
-import brooklyn.basic.BrooklynObjectInternal;
-import brooklyn.config.ConfigInheritance;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.Location;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Information about locations private to Brooklyn.
- */
-public interface LocationInternal extends BrooklynObjectInternal, Location {
-
-    @Beta
-    public static final ConfigKey<String> ORIGINAL_SPEC = ConfigKeys.newStringConfigKey("spec.original", "The original spec used to instantiate a location");
-    @Beta
-    public static final ConfigKey<String> FINAL_SPEC = ConfigKeys.newStringConfigKey("spec.final", "The actual spec (in a chain) which instantiates a location");
-    @Beta
-    public static final ConfigKey<String> NAMED_SPEC_NAME = ConfigKeys.newStringConfigKey("spec.named.name", "The name on the (first) named spec in a chain");
-    
-    /**
-     * Registers the given extension for the given type. If an extension already existed for
-     * this type, then this will override it.
-     * 
-     * @throws NullPointerException if extensionType or extension are null
-     * @throws IllegalArgumentException if extension does not implement extensionType
-     */
-    <T> void addExtension(Class<T> extensionType, T extension);
-
-    /**
-     * Get a record of the metadata of this location.
-     * <p/>
-     * <p>Metadata records are used to record an audit trail of events relating to location usage
-     * (for billing purposes, for example). Implementations (and subclasses) should override this
-     * method to return information useful for this purpose.</p>
-     *
-     * @return
-     */
-    public Map<String, String> toMetadataRecord();
-
-    /**
-     * @deprecated since 0.7.0; use {@link #config()}, such as {@code ((LocationInternal)location).config().getLocalBag()}
-     */
-    @Deprecated
-    ConfigBag getLocalConfigBag();
-
-    /**
-     * Returns all config, including that inherited from parents.
-     * 
-     * This method does not respect {@link ConfigInheritance} and so usage is discouraged.
-     * 
-     * @deprecated since 0.7.0; use {@link #config()}, such as {@code ((LocationInternal)location).config().getBag()}
-     */
-    @Deprecated
-    ConfigBag getAllConfigBag();
-
-    /**
-     * Users are strongly discouraged from calling or overriding this method.
-     * It is for internal calls only, relating to persisting/rebinding entities.
-     * This method may change (or be removed) in a future release without notice.
-     */
-    @Override
-    @Beta
-    RebindSupport<LocationMemento> getRebindSupport();
-    
-    ManagementContext getManagementContext();
-}


[42/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/access/PortForwardManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/access/PortForwardManager.java b/core/src/main/java/brooklyn/location/access/PortForwardManager.java
deleted file mode 100644
index 71c3974..0000000
--- a/core/src/main/java/brooklyn/location/access/PortForwardManager.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.Location;
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.net.HostAndPort;
-
-import java.util.Collection;
-
-/**
- * Acts as a registry for existing port mappings (e.g. the public endpoints for accessing specific
- * ports on private VMs). This could be using DNAT, or iptables port-forwarding, or Docker port-mapping 
- * via the host, or any other port mapping approach.
- * 
- * Also controls the allocation of ports via {@link #acquirePublicPort(String)}
- * (e.g. for port-mapping with DNAT, then which port to use for the public side).
- * 
- * Implementations typically will not know anything about what the firewall/IP actually is, they just 
- * handle a unique identifier for it.
- * 
- * To use, see {@link PortForwardManagerLocationResolver}, with code such as 
- * {@code managementContext.getLocationRegistry().resolve("portForwardManager(scope=global)")}.
- * 
- * @see PortForwardManagerImpl for implementation notes and considerations.
- */
-@Beta
-public interface PortForwardManager extends Location {
-
-    @Beta
-    class AssociationMetadata {
-        private final String publicIpId;
-        private final HostAndPort publicEndpoint;
-        private final Location location;
-        private final int privatePort;
-
-        /**
-         * Users are discouraged from calling this constructor; the signature may change in future releases.
-         * Instead, instances will be created automatically by Brooklyn to be passed to the
-         * {@link AssociationListener#onAssociationCreated(AssociationMetadata)} method.
-         */
-        public AssociationMetadata(String publicIpId, HostAndPort publicEndpoint, Location location, int privatePort) {
-            this.publicIpId = publicIpId;
-            this.publicEndpoint = publicEndpoint;
-            this.location = location;
-            this.privatePort = privatePort;
-        }
-
-        public String getPublicIpId() {
-            return publicIpId;
-        }
-
-        public HostAndPort getPublicEndpoint() {
-            return publicEndpoint;
-        }
-
-        public Location getLocation() {
-            return location;
-        }
-
-        public int getPrivatePort() {
-            return privatePort;
-        }
-
-        public String toString() {
-            return Objects.toStringHelper(this)
-                    .add("publicIpId", publicIpId)
-                    .add("publicEndpoint", publicEndpoint)
-                    .add("location", location)
-                    .add("privatePort", privatePort)
-                    .toString();
-        }
-    }
-
-    @Beta
-    interface AssociationListener {
-        void onAssociationCreated(AssociationMetadata metadata);
-        void onAssociationDeleted(AssociationMetadata metadata);
-    }
-
-    /**
-     * The intention is that there is one PortForwardManager instance per "scope". If you 
-     * use global, then it will be a shared instance (for that management context). If you 
-     * pass in your own name (e.g. "docker-fjie3") then it will shared with just any other
-     * places that use that same location spec (e.g. {@code portForwardManager(scope=docker-fjie3)}).
-     */
-    // TODO Note: using name "scope" rather than "brooklyn.portForwardManager.scope" so that location spec 
-    // "portForwardManager(scope=global)" works, rather than having to do 
-    // portForwardManager(brooklyn.portForwardManager.scope=global).
-    // The config being read by the PortForwardManagerLocationResolver doesn't respect @SetFromFlag("scope").
-    public static final ConfigKey<String> SCOPE = ConfigKeys.newStringConfigKey(
-            "scope",
-            "The scope that this applies to, defaulting to global",
-            "global");
-
-    @Beta
-    public static final ConfigKey<Integer> PORT_FORWARD_MANAGER_STARTING_PORT = ConfigKeys.newIntegerConfigKey(
-            "brooklyn.portForwardManager.startingPort",
-            "The starting port for assigning port numbers, such as for DNAT",
-            11000);
-
-    public String getScope();
-
-    /**
-     * Reserves a unique public port on the given publicIpId.
-     * <p>
-     * Often followed by {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
-     * to enable {@link #lookup(String, int)} or {@link #lookup(Location, int)} respectively.
-     */
-    public int acquirePublicPort(String publicIpId);
-
-    /**
-     * Records a location and private port against a public endpoint (ip and port),
-     * to support {@link #lookup(Location, int)}.
-     * <p>
-     * Superfluous if {@link #acquirePublicPort(String, Location, int)} was used,
-     * but strongly recommended if {@link #acquirePublicPortExplicit(String, int)} was used
-     * e.g. if the location is not known ahead of time.
-     */
-    public void associate(String publicIpId, HostAndPort publicEndpoint, Location l, int privatePort);
-
-    /**
-     * Records a mapping for publicIpId:privatePort to a public endpoint, such that it can
-     * subsequently be looked up using {@link #lookup(String, int)}.
-     */
-    public void associate(String publicIpId, HostAndPort publicEndpoint, int privatePort);
-
-    /**
-     * Registers a listener, which will be notified each time a new port mapping is associated. See {@link #associate(String, HostAndPort, int)}
-     * and {@link #associate(String, HostAndPort, Location, int)}.
-     */
-    @Beta
-    public void addAssociationListener(AssociationListener listener, Predicate<? super AssociationMetadata> filter);
-
-    @Beta
-    public void removeAssociationListener(AssociationListener listener);
-    
-    /**
-     * Returns the public ip hostname and public port for use contacting the given endpoint.
-     * <p>
-     * Will return null if:
-     * <ul>
-     * <li>No publicPort is associated with this location and private port.
-     * <li>No publicIpId is associated with this location and private port.
-     * <li>No publicIpHostname is recorded against the associated publicIpId.
-     * </ul>
-     * Conceivably this may have to be access-location specific.
-     *
-     * @see #recordPublicIpHostname(String, String)
-     */
-    public HostAndPort lookup(Location l, int privatePort);
-
-    /**
-     * Returns the public endpoint (host and port) for use contacting the given endpoint.
-     * 
-     * Expects a previous call to {@link #associate(String, HostAndPort, int)}, to register
-     * the endpoint.
-     * 
-     * Will return null if there has not been a public endpoint associated with this pairing.
-     */
-    public HostAndPort lookup(String publicIpId, int privatePort);
-
-    /** 
-     * Clears the given port mapping, returning true if there was a match.
-     */
-    public boolean forgetPortMapping(String publicIpId, int publicPort);
-    
-    /** 
-     * Clears the port mappings associated with the given location, returning true if there were any matches.
-     */
-    public boolean forgetPortMappings(Location location);
-    
-    /** 
-     * Clears the port mappings associated with the given publicIpId, returning true if there were any matches.
-     */
-    public boolean forgetPortMappings(String publicIpId);
-    
-    public String toVerboseString();
-
-    
-    ///////////////////////////////////////////////////////////////////////////////////
-    // Deprecated
-    ///////////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Reserves a unique public port for the purpose of forwarding to the given target,
-     * associated with a given location for subsequent lookup purpose.
-     * <p>
-     * If already allocated, returns the previously allocated.
-     * 
-     * @deprecated since 0.7.0; use {@link #acquirePublicPort(String)}, and then use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
-     */
-    @Deprecated
-    public int acquirePublicPort(String publicIpId, Location l, int privatePort);
-
-    /** 
-     * Returns old mapping if it existed, null if it is new.
-     * 
-     * @deprecated since 0.7.0; use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
-     */
-    @Deprecated
-    public PortMapping acquirePublicPortExplicit(String publicIpId, int port);
-
-    /**
-     * Records a location and private port against a publicIp and public port,
-     * to support {@link #lookup(Location, int)}.
-     * <p>
-     * Superfluous if {@link #acquirePublicPort(String, Location, int)} was used,
-     * but strongly recommended if {@link #acquirePublicPortExplicit(String, int)} was used
-     * e.g. if the location is not known ahead of time.
-     * 
-     * @deprecated Use {@link #associate(String, HostAndPort, Location, int)}
-     */
-    @Deprecated
-    public void associate(String publicIpId, int publicPort, Location l, int privatePort);
-
-    /**
-     * Records a public hostname or address to be associated with the given publicIpId for lookup purposes.
-     * <p>
-     * Conceivably this may have to be access-location specific.
-     * 
-     * @deprecated Use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
-     */
-    @Deprecated
-    public void recordPublicIpHostname(String publicIpId, String hostnameOrPublicIpAddress);
-
-    /**
-     * Returns a recorded public hostname or address.
-     * 
-     * @deprecated Use {@link #lookup(String, int)} or {@link #lookup(Location, int)}
-     */
-    @Deprecated
-    public String getPublicIpHostname(String publicIpId);
-    
-    /**
-     * Clears a previous call to {@link #recordPublicIpHostname(String, String)}.
-     * 
-     * @deprecated Use {@link #forgetPortMapping(String, int)} or {@link #forgetPortMappings(Location)}
-     */
-    @Deprecated
-    public boolean forgetPublicIpHostname(String publicIpId);
-
-    /**
-     * Returns true if this implementation is a client which is immutable/safe for serialization
-     * i.e. it delegates to something on an entity or location elsewhere.
-     * 
-     * @deprecated since 0.7.0; no need to separate client-proxy from impl
-     */
-    @Deprecated
-    public boolean isClient();
-    
-
-    ///////////////////////////////////////////////////////////////////////////////////
-    // Deprecated; just internal
-    ///////////////////////////////////////////////////////////////////////////////////
-
-    /** 
-     * Returns the port mapping for a given publicIpId and public port.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Deprecated
-    public PortMapping getPortMappingWithPublicSide(String publicIpId, int publicPort);
-
-    /** 
-     * Returns the subset of port mappings associated with a given public IP ID.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Deprecated
-    public Collection<PortMapping> getPortMappingWithPublicIpId(String publicIpId);
-
-    /** 
-     * @see {@link #forgetPortMapping(String, int)} and {@link #forgetPortMappings(Location)}
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Deprecated
-    public boolean forgetPortMapping(PortMapping m);
-
-    /**
-     * Returns the public host and port for use accessing the given mapping.
-     * <p>
-     * Conceivably this may have to be access-location specific.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Deprecated
-    public HostAndPort getPublicHostAndPort(PortMapping m);
-
-    /** 
-     * Returns the subset of port mappings associated with a given location.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Deprecated
-    public Collection<PortMapping> getLocationPublicIpIds(Location l);
-        
-    /** 
-     * Returns the mapping to a given private port, or null if none.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Deprecated
-    public PortMapping getPortMappingWithPrivateSide(Location l, int privatePort);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/access/PortForwardManagerAuthority.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/access/PortForwardManagerAuthority.java b/core/src/main/java/brooklyn/location/access/PortForwardManagerAuthority.java
deleted file mode 100644
index 796328d..0000000
--- a/core/src/main/java/brooklyn/location/access/PortForwardManagerAuthority.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-
-import org.apache.brooklyn.api.entity.Entity;
-
-import brooklyn.entity.basic.EntityInternal;
-
-/**
- * @deprecated since 0.7.0; use {@link PortForwardManagerImpl}
- */
-@Deprecated
-public class PortForwardManagerAuthority extends PortForwardManagerImpl {
-    private Entity owningEntity;
-
-    public PortForwardManagerAuthority() {
-    }
-
-    public PortForwardManagerAuthority(Entity owningEntity) {
-        this.owningEntity = owningEntity;
-    }
-
-    protected void onChanged() {
-        if (owningEntity != null) {
-            ((EntityInternal) owningEntity).requestPersist();
-        } else {
-            super.onChanged();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/access/PortForwardManagerClient.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/access/PortForwardManagerClient.java b/core/src/main/java/brooklyn/location/access/PortForwardManagerClient.java
deleted file mode 100644
index 5013711..0000000
--- a/core/src/main/java/brooklyn/location/access/PortForwardManagerClient.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.event.AttributeSensor;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.location.Location;
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.net.HostAndPort;
-
-/**
- * @deprecated since 0.7.0; just use the {@link PortForwardManager}, or a direct reference to its impl {@link PortForwardManagerImpl}
- */
-@Deprecated
-public class PortForwardManagerClient implements PortForwardManager {
-
-    private static final long serialVersionUID = -295204304305332895L;
-    
-    protected final Supplier<PortForwardManager> delegateSupplier;
-    private transient volatile PortForwardManager _delegate;
-    
-    protected PortForwardManagerClient(Supplier<PortForwardManager> supplier) {
-        this.delegateSupplier = supplier;
-    }
-    
-    /** creates an instance given a supplier; 
-     * the supplier should be brooklyn-persistable, that is to say
-     * references should be in terms of entities/locations 
-     * which can retrieve an authoritative source even under cloning */
-    public static PortForwardManager fromSupplier(Supplier<PortForwardManager> supplier) {
-        return new PortForwardManagerClient(supplier);
-    }
-
-    /** creates an instance given an entity and an interface method it implements to retrieve the PortForwardManager */ 
-    public static PortForwardManager fromMethodOnEntity(final Entity entity, final String getterMethodOnEntity) {
-        Preconditions.checkNotNull(entity);
-        Preconditions.checkNotNull(getterMethodOnEntity);
-        return new PortForwardManagerClient(new Supplier<PortForwardManager>() {
-            @Override
-            public PortForwardManager get() {
-                PortForwardManager result;
-                try {
-                    result = (PortForwardManager) entity.getClass().getMethod(getterMethodOnEntity).invoke(entity);
-                } catch (Exception e) {
-                    Exceptions.propagateIfFatal(e);
-                    throw new IllegalStateException("Cannot invoke "+getterMethodOnEntity+" on "+entity+" ("+entity.getClass()+"): "+e, e);
-                }
-                if (result==null)
-                    throw new IllegalStateException("No PortForwardManager available via "+getterMethodOnEntity+" on "+entity+" (returned null)");
-                return result;
-            }
-        });
-    }
-
-    /** creates an instance given an entity and {@link AttributeSensor} to retrieve the PortForwardManager */ 
-    public static PortForwardManager fromAttributeOnEntity(final Entity entity, final AttributeSensor<PortForwardManager> attributeOnEntity) {
-        Preconditions.checkNotNull(entity);
-        Preconditions.checkNotNull(attributeOnEntity);
-        return new PortForwardManagerClient(new Supplier<PortForwardManager>() {
-            @Override
-            public PortForwardManager get() {
-                PortForwardManager result = entity.getAttribute(attributeOnEntity);
-                if (result==null)
-                    throw new IllegalStateException("No PortForwardManager available via "+attributeOnEntity+" on "+entity+" (returned null)");
-                return result;
-            }
-        });
-    }
-    
-    protected PortForwardManager getDelegate() {
-        if (_delegate==null) {
-            _delegate = delegateSupplier.get();
-        }
-        return _delegate;
-    }
-
-    @Override
-    public int acquirePublicPort(String publicIpId) {
-        return getDelegate().acquirePublicPort(publicIpId);
-    }
-
-    @Override
-    public void associate(String publicIpId, HostAndPort publicEndpoint, Location l, int privatePort) {
-        getDelegate().associate(publicIpId, publicEndpoint, l, privatePort);
-    }
-
-    @Override
-    public void associate(String publicIpId, HostAndPort publicEndpoint, int privatePort) {
-        getDelegate().associate(publicIpId, publicEndpoint, privatePort);
-    }
-
-    @Override
-    public HostAndPort lookup(Location l, int privatePort) {
-        return getDelegate().lookup(l, privatePort);
-    }
-
-    @Override
-    public HostAndPort lookup(String publicIpId, int privatePort) {
-        return getDelegate().lookup(publicIpId, privatePort);
-    }
-
-    @Override
-    public boolean forgetPortMapping(String publicIpId, int publicPort) {
-        return getDelegate().forgetPortMapping(publicIpId, publicPort);
-    }
-
-    @Override
-    public boolean forgetPortMappings(Location location) {
-        return getDelegate().forgetPortMappings(location);
-    }
-
-    @Override
-    public boolean forgetPortMappings(String publicIpId) {
-        return getDelegate().forgetPortMappings(publicIpId);
-    }
-
-    @Override
-    public String getId() {
-        return getDelegate().getId();
-    }
-
-    @Override
-    public String getScope() {
-        return getDelegate().getScope();
-    }
-
-    @Override
-    public void addAssociationListener(AssociationListener listener, Predicate<? super AssociationMetadata> filter) {
-        getDelegate().addAssociationListener(listener, filter);
-    }
-
-    @Override
-    public void removeAssociationListener(AssociationListener listener) {
-        getDelegate().removeAssociationListener(listener);
-    }
-
-    @Override
-    public String toVerboseString() {
-        return getClass().getName()+"[wrapping="+getDelegate().toVerboseString()+"]";
-    }
-
-    ///////////////////////////////////////////////////////////////////////////////////
-    // Deprecated
-    ///////////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Reserves a unique public port for the purpose of forwarding to the given target,
-     * associated with a given location for subsequent lookup purpose.
-     * <p>
-     * If already allocated, returns the previously allocated.
-     * 
-     * @deprecated since 0.7.0; use {@link #acquirePublicPort(String)}, and then use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
-     */
-    @Override
-    @Deprecated
-    public int acquirePublicPort(String publicIpId, Location l, int privatePort) {
-        return getDelegate().acquirePublicPort(publicIpId, l, privatePort);
-    }
-
-    /** 
-     * Returns old mapping if it existed, null if it is new.
-     * 
-     * @deprecated since 0.7.0; use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
-     */
-    @Override
-    @Deprecated
-    public PortMapping acquirePublicPortExplicit(String publicIpId, int publicPort) {
-        return getDelegate().acquirePublicPortExplicit(publicIpId, publicPort);
-    }
-
-    /**
-     * Records a location and private port against a publicIp and public port,
-     * to support {@link #lookup(Location, int)}.
-     * <p>
-     * Superfluous if {@link #acquirePublicPort(String, Location, int)} was used,
-     * but strongly recommended if {@link #acquirePublicPortExplicit(String, int)} was used
-     * e.g. if the location is not known ahead of time.
-     * 
-     * @deprecated Use {@link #associate(String, HostAndPort, Location, int)}
-     */
-    @Override
-    @Deprecated
-    public void associate(String publicIpId, int publicPort, Location l, int privatePort) {
-        getDelegate().associate(publicIpId, publicPort, l, privatePort);
-    }
-
-    /**
-     * Records a public hostname or address to be associated with the given publicIpId for lookup purposes.
-     * <p>
-     * Conceivably this may have to be access-location specific.
-     * 
-     * @deprecated Use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
-     */
-    @Override
-    @Deprecated
-    public void recordPublicIpHostname(String publicIpId, String hostnameOrPublicIpAddress) {
-        getDelegate().recordPublicIpHostname(publicIpId, hostnameOrPublicIpAddress);
-    }
-
-    /**
-     * Returns a recorded public hostname or address.
-     * 
-     * @deprecated Use {@link #lookup(String, int)} or {@link #lookup(Location, int)}
-     */
-    @Override
-    @Deprecated
-    public String getPublicIpHostname(String publicIpId) {
-        return getDelegate().getPublicIpHostname(publicIpId);
-    }
-    
-    /**
-     * Clears a previous call to {@link #recordPublicIpHostname(String, String)}.
-     * 
-     * @deprecated Use {@link #forgetPortMapping(String, int)} or {@link #forgetPortMapping(Location, int)}
-     */
-    @Override
-    @Deprecated
-    public boolean forgetPublicIpHostname(String publicIpId) {
-        return getDelegate().forgetPublicIpHostname(publicIpId);
-    }
-
-    @Override
-    @Deprecated
-    public boolean isClient() {
-        return true;
-    }
-
-
-    ///////////////////////////////////////////////////////////////////////////////////
-    // Deprecated; just internal
-    ///////////////////////////////////////////////////////////////////////////////////
-
-    /** 
-     * Returns the port mapping for a given publicIpId and public port.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Override
-    @Deprecated
-    public PortMapping getPortMappingWithPublicSide(String publicIpId, int publicPort) {
-        return getDelegate().getPortMappingWithPublicSide(publicIpId, publicPort);
-    }
-
-    /** 
-     * Returns the subset of port mappings associated with a given public IP ID.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Override
-    @Deprecated
-    public Collection<PortMapping> getPortMappingWithPublicIpId(String publicIpId) {
-        return getDelegate().getPortMappingWithPublicIpId(publicIpId);
-    }
-
-    /** 
-     * @see #forgetPortMapping(String, int)
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Override
-    @Deprecated
-    public boolean forgetPortMapping(PortMapping m) {
-        return getDelegate().forgetPortMapping(m);
-    }
-
-    /**
-     * Returns the public host and port for use accessing the given mapping.
-     * <p>
-     * Conceivably this may have to be access-location specific.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Override
-    @Deprecated
-    public HostAndPort getPublicHostAndPort(PortMapping m) {
-        return getDelegate().getPublicHostAndPort(m);
-    }
-
-    /** 
-     * Returns the subset of port mappings associated with a given location.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Override
-    @Deprecated
-    public Collection<PortMapping> getLocationPublicIpIds(Location l) {
-        return getDelegate().getLocationPublicIpIds(l);
-    }
-        
-    /** 
-     * Returns the mapping to a given private port, or null if none.
-     * 
-     * @deprecated since 0.7.0; this method will be internal only
-     */
-    @Override
-    @Deprecated
-    public PortMapping getPortMappingWithPrivateSide(Location l, int privatePort) {
-        return getDelegate().getPortMappingWithPrivateSide(l, privatePort);
-    }
-    
-    @Override
-    public String toString() {
-        return getClass().getName()+"[id="+getId()+"]";
-    }
-
-    @Override
-    public String getDisplayName() {
-        return getDelegate().getDisplayName();
-    }
-
-    @Override
-    public Location getParent() {
-        return getDelegate().getParent();
-    }
-
-    @Override
-    public Collection<Location> getChildren() {
-        return getDelegate().getChildren();
-    }
-
-    @Override
-    public void setParent(Location newParent) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean containsLocation(Location potentialDescendent) {
-        return getDelegate().containsLocation(potentialDescendent);
-    }
-
-    @Override
-    public <T> T getConfig(ConfigKey<T> key) {
-        return getDelegate().getConfig(key);
-    }
-
-    @Override
-    public <T> T getConfig(HasConfigKey<T> key) {
-        return getDelegate().getConfig(key);
-    }
-
-    @Override
-    public boolean hasConfig(ConfigKey<?> key, boolean includeInherited) {
-        return getDelegate().hasConfig(key, includeInherited);
-    }
-
-    @Override
-    public Map<String, Object> getAllConfig(boolean includeInherited) {
-        return getDelegate().getAllConfig(includeInherited);
-    }
-
-    @Override
-    public boolean hasExtension(Class<?> extensionType) {
-        return getDelegate().hasExtension(extensionType);
-    }
-
-    @Override
-    public <T> T getExtension(Class<T> extensionType) {
-        return getDelegate().getExtension(extensionType);
-    }
-
-    @Override
-    public String getCatalogItemId() {
-        return getDelegate().getCatalogItemId();
-    }
-
-    @Override
-    public TagSupport tags() {
-        return getDelegate().tags();
-    }
-
-    @Override
-    public <T> T setConfig(ConfigKey<T> key, T val) {
-        return getDelegate().setConfig(key, val);
-    }
-
-    @Override
-    public ConfigurationSupport config() {
-        return getDelegate().config();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java b/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java
deleted file mode 100644
index 75de91f..0000000
--- a/core/src/main/java/brooklyn/location/access/PortForwardManagerImpl.java
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.brooklyn.api.entity.rebind.RebindContext;
-import org.apache.brooklyn.api.entity.rebind.RebindSupport;
-import org.apache.brooklyn.mementos.LocationMemento;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.rebind.BasicLocationRebindSupport;
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.base.Objects.ToStringHelper;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.net.HostAndPort;
-
-/**
- * 
- * @author aled
- *
- * TODO This implementation is not efficient, and currently has a cap of about 50000 rules.
- * Need to improve the efficiency and scale.
- * A quick win could be to use a different portReserved counter for each publicIpId,
- * when calling acquirePublicPort?
- * 
- * TODO Callers need to be more careful in acquirePublicPort for which ports are actually in use.
- * If multiple apps sharing the same public-ip (e.g. in the same vcloud-director vOrg) then they 
- * must not allocate the same public port (e.g. ensure they share the same PortForwardManager
- * by using the same scope in 
- * {@code managementContext.getLocationRegistry().resolve("portForwardManager(scope=global)")}.
- * However, this still doesn't check if the port is *actually* available. For example, if a
- * different Brooklyn instance is also deploying there then we can get port conflicts, or if 
- * some ports in that range are already in use (e.g. due to earlier dev/test runs) then this
- * will not be respected. Callers should probably figure out the port number themselves, but
- * that also leads to concurrency issues.
- * 
- * TODO The publicIpId means different things to different callers:
- * <ul>
- *   <li> In acquirePublicPort() it is (often?) an identifier of the actual public ip.
- *   <li> In later calls to associate(), it is (often?) an identifier for the target machine
- *        such as the jcloudsMachine.getJcloudsId().
- * </ul>
- */
-@SuppressWarnings("serial")
-public class PortForwardManagerImpl extends AbstractLocation implements PortForwardManager {
-
-    private static final Logger log = LoggerFactory.getLogger(PortForwardManagerImpl.class);
-    
-    protected final Map<String,PortMapping> mappings = new LinkedHashMap<String,PortMapping>();
-
-    private final Map<AssociationListener, Predicate<? super AssociationMetadata>> associationListeners = new ConcurrentHashMap<AssociationListener, Predicate<? super AssociationMetadata>>();
-
-    @Deprecated
-    protected final Map<String,String> publicIpIdToHostname = new LinkedHashMap<String,String>();
-    
-    // horrible hack -- see javadoc above
-    private final AtomicInteger portReserved = new AtomicInteger(11000);
-
-    private final Object mutex = new Object();
-    
-    public PortForwardManagerImpl() {
-        super();
-        if (isLegacyConstruction()) {
-            log.warn("Deprecated construction of "+PortForwardManagerImpl.class.getName()+"; instead use location resolver");
-        }
-    }
-    
-    @Override
-    public void init() {
-        super.init();
-        Integer portStartingPoint;
-        Object rawPort = getAllConfigBag().getStringKey(PORT_FORWARD_MANAGER_STARTING_PORT.getName());
-        if (rawPort != null) {
-            portStartingPoint = getConfig(PORT_FORWARD_MANAGER_STARTING_PORT);
-        } else {
-            portStartingPoint = getManagementContext().getConfig().getConfig(PORT_FORWARD_MANAGER_STARTING_PORT);
-        }
-        portReserved.set(portStartingPoint);
-        log.debug(this+" set initial port to "+portStartingPoint);
-    }
-
-    // TODO Need to use attributes for these so they are persisted (once a location is an entity),
-    // rather than this deprecated approach of custom fields.
-    @Override
-    public RebindSupport<LocationMemento> getRebindSupport() {
-        return new BasicLocationRebindSupport(this) {
-            @Override public LocationMemento getMemento() {
-                Map<String, PortMapping> mappingsCopy;
-                Map<String,String> publicIpIdToHostnameCopy;
-                synchronized (mutex) {
-                    mappingsCopy = MutableMap.copyOf(mappings);
-                    publicIpIdToHostnameCopy = MutableMap.copyOf(publicIpIdToHostname);
-                }
-                return getMementoWithProperties(MutableMap.<String,Object>of(
-                        "mappings", mappingsCopy, 
-                        "portReserved", portReserved.get(), 
-                        "publicIpIdToHostname", publicIpIdToHostnameCopy));
-            }
-            @Override
-            protected void doReconstruct(RebindContext rebindContext, LocationMemento memento) {
-                super.doReconstruct(rebindContext, memento);
-                mappings.putAll( Preconditions.checkNotNull((Map<String, PortMapping>) memento.getCustomField("mappings"), "mappings was not serialized correctly"));
-                portReserved.set( (Integer)memento.getCustomField("portReserved"));
-                publicIpIdToHostname.putAll( Preconditions.checkNotNull((Map<String, String>)memento.getCustomField("publicIpIdToHostname"), "publicIpIdToHostname was not serialized correctly") );
-            }
-        };
-    }
-    
-    @Override
-    public int acquirePublicPort(String publicIpId) {
-        int port;
-        synchronized (mutex) {
-            // far too simple -- see javadoc above
-            port = getNextPort();
-            
-            // TODO When delete deprecated code, stop registering PortMapping until associate() is called
-            PortMapping mapping = new PortMapping(publicIpId, port, null, -1);
-            log.debug(this+" allocating public port "+port+" on "+publicIpId+" (no association info yet)");
-            
-            mappings.put(makeKey(publicIpId, port), mapping);
-        }
-        onChanged();
-        return port;
-    }
-
-    protected int getNextPort() {
-        // far too simple -- see javadoc above
-        return portReserved.getAndIncrement();
-    }
-    
-    @Override
-    public void associate(String publicIpId, HostAndPort publicEndpoint, Location l, int privatePort) {
-        associateImpl(publicIpId, publicEndpoint, l, privatePort);
-        emitAssociationCreatedEvent(publicIpId, publicEndpoint, l, privatePort);
-    }
-
-    @Override
-    public void associate(String publicIpId, HostAndPort publicEndpoint, int privatePort) {
-        associateImpl(publicIpId, publicEndpoint, null, privatePort);
-        emitAssociationCreatedEvent(publicIpId, publicEndpoint, null, privatePort);
-    }
-
-    protected void associateImpl(String publicIpId, HostAndPort publicEndpoint, Location l, int privatePort) {
-        synchronized (mutex) {
-            String publicIp = publicEndpoint.getHostText();
-            int publicPort = publicEndpoint.getPort();
-            recordPublicIpHostname(publicIpId, publicIp);
-            PortMapping mapping = new PortMapping(publicIpId, publicEndpoint, l, privatePort);
-            PortMapping oldMapping = getPortMappingWithPublicSide(publicIpId, publicPort);
-            log.debug(this+" associating public "+publicEndpoint+" on "+publicIpId+" with private port "+privatePort+" at "+l+" ("+mapping+")"
-                    +(oldMapping == null ? "" : " (overwriting "+oldMapping+" )"));
-            mappings.put(makeKey(publicIpId, publicPort), mapping);
-        }
-        onChanged();
-    }
-
-    private void emitAssociationCreatedEvent(String publicIpId, HostAndPort publicEndpoint, Location location, int privatePort) {
-        AssociationMetadata metadata = new AssociationMetadata(publicIpId, publicEndpoint, location, privatePort);
-        for (Map.Entry<AssociationListener, Predicate<? super AssociationMetadata>> entry : associationListeners.entrySet()) {
-            if (entry.getValue().apply(metadata)) {
-                try {
-                    entry.getKey().onAssociationCreated(metadata);
-                } catch (Exception e) {
-                    Exceptions.propagateIfFatal(e);
-                    log.warn("Exception thrown when emitting association creation event " + metadata, e);
-                }
-            }
-        }
-    }
-
-    @Override
-    public HostAndPort lookup(Location l, int privatePort) {
-        synchronized (mutex) {
-            for (PortMapping m: mappings.values()) {
-                if (l.equals(m.target) && privatePort == m.privatePort)
-                    return getPublicHostAndPort(m);
-            }
-        }
-        return null;
-    }
-    
-    @Override
-    public HostAndPort lookup(String publicIpId, int privatePort) {
-        synchronized (mutex) {
-            for (PortMapping m: mappings.values()) {
-                if (publicIpId.equals(m.publicIpId) && privatePort==m.privatePort)
-                    return getPublicHostAndPort(m);
-            }
-        }
-        return null;
-    }
-    
-    @Override
-    public boolean forgetPortMapping(String publicIpId, int publicPort) {
-        PortMapping old;
-        synchronized (mutex) {
-            old = mappings.remove(makeKey(publicIpId, publicPort));
-            if (old != null) {
-                emitAssociationDeletedEvent(associationMetadataFromPortMapping(old));
-            }
-            log.debug("cleared port mapping for "+publicIpId+":"+publicPort+" - "+old);
-        }
-        if (old != null) onChanged();
-        return (old != null);
-    }
-    
-    @Override
-    public boolean forgetPortMappings(Location l) {
-        List<PortMapping> result = Lists.newArrayList();
-        synchronized (mutex) {
-            for (Iterator<PortMapping> iter = mappings.values().iterator(); iter.hasNext();) {
-                PortMapping m = iter.next();
-                if (l.equals(m.target)) {
-                    iter.remove();
-                    result.add(m);
-                    emitAssociationDeletedEvent(associationMetadataFromPortMapping(m));
-                }
-            }
-        }
-        if (log.isDebugEnabled()) log.debug("cleared all port mappings for "+l+" - "+result);
-        if (!result.isEmpty()) {
-            onChanged();
-        }
-        return !result.isEmpty();
-    }
-    
-    @Override
-    public boolean forgetPortMappings(String publicIpId) {
-        List<PortMapping> result = Lists.newArrayList();
-        synchronized (mutex) {
-            for (Iterator<PortMapping> iter = mappings.values().iterator(); iter.hasNext();) {
-                PortMapping m = iter.next();
-                if (publicIpId.equals(m.publicIpId)) {
-                    iter.remove();
-                    result.add(m);
-                    emitAssociationDeletedEvent(associationMetadataFromPortMapping(m));
-                }
-            }
-        }
-        if (log.isDebugEnabled()) log.debug("cleared all port mappings for "+publicIpId+" - "+result);
-        if (!result.isEmpty()) {
-            onChanged();
-        }
-        return !result.isEmpty();
-    }
-
-    private void emitAssociationDeletedEvent(AssociationMetadata metadata) {
-        for (Map.Entry<AssociationListener, Predicate<? super AssociationMetadata>> entry : associationListeners.entrySet()) {
-            if (entry.getValue().apply(metadata)) {
-                try {
-                    entry.getKey().onAssociationDeleted(metadata);
-                } catch (Exception e) {
-                    Exceptions.propagateIfFatal(e);
-                    log.warn("Exception thrown when emitting association creation event " + metadata, e);
-                }
-            }
-        }
-    }
-    
-    @Override
-    protected ToStringHelper string() {
-        int size;
-        synchronized (mutex) {
-            size = mappings.size();
-        }
-        return super.string().add("scope", getScope()).add("mappingsSize", size);
-    }
-
-    @Override
-    public String toVerboseString() {
-        String mappingsStr;
-        synchronized (mutex) {
-            mappingsStr = mappings.toString();
-        }
-        return string().add("mappings", mappingsStr).toString();
-    }
-
-    @Override
-    public String getScope() {
-        return checkNotNull(getConfig(SCOPE), "scope");
-    }
-
-    @Override
-    public boolean isClient() {
-        return false;
-    }
-
-    @Override
-    public void addAssociationListener(AssociationListener listener, Predicate<? super AssociationMetadata> filter) {
-        associationListeners.put(listener, filter);
-    }
-
-    @Override
-    public void removeAssociationListener(AssociationListener listener) {
-        associationListeners.remove(listener);
-    }
-
-    protected String makeKey(String publicIpId, int publicPort) {
-        return publicIpId+":"+publicPort;
-    }
-
-    private AssociationMetadata associationMetadataFromPortMapping(PortMapping portMapping) {
-        String publicIpId = portMapping.getPublicEndpoint().getHostText();
-        HostAndPort publicEndpoint = portMapping.getPublicEndpoint();
-        Location location = portMapping.getTarget();
-        int privatePort = portMapping.getPrivatePort();
-        return new AssociationMetadata(publicIpId, publicEndpoint, location, privatePort);
-    }
-    
-    ///////////////////////////////////////////////////////////////////////////////////
-    // Internal state, for generating memento
-    ///////////////////////////////////////////////////////////////////////////////////
-
-    public List<PortMapping> getPortMappings() {
-        synchronized (mutex) {
-            return ImmutableList.copyOf(mappings.values());
-        }
-    }
-    
-    public Map<String, Integer> getPortCounters() {
-        return ImmutableMap.of("global", portReserved.get());
-    }
-
-    
-    ///////////////////////////////////////////////////////////////////////////////////
-    // Deprecated
-    ///////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    @Deprecated
-    public PortMapping acquirePublicPortExplicit(String publicIpId, int port) {
-        PortMapping mapping = new PortMapping(publicIpId, port, null, -1);
-        log.debug("assigning explicit public port "+port+" at "+publicIpId);
-        PortMapping result;
-        synchronized (mutex) {
-            result = mappings.put(makeKey(publicIpId, port), mapping);
-        }
-        onChanged();
-        return result;
-    }
-
-    @Override
-    @Deprecated
-    public boolean forgetPortMapping(PortMapping m) {
-        return forgetPortMapping(m.publicIpId, m.publicPort);
-    }
-
-    @Override
-    @Deprecated
-    public void recordPublicIpHostname(String publicIpId, String hostnameOrPublicIpAddress) {
-        log.debug("recording public IP "+publicIpId+" associated with "+hostnameOrPublicIpAddress);
-        synchronized (mutex) {
-            String old = publicIpIdToHostname.put(publicIpId, hostnameOrPublicIpAddress);
-            if (old!=null && !old.equals(hostnameOrPublicIpAddress))
-                log.warn("Changing hostname recorded against public IP "+publicIpId+"; from "+old+" to "+hostnameOrPublicIpAddress);
-        }
-        onChanged();
-    }
-
-    @Override
-    @Deprecated
-    public String getPublicIpHostname(String publicIpId) {
-        synchronized (mutex) {
-            return publicIpIdToHostname.get(publicIpId);
-        }
-    }
-    
-    @Override
-    @Deprecated
-    public boolean forgetPublicIpHostname(String publicIpId) {
-        log.debug("forgetting public IP "+publicIpId+" association");
-        boolean result;
-        synchronized (mutex) {
-            result = (publicIpIdToHostname.remove(publicIpId) != null);
-        }
-        onChanged();
-        return result;
-    }
-
-    @Override
-    @Deprecated
-    public int acquirePublicPort(String publicIpId, Location l, int privatePort) {
-        int publicPort;
-        synchronized (mutex) {
-            PortMapping old = getPortMappingWithPrivateSide(l, privatePort);
-            // only works for 1 public IP ID per location (which is the norm)
-            if (old!=null && old.publicIpId.equals(publicIpId)) {
-                log.debug("request to acquire public port at "+publicIpId+" for "+l+":"+privatePort+", reusing old assignment "+old);
-                return old.getPublicPort();
-            }
-            
-            publicPort = acquirePublicPort(publicIpId);
-            log.debug("request to acquire public port at "+publicIpId+" for "+l+":"+privatePort+", allocating "+publicPort);
-            associateImpl(publicIpId, publicPort, l, privatePort);
-        }
-        onChanged();
-        return publicPort;
-    }
-
-    @Override
-    @Deprecated
-    public void associate(String publicIpId, int publicPort, Location l, int privatePort) {
-        synchronized (mutex) {
-            associateImpl(publicIpId, publicPort, l, privatePort);
-        }
-        onChanged();
-    }
-
-    protected void associateImpl(String publicIpId, int publicPort, Location l, int privatePort) {
-        synchronized (mutex) {
-            PortMapping mapping = new PortMapping(publicIpId, publicPort, l, privatePort);
-            PortMapping oldMapping = getPortMappingWithPublicSide(publicIpId, publicPort);
-            log.debug("associating public port "+publicPort+" on "+publicIpId+" with private port "+privatePort+" at "+l+" ("+mapping+")"
-                    +(oldMapping == null ? "" : " (overwriting "+oldMapping+" )"));
-            mappings.put(makeKey(publicIpId, publicPort), mapping);
-        }
-    }
-
-    ///////////////////////////////////////////////////////////////////////////////////
-    // Internal only; make protected when deprecated interface method removed
-    ///////////////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public HostAndPort getPublicHostAndPort(PortMapping m) {
-        if (m.publicEndpoint == null) {
-            String hostname = getPublicIpHostname(m.publicIpId);
-            if (hostname==null)
-                throw new IllegalStateException("No public hostname associated with "+m.publicIpId+" (mapping "+m+")");
-            return HostAndPort.fromParts(hostname, m.publicPort);
-        } else {
-            return m.publicEndpoint;
-        }
-    }
-
-    @Override
-    public PortMapping getPortMappingWithPublicSide(String publicIpId, int publicPort) {
-        synchronized (mutex) {
-            return mappings.get(makeKey(publicIpId, publicPort));
-        }
-    }
-
-    @Override
-    public Collection<PortMapping> getPortMappingWithPublicIpId(String publicIpId) {
-        List<PortMapping> result = new ArrayList<PortMapping>();
-        synchronized (mutex) {
-            for (PortMapping m: mappings.values())
-                if (publicIpId.equals(m.publicIpId)) result.add(m);
-        }
-        return result;
-    }
-
-    /** returns the subset of port mappings associated with a given location */
-    @Override
-    public Collection<PortMapping> getLocationPublicIpIds(Location l) {
-        List<PortMapping> result = new ArrayList<PortMapping>();
-        synchronized (mutex) {
-            for (PortMapping m: mappings.values())
-                if (l.equals(m.getTarget())) result.add(m);
-        }
-        return result;
-    }
-
-    @Override
-    public PortMapping getPortMappingWithPrivateSide(Location l, int privatePort) {
-        synchronized (mutex) {
-            for (PortMapping m: mappings.values())
-                if (l.equals(m.getTarget()) && privatePort==m.privatePort) return m;
-        }
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/access/PortForwardManagerLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/access/PortForwardManagerLocationResolver.java b/core/src/main/java/brooklyn/location/access/PortForwardManagerLocationResolver.java
deleted file mode 100644
index e56d1c0..0000000
--- a/core/src/main/java/brooklyn/location/access/PortForwardManagerLocationResolver.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.AbstractLocationResolver;
-import brooklyn.location.basic.LocationConfigUtils;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.basic.LocationPredicates;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-
-public class PortForwardManagerLocationResolver extends AbstractLocationResolver {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PortForwardManagerLocationResolver.class);
-
-    public static final String PREFIX = "portForwardManager";
-
-    @Override
-    public String getPrefix() {
-        return PREFIX;
-    }
-
-    @Override
-    public Location newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        ConfigBag config = extractConfig(locationFlags, spec, registry);
-        Map globalProperties = registry.getProperties();
-        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
-        String scope = config.get(PortForwardManager.SCOPE);
-
-        Optional<Location> result = Iterables.tryFind(managementContext.getLocationManager().getLocations(), 
-                Predicates.and(
-                        Predicates.instanceOf(PortForwardManager.class), 
-                        LocationPredicates.configEqualTo(PortForwardManager.SCOPE, scope)));
-        
-        if (result.isPresent()) {
-            return result.get();
-        } else {
-            PortForwardManager loc = managementContext.getLocationManager().createLocation(LocationSpec.create(PortForwardManagerImpl.class)
-                    .configure(config.getAllConfig())
-                    .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
-            
-            if (LOG.isDebugEnabled()) LOG.debug("Created "+loc+" for scope "+scope);
-            return loc;
-        }
-    }
-
-    @Override
-    protected Class<? extends Location> getLocationType() {
-        return PortForwardManager.class;
-    }
-
-    @Override
-    protected SpecParser getSpecParser() {
-        return new AbstractLocationResolver.SpecParser(getPrefix()).setExampleUsage("\"portForwardManager\" or \"portForwardManager(scope=global)\"");
-    }
-    
-    @Override
-    protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        ConfigBag config = super.extractConfig(locationFlags, spec, registry);
-        config.putAsStringKeyIfAbsent("name", "localhost");
-        return config;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/access/PortMapping.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/access/PortMapping.java b/core/src/main/java/brooklyn/location/access/PortMapping.java
deleted file mode 100644
index aaf0ca5..0000000
--- a/core/src/main/java/brooklyn/location/access/PortMapping.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import javax.annotation.Nullable;
-
-import brooklyn.location.Location;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-import com.google.common.net.HostAndPort;
-
-public class PortMapping {
-
-    final String publicIpId;
-    final HostAndPort publicEndpoint;
-    final int publicPort;
-
-    final Location target;
-    final int privatePort;
-    // TODO CIDR's ?
-
-    public PortMapping(String publicIpId, HostAndPort publicEndpoint, Location target, int privatePort) {
-        this.publicIpId = checkNotNull(publicIpId, "publicIpId");
-        this.publicEndpoint = checkNotNull(publicEndpoint, "publicEndpoint");
-        this.publicPort = publicEndpoint.getPort();
-        this.target = target;
-        this.privatePort = privatePort;
-    }
-    
-    public PortMapping(String publicIpId, int publicPort, Location target, int privatePort) {
-        this.publicIpId = checkNotNull(publicIpId, "publicIpId");
-        this.publicEndpoint = null;
-        this.publicPort = publicPort;
-        this.target = target;
-        this.privatePort = privatePort;
-    }
-
-    // In a release after 0.7.0, this will no longer be @Nullable
-    @Beta
-    @Nullable
-    public HostAndPort getPublicEndpoint() {
-        return publicEndpoint;
-    }
-
-    public int getPublicPort() {
-        return publicPort;
-    }
-
-    public Location getTarget() {
-        return target;
-    }
-    
-    public int getPrivatePort() {
-        return privatePort;
-    }
-    
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(this)
-                .add("publicIpId", publicIpId+":"+publicPort)
-                .add("publicEndpoint", (publicEndpoint == null ? publicPort : publicEndpoint))
-                .add("targetLocation", target)
-                .add("targetPort", privatePort)
-                .toString();
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof PortMapping)) return false;
-        PortMapping opm = (PortMapping)obj;
-        return Objects.equal(publicIpId, opm.publicIpId) &&
-            Objects.equal(publicPort, opm.publicPort) &&
-            Objects.equal(target, opm.target) &&
-            Objects.equal(privatePort, opm.privatePort);
-    }
-    
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(publicIpId, publicPort, target, privatePort);
-    }
-    
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java b/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
deleted file mode 100644
index a5eb1cc..0000000
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocation.java
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static brooklyn.util.GroovyJavaMethods.elvis;
-import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.Closeable;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.brooklyn.api.entity.rebind.RebindSupport;
-import org.apache.brooklyn.api.entity.trait.Configurable;
-import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.mementos.LocationMemento;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.basic.AbstractBrooklynObject;
-import brooklyn.config.ConfigInheritance;
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.rebind.BasicLocationRebindSupport;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.internal.storage.Reference;
-import brooklyn.internal.storage.impl.BasicReference;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.geo.HasHostGeoInfo;
-import brooklyn.location.geo.HostGeoInfo;
-import brooklyn.management.internal.LocalLocationManager;
-import brooklyn.management.internal.ManagementContextInternal;
-import brooklyn.util.collections.SetFromLiveMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.flags.FlagUtils;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.stream.Streams;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/**
- * A basic implementation of the {@link Location} interface.
- *
- * This provides an implementation which works according to the requirements of
- * the interface documentation, and is ready to be extended to make more specialized locations.
- * 
- * Override {@link #configure(Map)} to add special initialization logic.
- */
-public abstract class AbstractLocation extends AbstractBrooklynObject implements LocationInternal, HasHostGeoInfo, Configurable {
-    
-    private static final long serialVersionUID = -7495805474138619830L;
-
-    /** @deprecated since 0.7.0 shouldn't be public */
-    @Deprecated
-    public static final Logger LOG = LoggerFactory.getLogger(AbstractLocation.class);
-
-    public static final ConfigKey<Location> PARENT_LOCATION = new BasicConfigKey<Location>(Location.class, "parentLocation");
-
-    public static final ConfigKey<Boolean> TEMPORARY_LOCATION = ConfigKeys.newBooleanConfigKey("temporaryLocation",
-            "Indicates that the location is a temporary location that has been created to test connectivity, and that" +
-            "the location's events should not be recorded by usage listeners", false);
-
-    private final AtomicBoolean configured = new AtomicBoolean();
-    
-    private Reference<Long> creationTimeUtc = new BasicReference<Long>(System.currentTimeMillis());
-    
-    // _not_ set from flag; configured explicitly in configure, because we also need to update the parent's list of children
-    private Reference<Location> parent = new BasicReference<Location>();
-    
-    // NB: all accesses should be synchronized
-    private Set<Location> children = Sets.newLinkedHashSet();
-
-    private Reference<String> name = new BasicReference<String>();
-    private boolean displayNameAutoGenerated = true;
-
-    private Reference<HostGeoInfo> hostGeoInfo = new BasicReference<HostGeoInfo>();
-
-    private BasicConfigurationSupport config = new BasicConfigurationSupport();
-    
-    private ConfigBag configBag = new ConfigBag();
-
-    private volatile boolean managed;
-
-    private boolean inConstruction;
-
-    private Reference<Map<Class<?>, Object>> extensions = new BasicReference<Map<Class<?>, Object>>(Maps.<Class<?>, Object>newConcurrentMap());
-
-    private final LocationDynamicType locationType;
-
-    /**
-     * Construct a new instance of an AbstractLocation.
-     */
-    public AbstractLocation() {
-        this(Maps.newLinkedHashMap());
-    }
-    
-    /**
-     * Construct a new instance of an AbstractLocation.
-     *
-     * The properties map recognizes the following keys:
-     * <ul>
-     * <li>name - a name for the location
-     * <li>parentLocation - the parent {@link Location}
-     * </ul>
-     * 
-     * Other common properties (retrieved via get/findLocationProperty) include:
-     * <ul>
-     * <li>latitude
-     * <li>longitude
-     * <li>displayName
-     * <li>iso3166 - list of iso3166-2 code strings
-     * <li>timeZone
-     * <li>abbreviatedName
-     * </ul>
-     */
-    public AbstractLocation(Map<?,?> properties) {
-        super(properties);
-        inConstruction = true;
-        
-        // When one calls getConfig(key), we want to use the default value specified on *this* location
-        // if it overrides the default config, by using the type object 
-        locationType = new LocationDynamicType(this);
-        
-        if (isLegacyConstruction()) {
-            AbstractBrooklynObject checkWeGetThis = configure(properties);
-            assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this;
-
-            boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
-            if (!deferConstructionChecks) {
-                FlagUtils.checkRequiredFields(this);
-            }
-        }
-        
-        inConstruction = false;
-    }
-
-    protected void assertNotYetManaged() {
-        if (!inConstruction && Locations.isManaged(this)) {
-            LOG.warn("Configuration being made to {} after deployment; may not be supported in future versions", this);
-        }
-        //throw new IllegalStateException("Cannot set configuration "+key+" on active location "+this)
-    }
-
-    public void setManagementContext(ManagementContextInternal managementContext) {
-        super.setManagementContext(managementContext);
-        if (displayNameAutoGenerated && getId() != null) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4)));
-
-        if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_USE_BROOKLYN_LIVE_OBJECTS_DATAGRID_STORAGE)) {
-            Location oldParent = parent.get();
-            Set<Location> oldChildren = children;
-            Map<String, Object> oldConfig = configBag.getAllConfig();
-            Long oldCreationTimeUtc = creationTimeUtc.get();
-            String oldDisplayName = name.get();
-            HostGeoInfo oldHostGeoInfo = hostGeoInfo.get();
-
-            parent = managementContext.getStorage().getReference(getId()+"-parent");
-            children = SetFromLiveMap.create(managementContext.getStorage().<Location,Boolean>getMap(getId()+"-children"));
-            creationTimeUtc = managementContext.getStorage().getReference(getId()+"-creationTime");
-            hostGeoInfo = managementContext.getStorage().getReference(getId()+"-hostGeoInfo");
-            name = managementContext.getStorage().getReference(getId()+"-displayName");
-
-            // Only override stored defaults if we have actual values. We might be in setManagementContext
-            // because we are reconstituting an existing entity in a new brooklyn management-node (in which
-            // case believe what is already in the storage), or we might be in the middle of creating a new 
-            // entity. Normally for a new entity (using EntitySpec creation approach), this will get called
-            // before setting the parent etc. However, for backwards compatibility we still support some
-            // things calling the entity's constructor directly.
-            if (oldParent != null) parent.set(oldParent);
-            if (oldChildren.size() > 0) children.addAll(oldChildren);
-            if (creationTimeUtc.isNull()) creationTimeUtc.set(oldCreationTimeUtc);
-            if (hostGeoInfo.isNull()) hostGeoInfo.set(oldHostGeoInfo);
-            if (name.isNull()) {
-                name.set(oldDisplayName);
-            } else {
-                displayNameAutoGenerated = false;
-            }
-
-            configBag = ConfigBag.newLiveInstance(managementContext.getStorage().<String,Object>getMap(getId()+"-config"));
-            if (oldConfig.size() > 0) {
-                configBag.putAll(oldConfig);
-            }
-        }
-    }
-
-    /**
-     * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly;
-     * see overridden method for more info
-     */
-    @SuppressWarnings("serial")
-    @Override
-    @Deprecated
-    public AbstractLocation configure(Map<?,?> properties) {
-        assertNotYetManaged();
-        
-        boolean firstTime = !configured.getAndSet(true);
-            
-        configBag.putAll(properties);
-        
-        if (properties.containsKey(PARENT_LOCATION.getName())) {
-            // need to ensure parent's list of children is also updated
-            setParent(configBag.get(PARENT_LOCATION));
-            
-            // don't include parentLocation in configBag, as breaks rebind
-            configBag.remove(PARENT_LOCATION);
-        }
-
-        // NB: flag-setting done here must also be done in BasicLocationRebindSupport 
-        FlagUtils.setFieldsFromFlagsWithBag(this, properties, configBag, firstTime);
-        FlagUtils.setAllConfigKeys(this, configBag, false);
-
-        if (properties.containsKey("displayName")) {
-            name.set((String) removeIfPossible(properties, "displayName"));
-            displayNameAutoGenerated = false;
-        } else if (properties.containsKey("name")) {
-            name.set((String) removeIfPossible(properties, "name"));
-            displayNameAutoGenerated = false;
-        } else if (isLegacyConstruction()) {
-            name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4)));
-            displayNameAutoGenerated = true;
-        }
-
-        // TODO Explicitly dealing with iso3166 here because want custom splitter rule comma-separated string.
-        // Is there a better way to do it (e.g. more similar to latitude, where configKey+TypeCoercion is enough)?
-        if (groovyTruth(properties.get("iso3166"))) {
-            Object rawCodes = removeIfPossible(properties, "iso3166");
-            Set<String> codes;
-            if (rawCodes instanceof CharSequence) {
-                codes = ImmutableSet.copyOf(Splitter.on(",").trimResults().split((CharSequence)rawCodes));
-            } else {
-                codes = TypeCoercions.coerce(rawCodes, new TypeToken<Set<String>>() {});
-            }
-            configBag.put(LocationConfigKeys.ISO_3166, codes);
-        }
-        
-        return this;
-    }
-
-    // TODO ensure no callers rely on 'remove' semantics, and don't remove;
-    // or perhaps better use a config bag so we know what is used v unused
-    private static Object removeIfPossible(Map<?,?> map, Object key) {
-        try {
-            return map.remove(key);
-        } catch (Exception e) {
-            return map.get(key);
-        }
-    }
-    
-    public boolean isManaged() {
-        return getManagementContext() != null && managed;
-    }
-
-    public void onManagementStarted() {
-        if (displayNameAutoGenerated) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4)));
-        this.managed = true;
-    }
-    
-    public void onManagementStopped() {
-        this.managed = false;
-        if (getManagementContext().isRunning()) {
-            BrooklynStorage storage = ((ManagementContextInternal)getManagementContext()).getStorage();
-            storage.remove(getId()+"-parent");
-            storage.remove(getId()+"-children");
-            storage.remove(getId()+"-creationTime");
-            storage.remove(getId()+"-hostGeoInfo");
-            storage.remove(getId()+"-displayName");
-            storage.remove(getId()+"-config");
-        }
-    }
-    
-    @Override
-    public String getDisplayName() {
-        return name.get();
-    }
-    
-    protected boolean isDisplayNameAutoGenerated() {
-        return displayNameAutoGenerated;
-    }
-    
-    @Override
-    public Location getParent() {
-        return parent.get();
-    }
-    
-    @Override
-    public Collection<Location> getChildren() {
-        synchronized (children) {
-            return ImmutableList.copyOf(children);
-        }
-    }
-
-    @Override
-    public void setParent(Location newParent) {
-        setParent(newParent, true);
-    }
-    
-    public void setParent(Location newParent, boolean updateChildListParents) {
-        if (newParent == this) {
-            throw new IllegalArgumentException("Location cannot be its own parent: "+this);
-        }
-        if (newParent == parent.get()) {
-            return; // no-op; already have desired parent
-        }
-        
-        if (parent.get() != null) {
-            Location oldParent = parent.get();
-            parent.set(null);
-            if (updateChildListParents)
-                ((AbstractLocation)oldParent).removeChild(this);
-        }
-        // TODO Should we support a location changing parent? The resulting unmanage/manage might cause problems.
-        // The code above suggests we do, but maybe we should warn or throw error, or at least test it!
-        
-        parent.set(newParent);
-        if (newParent != null) {
-            if (updateChildListParents)
-                ((AbstractLocation)newParent).addChild(this);
-        }
-        
-        onChanged();
-    }
-
-    @Override
-    public ConfigurationSupportInternal config() {
-        return config ;
-    }
-
-    private class BasicConfigurationSupport implements ConfigurationSupportInternal {
-
-        @Override
-        public <T> T get(ConfigKey<T> key) {
-            if (hasConfig(key, false)) return getLocalBag().get(key);
-            if (getParent() != null && isInherited(key)) {
-                return getParent().getConfig(key);
-            }
-            
-            // In case this entity class has overridden the given key (e.g. to set default), then retrieve this entity's key
-            // TODO when locations become entities, the duplication of this compared to EntityConfigMap.getConfig will disappear.
-            @SuppressWarnings("unchecked")
-            ConfigKey<T> ownKey = (ConfigKey<T>) elvis(locationType.getConfigKey(key.getName()), key);
-
-            return ownKey.getDefaultValue();
-        }
-
-        @Override
-        public <T> T get(HasConfigKey<T> key) {
-            return get(key.getConfigKey());
-        }
-
-        @Override
-        public <T> T set(ConfigKey<T> key, T val) {
-            T result = configBag.put(key, val);
-            onChanged();
-            return result;
-        }
-
-        @Override
-        public <T> T set(HasConfigKey<T> key, T val) {
-            return set(key.getConfigKey(), val);
-        }
-
-        @Override
-        public <T> T set(ConfigKey<T> key, Task<T> val) {
-            // TODO Support for locations
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public <T> T set(HasConfigKey<T> key, Task<T> val) {
-            // TODO Support for locations
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public ConfigBag getBag() {
-            ConfigBag result = ConfigBag.newInstanceExtending(configBag, ImmutableMap.of());
-            Location p = getParent();
-            if (p!=null) result.putIfAbsent(((LocationInternal)p).config().getBag());
-            return result;
-        }
-
-        @Override
-        public ConfigBag getLocalBag() {
-            return configBag;
-        }
-
-        @Override
-        public Maybe<Object> getRaw(ConfigKey<?> key) {
-            if (hasConfig(key, false)) return Maybe.of(getLocalBag().getStringKey(key.getName()));
-            if (getParent() != null && isInherited(key)) return ((LocationInternal)getParent()).config().getRaw(key);
-            return Maybe.absent();
-        }
-
-        @Override
-        public Maybe<Object> getRaw(HasConfigKey<?> key) {
-            return getRaw(key.getConfigKey());
-        }
-
-        @Override
-        public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
-            if (hasConfig(key, false)) return Maybe.of(getLocalBag().getStringKey(key.getName()));
-            return Maybe.absent();
-        }
-
-        @Override
-        public Maybe<Object> getLocalRaw(HasConfigKey<?> key) {
-            return getLocalRaw(key.getConfigKey());
-        }
-
-        @Override
-        public void addToLocalBag(Map<String, ?> vals) {
-            configBag.putAll(vals);
-        }
-
-        @Override
-        public void removeFromLocalBag(String key) {
-            configBag.remove(key);
-        }
-
-        @Override
-        public void refreshInheritedConfig() {
-            // no-op for location
-        }
-        
-        @Override
-        public void refreshInheritedConfigOfChildren() {
-            // no-op for location
-        }
-        
-        private boolean hasConfig(ConfigKey<?> key, boolean includeInherited) {
-            if (includeInherited && isInherited(key)) {
-                return getBag().containsKey(key);
-            } else {
-                return getLocalBag().containsKey(key);
-            }
-        }
-        
-        private boolean isInherited(ConfigKey<?> key) {
-            ConfigInheritance inheritance = key.getInheritance();
-            if (inheritance==null) inheritance = getDefaultInheritance();
-            return inheritance.isInherited(key, getParent(), AbstractLocation.this);
-        }
-
-        private ConfigInheritance getDefaultInheritance() {
-            return ConfigInheritance.ALWAYS;
-        }
-    }
-    
-    @Override
-    public <T> T getConfig(HasConfigKey<T> key) {
-        return config().get(key);
-    }
-
-    @Override
-    public <T> T getConfig(ConfigKey<T> key) {
-        return config().get(key);
-    }
-
-    @Override
-    @Deprecated
-    public boolean hasConfig(ConfigKey<?> key, boolean includeInherited) {
-        return config.hasConfig(key, includeInherited);
-    }
-
-    @Override
-    @Deprecated
-    public Map<String,Object> getAllConfig(boolean includeInherited) {
-        // TODO Have no information about what to include/exclude inheritance wise.
-        // however few things use getAllConfigBag()
-        ConfigBag bag = (includeInherited ? config().getBag() : config().getLocalBag());
-        return bag.getAllConfig();
-    }
-    
-    @Override
-    @Deprecated
-    public ConfigBag getAllConfigBag() {
-        // TODO see comments in EntityConfigMap and on interface methods. 
-        // here ConfigBag is used exclusively so
-        // we have no information about what to include/exclude inheritance wise.
-        // however few things use getAllConfigBag()
-        return config().getBag();
-    }
-    
-    @Override
-    public ConfigBag getLocalConfigBag() {
-        return config().getLocalBag();
-    }
-
-    /** 
-     * @deprecated since 0.7; use {@link #getLocalConfigBag()}
-     * @since 0.6
-     */
-    @Deprecated
-    public ConfigBag getRawLocalConfigBag() {
-        return config().getLocalBag();
-    }
-    
-    @Override
-    @Deprecated
-    public <T> T setConfig(ConfigKey<T> key, T value) {
-        return config().set(key, value);
-    }
-
-    /**
-     * @since 0.6.0 (?) - use getDisplayName
-     * @deprecated since 0.7.0; use {@link #getDisplayName()}
-     */
-    @Deprecated
-    public void setName(String newName) {
-        setDisplayName(newName);
-    }
-
-    public void setDisplayName(String newName) {
-        name.set(newName);
-        displayNameAutoGenerated = false;
-        onChanged();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (! (o instanceof Location)) {
-            return false;
-        }
-
-        Location l = (Location) o;
-        return getId().equals(l.getId());
-    }
-
-    @Override
-    public int hashCode() {
-        return getId().hashCode();
-    }
-
-    @Override
-    public boolean containsLocation(Location potentialDescendent) {
-        Location loc = potentialDescendent;
-        while (loc != null) {
-            if (this == loc) return true;
-            loc = loc.getParent();
-        }
-        return false;
-    }
-
-    protected <T extends Location> T addChild(LocationSpec<T> spec) {
-        T child = getManagementContext().getLocationManager().createLocation(spec);
-        addChild(child);
-        return child;
-    }
-    
-    @SuppressWarnings("deprecation")
-    public void addChild(Location child) {
-        // Previously, setParent delegated to addChildLocation and we sometimes ended up with
-        // duplicate entries here. Instead this now uses a similar scheme to 
-        // AbstractLocation.setParent/addChild (with any weaknesses for distribution that such a 
-        // scheme might have...).
-        // 
-        // We continue to use a list to allow identical-looking locations, but they must be different 
-        // instances.
-        
-        synchronized (children) {
-            for (Location contender : children) {
-                if (contender == child) {
-                    // don't re-add; no-op
-                    return;
-                }
-            }
-
-            children.add(child);
-        }
-        
-        if (isManaged()) {
-            if (!getManagementContext().getLocationManager().isManaged(child)) {
-                Locations.manage(child, getManagementContext());
-            }
-        } else if (getManagementContext() != null) {
-            if (((LocalLocationManager)getManagementContext().getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) {
-                ((ManagementContextInternal)getManagementContext()).prePreManage(child);
-            }
-        }
-
-        children.add(child);
-        child.setParent(this);
-        
-        onChanged();
-    }
-    
-    public boolean removeChild(Location child) {
-        boolean removed;
-        synchronized (children) {
-            removed = children.remove(child);
-        }
-        if (removed) {
-            if (child instanceof Closeable) {
-                Streams.closeQuietly((Closeable)child);
-            }
-            child.setParent(null);
-            
-            if (isManaged()) {
-                getManagementContext().getLocationManager().unmanage(child);
-            }
-        }
-        onChanged();
-        return removed;
-    }
-
-    protected void onChanged() {
-        // currently changes simply trigger re-persistence; there is no intermediate listener as we do for EntityChangeListener
-        if (isManaged()) {
-            getManagementContext().getRebindManager().getChangeListener().onChanged(this);
-        }
-    }
-
-    /** Default String representation is simplified name of class, together with selected fields. */
-    @Override
-    public String toString() {
-        return string().toString();
-    }
-    
-    @Override
-    public String toVerboseString() {
-        return toString();
-    }
-
-    /** override this, adding to the returned value, to supply additional fields to include in the toString */
-    protected ToStringHelper string() {
-        return Objects.toStringHelper(getClass()).add("id", getId()).add("name", name);
-    }
-    
-    @Override
-    public HostGeoInfo getHostGeoInfo() { return hostGeoInfo.get(); }
-    
-    public void setHostGeoInfo(HostGeoInfo hostGeoInfo) {
-        if (hostGeoInfo!=null) { 
-            this.hostGeoInfo.set(hostGeoInfo);
-            setConfig(LocationConfigKeys.LATITUDE, hostGeoInfo.latitude); 
-            setConfig(LocationConfigKeys.LONGITUDE, hostGeoInfo.longitude); 
-        } 
-    }
-
-    @Override
-    public RebindSupport<LocationMemento> getRebindSupport() {
-        return new BasicLocationRebindSupport(this);
-    }
-    
-    @Override
-    public boolean hasExtension(Class<?> extensionType) {
-        return extensions.get().containsKey(checkNotNull(extensionType, "extensionType"));
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T> T getExtension(Class<T> extensionType) {
-        Object extension = extensions.get().get(checkNotNull(extensionType, "extensionType"));
-        if (extension == null) {
-            throw new IllegalArgumentException("No extension of type "+extensionType+" registered for location "+this);
-        }
-        return (T) extension;
-    }
-    
-    @Override
-    public <T> void addExtension(Class<T> extensionType, T extension) {
-        checkNotNull(extensionType, "extensionType");
-        checkNotNull(extension, "extension");
-        checkArgument(extensionType.isInstance(extension), "extension %s does not implement %s", extension, extensionType);
-        extensions.get().put(extensionType, extension);
-    }
-
-    @Override
-    public Map<String, String> toMetadataRecord() {
-        ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
-        if (getDisplayName() != null) builder.put("displayName", getDisplayName());
-        if (getParent() != null && getParent().getDisplayName() != null) {
-            builder.put("parentDisplayName", getParent().getDisplayName());
-        }
-        return builder.build();
-    }
-}



[24/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
new file mode 100644
index 0000000..d689512
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
@@ -0,0 +1,575 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Networking;
+import brooklyn.util.stream.Streams;
+
+/**
+ * Provisions {@link SshMachineLocation}s in a specific location from a list of known machines
+ */
+public class FixedListMachineProvisioningLocationTest {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(FixedListMachineProvisioningLocationTest.class);
+
+    SshMachineLocation machine;
+    LocalManagementContext mgmt;
+    FixedListMachineProvisioningLocation<SshMachineLocation> provisioner;
+    FixedListMachineProvisioningLocation<SshMachineLocation> provisioner2;
+    
+    @SuppressWarnings("unchecked")
+    @BeforeMethod(alwaysRun=true)
+    public void createProvisioner() throws UnknownHostException {
+        mgmt = LocalManagementContextForTests.newInstance();
+        
+        machine = mgmt.getLocationManager().createLocation(MutableMap.of("address", Inet4Address.getByName("192.168.144.200")), SshMachineLocation.class);
+        provisioner = mgmt.getLocationManager().createLocation(
+                MutableMap.of("machines", MutableList.of(machine)),
+                FixedListMachineProvisioningLocation.class);
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (provisioner != null) Streams.closeQuietly(provisioner);
+        if (provisioner2 != null) Streams.closeQuietly(provisioner2);
+        Entities.destroyAll(mgmt);
+    }
+    
+    @Test
+    public void testSetsChildLocations() throws NoMachinesAvailableException {
+        // Available machines should be listed as children
+        assertEquals(ImmutableList.copyOf(provisioner.getChildren()), ImmutableList.of(machine));
+        
+        // In-use machines should also be listed as children
+        provisioner.obtain();
+        assertEquals(ImmutableList.copyOf(provisioner.getChildren()), ImmutableList.of(machine));
+    }
+
+    @Test
+    public void canObtainMachine() throws NoMachinesAvailableException {
+        SshMachineLocation obtained = provisioner.obtain();
+        assertEquals(obtained, machine);
+    }
+
+    @SuppressWarnings("unused")
+    @Test(expectedExceptions = { NoMachinesAvailableException.class })
+    public void throwsExceptionIfNoMachinesAvailable() throws NoMachinesAvailableException {
+        SshMachineLocation machine1 = provisioner.obtain();
+        SshMachineLocation machine2 = provisioner.obtain();
+        fail("Did not throw NoMachinesAvailableException as expected");
+    }
+
+    @Test
+    public void canGetAMachineReturnItAndObtainItAgain() throws NoMachinesAvailableException {
+        SshMachineLocation obtained = provisioner.obtain();
+        provisioner.release(obtained);
+        SshMachineLocation obtained2 = provisioner.obtain();
+        assertEquals(obtained2, machine);
+    }
+
+    @Test
+    public void theBuilder() throws NoMachinesAvailableException {
+        provisioner2 =
+            new FixedListMachineProvisioningLocation.Builder(mgmt.getLocationManager()).
+                user("u1").
+                addAddress("192.168.0.1").
+                addAddress("u2@192.168.0.2").
+                addAddress("192.168.0.{3,4}").
+                addAddresses("192.168.0.{6-8}").
+                addAddressMultipleTimes("192.168.0.{8,7}", 2).
+                addAddress("u3@192.168.0.{11-20}").
+                build();
+        assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0.1");
+        assertUserAndHost(provisioner2.obtain(), "u2", "192.168.0.2");
+        for (int i=3; i<=4; i++) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
+        for (int i=6; i<=8; i++) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
+        for (int j=0; j<2; j++)
+            for (int i=8; i>=7; i--) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
+        for (int i=11; i<=20; i++) assertUserAndHost(provisioner2.obtain(), "u3", "192.168.0."+i);
+        try { 
+            provisioner2.obtain();
+            fail("Should not have obtained");  //throws error so not caught below
+        } catch (Exception e) {
+            /** expected */
+        }
+    }
+    
+    @Test
+    public void theBuilderLegacy() throws NoMachinesAvailableException {
+        provisioner2 =
+            new FixedListMachineProvisioningLocation.Builder(mgmt.getLocationManager()).
+                user("u1").
+                addAddress("192.168.0.1").
+                addAddress("u2@192.168.0.2").
+                addAddress("192.168.0.{3,4}").
+                addAddresses("192.168.0.{6-8}").
+                addAddressMultipleTimes("192.168.0.{8,7}", 2).
+                addAddress("u3@192.168.0.{11-20}").
+                build();
+        assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0.1");
+        assertUserAndHost(provisioner2.obtain(), "u2", "192.168.0.2");
+        for (int i=3; i<=4; i++) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
+        for (int i=6; i<=8; i++) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
+        for (int j=0; j<2; j++)
+            for (int i=8; i>=7; i--) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
+        for (int i=11; i<=20; i++) assertUserAndHost(provisioner2.obtain(), "u3", "192.168.0."+i);
+        try { 
+            provisioner2.obtain();
+            fail("Should not have obtained");  //throws error so not caught below
+        } catch (Exception e) {
+            /** expected */
+        }
+    }
+    
+    @Test(expectedExceptions = { IllegalStateException.class })
+    public void throwsExceptionIfTryingToReleaseUnallocationMachine() throws NoMachinesAvailableException, UnknownHostException {
+        @SuppressWarnings("unused")
+        SshMachineLocation obtained = provisioner.obtain();
+        provisioner.release(new SshMachineLocation(MutableMap.of("address", Inet4Address.getByName("192.168.144.201"))));
+        fail("Did not throw IllegalStateException as expected");
+    }
+    
+    @Test
+    public void testCanAddMachineToPool() throws UnknownHostException, NoMachinesAvailableException {
+        SshMachineLocation machine2 = new SshMachineLocation(
+                MutableMap.of("address", Inet4Address.getByName("192.168.144.200")));
+        provisioner2 = new FixedListMachineProvisioningLocation<SshMachineLocation>(
+                MutableMap.of("machines", MutableList.of()));
+        provisioner2.addMachine(machine2);
+        
+        assertEquals(ImmutableList.copyOf(provisioner2.getChildren()), ImmutableList.of(machine2));
+        assertEquals(ImmutableSet.copyOf(provisioner2.getAvailable()), ImmutableSet.of(machine2));
+        
+        SshMachineLocation obtained = provisioner2.obtain();
+        assertEquals(obtained, machine2);
+        
+        // Can only obtain the added machien once though (i.e. not added multiple times somehow)
+        try {
+            SshMachineLocation obtained2 = provisioner2.obtain();
+            fail("obtained="+obtained2);
+        } catch (NoMachinesAvailableException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testCanRemoveAvailableMachineFromPool() {
+        provisioner.removeMachine(machine);
+        
+        Assert.assertTrue(provisioner.getChildren().isEmpty());
+        Assert.assertTrue(provisioner.getAvailable().isEmpty());
+        
+        try {
+            SshMachineLocation obtained = provisioner.obtain();
+            fail("obtained="+obtained);
+        } catch (NoMachinesAvailableException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testCanRemoveObtainedMachineFromPoolSoNotReallocated() throws NoMachinesAvailableException {
+        SshMachineLocation obtained = provisioner.obtain();
+        provisioner.removeMachine(obtained);
+        
+        // Continue to know about the machine until it is returned
+        assertEquals(ImmutableList.copyOf(provisioner.getChildren()), ImmutableList.of(machine));
+        Assert.assertTrue(provisioner.getAvailable().isEmpty());
+
+        // When released, the machine is then removed entirely
+        provisioner.release(obtained);
+
+        Assert.assertTrue(provisioner.getChildren().isEmpty());
+        Assert.assertTrue(provisioner.getAvailable().isEmpty());
+
+        // So no machines left; cannot re-obtain
+        try {
+            SshMachineLocation obtained2 = provisioner.obtain();
+            fail("obtained="+obtained2);
+        } catch (NoMachinesAvailableException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testObtainDesiredMachineThrowsIfNotKnown() throws Exception {
+        SshMachineLocation machine2 = new SshMachineLocation(
+                MutableMap.of("address", Inet4Address.getByName("192.168.144.201")));
+        try {
+            SshMachineLocation obtained = provisioner.obtain(MutableMap.of("desiredMachine", machine2));
+            fail("obtained="+obtained);
+        } catch (IllegalStateException e) {
+            if (!e.toString().contains("machine unknown")) throw e;
+        }
+    }
+
+    @Test
+    public void testObtainDesiredMachineThrowsIfInUse() throws Exception {
+        provisioner.addMachine(new SshMachineLocation(
+                MutableMap.of("address", Inet4Address.getByName("192.168.144.201"))));
+        SshMachineLocation obtained = provisioner.obtain();
+        try {
+            SshMachineLocation obtained2 = provisioner.obtain(MutableMap.of("desiredMachine", obtained));
+            fail("obtained2="+obtained2);
+        } catch (IllegalStateException e) {
+            if (!e.toString().contains("machine in use")) throw e;
+        }
+    }
+
+    @Test
+    public void testObtainDesiredMachineReturnsDesired() throws Exception {
+        int desiredMachineIndex = 10;
+        SshMachineLocation desiredMachine = null;
+        for (int i = 0; i < 20; i++) {
+            SshMachineLocation newMachine = new SshMachineLocation(
+                    MutableMap.of("address", Inet4Address.getByName("192.168.144."+(201+i))));
+            if (i == desiredMachineIndex) desiredMachine = newMachine;
+            provisioner.addMachine(newMachine);
+        }
+        SshMachineLocation obtained = provisioner.obtain(MutableMap.of("desiredMachine", desiredMachine));
+        assertEquals(obtained, desiredMachine);
+    }
+
+    @Test
+    public void testAddAndRemoveChildUpdatesMachinesSet() throws Exception {
+        SshMachineLocation anotherMachine = new SshMachineLocation(
+                MutableMap.of("address", Inet4Address.getByName("192.168.144.201")));
+        provisioner.addChild(anotherMachine);
+        assertEquals(provisioner.getAllMachines(), ImmutableSet.of(machine, anotherMachine));
+        
+        provisioner.removeChild(anotherMachine);
+        assertEquals(provisioner.getAllMachines(), ImmutableSet.of(machine));
+    }
+    
+    @Test
+    public void testCanAddAlreadyParentedMachine() throws UnknownHostException, NoMachinesAvailableException {
+        provisioner.obtain(); // so no machines left
+        
+        FixedListMachineProvisioningLocation<SshMachineLocation> provisioner2 = new FixedListMachineProvisioningLocation.Builder(mgmt.getLocationManager())
+            .addAddress("1.2.3.4")
+            .build();
+        SshMachineLocation machine = provisioner2.obtain();
+        
+        provisioner.addMachine(machine);
+        assertEquals(provisioner.obtain(), machine);
+    }
+
+    @Test
+    public void testCanCreateWithAlreadyParentedMachine() throws UnknownHostException, NoMachinesAvailableException {
+        machine = provisioner.obtain();
+        
+        FixedListMachineProvisioningLocation<SshMachineLocation> provisioner2 = new FixedListMachineProvisioningLocation.Builder(mgmt.getLocationManager())
+            .add(machine)
+            .build();
+        assertEquals(provisioner2.obtain(), machine);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testMachinesObtainedInOrder() throws Exception {
+        List<SshMachineLocation> machines = ImmutableList.of(
+                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.1"))),
+                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.6"))),
+                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.3"))),
+                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.4"))),
+                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.5"))));
+        
+        provisioner2 = mgmt.getLocationManager().createLocation(
+                MutableMap.of("machines", machines),
+                FixedListMachineProvisioningLocation.class);
+
+        for (SshMachineLocation expected : machines) {
+            assertEquals(provisioner2.obtain(), expected);
+        }
+    }
+    
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testMachineChooser() throws Exception {
+        List<SshMachineLocation> machines = Lists.newArrayList();
+        for (int i = 0; i < 10; i++) {
+            machines.add(mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1."+i))));
+        }
+        final List<SshMachineLocation> desiredOrder = randomized(machines);
+        
+        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
+            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
+                for (SshMachineLocation contender : desiredOrder) {
+                    if (Iterables.contains(input, contender)) {
+                        return contender;
+                    }
+                }
+                Assert.fail("No intersection of input="+input+" and desiredOrder="+desiredOrder);
+                return null; // unreachable code
+            }
+        };
+        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .configure("machines", machines)
+                .configure(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser));
+
+        List<SshMachineLocation> result = Lists.newArrayList();
+        for (int i = 0; i < machines.size(); i++) {
+            result.add(provisioner2.obtain());
+        }
+        assertEquals(result, desiredOrder, "result="+result+"; desired="+desiredOrder);
+        LOG.debug("chooser's desiredOrder="+desiredOrder);
+    }
+    
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testMachineChooserPassedToObtain() throws Exception {
+        List<SshMachineLocation> machines = Lists.newArrayList();
+        for (int i = 0; i < 10; i++) {
+            machines.add(mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1."+i))));
+        }
+        final List<SshMachineLocation> desiredOrder = randomized(machines);
+        
+        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
+            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
+                for (SshMachineLocation contender : desiredOrder) {
+                    if (Iterables.contains(input, contender)) {
+                        return contender;
+                    }
+                }
+                Assert.fail("No intersection of input="+input+" and desiredOrder="+desiredOrder);
+                return null; // unreachable code
+            }
+        };
+        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .configure("machines", machines));
+
+        List<SshMachineLocation> result = Lists.newArrayList();
+        for (int i = 0; i < machines.size(); i++) {
+            result.add(provisioner2.obtain(ImmutableMap.of(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser)));
+        }
+        assertEquals(result, desiredOrder, "result="+result+"; desired="+desiredOrder);
+        LOG.debug("chooser's desiredOrder="+desiredOrder);
+    }
+    
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testMachineChooserNotCalledWhenNoMachines() throws Exception {
+        List<SshMachineLocation> machines = ImmutableList.of(
+                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.1"))));
+        final AtomicInteger callCount = new AtomicInteger();
+        
+        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
+            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
+                callCount.incrementAndGet();
+                return Iterables.get(input, 0);
+            }
+        };
+        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .configure("machines", machines)
+                .configure(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser));
+        provisioner2.obtain();
+
+        // When no machines available should fail gracefully, without asking the "chooser"
+        try {
+            provisioner2.obtain();
+            fail("Expected "+NoMachinesAvailableException.class.getSimpleName());
+        } catch (NoMachinesAvailableException e) {
+            // Pass; sensible exception
+        }
+        assertEquals(callCount.get(), 1);
+    }
+    
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testFailsWhenMachineChooserReturnsAlreadyAllocatedMachine() throws Exception {
+        final SshMachineLocation machine1 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.1")));
+        final SshMachineLocation machine2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.2")));
+        List<SshMachineLocation> machines = ImmutableList.of(machine1, machine2);
+        
+        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
+            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
+                return machine1;
+            }
+        };
+        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .configure("machines", machines)
+                .configure(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser));
+        provisioner2.obtain();
+
+        // Should fail when tries to return same machine for a second time
+        try {
+            provisioner2.obtain();
+            fail("Expected "+IllegalStateException.class.getSimpleName());
+        } catch (IllegalStateException e) {
+            if (!e.toString().contains("Machine chooser attempted to choose ")) throw e;
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testFailsWhenMachineChooserReturnsInvalidMachine() throws Exception {
+        final SshMachineLocation machine1 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.1")));
+        final SshMachineLocation machineOther = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("2.2.2.1")));
+        List<SshMachineLocation> machines = ImmutableList.of(machine1);
+        
+        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
+            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
+                return machineOther;
+            }
+        };
+        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .configure("machines", machines)
+                .configure(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser));
+
+        // Call when no machines available should fail gracefully, without asking the "chooser"
+        try {
+            provisioner2.obtain();
+            fail("Expected "+IllegalStateException.class.getSimpleName());
+        } catch (IllegalStateException e) {
+            if (!e.toString().contains("Machine chooser attempted to choose ")) throw e;
+        }
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testMachineCustomizerSetOnByon() throws Exception {
+        machine = mgmt.getLocationManager().createLocation(MutableMap.of("address", Inet4Address.getByName("192.168.144.200")), SshMachineLocation.class);
+        RecordingMachineLocationCustomizer customizer = new RecordingMachineLocationCustomizer();
+        
+        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .configure("machines", ImmutableList.of(machine))
+                .configure(FixedListMachineProvisioningLocation.MACHINE_LOCATION_CUSTOMIZERS.getName(), ImmutableList.of(customizer)));
+                
+        SshMachineLocation obtained = provisioner2.obtain();
+        Assert.assertEquals(Iterables.getOnlyElement(customizer.calls), new RecordingMachineLocationCustomizer.Call("customize", ImmutableList.of(obtained)));
+        
+        provisioner2.release(obtained);
+        assertEquals(customizer.calls.size(), 2);
+        Assert.assertEquals(Iterables.get(customizer.calls, 1), new RecordingMachineLocationCustomizer.Call("preRelease", ImmutableList.of(obtained)));
+    }
+
+    @Test
+    public void testMachineCustomizerSetOnObtainCall() throws Exception {
+        RecordingMachineLocationCustomizer customizer = new RecordingMachineLocationCustomizer();
+        
+        SshMachineLocation obtained = provisioner.obtain(ImmutableMap.of(FixedListMachineProvisioningLocation.MACHINE_LOCATION_CUSTOMIZERS, ImmutableList.of(customizer)));
+        Assert.assertEquals(Iterables.getOnlyElement(customizer.calls), new RecordingMachineLocationCustomizer.Call("customize", ImmutableList.of(obtained)));
+        
+        provisioner.release(obtained);
+        assertEquals(customizer.calls.size(), 2);
+        Assert.assertEquals(customizer.calls.get(1), new RecordingMachineLocationCustomizer.Call("preRelease", ImmutableList.of(obtained)));
+    }
+
+    @Test
+    public void testMachineGivenCustomFlagForDurationOfUsage() throws Exception {
+        boolean origContains = machine.config().getBag().getAllConfig().containsKey("mykey");
+        SshMachineLocation obtained = provisioner.obtain(ImmutableMap.of("mykey", "myNewVal"));
+        Object obtainedVal = obtained.config().getBag().getAllConfig().get("mykey");
+        provisioner.release(obtained);
+        boolean releasedContains = obtained.config().getBag().getAllConfig().containsKey("mykey");
+        
+        assertEquals(obtained, machine);
+        assertFalse(origContains);
+        assertEquals(obtainedVal, "myNewVal");
+        assertFalse(releasedContains);
+    }
+    
+    @Test
+    public void testMachineConfigRestoredToDefaultsOnRelease() throws Exception {
+        ConfigKey<String> mykey = ConfigKeys.newStringConfigKey("mykey");
+        
+        boolean origContains = machine.config().getBag().getAllConfig().containsKey("mykey");
+        SshMachineLocation obtained = provisioner.obtain();
+        obtained.config().set(mykey, "myNewVal");
+        Object obtainedVal = obtained.config().getBag().getAllConfig().get("mykey");
+        
+        provisioner.release(obtained);
+        boolean releasedContains = machine.config().getBag().getAllConfig().containsKey("mykey");
+        releasedContains |= (machine.config().get(mykey) != null);
+        
+        assertEquals(obtained, machine);
+        assertFalse(origContains);
+        assertEquals(obtainedVal, "myNewVal");
+        assertFalse(releasedContains);
+    }
+    
+    @Test
+    public void testMachineGivenOverriddenFlagForDurationOfUsage() throws Exception {
+        SshMachineLocation machine2 = new SshMachineLocation(
+                MutableMap.of("address", Inet4Address.getByName("192.168.144.200"), "mykey", "myval"));
+        provisioner2 = new FixedListMachineProvisioningLocation<SshMachineLocation>(
+                MutableMap.of("machines", MutableList.of(machine2)));
+
+        Object origVal = machine2.config().getBag().getAllConfig().get("mykey");
+        SshMachineLocation obtained = provisioner2.obtain(ImmutableMap.of("mykey", "myNewVal"));
+        Object obtainedVal = obtained.config().getBag().getAllConfig().get("mykey");
+        provisioner2.release(obtained);
+        Object releasedVal = obtained.config().getBag().getAllConfig().get("mykey");
+        
+        assertEquals(obtained, machine2);
+        assertEquals(origVal, "myval");
+        assertEquals(obtainedVal, "myNewVal");
+        assertEquals(releasedVal, "myval");
+    }
+
+    private static <T> List<T> randomized(Iterable<T> list) {
+        // TODO inefficient implementation, but don't care for small tests
+        Random random = new Random();
+        List<T> result = Lists.newLinkedList();
+        for (T element : list) {
+            int index = (result.isEmpty() ? 0 : random.nextInt(result.size()));
+            result.add(index, element);
+        }
+        return result;
+    }
+    
+    private static void assertUserAndHost(SshMachineLocation l, String user, String host) {
+        assertEquals(l.getUser(), user);
+        assertEquals(l.getAddress().getHostAddress(), host);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java
new file mode 100644
index 0000000..2d66cb5
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java
@@ -0,0 +1,126 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import java.net.InetAddress;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+
+import com.google.common.collect.ImmutableMap;
+
+public class HostLocationResolverTest {
+    
+    private BrooklynProperties brooklynProperties;
+    private LocalManagementContext managementContext;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+        brooklynProperties = managementContext.getBrooklynProperties();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testThrowsOnInvalid() throws Exception {
+        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
+        assertThrowsIllegalArgument("host");
+    }
+    
+    @Test
+    public void testThrowsOnInvalidTarget() throws Exception {
+        assertThrowsIllegalArgument("host:()");
+    }
+    
+    @Test
+    public void resolveHosts() {
+        resolve("host:(\"1.1.1.1\")");
+        resolve("host:(\"localhost\")");
+    }
+    
+    @Test(groups="Integration")
+    public void resolveRealHosts() {
+        // must be online to resolve this
+        resolve("host:(\"www.foo.com\")");
+    }
+    
+    @Test
+    public void testNamedByonLocation() throws Exception {
+        brooklynProperties.put("brooklyn.location.named.mynamed", "host:(\"1.1.1.1\")");
+        
+        MachineProvisioningLocation<SshMachineLocation> loc = resolve("named:mynamed");
+        assertEquals(loc.obtain(ImmutableMap.of()).getAddress(), InetAddress.getByName("1.1.1.1"));
+    }
+
+    @Test
+    public void testPropertyScopePrescedence() throws Exception {
+        brooklynProperties.put("brooklyn.location.named.mynamed", "host:(\"1.1.1.1\")");
+        
+        // prefer those in "named" over everything else
+        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
+        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
+
+        // prefer location-generic if nothing else
+        brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
+
+        Map<String, Object> conf = resolve("named:mynamed").obtain(ImmutableMap.of()).config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
+        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
+    }
+
+    private void assertThrowsNoSuchElement(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (NoSuchElementException e) {
+            // success
+        }
+    }
+    
+    private void assertThrowsIllegalArgument(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private MachineProvisioningLocation<SshMachineLocation> resolve(String val) {
+        return (MachineProvisioningLocation<SshMachineLocation>) managementContext.getLocationRegistry().resolve(val);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LegacyAbstractLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LegacyAbstractLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LegacyAbstractLocationTest.java
new file mode 100644
index 0000000..10e59b3
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LegacyAbstractLocationTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.flags.SetFromFlag;
+
+import com.google.common.collect.ImmutableList;
+
+public class LegacyAbstractLocationTest {
+
+    private static class ConcreteLocation extends AbstractLocation {
+        @SetFromFlag(defaultVal="mydefault")
+        String myfield;
+
+        public ConcreteLocation() {
+            super();
+        }
+
+        public ConcreteLocation(Map properties) {
+            super(properties);
+        }
+    }
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown(){
+        // nothing to tear down; did not create a management context
+    }
+
+    @Test
+    public void testEquals() {
+        AbstractLocation l1 = new ConcreteLocation(MutableMap.of("id", "1", "name", "bob"));
+        AbstractLocation l2 = new ConcreteLocation(MutableMap.of("id", "1", "name", "frank"));
+        AbstractLocation l3 = new ConcreteLocation(MutableMap.of("id", "2", "name", "frank"));
+        assertEquals(l1, l2);
+        assertNotEquals(l2, l3);
+    }
+
+    @Test
+    public void nullNameAndParentLocationIsAcceptable() {
+        AbstractLocation location = new ConcreteLocation(MutableMap.of("name", null, "parentLocation", null));
+        assertEquals(location.getDisplayName(), null);
+        assertEquals(location.getParent(), null);
+    }
+
+    @Test
+    public void testSettingParentLocation() {
+        AbstractLocation location = new ConcreteLocation();
+        AbstractLocation locationSub = new ConcreteLocation();
+        locationSub.setParent(location);
+        
+        assertEquals(ImmutableList.copyOf(location.getChildren()), ImmutableList.of(locationSub));
+        assertEquals(locationSub.getParent(), location);
+    }
+
+    @Test
+    public void testClearingParentLocation() {
+        AbstractLocation location = new ConcreteLocation();
+        AbstractLocation locationSub = new ConcreteLocation();
+        locationSub.setParent(location);
+        
+        locationSub.setParent(null);
+        assertEquals(ImmutableList.copyOf(location.getChildren()), Collections.emptyList());
+        assertEquals(locationSub.getParent(), null);
+    }
+    
+    @Test
+    public void testContainsLocation() {
+        AbstractLocation location = new ConcreteLocation();
+        AbstractLocation locationSub = new ConcreteLocation();
+        locationSub.setParent(location);
+        
+        assertTrue(location.containsLocation(location));
+        assertTrue(location.containsLocation(locationSub));
+        assertFalse(locationSub.containsLocation(location));
+    }
+
+
+    @Test
+    public void queryingNameReturnsNameGivenInConstructor() {
+        String name = "Outer Mongolia";
+        AbstractLocation location = new ConcreteLocation(MutableMap.of("name", "Outer Mongolia"));
+        assertEquals(location.getDisplayName(), name);;
+    }
+
+    @Test
+    public void constructorParentLocationReturnsExpectedLocation() {
+        AbstractLocation parent = new ConcreteLocation(MutableMap.of("name", "Middle Earth"));
+        AbstractLocation child = new ConcreteLocation(MutableMap.of("name", "The Shire", "parentLocation", parent));
+        assertEquals(child.getParent(), parent);
+        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
+    }
+
+    @Test
+    public void setParentLocationReturnsExpectedLocation() {
+        AbstractLocation parent = new ConcreteLocation(MutableMap.of("name", "Middle Earth"));
+        AbstractLocation child = new ConcreteLocation(MutableMap.of("name", "The Shire"));
+        child.setParent(parent);
+        assertEquals(child.getParent(), parent);
+        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
+    }
+    
+    @Test
+    public void testAddChildToParentLocationReturnsExpectedLocation() {
+        AbstractLocation parent = new ConcreteLocation(MutableMap.of("id", "1"));
+        AbstractLocation child = new ConcreteLocation(MutableMap.of("id", "2"));
+        parent.addChild(child);
+        assertEquals(child.getParent(), parent);
+        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
+    }
+
+    @Test
+    public void testFieldSetFromFlag() {
+        ConcreteLocation loc = new ConcreteLocation(MutableMap.of("myfield", "myval"));
+        assertEquals(loc.myfield, "myval");
+    }
+    
+    @Test
+    public void testFieldSetFromFlagUsesDefault() {
+        ConcreteLocation loc = new ConcreteLocation();
+        assertEquals(loc.myfield, "mydefault");
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java
new file mode 100644
index 0000000..fd6f29c
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+
+import com.google.common.collect.ImmutableList;
+
+public class LocalhostLocationResolverTest {
+
+    private BrooklynProperties brooklynProperties;
+    private LocalManagementContext managementContext;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+        brooklynProperties = managementContext.getBrooklynProperties();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testTakesLocalhostScopedProperties() {
+        brooklynProperties.put("brooklyn.location.localhost.privateKeyFile", "myprivatekeyfile");
+        brooklynProperties.put("brooklyn.location.localhost.publicKeyFile", "mypublickeyfile");
+        brooklynProperties.put("brooklyn.location.localhost.privateKeyData", "myprivateKeyData");
+        brooklynProperties.put("brooklyn.location.localhost.publicKeyData", "myPublicKeyData");
+        brooklynProperties.put("brooklyn.location.localhost.privateKeyPassphrase", "myprivateKeyPassphrase");
+
+        Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
+        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
+        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
+        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
+        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
+    }
+
+    @Test
+    public void testTakesLocalhostDeprecatedScopedProperties() {
+        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "myprivatekeyfile");
+        brooklynProperties.put("brooklyn.localhost.publicKeyFile", "mypublickeyfile");
+        brooklynProperties.put("brooklyn.localhost.privateKeyData", "myprivateKeyData");
+        brooklynProperties.put("brooklyn.localhost.publicKeyData", "myPublicKeyData");
+        brooklynProperties.put("brooklyn.localhost.privateKeyPassphrase", "myprivateKeyPassphrase");
+
+        Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
+        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
+        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
+        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
+        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
+    }
+
+    @Test
+    public void testTakesDeprecatedProperties() {
+        brooklynProperties.put("brooklyn.localhost.private-key-file", "myprivatekeyfile");
+        brooklynProperties.put("brooklyn.localhost.public-key-file", "mypublickeyfile");
+        brooklynProperties.put("brooklyn.localhost.private-key-data", "myprivateKeyData");
+        brooklynProperties.put("brooklyn.localhost.public-key-data", "myPublicKeyData");
+        brooklynProperties.put("brooklyn.localhost.private-key-passphrase", "myprivateKeyPassphrase");
+        Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
+        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
+        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
+        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
+        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
+    }
+    
+    @Test
+    public void testPropertyScopePrescedence() {
+        brooklynProperties.put("brooklyn.location.named.mynamed", "localhost");
+        
+        // prefer those in "named" over everything else
+        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
+        brooklynProperties.put("brooklyn.location.localhost.privateKeyFile", "privateKeyFile-inProviderSpecific");
+        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
+
+        // prefer those in provider-specific over generic
+        brooklynProperties.put("brooklyn.location.localhost.publicKeyFile", "publicKeyFile-inProviderSpecific");
+        brooklynProperties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inGeneric");
+
+        // prefer location-generic if nothing else
+        brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
+
+        Map<String, Object> conf = resolve("named:mynamed").config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
+        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
+        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
+    }
+
+    @Test
+    public void testLocalhostLoads() {
+        Assert.assertTrue(resolve("localhost") instanceof LocalhostMachineProvisioningLocation);
+    }
+
+    @Test
+    public void testThrowsOnInvalid() throws Exception {
+        assertThrowsNoSuchElement("wrongprefix");
+        assertThrowsIllegalArgument("localhost(name=abc"); // no closing bracket
+        assertThrowsIllegalArgument("localhost(name)"); // no value for name
+        assertThrowsIllegalArgument("localhost(name=)"); // no value for name
+    }
+    
+
+    @Test
+    public void testAcceptsList() {
+        List<Location> l = getLocationResolver().resolve(ImmutableList.of("localhost"));
+        assertEquals(l.size(), 1, "l="+l);
+        assertTrue(l.get(0) instanceof LocalhostMachineProvisioningLocation, "l="+l);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRegistryCommaResolution() throws NoMachinesAvailableException {
+        List<Location> l;
+        l = getLocationResolver().resolve(JavaStringEscapes.unwrapJsonishListIfPossible("localhost,localhost,localhost"));
+        assertEquals(l.size(), 3, "l="+l);
+        assertTrue(l.get(0) instanceof LocalhostMachineProvisioningLocation, "l="+l);
+        assertTrue(l.get(1) instanceof LocalhostMachineProvisioningLocation, "l="+l);
+        assertTrue(l.get(2) instanceof LocalhostMachineProvisioningLocation, "l="+l);
+
+        // And check works if comma in brackets
+        l = getLocationResolver().resolve(JavaStringEscapes.unwrapJsonishListIfPossible(
+            "[ \"byon:(hosts=\\\"192.168.0.1\\\",user=bob)\", \"byon:(hosts=\\\"192.168.0.2\\\",user=bob2)\" ]"));
+        assertEquals(l.size(), 2, "l="+l);
+        assertTrue(l.get(0) instanceof FixedListMachineProvisioningLocation, "l="+l);
+        assertTrue(l.get(1) instanceof FixedListMachineProvisioningLocation, "l="+l);
+        assertEquals(((FixedListMachineProvisioningLocation<SshMachineLocation>)l.get(0)).obtain().getUser(), "bob");
+        assertEquals(((FixedListMachineProvisioningLocation<SshMachineLocation>)l.get(1)).obtain().getUser(), "bob2");
+    }
+
+    @Test(expectedExceptions={NoSuchElementException.class})
+    public void testRegistryCommaResolutionInListNotAllowed1() throws NoMachinesAvailableException {
+        // disallowed since 0.7.0
+        getLocationResolver().resolve(ImmutableList.of("localhost,localhost,localhost"));
+    }
+
+    @Test(expectedExceptions={IllegalArgumentException.class})
+    public void testRegistryCommaResolutionInListNotAllowed2() throws NoMachinesAvailableException {
+        // disallowed since 0.7.0
+        // fails because it interprets the entire string as a single spec, which does not parse
+        getLocationResolver().resolve(ImmutableList.of("localhost(),localhost()"));
+    }
+
+    @Test(expectedExceptions={IllegalArgumentException.class})
+    public void testRegistryCommaResolutionInListNotAllowed3() throws NoMachinesAvailableException {
+        // disallowed since 0.7.0
+        // fails because it interprets the entire string as a single spec, which does not parse
+        getLocationResolver().resolve(ImmutableList.of("localhost(name=a),localhost(name=b)"));
+    }
+
+    @Test(expectedExceptions={IllegalArgumentException.class})
+    public void testDoesNotAcceptsListOLists() {
+        ((BasicLocationRegistry)managementContext.getLocationRegistry()).resolve(ImmutableList.of(ImmutableList.of("localhost")));
+    }
+
+    @Test
+    public void testResolvesExplicitName() throws Exception {
+        Location location = resolve("localhost(name=myname)");
+        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
+        assertEquals(location.getDisplayName(), "myname");
+    }
+    
+    @Test
+    public void testWithOldStyleColon() throws Exception {
+        Location location = resolve("localhost:(name=myname)");
+        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
+        assertEquals(location.getDisplayName(), "myname");
+    }
+    
+    @Test
+    public void testResolvesPropertiesInSpec() throws Exception {
+        LocationInternal location = resolve("localhost(privateKeyFile=myprivatekeyfile,name=myname)");
+        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
+        assertEquals(location.getDisplayName(), "myname");
+        assertEquals(location.config().getBag().getStringKey("privateKeyFile"), "myprivatekeyfile");
+    }
+    
+    @Test
+    public void testResolvesDefaultName() throws Exception {
+        Location location = resolve("localhost");
+        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
+        assertEquals(location.getDisplayName(), "localhost");
+
+        Location location2 = resolve("localhost()");
+        assertTrue(location2 instanceof LocalhostMachineProvisioningLocation);
+        assertEquals(location2.getDisplayName(), "localhost");
+    }
+    
+    private BasicLocationRegistry getLocationResolver() {
+        return (BasicLocationRegistry) managementContext.getLocationRegistry();
+    }
+    
+    private LocationInternal resolve(String val) {
+        Location l = managementContext.getLocationRegistry().resolve(val);
+        Assert.assertNotNull(l);
+        return (LocationInternal) l;
+    }
+    
+    private void assertThrowsNoSuchElement(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (NoSuchElementException e) {
+            // success
+        }
+
+        // and check the long form returns an Absent (not throwing)
+        Assert.assertTrue(managementContext.getLocationRegistry().resolve(val, false, null).isAbsent());
+    }
+    
+    private void assertThrowsIllegalArgument(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+        
+        // and check the long form returns an Absent (not throwing)
+        Assert.assertTrue(managementContext.getLocationRegistry().resolve(val, false, null).isAbsent());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
new file mode 100644
index 0000000..d948eaf
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
@@ -0,0 +1,213 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
+
+import java.net.ServerSocket;
+
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Networking;
+
+public class LocalhostMachineProvisioningLocationTest {
+
+    private static final Logger log = LoggerFactory.getLogger(LocalhostMachineProvisioningLocationTest.class);
+    
+    private LocalManagementContext mgmt;
+
+    @BeforeMethod
+    @AfterClass
+    protected void clearStatics() {
+        LocalhostMachineProvisioningLocation.clearStaticData();
+    }
+    
+    @BeforeClass
+    protected void setup() {
+        mgmt = LocalManagementContextForTests.newInstance();
+    }
+    
+    @AfterClass
+    protected void teardown() {
+        Entities.destroyAll(mgmt);
+    }
+    
+    protected LocalhostMachineProvisioningLocation newLocalhostProvisioner() {
+        return mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+    }
+    
+    protected LocalhostMachineProvisioningLocation newLocalhostProvisionerWithAddress(String address) {
+        return mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class)
+            .configure("address", address));
+    }
+    
+    @Test
+    public void defaultInvocationCanProvisionALocalhostInstance() throws Exception {
+        LocalhostMachineProvisioningLocation provisioner = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+        SshMachineLocation machine = provisioner.obtain();
+        assertNotNull(machine);
+        assertEquals(machine.address, Networking.getLocalHost());
+    }
+
+    @Test
+    public void testUsesLocationNameProvided() throws Exception {
+        LocalhostMachineProvisioningLocation provisioner = newLocalhostProvisionerWithAddress("localhost");
+        assertEquals(((SshMachineLocation)provisioner.obtain()).getAddress().getHostName(), "localhost");
+
+        LocalhostMachineProvisioningLocation provisioner2 = newLocalhostProvisionerWithAddress("1.2.3.4");
+        assertEquals(((SshMachineLocation)provisioner2.obtain()).getAddress().getHostName(), "1.2.3.4");
+        
+        LocalhostMachineProvisioningLocation provisioner3 = newLocalhostProvisionerWithAddress("127.0.0.1");
+        assertEquals(((SshMachineLocation)provisioner3.obtain()).getAddress().getHostName(), "127.0.0.1");
+    }
+    
+    public void provisionWithASpecificNumberOfInstances() throws NoMachinesAvailableException {
+        LocalhostMachineProvisioningLocation provisioner = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class)
+            .configure("count", 2));
+
+        // first machine
+        SshMachineLocation first = provisioner.obtain();
+        assertNotNull(first);
+        assertEquals(first.address, Networking.getLocalHost());
+
+        // second machine
+        SshMachineLocation second = provisioner.obtain();
+        assertNotNull(second);
+        assertEquals(second.address, Networking.getLocalHost());
+
+        // third machine - fails
+        try {
+            SshMachineLocation third = provisioner.obtain();
+            fail("did not throw expected exception; got "+third);
+        } catch (NoMachinesAvailableException e) {
+            /* expected */
+        }
+    }
+    
+    @Test
+    public void obtainTwoAddressesInRangeThenDontObtain() throws Exception {
+        LocalhostMachineProvisioningLocation p = newLocalhostProvisioner();
+        SshMachineLocation m = p.obtain();
+
+        // Find two ports that are free, rather than risk false-negatives if a port was left open by something else.
+        int start = 48311;
+        while (true) {
+            if (Networking.isPortAvailable(m.getAddress(), start) && Networking.isPortAvailable(m.getAddress(), start+1)) {
+                break;
+            } else {
+                start++;
+            }
+        }
+        PortRange r = PortRanges.fromString(""+start+"-"+(start+1));
+        
+        try {
+            int i1 = m.obtainPort(r);
+            Assert.assertEquals(i1, start);
+            int i2 = m.obtainPort(r);
+            Assert.assertEquals(i2, start+1);
+            
+            //should fail
+            int i3 = m.obtainPort(r);
+            Assert.assertEquals(i3, -1);
+
+            //releasing and reapplying should succed
+            m.releasePort(i2);
+            int i4 = m.obtainPort(r);
+            Assert.assertEquals(i4, i2);
+
+        } finally {
+            m.releasePort(start);
+            m.releasePort(start+1);
+        }
+    }
+    
+    @Test
+    public void obtainLowNumberedPortsAutomatically() throws Exception {
+        LocalhostMachineProvisioningLocation p = newLocalhostProvisioner();
+        SshMachineLocation m = p.obtain();
+        int start = 983;  //random rarely used port, not that it matters
+        try {
+            int actual = m.obtainPort(PortRanges.fromInteger(start));
+            Assert.assertEquals(actual, start);
+        } finally {
+            m.releasePort(start);
+        }
+
+    }
+
+    @Test
+    public void obtainPortFailsIfInUse() throws Exception {
+        LocalhostMachineProvisioningLocation p = newLocalhostProvisioner();
+        SshMachineLocation m = p.obtain();
+        
+        // Find two ports that are free, rather than risk false-negatives if a port was left open by something else.
+        int start = 48311;
+        while (true) {
+            if (Networking.isPortAvailable(m.getAddress(), start) && Networking.isPortAvailable(m.getAddress(), start+1)) {
+                break;
+            } else {
+                start++;
+            }
+        }
+        PortRange r = PortRanges.fromString(""+start+"-"+(start+1));
+
+        ServerSocket ss = null;
+        try {
+            ss = new ServerSocket(start, 0, m.getAddress());
+            int i1 = m.obtainPort(r);
+            Assert.assertEquals(i1, start+1);
+        } finally {
+            if (ss!=null) ss.close();
+            m.releasePort(start);
+            m.releasePort(start+1);
+        }
+    }
+
+    @Test
+    public void obtainLocationWithGeography() throws Exception {
+        mgmt.getBrooklynProperties().put("brooklyn.location.named.lhx", "localhost");
+        // bogus location so very little chance of it being what maxmind returns!
+        mgmt.getBrooklynProperties().put("brooklyn.location.named.lhx.latitude", 42d);
+        mgmt.getBrooklynProperties().put("brooklyn.location.named.lhx.longitude", -20d);
+        MachineProvisioningLocation<?> p = (MachineProvisioningLocation<?>) mgmt.getLocationRegistry().resolve("named:lhx");
+        SshMachineLocation m = (SshMachineLocation) p.obtain(MutableMap.of());
+        HostGeoInfo geo = HostGeoInfo.fromLocation(m);
+        log.info("Geo info for "+m+" is: "+geo);
+        Assert.assertEquals(geo.latitude, 42d, 0.00001);
+        Assert.assertEquals(geo.longitude, -20d, 0.00001);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
new file mode 100644
index 0000000..fad4567
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.apache.brooklyn.location.Location;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+
+public class LocalhostProvisioningAndAccessTest {
+
+    private LocalManagementContext mgmt;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        mgmt = new LocalManagementContext(BrooklynProperties.Factory.newDefault());
+    }
+    
+    @AfterMethod(alwaysRun = true)
+    public void tearDown(){
+        if (mgmt != null) Entities.destroyAll(mgmt);
+    }
+
+    @Test(groups="Integration")
+    public void testProvisionAndConnect() throws Exception {
+        Location location = mgmt.getLocationRegistry().resolve("localhost");
+        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
+        SshMachineLocation m = ((LocalhostMachineProvisioningLocation)location).obtain();
+        int result = m.execCommands("test", Arrays.asList("echo hello world"));
+        assertEquals(result, 0);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java
new file mode 100644
index 0000000..b3e4f04
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.util.flags.SetFromFlag;
+
+import com.google.common.collect.ImmutableMap;
+
+public class LocationConfigTest {
+
+    // TODO Duplication of LocationConfigTest, but with locations instead of entities
+    
+    private ManagementContext managementContext;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+
+    @Test
+    public void testConfigBagContainsMatchesForConfigKeyName() throws Exception {
+        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
+                .configure("mylocation.myconfig", "myval1")
+                .configure("mylocation.myconfigwithflagname", "myval2"));
+        
+        assertEquals(loc.config().getBag().getAllConfig(), ImmutableMap.of("mylocation.myconfig", "myval1", "mylocation.myconfigwithflagname", "myval2"));
+        assertEquals(loc.config().getLocalBag().getAllConfig(), ImmutableMap.of("mylocation.myconfig", "myval1", "mylocation.myconfigwithflagname", "myval2"));
+        Assert.assertEquals(loc.getAllConfig(true), ImmutableMap.of("mylocation.myconfig", "myval1", "mylocation.myconfigwithflagname", "myval2"));
+        Assert.assertEquals(loc.getAllConfig(false), ImmutableMap.of("mylocation.myconfig", "myval1", "mylocation.myconfigwithflagname", "myval2"));
+    }
+
+    // TODO Note difference compared to Location, where both flag-name + config-key-name are in the ConfigBag
+    @Test
+    public void testConfigBagContainsMatchesForFlagName() throws Exception {
+        // Prefers flag-name, over config-key's name
+        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
+                .configure("myconfigflagname", "myval"));
+        
+        assertEquals(loc.config().getBag().getAllConfig(), ImmutableMap.of("mylocation.myconfigwithflagname", "myval", "myconfigflagname", "myval"));
+        assertEquals(loc.config().getLocalBag().getAllConfig(), ImmutableMap.of("mylocation.myconfigwithflagname", "myval", "myconfigflagname", "myval"));
+        Assert.assertEquals(loc.getAllConfig(true), ImmutableMap.of("mylocation.myconfigwithflagname", "myval", "myconfigflagname", "myval"));
+        Assert.assertEquals(loc.getAllConfig(false), ImmutableMap.of("mylocation.myconfigwithflagname", "myval", "myconfigflagname", "myval"));
+    }
+
+    @Test
+    public void testConfigBagContainsUnmatched() throws Exception {
+        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
+                .configure("notThere", "notThereVal"));
+        
+        assertEquals(loc.config().getBag().getAllConfig(), ImmutableMap.of("notThere", "notThereVal"));
+        assertEquals(loc.config().getLocalBag().getAllConfig(), ImmutableMap.of("notThere", "notThereVal"));
+        Assert.assertEquals(loc.getAllConfig(true), ImmutableMap.of("notThere", "notThereVal"));
+        Assert.assertEquals(loc.getAllConfig(false), ImmutableMap.of("notThere", "notThereVal"));
+    }
+    
+    // TODO Note difference from entity: child's bag contains both the flag-name and the config-key-name
+    @Test
+    public void testChildConfigBagInheritsUnmatchedAtParent() throws Exception {
+        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
+                .configure("mychildlocation.myconfig", "myval1")
+                .configure("notThere", "notThereVal"));
+
+        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
+                .parent(loc));
+
+        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfig", "myval1", "notThere", "notThereVal"));
+        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of());
+        Assert.assertEquals(child.getAllConfig(true), ImmutableMap.of("mychildlocation.myconfig", "myval1", "notThere", "notThereVal"));
+        Assert.assertEquals(child.getAllConfig(false), ImmutableMap.of());
+    }
+    
+    // TODO Fails for location, but passes for entity; not worth fixing here; locations will soon be entities!
+    @Test(groups="WIP")
+    public void testChildConfigBagInheritsFlagNameFromParentSetsOwnConfigKey() throws Exception {
+        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
+                .configure("mychildconfigflagname", "myval"));
+
+        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
+                .parent(loc));
+
+        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "myval"));
+        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of());
+        Assert.assertEquals(child.getAllConfig(true), ImmutableMap.of("mychildlocation.myconfigwithflagname", "myval"));
+        Assert.assertEquals(child.getAllConfig(false), ImmutableMap.of());
+    }
+    
+    @Test
+    public void testChildInheritsFromParent() throws Exception {
+        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
+                .configure("mylocation.myconfig", "myval1"));
+
+        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
+                .parent(loc));
+
+        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mylocation.myconfig", "myval1"));
+        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of());
+        Assert.assertEquals(child.getAllConfig(true), ImmutableMap.of("mylocation.myconfig", "myval1"));
+        Assert.assertEquals(child.getAllConfig(false), ImmutableMap.of());
+    }
+    
+    @Test
+    public void testChildCanOverrideConfigUsingKeyName() throws Exception {
+        LocationInternal location = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
+                .configure("mychildlocation.myconfigwithflagname", "myval")
+                .configure("notThere", "notThereVal"));
+
+        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
+                .parent(location)
+                .configure("mychildlocation.myconfigwithflagname", "overrideMyval")
+                .configure("notThere", "overrideNotThereVal"));
+
+        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal"));
+        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal"));
+        Assert.assertEquals(child.getAllConfig(true), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal"));
+        Assert.assertEquals(child.getAllConfig(false), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal"));
+    }
+    
+    // TODO Note difference compared to Location, where both flag-name + config-key-name are in the ConfigBag
+    @Test
+    public void testChildCanOverrideConfigUsingFlagName() throws Exception {
+        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
+                .configure("mychildlocation.myconfigwithflagname", "myval"));
+
+        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
+                .parent(loc)
+                .configure("mychildconfigflagname", "overrideMyval"));
+
+        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "mychildconfigflagname", "overrideMyval"));
+        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "mychildconfigflagname", "overrideMyval"));
+        Assert.assertEquals(child.getAllConfig(true), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "mychildconfigflagname", "overrideMyval"));
+        Assert.assertEquals(child.getAllConfig(false), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "mychildconfigflagname", "overrideMyval"));
+    }
+    
+    @Test
+    public void testLocationCanOverrideConfigDefaultValue() throws Exception {
+        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class));
+        LocationInternal subloc = managementContext.getLocationManager().createLocation(LocationSpec.create(MySubLocation.class));
+
+        Assert.assertEquals(loc.getConfig(MyLocation.MY_CONFIG_WITH_DEFAULT), "mydefault");
+        Assert.assertEquals(loc.getConfig(ConfigKeys.newStringConfigKey("mylocation.myconfigwithdefault", "", "differentdefault")), "mydefault");
+        
+        Assert.assertEquals(subloc.getConfig(MySubLocation.MY_CONFIG_WITH_DEFAULT), "mysubdefault");
+        Assert.assertEquals(subloc.getConfig(MyLocation.MY_CONFIG_WITH_DEFAULT), "mysubdefault");
+    }
+    
+    @SuppressWarnings("serial")
+    public static class MyLocation extends AbstractLocation {
+        public static final ConfigKey<String> MY_CONFIG = ConfigKeys.newStringConfigKey("mylocation.myconfig");
+
+        @SetFromFlag("myconfigflagname")
+        public static final ConfigKey<String> MY_CONFIG_WITH_FLAGNAME = ConfigKeys.newStringConfigKey("mylocation.myconfigwithflagname");
+        
+        public static final ConfigKey<String> MY_CONFIG_WITH_DEFAULT = ConfigKeys.newStringConfigKey("mylocation.myconfigwithdefault", "", "mydefault");
+    }
+    
+    @SuppressWarnings("serial")
+    public static class MyChildLocation extends AbstractLocation {
+        public static final ConfigKey<String> MY_CHILD_CONFIG = ConfigKeys.newStringConfigKey("mychildlocation.myconfig");
+
+        @SetFromFlag("mychildconfigflagname")
+        public static final ConfigKey<String> MY_CHILD_CONFIG_WITH_FLAGNAME = ConfigKeys.newStringConfigKey("mychildlocation.myconfigwithflagname");
+    }
+    
+    @SuppressWarnings("serial")
+    public static class MySubLocation extends MyLocation {
+        public static final ConfigKey<String> MY_CONFIG_WITH_DEFAULT = ConfigKeys.newConfigKeyWithDefault(MyLocation.MY_CONFIG_WITH_DEFAULT, "mysubdefault");
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigUtilsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigUtilsTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigUtilsTest.java
new file mode 100644
index 0000000..e9197a1
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigUtilsTest.java
@@ -0,0 +1,155 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.io.File;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.util.config.ConfigBag;
+
+@Test
+public class LocationConfigUtilsTest {
+
+    // set these system properties differently if needed to fix your tests
+    public static final String SSH_PRIVATE_KEY_FILE_WITH_TILDE = System.getProperty("sshPrivateKey", "~/.ssh/id_rsa");
+    public static final String SSH_PUBLIC_KEY_FILE_WITH_TILDE = System.getProperty("sshPublicKey", "~/.ssh/id_rsa.pub");
+    // these should work as they are on classpath
+    public static final String SSH_PRIVATE_KEY_FILE_WITH_PASSPHRASE = System.getProperty("sshPrivateKeyWithPassphrase", "/brooklyn/util/crypto/sample_rsa_passphrase.pem");
+    public static final String SSH_PRIVATE_KEY_FILE = System.getProperty("sshPrivateKeySample", "/org/apache/brooklyn/location/basic/sample_id_rsa");
+    public static final String SSH_PUBLIC_KEY_FILE = System.getProperty("sshPublicKeySample", "/org/apache/brooklyn/location/basic/sample_id_rsa.pub");
+    
+    public void testPreferPrivateKeyDataOverFile() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PRIVATE_KEY_DATA, "mydata");
+        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE);
+        
+        LocationConfigUtils.OsCredential creds = LocationConfigUtils.getOsCredential(config).doKeyValidation(false);
+        Assert.assertTrue(creds.hasKey());
+        // warnings, as it is malformed
+        Assert.assertFalse(creds.getWarningMessages().isEmpty());
+
+        String data = creds.getPrivateKeyData();
+        assertEquals(data, "mydata");
+    }
+
+    @Test(expectedExceptions=IllegalStateException.class)
+    public void testInvalidKeyData() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PRIVATE_KEY_DATA, "mydata");
+        
+        LocationConfigUtils.OsCredential creds = LocationConfigUtils.getOsCredential(config).doKeyValidation(false);
+        Assert.assertTrue(creds.hasKey());
+        Assert.assertFalse(creds.getWarningMessages().isEmpty());
+        
+        creds.checkNoErrors();
+    }
+
+    public void testPreferPublicKeyDataOverFileAndNoPrivateKeyRequired() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PUBLIC_KEY_DATA, "mydata");
+        config.put(LocationConfigKeys.PUBLIC_KEY_FILE, SSH_PUBLIC_KEY_FILE);
+        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, "");
+        
+        LocationConfigUtils.OsCredential creds = LocationConfigUtils.getOsCredential(config);
+        String data = creds.getPublicKeyData();
+        assertEquals(data, "mydata");
+        Assert.assertNull(creds.getPreferredCredential());
+        Assert.assertFalse(creds.hasPassword());
+        Assert.assertFalse(creds.hasKey());
+        // and not even any warnings here
+        Assert.assertTrue(creds.getWarningMessages().isEmpty());
+    }
+    
+    @Test(groups="Integration")  // requires ~/.ssh/id_rsa
+    public void testReadsPrivateKeyFileWithTildePath() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE_WITH_TILDE);
+
+        // don't mind if it has a passphrase
+        String data = LocationConfigUtils.getOsCredential(config).doKeyValidation(false).getPreferredCredential();
+        assertTrue(data != null && data.length() > 0);
+    }
+    
+    @Test(groups="Integration")
+    public void testReadsPrivateKeyFileWithPassphrase() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE_WITH_PASSPHRASE);
+
+        LocationConfigUtils.OsCredential cred = LocationConfigUtils.getOsCredential(config).doKeyValidation(false);
+        String data = cred.getPreferredCredential();
+        assertTrue(data != null && data.length() > 0);
+        Assert.assertFalse(data.isEmpty());
+        
+        cred.doKeyValidation(true);
+        try {
+            cred.checkNoErrors();
+            Assert.fail("check should fail as passphrase needed");
+        } catch (IllegalStateException exception) {
+        }
+
+        config.put(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE, "passphrase");
+        cred.checkNoErrors();
+        
+        config.put(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE, "wrong_passphrase");
+        try {
+            cred.checkNoErrors();
+            Assert.fail("check should fail as passphrase needed");
+        } catch (IllegalStateException exception) {
+        }
+    }
+    
+    public void testReadsPrivateKeyFileWithMultipleColonSeparatedFilesWithGoodLast() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, "/path/does/not/exist"+File.pathSeparator+SSH_PRIVATE_KEY_FILE);
+        
+        String data = LocationConfigUtils.getOsCredential(config).getPreferredCredential();
+        assertTrue(data != null && data.length() > 0);
+    }
+    
+    public void testReadsPrivateKeyFileWithMultipleColonSeparatedFilesWithGoodFirst() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE+File.pathSeparator+"/path/does/not/exist");
+
+        String data = LocationConfigUtils.getOsCredential(config).getPreferredCredential();
+        assertTrue(data != null && data.length() > 0);
+    }
+    
+    @Test(groups="Integration")  // requires ~/.ssh/id_rsa
+    public void testReadsPublicKeyFileWithTildePath() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PUBLIC_KEY_FILE, SSH_PUBLIC_KEY_FILE_WITH_TILDE);
+        
+        // don't mind if it has a passphrase
+        String data = LocationConfigUtils.getOsCredential(config).doKeyValidation(false).getPublicKeyData();
+        assertTrue(data != null && data.length() > 0);
+    }
+    
+    public void testInfersPublicKeyFileFromPrivateKeyFile() throws Exception {
+        ConfigBag config = ConfigBag.newInstance();
+        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE);
+        
+        String data = LocationConfigUtils.getOsCredential(config).getPublicKeyData();
+        assertTrue(data != null && data.length() > 0);
+    }
+}


[38/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java b/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
deleted file mode 100644
index 1b66761..0000000
--- a/core/src/main/java/brooklyn/location/basic/SshMachineLocation.java
+++ /dev/null
@@ -1,1031 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static brooklyn.util.GroovyJavaMethods.truth;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PipedInputStream;
-import java.io.PipedOutputStream;
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.security.KeyPair;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.management.Task;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.base.Throwables;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.cache.RemovalListener;
-import com.google.common.cache.RemovalNotification;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.net.HostAndPort;
-import com.google.common.reflect.TypeToken;
-
-import brooklyn.config.BrooklynLogging;
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.config.ConfigUtils;
-import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.event.basic.MapConfigKey;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.OsDetails;
-import brooklyn.location.PortRange;
-import brooklyn.location.PortSupplier;
-import brooklyn.location.access.PortForwardManager;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.crypto.SecureKeys;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.exceptions.RuntimeInterruptedException;
-import brooklyn.util.file.ArchiveUtils;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.guava.KeyTransformingLoadingCache.KeyTransformingSameTypeLoadingCache;
-import brooklyn.util.internal.ssh.ShellTool;
-import brooklyn.util.internal.ssh.SshException;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.internal.ssh.sshj.SshjTool;
-import brooklyn.util.mutex.MutexSupport;
-import brooklyn.util.mutex.WithMutexes;
-import brooklyn.util.net.Urls;
-import brooklyn.util.pool.BasicPool;
-import brooklyn.util.pool.Pool;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.stream.KnownSizeInputStream;
-import brooklyn.util.stream.ReaderInputStream;
-import brooklyn.util.stream.StreamGobbler;
-import brooklyn.util.task.ScheduledTask;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.task.system.internal.ExecWithLoggingHelpers;
-import brooklyn.util.task.system.internal.ExecWithLoggingHelpers.ExecRunner;
-import brooklyn.util.text.Strings;
-import brooklyn.util.time.Duration;
-import groovy.lang.Closure;
-
-/**
- * Operations on a machine that is accessible via ssh.
- * <p>
- * We expose two ways of running scripts.
- * The execCommands method passes lines to bash and is lightweight but fragile.
- * The execScript method creates a script on the remote machine. It is portable but heavier.
- * <p>
- * Additionally there are routines to copyTo, copyFrom; and installTo (which tries a curl, and falls back to copyTo
- * in event the source is accessible by the caller only).
- */
-public class SshMachineLocation extends AbstractLocation implements MachineLocation, PortSupplier, WithMutexes, Closeable {
-
-    /** @deprecated since 0.7.0 shouldn't be public */
-    public static final Logger LOG = LoggerFactory.getLogger(SshMachineLocation.class);
-    /** @deprecated since 0.7.0 shouldn't be public */
-    public static final Logger logSsh = LoggerFactory.getLogger(BrooklynLogging.SSH_IO);
-    
-    // Use a sane timeout when doing a connectivity test
-    private static final int SSHABLE_CONNECT_TIMEOUT = (int)Duration.minutes(2).toMilliseconds();
-
-    public static final ConfigKey<Duration> SSH_CACHE_EXPIRY_DURATION = ConfigKeys.newConfigKey(Duration.class,
-            "sshCacheExpiryDuration", "Expiry time for unused cached ssh connections", Duration.FIVE_MINUTES);
-
-    public static final ConfigKey<MachineDetails> MACHINE_DETAILS = ConfigKeys.newConfigKey(
-            MachineDetails.class,
-            "machineDetails");
-
-    public static final ConfigKey<Boolean> DETECT_MACHINE_DETAILS = ConfigKeys.newBooleanConfigKey("detectMachineDetails",
-            "Attempt to detect machine details automatically. Works with SSH-accessible Linux instances.", true);
-
-    public static final ConfigKey<Iterable<String>> PRIVATE_ADDRESSES = ConfigKeys.newConfigKey(
-            new TypeToken<Iterable<String>>() {},
-            "privateAddresses",
-            "Private addresses of this machine, e.g. those within the private network", 
-            null);
-
-    public static final ConfigKey<Map<Integer, String>> TCP_PORT_MAPPINGS = ConfigKeys.newConfigKey(
-            new TypeToken<Map<Integer, String>>() {},
-            "tcpPortMappings",
-            "NAT'ed ports, giving the mapping from private TCP port to a public host:port", 
-            null);
-
-    @SetFromFlag
-    protected String user;
-
-    @SetFromFlag(nullable = false)
-    protected InetAddress address;
-
-    // TODO should not allow this to be set from flag; it is not persisted so that will be lost
-    // (mainly used for localhost currently so not a big problem)
-    @Nullable  // lazily initialized; use getMutexSupport()
-    @SetFromFlag
-    private transient WithMutexes mutexSupport;
-
-    @SetFromFlag
-    private Set<Integer> usedPorts;
-
-    private volatile MachineDetails machineDetails;
-    private final Object machineDetailsLock = new Object();
-
-    public static final ConfigKey<String> SSH_HOST = BrooklynConfigKeys.SSH_CONFIG_HOST;
-    public static final ConfigKey<Integer> SSH_PORT = BrooklynConfigKeys.SSH_CONFIG_PORT;
-
-    public static final ConfigKey<String> SSH_EXECUTABLE = ConfigKeys.newStringConfigKey("sshExecutable",
-            "Allows an `ssh` executable file to be specified, to be used in place of the default (programmatic) java ssh client");
-    public static final ConfigKey<String> SCP_EXECUTABLE = ConfigKeys.newStringConfigKey("scpExecutable",
-            "Allows an `scp` executable file to be specified, to be used in place of the default (programmatic) java ssh client");
-
-    // TODO remove
-    public static final ConfigKey<String> PASSWORD = SshTool.PROP_PASSWORD;
-    public static final ConfigKey<String> PRIVATE_KEY_FILE = SshTool.PROP_PRIVATE_KEY_FILE;
-    public static final ConfigKey<String> PRIVATE_KEY_DATA = SshTool.PROP_PRIVATE_KEY_DATA;
-    public static final ConfigKey<String> PRIVATE_KEY_PASSPHRASE = SshTool.PROP_PRIVATE_KEY_PASSPHRASE;
-
-    public static final ConfigKey<String> SCRIPT_DIR = ConfigKeys.newStringConfigKey(
-            "scriptDir", "directory where scripts should be placed and executed on the SSH target machine");
-    public static final ConfigKey<Map<String,Object>> SSH_ENV_MAP = new MapConfigKey<Object>(
-            Object.class, "env", "environment variables to pass to the remote SSH shell session");
-
-    public static final ConfigKey<Boolean> ALLOCATE_PTY = SshTool.PROP_ALLOCATE_PTY;
-
-    public static final ConfigKey<OutputStream> STDOUT = new BasicConfigKey<OutputStream>(OutputStream.class, "out");
-    public static final ConfigKey<OutputStream> STDERR = new BasicConfigKey<OutputStream>(OutputStream.class, "err");
-    public static final ConfigKey<Boolean> NO_STDOUT_LOGGING = ConfigKeys.newBooleanConfigKey(
-            "noStdoutLogging", "whether to disable logging of stdout from SSH commands (e.g. for verbose commands)", false);
-    public static final ConfigKey<Boolean> NO_STDERR_LOGGING = ConfigKeys.newBooleanConfigKey(
-            "noStderrLogging", "whether to disable logging of stderr from SSH commands (e.g. for verbose commands)", false);
-    public static final ConfigKey<String> LOG_PREFIX = ConfigKeys.newStringConfigKey("logPrefix");
-
-    public static final ConfigKey<String> LOCAL_TEMP_DIR = SshTool.PROP_LOCAL_TEMP_DIR;
-
-    public static final ConfigKey<Boolean> CLOSE_CONNECTION = ConfigKeys.newBooleanConfigKey("close", "Close the SSH connection after use", false);
-    public static final ConfigKey<String> UNIQUE_ID = ConfigKeys.newStringConfigKey("unique", "Unique ID for the SSH connection");
-
-    /**
-     * Specifies config keys where a change in the value does not require a new SshTool instance,
-     * i.e. they can be specified per command on the tool
-     */
-    // TODO: Fully specify.
-    public static final Set<ConfigKey<?>> REUSABLE_SSH_PROPS = ImmutableSet.of(
-            STDOUT, STDERR, SCRIPT_DIR, CLOSE_CONNECTION,
-            SshTool.PROP_SCRIPT_HEADER, SshTool.PROP_PERMISSIONS, SshTool.PROP_LAST_MODIFICATION_DATE,
-            SshTool.PROP_LAST_ACCESS_DATE, SshTool.PROP_OWNER_UID, SshTool.PROP_SSH_RETRY_DELAY);
-
-    public static final Set<HasConfigKey<?>> ALL_SSH_CONFIG_KEYS =
-            ImmutableSet.<HasConfigKey<?>>builder()
-                    .addAll(ConfigUtils.getStaticKeysOnClass(SshMachineLocation.class))
-                    .addAll(ConfigUtils.getStaticKeysOnClass(SshTool.class))
-                    .build();
-
-    public static final Set<String> ALL_SSH_CONFIG_KEY_NAMES =
-            ImmutableSet.copyOf(Iterables.transform(ALL_SSH_CONFIG_KEYS, new Function<HasConfigKey<?>,String>() {
-                @Override
-                public String apply(HasConfigKey<?> input) {
-                    return input.getConfigKey().getName();
-                }
-            }));
-
-    /**
-     * The set of config keys on this location which become default values for properties when invoking an SSH
-     * operation.
-     */
-    @Beta
-    public static final Set<ConfigKey<?>> SSH_CONFIG_GIVEN_TO_PROPS = ImmutableSet.<ConfigKey<?>>of(
-            SCRIPT_DIR);
-
-    private Task<?> cleanupTask;
-    /** callers should use {@link #getSshPoolCache()} */
-    @Nullable 
-    private transient LoadingCache<Map<String, ?>, Pool<SshTool>> sshPoolCacheOrNull;
-
-    public SshMachineLocation() {
-        this(MutableMap.of());
-    }
-
-    public SshMachineLocation(Map properties) {
-        super(properties);
-        usedPorts = (usedPorts != null) ? Sets.newLinkedHashSet(usedPorts) : Sets.<Integer>newLinkedHashSet();
-    }
-
-    @Override
-    public void init() {
-        super.init();
-
-        // Register any pre-existing port-mappings with the PortForwardManager
-        Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
-        if (tcpPortMappings != null) {
-            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
-            for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
-                int targetPort = entry.getKey();
-                HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
-                if (!publicEndpoint.hasPort()) {
-                    throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
-                }
-                pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
-            }
-        }
-    }
-    
-    private final transient Object poolCacheMutex = new Object();
-    @Nonnull
-    private LoadingCache<Map<String, ?>, Pool<SshTool>> getSshPoolCache() {
-        synchronized (poolCacheMutex) {
-            if (sshPoolCacheOrNull==null) {
-                sshPoolCacheOrNull = buildSshToolPoolCacheLoader();
-                addSshPoolCacheCleanupTask();
-            }
-        }
-        return sshPoolCacheOrNull;
-    }
-
-    private LoadingCache<Map<String, ?>, Pool<SshTool>> buildSshToolPoolCacheLoader() {
-        // TODO: Appropriate numbers for maximum size and expire after access
-        // At the moment every SshMachineLocation instance creates its own pool.
-        // It might make more sense to create one pool and inject it into all SshMachineLocations.
-        Duration expiryDuration = getConfig(SSH_CACHE_EXPIRY_DURATION);
-        
-        LoadingCache<Map<String, ?>, Pool<SshTool>> delegate = CacheBuilder.newBuilder()
-                .maximumSize(10)
-                .expireAfterAccess(expiryDuration.toMilliseconds(), TimeUnit.MILLISECONDS)
-                .recordStats()
-                .removalListener(new RemovalListener<Map<String, ?>, Pool<SshTool>>() {
-                    // TODO: Does it matter that this is synchronous? - Can closing pools cause long delays?
-                    @Override
-                    public void onRemoval(RemovalNotification<Map<String, ?>, Pool<SshTool>> notification) {
-                        Pool<SshTool> removed = notification.getValue();
-                        if (removed == null) {
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("Pool evicted from SshTool cache is null so we can't call pool.close(). " +
-                                        "It's probably already been garbage collected. Eviction cause: {} ",
-                                        notification.getCause().name());
-                            }
-                        } else {
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("{} evicted from SshTool cache. Eviction cause: {}",
-                                        removed, notification.getCause().name());
-                            }
-                            try {
-                                removed.close();
-                            } catch (IOException e) {
-                                if (LOG.isDebugEnabled()) {
-                                    LOG.debug("Exception closing "+removed, e);
-                                }
-                            }
-                        }
-                    }
-                })
-                .build(new CacheLoader<Map<String, ?>, Pool<SshTool>>() {
-                    public Pool<SshTool> load(Map<String, ?> properties) {
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("{} building ssh pool for {} with properties: {}",
-                                    new Object[] {this, getSshHostAndPort(), properties});
-                        }
-                        return buildPool(properties);
-                    }
-                });
-
-        final Set<String> reusableSshProperties = ImmutableSet.copyOf(
-                Iterables.transform(REUSABLE_SSH_PROPS, new Function<ConfigKey<?>, String>() {
-                    @Override public String apply(ConfigKey<?> input) {
-                        return input.getName();
-                    }
-                }));
-        // Groovy-eclipse compiler refused to compile `KeyTransformingSameTypeLoadingCache.from(...)`
-        return new KeyTransformingSameTypeLoadingCache<Map<String, ?>, Pool<SshTool>>(
-                delegate,
-                new Function<Map<String, ?>, Map<String, ?>>() {
-                    @Override
-                    public Map<String, ?> apply(@Nullable Map<String, ?> input) {
-                        Map<String, Object> copy = new HashMap<String, Object>(input);
-                        copy.keySet().removeAll(reusableSshProperties);
-                        return copy;
-                    }
-                });
-    }
-
-    private BasicPool<SshTool> buildPool(final Map<String, ?> properties) {
-        return BasicPool.<SshTool>builder()
-                .name(getDisplayName()+"@"+address+":"+getPort()+
-                        (config().getRaw(SSH_HOST).isPresent() ? "("+getConfig(SSH_HOST)+":"+getConfig(SSH_PORT)+")" : "")+
-                        ":hash"+System.identityHashCode(this))
-                .supplier(new Supplier<SshTool>() {
-                        @Override public SshTool get() {
-                            return connectSsh(properties);
-                        }})
-                .viabilityChecker(new Predicate<SshTool>() {
-                        @Override public boolean apply(SshTool input) {
-                            return input != null && input.isConnected();
-                        }})
-                .closer(new Function<SshTool,Void>() {
-                        @Override public Void apply(SshTool input) {
-                            if (LOG.isDebugEnabled()) {
-                                LOG.debug("{} closing pool for {}", this, input);
-                            }
-                            try {
-                                input.disconnect();
-                            } catch (Exception e) {
-                                if (logSsh.isDebugEnabled()) logSsh.debug("On machine "+SshMachineLocation.this+", ssh-disconnect failed", e);
-                            }
-                            return null;
-                        }})
-                .build();
-    }
-
-    @Override
-    public SshMachineLocation configure(Map<?,?> properties) {
-        super.configure(properties);
-
-        // TODO Note that check for addresss!=null is done automatically in super-constructor, in FlagUtils.checkRequiredFields
-        // Yikes, dangerous code for accessing fields of sub-class in super-class' constructor! But getting away with it so far!
-
-        boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
-        if (!deferConstructionChecks) {
-            if (getDisplayName() == null) {
-                setDisplayName((truth(user) ? user+"@" : "") + address.getHostName());
-            }
-        }
-        return this;
-    }
-    
-    private transient final Object mutexSupportCreationLock = new Object();
-    protected WithMutexes getMutexSupport() {
-        synchronized (mutexSupportCreationLock) {
-            // create on demand so that it is not null after serialization
-            if (mutexSupport == null) {
-                mutexSupport = new MutexSupport();
-            }
-            return mutexSupport;
-        }
-    }
-    
-    protected void addSshPoolCacheCleanupTask() {
-        if (cleanupTask!=null && !cleanupTask.isDone()) {
-            return;
-        }
-        if (getManagementContext()==null || getManagementContext().getExecutionManager()==null) {
-            LOG.debug("No management context for "+this+"; ssh-pool cache will only be closed when machine is closed");
-            return;
-        }
-        
-        Callable<Task<?>> cleanupTaskFactory = new Callable<Task<?>>() {
-            @Override public Task<Void> call() {
-                return Tasks.<Void>builder().dynamic(false).tag(BrooklynTaskTags.TRANSIENT_TASK_TAG)
-                    .name("ssh-location cache cleaner").body(new Callable<Void>() {
-                    @Override public Void call() {
-                        try {
-                            if (sshPoolCacheOrNull != null) sshPoolCacheOrNull.cleanUp();
-                            if (!SshMachineLocation.this.isManaged()) {
-                                if (sshPoolCacheOrNull != null) sshPoolCacheOrNull.invalidateAll();
-                                cleanupTask.cancel(false);
-                                sshPoolCacheOrNull = null;
-                            }
-                            return null;
-                        } catch (Exception e) {
-                            // Don't rethrow: the behaviour of executionManager is different from a scheduledExecutorService,
-                            // if we throw an exception, then our task will never get executed again
-                            LOG.warn("Problem cleaning up ssh-pool-cache", e);
-                            return null;
-                        } catch (Throwable t) {
-                            LOG.warn("Problem cleaning up ssh-pool-cache (rethrowing)", t);
-                            throw Exceptions.propagate(t);
-                        }
-                    }}).build();
-            }
-        };
-        
-        Duration expiryDuration = getConfig(SSH_CACHE_EXPIRY_DURATION);
-        cleanupTask = getManagementContext().getExecutionManager().submit(new ScheduledTask(
-            MutableMap.of("displayName", "scheduled[ssh-location cache cleaner]"), cleanupTaskFactory).period(expiryDuration));
-    }
-    
-    // TODO close has been used for a long time to perform clean-up wanted on unmanagement, but that's not clear; 
-    // we should probably expose a mechanism such as that in Entity (or re-use Entity for locations!)
-    @Override
-    public void close() throws IOException {
-        if (sshPoolCacheOrNull != null) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("{} invalidating all entries in ssh pool cache. Final stats: {}", this, sshPoolCacheOrNull.stats());
-            }
-            sshPoolCacheOrNull.invalidateAll();
-        }
-        if (cleanupTask != null) {
-            cleanupTask.cancel(false);
-            cleanupTask = null;
-            sshPoolCacheOrNull = null;
-        }
-    }
-
-    // should not be necessary, and causes objects to be kept around a lot longer than desired
-//    @Override
-//    protected void finalize() throws Throwable {
-//        try {
-//            close();
-//        } finally {
-//            super.finalize();
-//        }
-//    }
-
-    @Override
-    public InetAddress getAddress() {
-        return address;
-    }
-
-    @Override
-    public String getHostname() {
-        String hostname = address.getHostName();
-        return (hostname == null || hostname.equals(address.getHostAddress())) ? null : hostname;
-    }
-    
-    @Override
-    public Set<String> getPublicAddresses() {
-        return ImmutableSet.of(address.getHostAddress());
-    }
-    
-    @Override
-    public Set<String> getPrivateAddresses() {
-        Iterable<String> result = getConfig(PRIVATE_ADDRESSES);
-        return (result == null) ? ImmutableSet.<String>of() : ImmutableSet.copyOf(result);
-    }
-
-    public HostAndPort getSshHostAndPort() {
-        String host = getConfig(SSH_HOST);
-        if (host == null || Strings.isEmpty(host))
-            host = address.getHostName();
-        Integer port = getConfig(SSH_PORT);
-        if (port == null || port == 0)
-            port = 22;
-        return HostAndPort.fromParts(host, port);
-    }
-
-    public String getUser() {
-        if (!truth(user)) {
-            if (config().getLocalRaw(SshTool.PROP_USER).isPresent()) {
-                LOG.warn("User configuration for "+this+" set after deployment; deprecated behaviour may not be supported in future versions");
-            }
-            return getConfig(SshTool.PROP_USER);
-        }
-        return user;
-    }
-
-    /** port for SSHing */
-    public int getPort() {
-        return getConfig(SshTool.PROP_PORT);
-    }
-
-    protected <T> T execSsh(final Map<String, ?> props, final Function<ShellTool, T> task) {
-        final LoadingCache<Map<String, ?>, Pool<SshTool>> sshPoolCache = getSshPoolCache();
-        Pool<SshTool> pool = sshPoolCache.getUnchecked(props);
-        if (LOG.isTraceEnabled()) {
-            LOG.trace("{} execSsh got pool: {}", this, pool);
-        }
-
-        if (truth(props.get(CLOSE_CONNECTION.getName()))) {
-            Function<SshTool, T> close = new Function<SshTool, T>() {
-                @Override
-                public T apply(SshTool input) {
-                    T result = task.apply(input);
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("{} invalidating all sshPoolCache entries: {}", SshMachineLocation.this, sshPoolCache.stats().toString());
-                    }
-                    sshPoolCache.invalidateAll();
-                    sshPoolCache.cleanUp();
-                    return result;
-                }
-            };
-            return pool.exec(close);
-        } else {
-            return pool.exec(task);
-        }
-    }
-
-    protected SshTool connectSsh() {
-        return connectSsh(ImmutableMap.of());
-    }
-
-    protected boolean previouslyConnected = false;
-    protected SshTool connectSsh(Map props) {
-        try {
-            if (!truth(user)) {
-                String newUser = getUser();
-                if (LOG.isTraceEnabled()) LOG.trace("For "+this+", setting user in connectSsh: oldUser="+user+"; newUser="+newUser);
-                user = newUser;
-            }
-
-            ConfigBag args = new ConfigBag()
-                .configure(SshTool.PROP_USER, user)
-                // default value of host, overridden if SSH_HOST is supplied
-                .configure(SshTool.PROP_HOST, address.getHostName());
-
-            for (Map.Entry<String,Object> entry: config().getBag().getAllConfig().entrySet()) {
-                String key = entry.getKey();
-                if (key.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
-                    key = Strings.removeFromStart(key, SshTool.BROOKLYN_CONFIG_KEY_PREFIX);
-                } else if (ALL_SSH_CONFIG_KEY_NAMES.contains(entry.getKey())) {
-                    // key should be included, and does not need to be changed
-
-                    // TODO make this config-setting mechanism more universal
-                    // currently e.g. it will not admit a tool-specific property.
-                    // thinking either we know about the tool here,
-                    // or we don't allow unadorned keys to be set
-                    // (require use of BROOKLYN_CONFIG_KEY_PREFIX)
-                } else {
-                    // this key is not applicable here; ignore it
-                    continue;
-                }
-                args.putStringKey(key, entry.getValue());
-            }
-
-            // Explicit props trump all.
-            args.putAll(props);
-
-            if (LOG.isTraceEnabled()) LOG.trace("creating ssh session for "+args);
-            if (!user.equals(args.get(SshTool.PROP_USER))) {
-                LOG.warn("User mismatch configuring ssh for "+this+": preferring user "+args.get(SshTool.PROP_USER)+" over "+user);
-                user = args.get(SshTool.PROP_USER);
-            }
-
-            // look up tool class
-            String sshToolClass = args.get(SshTool.PROP_TOOL_CLASS);
-            if (sshToolClass==null) sshToolClass = SshjTool.class.getName();
-            SshTool ssh = (SshTool) Class.forName(sshToolClass).getConstructor(Map.class).newInstance(args.getAllConfig());
-
-            if (LOG.isTraceEnabled()) LOG.trace("using ssh-tool {} (of type {}); props ", ssh, sshToolClass);
-
-            Tasks.setBlockingDetails("Opening ssh connection");
-            try { ssh.connect(); } finally { Tasks.setBlockingDetails(null); }
-            previouslyConnected = true;
-            return ssh;
-        } catch (Exception e) {
-            if (previouslyConnected) throw Throwables.propagate(e);
-            // subsequence connection (above) most likely network failure, our remarks below won't help
-            // on first connection include additional information if we can't connect, to help with debugging
-            String rootCause = Throwables.getRootCause(e).getMessage();
-            throw new IllegalStateException("Cannot establish ssh connection to "+user+" @ "+this+
-                    (rootCause!=null && !rootCause.isEmpty() ? " ("+rootCause+")" : "")+". \n"+
-                    "Ensure that passwordless and passphraseless ssh access is enabled using standard keys from ~/.ssh or " +
-                    "as configured in brooklyn.properties. " +
-                    "Check that the target host is accessible, " +
-                    "that credentials are correct (location and permissions if using a key), " +
-                    "that the SFTP subsystem is available on the remote side, " +
-                    "and that there is sufficient random noise in /dev/random on both ends. " +
-                    "To debug less common causes, see the original error in the trace or log, and/or enable 'net.schmizz' (sshj) logging."
-                    , e);
-        }
-    }
-
-    // TODO submitCommands and submitScript which submit objects we can subsequently poll (cf JcloudsSshMachineLocation.submitRunScript)
-
-    /**
-     * Executes a set of commands, directly on the target machine (no wrapping in script).
-     * Joined using {@literal ;} by default.
-     * <p>
-     * Stdout and stderr will be logged automatically to brooklyn.SSH logger, unless the
-     * flags 'noStdoutLogging' and 'noStderrLogging' are set. To set a logging prefix, use
-     * the flag 'logPrefix'.
-     * <p>
-     * Currently runs the commands in an interactive/login shell
-     * by passing each as a line to bash. To terminate early, use:
-     * <pre>
-     * foo || exit 1
-     * </pre>
-     * It may be desirable instead, in some situations, to wrap as:
-     * <pre>
-     * { line1 ; } && { line2 ; } ...
-     * </pre>
-     * and run as a single command (possibly not as an interacitve/login
-     * shell) causing the script to exit on the first command which fails.
-     * <p>
-     * Currently this has to be done by the caller.
-     * (If desired we can add a flag {@code exitIfAnyNonZero} to support this mode,
-     * and/or {@code commandPrepend} and {@code commandAppend} similar to
-     * (currently supported in SshjTool) {@code separator}.)
-     */
-    public int execCommands(String summaryForLogging, List<String> commands) {
-        return execCommands(MutableMap.<String,Object>of(), summaryForLogging, commands, MutableMap.<String,Object>of());
-    }
-    public int execCommands(Map<String,?> props, String summaryForLogging, List<String> commands) {
-        return execCommands(props, summaryForLogging, commands, MutableMap.<String,Object>of());
-    }
-    public int execCommands(String summaryForLogging, List<String> commands, Map<String,?> env) {
-        return execCommands(MutableMap.<String,Object>of(), summaryForLogging, commands, env);
-    }
-    public int execCommands(Map<String,?> props, String summaryForLogging, List<String> commands, Map<String,?> env) {
-        return newExecWithLoggingHelpers().execCommands(augmentPropertiesWithSshConfigGivenToProps(props), summaryForLogging, commands, env);
-    }
-
-    /**
-     * Executes a set of commands, wrapped as a script sent to the remote machine.
-     * <p>
-     * Stdout and stderr will be logged automatically to brooklyn.SSH logger, unless the
-     * flags 'noStdoutLogging' and 'noStderrLogging' are set. To set a logging prefix, use
-     * the flag 'logPrefix'.
-     */
-    public int execScript(String summaryForLogging, List<String> commands) {
-        return execScript(MutableMap.<String,Object>of(), summaryForLogging, commands, MutableMap.<String,Object>of());
-    }
-    public int execScript(Map<String,?> props, String summaryForLogging, List<String> commands) {
-        return execScript(props, summaryForLogging, commands, MutableMap.<String,Object>of());
-    }
-    public int execScript(String summaryForLogging, List<String> commands, Map<String,?> env) {
-        return execScript(MutableMap.<String,Object>of(), summaryForLogging, commands, env);
-    }
-    public int execScript(Map<String,?> props, String summaryForLogging, List<String> commands, Map<String,?> env) {
-        return newExecWithLoggingHelpers().execScript(augmentPropertiesWithSshConfigGivenToProps(props), summaryForLogging, commands, env);
-    }
-
-    private Map<String, Object> augmentPropertiesWithSshConfigGivenToProps(Map<String, ?> props) {
-        Map<String,Object> augmentedProps = Maps.newHashMap(props);
-        for (ConfigKey<?> config : SSH_CONFIG_GIVEN_TO_PROPS) {
-            if (!augmentedProps.containsKey(config.getName()) && hasConfig(config, true))
-                augmentedProps.put(config.getName(), getConfig(config));
-        }
-        return augmentedProps;
-    }
-
-    protected ExecWithLoggingHelpers newExecWithLoggingHelpers() {
-        return new ExecWithLoggingHelpers("SSH") {
-            @Override
-            protected <T> T execWithTool(MutableMap<String, Object> props, Function<ShellTool, T> function) {
-                return execSsh(props, function);
-            }
-            @Override
-            protected void preExecChecks() {
-                Preconditions.checkNotNull(address, "host address must be specified for ssh");
-            }
-            @Override
-            protected String constructDefaultLoggingPrefix(ConfigBag execFlags) {
-                String hostname = getAddress().getHostName();
-                Integer port = execFlags.peek(SshTool.PROP_PORT);
-                if (port == null) port = getConfig(ConfigUtils.prefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, SshTool.PROP_PORT));
-                return (user != null ? user+"@" : "") + hostname + (port != null ? ":"+port : "");
-            }
-            @Override
-            protected String getTargetName() {
-                return ""+SshMachineLocation.this;
-            }
-        }.logger(logSsh);
-    }
-
-    /**
-     * @deprecated since 0.7.0; use {@link #execCommands(Map, String, List, Map), and rely on that calling the execWithLogging
-     */
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    @Deprecated
-    protected int execWithLogging(Map<String,?> props, String summaryForLogging, List<String> commands, Map env, final Closure<Integer> execCommand) {
-        return newExecWithLoggingHelpers().execWithLogging(props, summaryForLogging, commands, env, new ExecRunner() {
-                @Override public int exec(ShellTool ssh, Map<String, ?> flags, List<String> cmds, Map<String, ?> env) {
-                    return execCommand.call(ssh, flags, cmds, env);
-                }});
-    }
-
-    public int copyTo(File src, File destination) {
-        return copyTo(MutableMap.<String,Object>of(), src, destination);
-    }
-    public int copyTo(Map<String,?> props, File src, File destination) {
-        return copyTo(props, src, destination.getPath());
-    }
-
-    public int copyTo(File src, String destination) {
-        return copyTo(MutableMap.<String,Object>of(), src, destination);
-    }
-    public int copyTo(Map<String,?> props, File src, String destination) {
-        Preconditions.checkNotNull(address, "Host address must be specified for scp");
-        Preconditions.checkArgument(src.exists(), "File %s must exist for scp", src.getPath());
-        try {
-            return copyTo(props, new FileInputStream(src), src.length(), destination);
-        } catch (FileNotFoundException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-    public int copyTo(Reader src, String destination) {
-        return copyTo(MutableMap.<String,Object>of(), src, destination);
-    }
-    public int copyTo(Map<String,?> props, Reader src, String destination) {
-        return copyTo(props, new ReaderInputStream(src), destination);
-    }
-    public int copyTo(InputStream src, String destination) {
-        return copyTo(MutableMap.<String,Object>of(), src, destination);
-    }
-    public int copyTo(InputStream src, long filesize, String destination) {
-        return copyTo(MutableMap.<String,Object>of(), src, filesize, destination);
-    }
-    // FIXME the return code is not a reliable indicator of success or failure
-    public int copyTo(final Map<String,?> props, final InputStream src, final long filesize, final String destination) {
-        if (filesize == -1) {
-            return copyTo(props, src, destination);
-        } else {
-            return execSsh(props, new Function<ShellTool,Integer>() {
-                public Integer apply(ShellTool ssh) {
-                    return ((SshTool) ssh).copyToServer(props, new KnownSizeInputStream(src, filesize), destination);
-                }});
-        }
-    }
-    // FIXME the return code is not a reliable indicator of success or failure
-    // Closes input stream before returning
-    public int copyTo(final Map<String,?> props, final InputStream src, final String destination) {
-        return execSsh(props, new Function<ShellTool,Integer>() {
-            public Integer apply(ShellTool ssh) {
-                return ((SshTool)ssh).copyToServer(props, src, destination);
-            }});
-    }
-
-    // FIXME the return code is not a reliable indicator of success or failure
-    public int copyFrom(String remote, String local) {
-        return copyFrom(MutableMap.<String,Object>of(), remote, local);
-    }
-    public int copyFrom(final Map<String,?> props, final String remote, final String local) {
-        return execSsh(props, new Function<ShellTool,Integer>() {
-            public Integer apply(ShellTool ssh) {
-                return ((SshTool)ssh).copyFromServer(props, remote, new File(local));
-            }});
-    }
-
-    public int installTo(String url, String destPath) {
-        return installTo(MutableMap.<String, Object>of(), url, destPath);
-    }
-
-    public int installTo(Map<String,?> props, String url, String destPath) {
-        return installTo(ResourceUtils.create(this), props, url, destPath);
-    }
-
-    public int installTo(ResourceUtils loader, String url, String destPath) {
-        return installTo(loader, MutableMap.<String, Object>of(), url, destPath);
-    }
-
-    /**
-     * Installs the given URL at the indicated destination path.
-     * <p>
-     * Attempts to curl the source URL on the remote machine,
-     * then if that fails, loads locally (from classpath or file) and transfers.
-     * <p>
-     * Use {@link ArchiveUtils} to handle directories and their contents properly.
-     *
-     * TODO allow s3://bucket/file URIs for AWS S3 resources
-     * TODO use PAX-URL style URIs for maven artifacts
-     * TODO use subtasks here for greater visibility?; deprecate in favour of SshTasks.installFromUrl?
-     *
-     * @param utils A {@link ResourceUtils} that can resolve the source URLs
-     * @param url The source URL to be installed
-     * @param destPath The file to be created on the destination
-     *
-     * @see ArchiveUtils#deploy(String, SshMachineLocation, String)
-     * @see ArchiveUtils#deploy(String, SshMachineLocation, String, String)
-     * @see ResourceUtils#getResourceFromUrl(String)
-     */
-    public int installTo(ResourceUtils utils, Map<String,?> props, String url, String destPath) {
-        LOG.debug("installing {} to {} on {}, attempting remote curl", new Object[] { url, destPath, this });
-
-        try {
-            PipedInputStream insO = new PipedInputStream(); OutputStream outO = new PipedOutputStream(insO);
-            PipedInputStream insE = new PipedInputStream(); OutputStream outE = new PipedOutputStream(insE);
-            StreamGobbler sgsO = new StreamGobbler(insO, null, LOG); sgsO.setLogPrefix("[curl @ "+address+":stdout] ").start();
-            StreamGobbler sgsE = new StreamGobbler(insE, null, LOG); sgsE.setLogPrefix("[curl @ "+address+":stdout] ").start();
-            Map<String, ?> sshProps = MutableMap.<String, Object>builder().putAll(props).put("out", outO).put("err", outE).build();
-            int result = execScript(sshProps, "copying remote resource "+url+" to server",  ImmutableList.of(
-                    BashCommands.INSTALL_CURL, // TODO should hold the 'installing' mutex
-                    "mkdir -p `dirname '"+destPath+"'`",
-                    "curl "+url+" -L --silent --insecure --show-error --fail --connect-timeout 60 --max-time 600 --retry 5 -o '"+destPath+"'"));
-            sgsO.close();
-            sgsE.close();
-            if (result != 0) {
-                LOG.debug("installing {} to {} on {}, curl failed, attempting local fetch and copy", new Object[] { url, destPath, this });
-                try {
-                    Tasks.setBlockingDetails("retrieving resource "+url+" for copying across");
-                    InputStream stream = utils.getResourceFromUrl(url);
-                    Tasks.setBlockingDetails("copying resource "+url+" to server");
-                    result = copyTo(props, stream, destPath);
-                } finally {
-                    Tasks.setBlockingDetails(null);
-                }
-            }
-            if (result == 0) {
-                LOG.debug("installing {} complete; {} on {}", new Object[] { url, destPath, this });
-            } else {
-                LOG.warn("installing {} failed; {} on {}: {}", new Object[] { url, destPath, this, result });
-            }
-            return result;
-        } catch (IOException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "SshMachineLocation["+getDisplayName()+":"+address+":"+getPort()+"@"+getId()+"]";
-    }
-
-    @Override
-    public String toVerboseString() {
-        return Objects.toStringHelper(this).omitNullValues()
-                .add("id", getId()).add("name", getDisplayName())
-                .add("user", getUser()).add("address", getAddress()).add("port", getPort())
-                .add("parentLocation", getParent())
-                .toString();
-    }
-
-    /**
-     * @see #obtainPort(PortRange)
-     * @see PortRanges#ANY_HIGH_PORT
-     */
-    @Override
-    public boolean obtainSpecificPort(int portNumber) {
-        synchronized (usedPorts) {
-            // TODO Does not yet check if the port really is free on this machine
-            if (usedPorts.contains(portNumber)) {
-                return false;
-            } else {
-                usedPorts.add(portNumber);
-                return true;
-            }
-        }
-    }
-
-    @Override
-    public int obtainPort(PortRange range) {
-        synchronized (usedPorts) {
-            for (int p: range)
-                if (obtainSpecificPort(p)) return p;
-            if (LOG.isDebugEnabled()) LOG.debug("unable to find port in {} on {}; returning -1", range, this);
-            return -1;
-        }
-    }
-
-    @Override
-    public void releasePort(int portNumber) {
-        synchronized (usedPorts) {
-            usedPorts.remove((Object) portNumber);
-        }
-    }
-
-    public boolean isSshable() {
-        String cmd = "date";
-        try {
-            try {
-                Socket s = new Socket();
-                s.connect(new InetSocketAddress(getAddress(), getPort()), SSHABLE_CONNECT_TIMEOUT);
-                s.close();
-            } catch (IOException e) {
-                if (LOG.isDebugEnabled()) LOG.debug(""+this+" not [yet] reachable (socket "+getAddress()+":"+getPort()+"): "+e);
-                return false;
-            }
-            // this should do execCommands because sftp subsystem might not be available (or sometimes seems to take a while for it to become so?)
-            int result = execCommands(MutableMap.<String,Object>of(), "isSshable", ImmutableList.of(cmd));
-            if (result == 0) {
-                return true;
-            } else {
-                if (LOG.isDebugEnabled()) LOG.debug("Not reachable: {}, executing `{}`, exit code {}", new Object[] {this, cmd, result});
-                return false;
-            }
-        } catch (SshException e) {
-            if (LOG.isDebugEnabled()) LOG.debug("Exception checking if "+this+" is reachable; assuming not", e);
-            return false;
-        } catch (IllegalStateException e) {
-            if (LOG.isDebugEnabled()) LOG.debug("Exception checking if "+this+" is reachable; assuming not", e);
-            return false;
-        } catch (RuntimeException e) {
-            if (Exceptions.getFirstThrowableOfType(e, IOException.class) != null) {
-                if (LOG.isDebugEnabled()) LOG.debug("Exception checking if "+this+" is reachable; assuming not", e);
-                return false;
-            } else {
-                throw e;
-            }
-        }
-    }
-
-    @Override
-    public OsDetails getOsDetails() {
-        return getMachineDetails().getOsDetails();
-    }
-
-    @Override
-    public MachineDetails getMachineDetails() {
-        synchronized (machineDetailsLock) {
-            if (machineDetails == null) {
-                machineDetails = getConfig(MACHINE_DETAILS);
-            }
-            if (machineDetails == null) {
-                machineDetails = inferMachineDetails();
-            }
-        }
-        return machineDetails;
-    }
-
-    protected MachineDetails inferMachineDetails() {
-        boolean detectionEnabled = getConfig(DETECT_MACHINE_DETAILS);
-        if (!detectionEnabled)
-            return new BasicMachineDetails(new BasicHardwareDetails(-1, -1), new BasicOsDetails("UNKNOWN", "UNKNOWN", "UNKNOWN"));
-
-        Tasks.setBlockingDetails("Waiting for machine details");
-        try {
-            return BasicMachineDetails.forSshMachineLocation(this);
-        } finally {
-            Tasks.resetBlockingDetails();
-        }
-    }
-
-    @Override
-    public void acquireMutex(String mutexId, String description) throws RuntimeInterruptedException {
-        try {
-            getMutexSupport().acquireMutex(mutexId, description);
-        } catch (InterruptedException ie) {
-            throw new RuntimeInterruptedException("Interrupted waiting for mutex: " + mutexId, ie);
-        }
-    }
-
-    @Override
-    public boolean tryAcquireMutex(String mutexId, String description) {
-        return getMutexSupport().tryAcquireMutex(mutexId, description);
-    }
-
-    @Override
-    public void releaseMutex(String mutexId) {
-        getMutexSupport().releaseMutex(mutexId);
-    }
-
-    @Override
-    public boolean hasMutex(String mutexId) {
-        return getMutexSupport().hasMutex(mutexId);
-    }
-
-    //We want the SshMachineLocation to be serializable and therefore the pool needs to be dealt with correctly.
-    //In this case we are not serializing the pool (we made the field transient) and create a new pool when deserialized.
-    //This fix is currently needed for experiments, but isn't used in normal Brooklyn usage.
-    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-        getSshPoolCache();
-    }
-
-    /** returns the un-passphrased key-pair info if a key is being used, or else null */
-    public KeyPair findKeyPair() {
-        String fn = getConfig(SshTool.PROP_PRIVATE_KEY_FILE);
-        ResourceUtils r = ResourceUtils.create(this);
-        if (fn!=null) return SecureKeys.readPem(r.getResourceFromUrl(fn), getConfig(SshTool.PROP_PRIVATE_KEY_PASSPHRASE));
-        String data = getConfig(SshTool.PROP_PRIVATE_KEY_DATA);
-        if (data!=null) return SecureKeys.readPem(new ReaderInputStream(new StringReader(data)), getConfig(SshTool.PROP_PRIVATE_KEY_PASSPHRASE));
-        if (findPassword()!=null)
-            // if above not specified, and password is, use password
-            return null;
-        // fall back to id_rsa and id_dsa
-        if (new File( Urls.mergePaths(System.getProperty("user.home"), ".ssh/id_rsa") ).exists() )
-            return SecureKeys.readPem(r.getResourceFromUrl("~/.ssh/id_rsa"), getConfig(SshTool.PROP_PRIVATE_KEY_PASSPHRASE));
-        if (new File( Urls.mergePaths(System.getProperty("user.home"), ".ssh/id_dsa") ).exists() )
-            return SecureKeys.readPem(r.getResourceFromUrl("~/.ssh/id_dsa"), getConfig(SshTool.PROP_PRIVATE_KEY_PASSPHRASE));
-        LOG.warn("Unable to extract any key or passphrase data in request to findKeyPair for "+this);
-        return null;
-    }
-
-    /** returns the password being used to log in, if a password is being used, or else null */
-    public String findPassword() {
-        return getConfig(SshTool.PROP_PASSWORD);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/SupportsPortForwarding.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/SupportsPortForwarding.java b/core/src/main/java/brooklyn/location/basic/SupportsPortForwarding.java
deleted file mode 100644
index 5465ef4..0000000
--- a/core/src/main/java/brooklyn/location/basic/SupportsPortForwarding.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import brooklyn.util.net.Cidr;
-
-import com.google.common.net.HostAndPort;
-
-public interface SupportsPortForwarding {
-
-    /** returns an endpoint suitable for contacting the indicated private port on this object,
-     * from the given Cidr, creating it if necessary and possible; 
-     * may return null if forwarding not available 
-     */
-    public HostAndPort getSocketEndpointFor(Cidr accessor, int privatePort);
-    
-    /** marker on a location to indicate that port forwarding should be done automatically
-     * for attempts to access from Brooklyn
-     */
-    public interface RequiresPortForwarding extends SupportsPortForwarding {
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java b/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java
deleted file mode 100644
index 3504ec0..0000000
--- a/core/src/main/java/brooklyn/location/basic/WinRmMachineLocation.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import org.apache.commons.codec.binary.Base64;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.net.HostAndPort;
-import com.google.common.reflect.TypeToken;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.OsDetails;
-import brooklyn.location.access.PortForwardManager;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.time.Duration;
-import brooklyn.util.time.Time;
-import io.cloudsoft.winrm4j.winrm.WinRmTool;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
-public class WinRmMachineLocation extends AbstractLocation implements MachineLocation {
-
-    private static final Logger LOG = LoggerFactory.getLogger(WinRmMachineLocation.class);
-
-    // FIXME Respect `port` config when using {@link WinRmTool}
-    public static final ConfigKey<Integer> WINRM_PORT = ConfigKeys.newIntegerConfigKey(
-            "port",
-            "WinRM port to use when connecting to the remote machine",
-            5985);
-    
-    // TODO merge with {link SshTool#PROP_USER} and {@link SshMachineLocation#user}
-    public static final ConfigKey<String> USER = ConfigKeys.newStringConfigKey("user",
-            "Username to use when connecting to the remote machine");
-
-    // TODO merge with {link SshTool#PROP_PASSWORD}
-    public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password",
-            "Password to use when connecting to the remote machine");
-
-    public static final ConfigKey<Integer> COPY_FILE_CHUNK_SIZE_BYTES = ConfigKeys.newIntegerConfigKey("windows.copy.file.size.bytes",
-            "Size of file chunks (in bytes) to be used when copying a file to the remote server", 1024);
-
-     public static final ConfigKey<InetAddress> ADDRESS = ConfigKeys.newConfigKey(
-            InetAddress.class,
-            "address",
-            "Address of the remote machine");
-
-    public static final ConfigKey<Integer> EXECUTION_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
-            "windows.exec.attempts",
-            "Number of attempts to execute a remote command",
-            1);
-    
-    // TODO See SshTool#PROP_SSH_TRIES, where it was called "sshTries"; remove duplication? Merge into one well-named thing?
-    public static final ConfigKey<Integer> EXEC_TRIES = ConfigKeys.newIntegerConfigKey(
-            "execTries", 
-            "Max number of times to attempt WinRM operations", 
-            10);
-
-    public static final ConfigKey<Iterable<String>> PRIVATE_ADDRESSES = ConfigKeys.newConfigKey(
-            new TypeToken<Iterable<String>>() {},
-            "privateAddresses",
-            "Private addresses of this machine, e.g. those within the private network", 
-            null);
-
-    public static final ConfigKey<Map<Integer, String>> TCP_PORT_MAPPINGS = ConfigKeys.newConfigKey(
-            new TypeToken<Map<Integer, String>>() {},
-            "tcpPortMappings",
-            "NAT'ed ports, giving the mapping from private TCP port to a public host:port", 
-            null);
-
-    @Override
-    public InetAddress getAddress() {
-        return getConfig(ADDRESS);
-    }
-
-    @Override
-    public OsDetails getOsDetails() {
-        return null;
-    }
-
-    @Override
-    public MachineDetails getMachineDetails() {
-        return null;
-    }
-
-    @Nullable
-    @Override
-    public String getHostname() {
-        InetAddress address = getAddress();
-        return (address != null) ? address.getHostAddress() : null;
-    }
-
-    @Nullable
-    protected String getHostAndPort() {
-        String host = getHostname();
-        return (host == null) ? null : host + ":" + config().get(WINRM_PORT);
-    }
-
-    @Override
-    public Set<String> getPublicAddresses() {
-        InetAddress address = getAddress();
-        return (address == null) ? ImmutableSet.<String>of() : ImmutableSet.of(address.getHostAddress());
-    }
-    
-    @Override
-    public Set<String> getPrivateAddresses() {
-        Iterable<String> result = getConfig(PRIVATE_ADDRESSES);
-        return (result == null) ? ImmutableSet.<String>of() : ImmutableSet.copyOf(result);
-    }
-
-    public WinRmToolResponse executeScript(String script) {
-        return executeScript(ImmutableList.of(script));
-    }
-
-    public WinRmToolResponse executeScript(List<String> script) {
-        int execTries = getRequiredConfig(EXEC_TRIES);
-        Collection<Throwable> exceptions = Lists.newArrayList();
-        for (int i = 0; i < execTries; i++) {
-            try {
-                return executeScriptNoRetry(script);
-            } catch (Exception e) {
-                Exceptions.propagateIfFatal(e);
-                if (i == (execTries+1)) {
-                    LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
-                } else if (i == 0) {
-                    LOG.warn("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
-                } else {
-                    LOG.debug("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
-                }
-                exceptions.add(e);
-            }
-        }
-        throw Exceptions.propagate("failed to execute shell script", exceptions);
-    }
-
-    protected WinRmToolResponse executeScriptNoRetry(List<String> script) {
-        WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
-        WinRmToolResponse response = winRmTool.executeScript(script);
-        return response;
-    }
-
-    public WinRmToolResponse executePsScript(String psScript) {
-        return executePsScript(ImmutableList.of(psScript));
-    }
-
-    public WinRmToolResponse executePsScript(List<String> psScript) {
-        int execTries = getRequiredConfig(EXEC_TRIES);
-        Collection<Throwable> exceptions = Lists.newArrayList();
-        for (int i = 0; i < execTries; i++) {
-            try {
-                return executePsScriptNoRetry(psScript);
-            } catch (Exception e) {
-                Exceptions.propagateIfFatal(e);
-                if (i == (execTries+1)) {
-                    LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
-                } else if (i == 0) {
-                    LOG.warn("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
-                    Time.sleep(Duration.FIVE_SECONDS);
-                } else {
-                    LOG.debug("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
-                    Time.sleep(Duration.FIVE_SECONDS);
-                }
-                exceptions.add(e);
-            }
-        }
-        throw Exceptions.propagate("failed to execute powershell script", exceptions);
-    }
-
-    public WinRmToolResponse executePsScriptNoRetry(List<String> psScript) {
-        WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
-        WinRmToolResponse response = winRmTool.executePs(psScript);
-        return response;
-    }
-
-    public int copyTo(File source, String destination) {
-        FileInputStream sourceStream = null;
-        try {
-            sourceStream = new FileInputStream(source);
-            return copyTo(sourceStream, destination);
-        } catch (FileNotFoundException e) {
-            throw Exceptions.propagate(e);
-        } finally {
-            if (sourceStream != null) {
-                Streams.closeQuietly(sourceStream);
-            }
-        }
-    }
-
-    public int copyTo(InputStream source, String destination) {
-        executePsScript(ImmutableList.of("rm -ErrorAction SilentlyContinue " + destination));
-        try {
-            int chunkSize = getConfig(COPY_FILE_CHUNK_SIZE_BYTES);
-            byte[] inputData = new byte[chunkSize];
-            int bytesRead;
-            int expectedFileSize = 0;
-            while ((bytesRead = source.read(inputData)) > 0) {
-                byte[] chunk;
-                if (bytesRead == chunkSize) {
-                    chunk = inputData;
-                } else {
-                    chunk = Arrays.copyOf(inputData, bytesRead);
-                }
-                executePsScript(ImmutableList.of("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
-                        expectedFileSize + ")) {Add-Content -Encoding Byte -path " + destination +
-                        " -value ([System.Convert]::FromBase64String(\"" + new String(Base64.encodeBase64(chunk)) + "\"))}"));
-                expectedFileSize += bytesRead;
-            }
-
-            return 0;
-        } catch (java.io.IOException e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    @Override
-    public void init() {
-        super.init();
-
-        // Register any pre-existing port-mappings with the PortForwardManager
-        Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
-        if (tcpPortMappings != null) {
-            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
-            for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
-                int targetPort = entry.getKey();
-                HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
-                if (!publicEndpoint.hasPort()) {
-                    throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
-                }
-                pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
-            }
-        }
-    }
-    public String getUser() {
-        return config().get(USER);
-    }
-
-    private String getPassword() {
-        return config().get(PASSWORD);
-    }
-
-    private <T> T getRequiredConfig(ConfigKey<T> key) {
-        return checkNotNull(getConfig(key), "key %s must be set", key);
-    }
-    
-    public static String getDefaultUserMetadataString() {
-        // Using an encoded command obviates the need to escape
-        String unencodePowershell = Joiner.on("\r\n").join(ImmutableList.of(
-                // Allow TS connections
-                "$RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\\CIMV2\\TerminalServices -Authentication PacketPrivacy",
-                "$RDP.SetAllowTSConnections(1,1)",
-                "Set-ExecutionPolicy Unrestricted -Force",
-                // Set unlimited values for remote execution limits
-                "Set-Item WSMan:\\localhost\\Shell\\MaxConcurrentUsers 100",
-                "Set-Item WSMan:\\localhost\\Shell\\MaxMemoryPerShellMB 0",
-                "Set-Item WSMan:\\localhost\\Shell\\MaxProcessesPerShell 0",
-                "Set-Item WSMan:\\localhost\\Shell\\MaxShellsPerUser 0",
-                "New-ItemProperty \"HKLM:\\System\\CurrentControlSet\\Control\\LSA\" -Name \"SuppressExtendedProtection\" -Value 1 -PropertyType \"DWord\"",
-                // The following allows scripts to re-authenticate with local credential - this is required
-                // as certain operations cannot be performed with remote credentials
-                "$allowed = @('WSMAN/*')",
-                "$key = 'hklm:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CredentialsDelegation'",
-                "if (!(Test-Path $key)) {",
-                "    md $key",
-                "}",
-                "New-ItemProperty -Path $key -Name AllowFreshCredentials -Value 1 -PropertyType Dword -Force",
-                "New-ItemProperty -Path $key -Name AllowFreshCredentialsWhenNTLMOnly -Value 1 -PropertyType Dword -Force",
-                "$credKey = Join-Path $key 'AllowFreshCredentials'",
-                "if (!(Test-Path $credKey)) {",
-                "    md $credkey",
-                "}",
-                "$ntlmKey = Join-Path $key 'AllowFreshCredentialsWhenNTLMOnly'",
-                "if (!(Test-Path $ntlmKey)) {",
-                "    md $ntlmKey",
-                "}",
-                "$i = 1",
-                "$allowed |% {",
-                "    # Script does not take into account existing entries in this key",
-                "    New-ItemProperty -Path $credKey -Name $i -Value $_ -PropertyType String -Force",
-                "    New-ItemProperty -Path $ntlmKey -Name $i -Value $_ -PropertyType String -Force",
-                "    $i++",
-                "}"
-        ));
-
-        String encoded = new String(Base64.encodeBase64(unencodePowershell.getBytes(Charsets.UTF_16LE)));
-        return "winrm quickconfig -q & " +
-                "winrm set winrm/config/service/auth @{Basic=\"true\"} & " +
-                "winrm set winrm/config/service/auth @{CredSSP=\"true\"} & " +
-                "winrm set winrm/config/client/auth @{CredSSP=\"true\"} & " +
-                "winrm set winrm/config/client @{AllowUnencrypted=\"true\"} & " +
-                "winrm set winrm/config/service @{AllowUnencrypted=\"true\"} & " +
-                "winrm set winrm/config/winrs @{MaxConcurrentUsers=\"100\"} & " +
-                "winrm set winrm/config/winrs @{MaxMemoryPerShellMB=\"0\"} & " +
-                "winrm set winrm/config/winrs @{MaxProcessesPerShell=\"0\"} & " +
-                "winrm set winrm/config/winrs @{MaxShellsPerUser=\"0\"} & " +
-                "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any & " +
-                "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any & " +
-                "powershell -EncodedCommand " + encoded;
-        /* TODO: Find out why scripts with new line characters aren't working on AWS. The following appears as if it *should*
-           work but doesn't - the script simply isn't run. By connecting to the machine via RDP, you can get the script
-           from 'http://169.254.169.254/latest/user-data', and running it at the command prompt works, but for some
-           reason the script isn't run when the VM is provisioned
-        */
-//        return Joiner.on("\r\n").join(ImmutableList.of(
-//                "winrm quickconfig -q",
-//                "winrm set winrm/config/service/auth @{Basic=\"true\"}",
-//                "winrm set winrm/config/client @{AllowUnencrypted=\"true\"}",
-//                "winrm set winrm/config/service @{AllowUnencrypted=\"true\"}",
-//                "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any",
-//                "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any",
-//                // Using an encoded command necessitates the need to escape. The unencoded command is as follows:
-//                // $RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\CIMV2\TerminalServices -Authentication PacketPrivacy
-//                // $Result = $RDP.SetAllowTSConnections(1,1)
-//                "powershell -EncodedCommand JABSAEQAUAAgAD0AIABHAGUAdAAtAFcAbQBpAE8AYgBqAGUAYwB0ACAALQBDAGwAYQBzAHMAI" +
-//                        "ABXAGkAbgAzADIAXwBUAGUAcgBtAGkAbgBhAGwAUwBlAHIAdgBpAGMAZQBTAGUAdAB0AGkAbgBnACAALQBDAG8AbQBwA" +
-//                        "HUAdABlAHIATgBhAG0AZQAgACQAZQBuAHYAOgBjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQAgAC0ATgBhAG0AZQBzAHAAY" +
-//                        "QBjAGUAIAByAG8AbwB0AFwAQwBJAE0AVgAyAFwAVABlAHIAbQBpAG4AYQBsAFMAZQByAHYAaQBjAGUAcwAgAC0AQQB1A" +
-//                        "HQAaABlAG4AdABpAGMAYQB0AGkAbwBuACAAUABhAGMAawBlAHQAUAByAGkAdgBhAGMAeQANAAoAJABSAGUAcwB1AGwAd" +
-//                        "AAgAD0AIAAkAFIARABQAC4AUwBlAHQAQQBsAGwAbwB3AFQAUwBDAG8AbgBuAGUAYwB0AGkAbwBuAHMAKAAxACwAMQApAA=="
-//        ));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java b/core/src/main/java/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
deleted file mode 100644
index 216fcc1..0000000
--- a/core/src/main/java/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 brooklyn.location.cloud;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-
-import brooklyn.location.Location;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-@Beta
-public abstract class AbstractAvailabilityZoneExtension implements AvailabilityZoneExtension {
-
-    protected final ManagementContext managementContext;
-    protected final AtomicReference<List<Location>> subLocations = new AtomicReference<List<Location>>();
-    private final Object mutex = new Object();
-    
-    public AbstractAvailabilityZoneExtension(ManagementContext managementContext) {
-        this.managementContext = checkNotNull(managementContext, "managementContext");
-    }
-
-    @Override
-    public List<Location> getSubLocations(int max) {
-        List<Location> all = getAllSubLocations();
-        return all.subList(0, Math.min(max, all.size()));
-    }
-
-    @Override
-    public List<Location> getSubLocationsByName(Predicate<? super String> namePredicate, int max) {
-        List<Location> result = Lists.newArrayList();
-        List<Location> all = getAllSubLocations();
-        for (Location loc : all) {
-            if (isNameMatch(loc, namePredicate)) {
-                result.add(loc);
-            }
-        }
-        return Collections.<Location>unmodifiableList(result);
-    }
-
-    @Override
-    public List<Location> getAllSubLocations() {
-        synchronized (mutex) {
-            if (subLocations.get() == null) {
-                List<Location> result = doGetAllSubLocations();
-                subLocations.set(ImmutableList.copyOf(result));
-            }
-        }
-        return subLocations.get();
-    }
-
-    /**
-     * <strong>Note</strong> this method can be called while synchronized on {@link #mutex}.
-     */
-    // TODO bad pattern, as this will likely call alien code (such as asking cloud provider?!)
-    protected abstract List<Location> doGetAllSubLocations();
-
-    protected abstract boolean isNameMatch(Location loc, Predicate<? super String> namePredicate);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java b/core/src/main/java/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
deleted file mode 100644
index 36b9914..0000000
--- a/core/src/main/java/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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 brooklyn.location.cloud;
-
-import java.util.Collection;
-import java.util.Map;
-
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.internal.ssh.SshTool;
-
-public abstract class AbstractCloudMachineProvisioningLocation extends AbstractLocation
-implements MachineProvisioningLocation<MachineLocation>, CloudLocationConfig
-{
-   public AbstractCloudMachineProvisioningLocation() {
-      super();
-   }
-
-    /** typically wants at least ACCESS_IDENTITY and ACCESS_CREDENTIAL */
-    public AbstractCloudMachineProvisioningLocation(Map<?,?> conf) {
-        super(conf);
-    }
-
-    /** uses reflection to create an object of the same type, assuming a Map constructor;
-     * subclasses can extend and downcast the result */
-    @Override
-    public AbstractCloudMachineProvisioningLocation newSubLocation(Map<?,?> newFlags) {
-        return newSubLocation(getClass(), newFlags);
-    }
-
-    public AbstractCloudMachineProvisioningLocation newSubLocation(Class<? extends AbstractCloudMachineProvisioningLocation> type, Map<?,?> newFlags) {
-        // TODO should be able to use ConfigBag.newInstanceExtending; would require moving stuff around to api etc
-        // TODO was previously `return LocationCreationUtils.newSubLocation(newFlags, this)`; need to retest on CloudStack etc
-        return getManagementContext().getLocationManager().createLocation(LocationSpec.create(type)
-                .parent(this)
-                .configure(config().getLocalBag().getAllConfig()) // FIXME Should this just be inherited?
-                .configure(newFlags));
-    }
-    
-    @Override
-    public Map<String, Object> getProvisioningFlags(Collection<String> tags) {
-        if (tags.size() > 0) {
-            LOG.warn("Location {}, ignoring provisioning tags {}", this, tags);
-        }
-        return MutableMap.<String, Object>of();
-    }
-
-    // ---------------- utilities --------------------
-    
-    protected ConfigBag extractSshConfig(ConfigBag setup, ConfigBag alt) {
-        ConfigBag sshConfig = new ConfigBag();
-        
-        if (setup.containsKey(PASSWORD)) {
-            sshConfig.put(SshTool.PROP_PASSWORD, setup.get(PASSWORD));
-        } else if (alt.containsKey(PASSWORD)) {
-            sshConfig.put(SshTool.PROP_PASSWORD, alt.get(PASSWORD));
-        }
-        
-        if (setup.containsKey(PRIVATE_KEY_DATA)) {
-            sshConfig.put(SshTool.PROP_PRIVATE_KEY_DATA, setup.get(PRIVATE_KEY_DATA));
-        } else if (setup.containsKey(PRIVATE_KEY_FILE)) {
-            sshConfig.put(SshTool.PROP_PRIVATE_KEY_FILE, setup.get(PRIVATE_KEY_FILE));
-        } else if (alt.containsKey(PRIVATE_KEY_DATA)) {
-            sshConfig.put(SshTool.PROP_PRIVATE_KEY_DATA, alt.get(PRIVATE_KEY_DATA));
-        }
-        
-        if (setup.containsKey(PRIVATE_KEY_PASSPHRASE)) {
-            // NB: not supported in jclouds (but it is by our ssh tool)
-            sshConfig.put(SshTool.PROP_PRIVATE_KEY_PASSPHRASE, setup.get(PRIVATE_KEY_PASSPHRASE));
-        }
-
-        // TODO extract other SshTool properties ?
-        
-        return sshConfig;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/cloud/AvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/cloud/AvailabilityZoneExtension.java b/core/src/main/java/brooklyn/location/cloud/AvailabilityZoneExtension.java
deleted file mode 100644
index 161da8d..0000000
--- a/core/src/main/java/brooklyn/location/cloud/AvailabilityZoneExtension.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 brooklyn.location.cloud;
-
-import java.util.List;
-
-import brooklyn.entity.group.DynamicCluster;
-import brooklyn.location.Location;
-import brooklyn.location.basic.MultiLocation;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Predicate;
-
-/**
- * For a location that has sub-zones within it (e.g. an AWS region has availability zones that can be
- * mapped as sub-locations), this extension interface allows those to be accessed and used.
- * For some well-known clouds, the availability zones are automatically set, although for others they may
- * have to be configured explicitly. The "multi:(locs,...)" location descriptor (cf {@link MultiLocation}) allows
- * this to be down at runtime.
- * <p>
- * Note that only entities which are explicitly aware of the {@link AvailabilityZoneExtension}
- * will use availability zone information. For example {@link DynamicCluster} 
- * <p>
- * Implementers are strongly encouraged to extend {@link AbstractAvailabilityZoneExtension}
- * which has useful behaviour, rather than attempt to implement this interface directly.
- * 
- * @since 0.6.0
- */
-@Beta
-public interface AvailabilityZoneExtension {
-
-    List<Location> getAllSubLocations();
-
-    List<Location> getSubLocations(int max);
-
-    List<Location> getSubLocationsByName(Predicate<? super String> namePredicate, int max);
-
-}


[05/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java b/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java
index 5fe62ea..86cb6a7 100644
--- a/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java
+++ b/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java
@@ -35,7 +35,7 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.effector.EffectorTasks;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.net.Urls;
 import brooklyn.util.task.BasicExecutionManager;
 import brooklyn.util.task.DynamicTasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/software/MachineInitTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/MachineInitTasks.java b/software/base/src/main/java/brooklyn/entity/software/MachineInitTasks.java
index 9492fc3..2e68f6f 100644
--- a/software/base/src/main/java/brooklyn/entity/software/MachineInitTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/MachineInitTasks.java
@@ -32,7 +32,7 @@ import com.google.common.collect.Lists;
 
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.EntityInternal;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.net.Protocol;
 import brooklyn.util.ssh.BashCommands;
 import brooklyn.util.ssh.IptablesCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
index 4036f16..8c68442 100644
--- a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
@@ -31,6 +31,7 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.location.MachineManagementMixins;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,17 +63,17 @@ import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineManagementMixins.SuspendsMachines;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineManagementMixins.SuspendsMachines;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
@@ -898,7 +899,7 @@ public abstract class MachineLifecycleEffectorTasks {
      * {@link SuspendsMachines suspending machines}.
      *
      * @throws java.lang.UnsupportedOperationException if the entity's provisioner cannot suspend machines.
-     * @see brooklyn.location.MachineManagementMixins.SuspendsMachines
+     * @see MachineManagementMixins.SuspendsMachines
      */
     protected StopMachineDetails<Integer> suspendAnyProvisionedMachines() {
         @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java b/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java
index 6b78ccd..28888e9 100644
--- a/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java
+++ b/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java
@@ -18,7 +18,7 @@
  */
 package brooklyn.entity.software;
 
-import brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.config.ConfigBag;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java
index 9530a6c..c3590b4 100644
--- a/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java
@@ -39,9 +39,9 @@ import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.effector.EffectorTasks;
 import brooklyn.entity.effector.EffectorTasks.EffectorTaskFactory;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/META-INF/services/brooklyn.location.LocationResolver b/software/base/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
deleted file mode 100644
index 2a041b4..0000000
--- a/software/base/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
+++ /dev/null
@@ -1 +0,0 @@
-brooklyn.entity.pool.ServerPoolLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver b/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
new file mode 100644
index 0000000..2a041b4
--- /dev/null
+++ b/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
@@ -0,0 +1 @@
+brooklyn.entity.pool.ServerPoolLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
index 85de4ab..40a906c 100644
--- a/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
@@ -25,9 +25,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
-import brooklyn.location.Location;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsLocationConfig;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
index 766822b..72bf949 100644
--- a/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
@@ -30,7 +30,7 @@ import org.testng.annotations.Test;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
index 5ff72d9..3afd6c3 100644
--- a/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
@@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableMap;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.text.StringShortener;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java
index b1860ac..257cacf 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/AbstractSoftwareProcessRestartIntegrationTest.java
@@ -30,7 +30,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters;
 import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.collections.CollectionFunctionals;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java b/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java
index b742b44..792b46d 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/DoNothingSoftwareProcessDriver.java
@@ -20,7 +20,7 @@ package brooklyn.entity.basic;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 /**
  * Implements methods in {@link brooklyn.entity.basic.AbstractSoftwareProcessSshDriver}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java b/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
index 2ad2add..602eefe 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
@@ -31,9 +31,9 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java
index c408604..21ba4e8 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java
@@ -38,9 +38,9 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.SoftwareProcessEntityTest.MyService;
 import brooklyn.entity.basic.SoftwareProcessEntityTest.SimulatedDriver;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.task.TaskInternal;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java
index 81ad9da..fd70e7e 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java
@@ -41,11 +41,11 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.basic.SoftwareProcessEntityTest.MyService;
 import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.flags.SetFromFlag;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java
index bdbccd2..b66e3dd 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java
@@ -63,13 +63,13 @@ import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.software.MachineLifecycleEffectorTasksTest;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.SimulatedLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java
index 7642ce2..65d9037 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java
@@ -25,7 +25,6 @@ import static org.testng.Assert.assertTrue;
 import java.io.File;
 import java.io.IOException;
 import java.io.StringReader;
-import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -40,13 +39,12 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.BrooklynNetworkUtils;
 import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;
 import brooklyn.util.stream.KnownSizeInputStream;
 import brooklyn.util.stream.Streams;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java
index 5e60ba5..388d78d 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java
@@ -32,7 +32,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.effector.EffectorAndBody;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
index de9a247..0bd1b09 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
@@ -32,7 +32,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.SoftwareProcess.ChildStartableMode;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/lifecycle/MyEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/MyEntityImpl.java b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/MyEntityImpl.java
index aa57e19..c8eca43 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/MyEntityImpl.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/MyEntityImpl.java
@@ -26,7 +26,7 @@ import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.SoftwareProcessDriver;
 import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java
index df89383..52929a9 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java
@@ -33,8 +33,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.BrooklynTaskTags.WrappedStream;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.repeat.Repeater;
 import brooklyn.util.task.BasicExecutionContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java
index 3cb8e6a..c5efb0e 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java
@@ -40,9 +40,9 @@ import brooklyn.entity.basic.SoftwareProcessEntityTest.MyServiceImpl;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Functions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/basic/lifecycle/StartStopSshDriverTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/StartStopSshDriverTest.java b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/StartStopSshDriverTest.java
index 70f5341..1ef3e94 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/StartStopSshDriverTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/StartStopSshDriverTest.java
@@ -41,7 +41,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynClusterIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynClusterIntegrationTest.java
index ea9bfff..a961208 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynClusterIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynClusterIntegrationTest.java
@@ -32,7 +32,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
index eb84f68..a088996 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
@@ -58,17 +58,15 @@ import brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
 import brooklyn.entity.brooklynnode.BrooklynNode.StopNodeAndKillAppsEffector;
 import brooklyn.entity.proxying.EntityProxyImpl;
 import brooklyn.event.feed.http.JsonFunctions;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Functionals;
-import brooklyn.util.guava.Maybe;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;
 import brooklyn.util.javalang.JavaClassNames;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
index cf6cfd8..d07cc89 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
@@ -37,8 +37,8 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
index e903351..4268998 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
@@ -29,7 +29,7 @@ import brooklyn.entity.brooklynnode.CallbackEntityHttpClient.Request;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityPriorityEffectorBody;
 import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Function;
 import com.google.common.reflect.TypeToken;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
index 4366873..8aae8a2 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
@@ -26,7 +26,7 @@ import brooklyn.entity.brooklynnode.BrooklynNodeImpl.DeployBlueprintEffectorBody
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /** Implementation of BrooklynNode which just presents the node where this is running, for convenience;
  * 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java b/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java
index 4150ec9..50176e0 100644
--- a/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java
+++ b/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java
@@ -29,15 +29,14 @@ import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.EntityInternal;
-import brooklyn.location.Location;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.io.FileUtil;
 import brooklyn.util.stream.InputStreamSupplier;
 
 import com.google.common.base.Throwables;
-import com.google.common.io.ByteSource;
 import com.google.common.io.Files;
 
 public class ChefLiveTestSupport extends BrooklynAppLiveTestSupport {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java b/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java
index 9527d0b..23a6255 100644
--- a/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java
@@ -22,8 +22,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.chef.ChefLiveTestSupport;
 import brooklyn.entity.software.mysql.AbstractToyMySqlEntityTest;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 public abstract class AbstractChefToyMySqlEntityLiveTest extends AbstractToyMySqlEntityTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java b/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java
index fdfca3f..42d7429 100644
--- a/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java
+++ b/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java
@@ -21,8 +21,8 @@ package brooklyn.entity.driver;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 
 import brooklyn.entity.basic.SoftwareProcessDriver;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 public class MockSshDriver implements SoftwareProcessDriver {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java b/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
index d0ccb2c..c9e85f4 100644
--- a/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
@@ -33,12 +33,12 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.basic.SoftwareProcess;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.MultiLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.MultiLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java b/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
index 475f788..8505ba7 100644
--- a/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
@@ -36,8 +36,8 @@ import brooklyn.entity.java.UsesJmx.JmxAgentModes;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.feed.jmx.JmxAttributePollConfig;
 import brooklyn.event.feed.jmx.JmxFeed;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.JmxService;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java b/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
index 3f44b6f..1896ed5 100644
--- a/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
@@ -36,9 +36,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java
index bf824c9..ec825ec 100644
--- a/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java
@@ -35,9 +35,9 @@ import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.lifecycle.MyEntity;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppRebindTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppRebindTest.java b/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppRebindTest.java
index d139001..41ec5c5 100644
--- a/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppRebindTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppRebindTest.java
@@ -38,7 +38,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.JavaOptsTest.TestingJavaOptsVanillaJavaAppImpl;
 import brooklyn.entity.rebind.RebindTestUtils;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java b/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java
index d9d486e..73a2675 100644
--- a/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java
@@ -53,8 +53,8 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.event.feed.jmx.JmxHelper;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.test.Asserts;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java b/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java
index f902ecd..344f8f3 100644
--- a/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java
@@ -27,7 +27,7 @@ import org.testng.annotations.Test;
 import com.google.common.collect.ImmutableList;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 public class MachineEntityEc2LiveTest extends AbstractEc2LiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java b/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java
index 268a7db..0996b88 100644
--- a/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java
+++ b/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java
@@ -35,10 +35,10 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java
index 099a2f2..6a7e297 100644
--- a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java
@@ -33,7 +33,7 @@ import com.google.common.collect.ImmutableList;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Attributes;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 
 public class ServerPoolLiveTest extends AbstractServerPoolTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java
index daac862..6b6c045 100644
--- a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java
+++ b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java
@@ -37,10 +37,10 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.dynamic.DynamicLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.dynamic.DynamicLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java
index 9876dc4..ef7c8c4 100644
--- a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java
+++ b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java
@@ -34,8 +34,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Lifecycle;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java b/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java
index 8611536..9367e40 100644
--- a/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java
+++ b/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java
@@ -34,8 +34,8 @@ import brooklyn.entity.basic.VanillaSoftwareProcess;
 import brooklyn.entity.basic.VanillaSoftwareProcessImpl;
 import brooklyn.entity.basic.VanillaSoftwareProcessSshDriver;
 import brooklyn.entity.effector.EffectorTasks;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.ssh.BashCommands;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java b/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java
index facc56b..e64ccdb 100644
--- a/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java
@@ -21,7 +21,7 @@ package brooklyn.entity.software;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java b/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java
index 7e542ea..2fcd1df 100644
--- a/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java
@@ -50,7 +50,7 @@ import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters.StopMode;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.jclouds.BailOutJcloudsLocation;
+import org.apache.brooklyn.location.jclouds.BailOutJcloudsLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.task.TaskInternal;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java b/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java
index 0529262..ae5f436 100644
--- a/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java
@@ -34,9 +34,9 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.software.SshEffectorTasks.SshEffectorBody;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.system.ProcessTaskWrapper;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java b/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java
index c726b44..dcea2bb 100644
--- a/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java
@@ -34,11 +34,10 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.exceptions.PropagatedRuntimeException;
 import brooklyn.util.net.Urls;
 import brooklyn.util.task.ssh.SshFetchTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java b/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
index c8d0680..81a2a5b 100644
--- a/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
@@ -31,7 +31,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.TestHttpRequestHandler;
 import brooklyn.test.TestHttpServer;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java b/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java
index c5dc34c..6521467 100644
--- a/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java
@@ -30,10 +30,10 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.task.system.ProcessTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java b/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java
index f894ca1..b7144dd 100644
--- a/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java
+++ b/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java
@@ -32,11 +32,11 @@ import brooklyn.entity.basic.BasicStartable;
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.BasicOsDetails.OsVersions;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.BasicOsDetails.OsVersions;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.ssh.BashCommands;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.task.Tasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityTest.java b/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityTest.java
index 7077c6e..2299831 100644
--- a/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityTest.java
@@ -25,7 +25,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java
index 40d77d1..c69fb37 100644
--- a/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java
@@ -38,8 +38,8 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java b/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java
index 2e543f1..2db5108 100644
--- a/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java
+++ b/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java
@@ -28,9 +28,9 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.EmptySoftwareProcessImpl;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/event/feed/jmx/JmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/event/feed/jmx/JmxFeedTest.java b/software/base/src/test/java/brooklyn/event/feed/jmx/JmxFeedTest.java
index 0a3322c..ba1050d 100644
--- a/software/base/src/test/java/brooklyn/event/feed/jmx/JmxFeedTest.java
+++ b/software/base/src/test/java/brooklyn/event/feed/jmx/JmxFeedTest.java
@@ -59,7 +59,6 @@ import org.testng.annotations.Test;
 import org.testng.collections.Lists;
 
 import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.JmxSupport;
@@ -69,9 +68,9 @@ import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.basic.BasicNotificationSensor;
 import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.test.GeneralisedDynamicMBean;
 import brooklyn.test.JmxService;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java b/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java
index db8c15c..6e444c1 100644
--- a/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java
+++ b/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java
@@ -42,9 +42,9 @@ import brooklyn.entity.java.UsesJmx.JmxAgentModes;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
 import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.test.GeneralisedDynamicMBean;
 import brooklyn.test.JmxService;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/location/basic/MachineDetailsEc2LiveTest.java b/software/base/src/test/java/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
deleted file mode 100644
index 101cb7c..0000000
--- a/software/base/src/test/java/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.entity.basic.EmptySoftwareProcess;
-import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.OsDetails;
-import brooklyn.util.collections.MutableMap;
-
-// This test really belongs in brooklyn-location but depends on AbstractEc2LiveTest in brooklyn-software-base
-public class MachineDetailsEc2LiveTest extends AbstractEc2LiveTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsEc2LiveTest.class);
-    private static final int TIMEOUT_MS = 1000 * 60 * 10; // ten minutes
-
-    @Override
-    protected void doTest(Location loc) throws Exception {
-        Entity testEntity = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
-        app.start(ImmutableList.of(loc));
-        EntityTestUtils.assertAttributeEqualsEventually(MutableMap.of("timeout", TIMEOUT_MS),
-                testEntity, Startable.SERVICE_UP, true);
-
-        SshMachineLocation sshLoc = Locations.findUniqueSshMachineLocation(testEntity.getLocations()).get();
-        MachineDetails machine = app.getExecutionContext()
-                .submit(BasicMachineDetails.taskForSshMachineLocation(sshLoc))
-                .getUnchecked();
-        LOG.info("Found the following at {}: {}", loc, machine);
-        assertNotNull(machine);
-        OsDetails details = machine.getOsDetails();
-        assertNotNull(details);
-        assertNotNull(details.getArch());
-        assertNotNull(details.getName());
-        assertNotNull(details.getVersion());
-        assertFalse(details.getArch().startsWith("architecture:"));
-        assertFalse(details.getName().startsWith("name:"));
-        assertFalse(details.getVersion().startsWith("version:"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java b/software/base/src/test/java/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
deleted file mode 100644
index 7cc77ef..0000000
--- a/software/base/src/test/java/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-
-import brooklyn.entity.AbstractGoogleComputeLiveTest;
-import brooklyn.entity.basic.EmptySoftwareProcess;
-import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.OsDetails;
-import brooklyn.util.collections.MutableMap;
-
-// This test really belongs in brooklyn-location but depends on AbstractGoogleComputeLiveTest in brooklyn-software-base
-public class MachineDetailsGoogleComputeLiveTest extends AbstractGoogleComputeLiveTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsGoogleComputeLiveTest.class);
-
-    @Override
-    protected void doTest(Location loc) throws Exception {
-        Entity testEntity = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
-        app.start(ImmutableList.of(loc));
-        EntityTestUtils.assertAttributeEqualsEventually(testEntity, Startable.SERVICE_UP, true);
-
-        SshMachineLocation sshLoc = Locations.findUniqueSshMachineLocation(testEntity.getLocations()).get();
-        MachineDetails machine = app.getExecutionContext()
-                .submit(BasicMachineDetails.taskForSshMachineLocation(sshLoc))
-                .getUnchecked();
-        LOG.info("Found the following at {}: {}", loc, machine);
-        assertNotNull(machine);
-        OsDetails details = machine.getOsDetails();
-        assertNotNull(details);
-        assertNotNull(details.getArch());
-        assertNotNull(details.getName());
-        assertNotNull(details.getVersion());
-        assertFalse(details.getArch().startsWith("architecture:"));
-        assertFalse(details.getName().startsWith("name:"));
-        assertFalse(details.getVersion().startsWith("version:"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/location/basic/WinRmMachineLocationLiveTest.java b/software/base/src/test/java/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
deleted file mode 100644
index 5baf071..0000000
--- a/software/base/src/test/java/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.BrooklynAppLiveTestSupport;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsWinRmMachineLocation;
-import brooklyn.management.internal.ManagementContextInternal;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class WinRmMachineLocationLiveTest {
-    
-    // FIXME failing locally with:
-    //   Caused by: Traceback (most recent call last):
-    //     File "__pyclasspath__/winrm/__init__.py", line 40, in run_cmd
-    //     File "__pyclasspath__/winrm/protocol.py", line 118, in open_shell
-    //     File "__pyclasspath__/winrm/protocol.py", line 190, in send_message
-    //     File "__pyclasspath__/winrm/transport.py", line 112, in send_message
-    //     winrm.exceptions.WinRMTransportError: 500 WinRMTransport. [Errno 20001] getaddrinfo failed
-    //     at org.python.core.PyException.doRaise(PyException.java:226)
-
-    private static final Logger LOG = LoggerFactory.getLogger(BrooklynAppLiveTestSupport.class);
-
-    protected JcloudsLocation loc;
-    protected TestApplication app;
-    protected ManagementContextInternal mgmt;
-
-    private JcloudsWinRmMachineLocation machine;
-    
-    @BeforeClass(alwaysRun=true)
-    public void setUpClass() throws Exception {
-        mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newDefault());
-        JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve("jclouds:aws-ec2:us-west-2", ImmutableMap.of(
-                "inboundPorts", ImmutableList.of(5985, 3389),
-                "displayName", "AWS Oregon (Windows)",
-                "imageId", "us-west-2/ami-8fd3f9bf",
-                "hardwareId", "m3.medium",
-                "useJcloudsSshInit", false));
-        machine = (JcloudsWinRmMachineLocation) loc.obtain();
-    }
-
-    @AfterClass(alwaysRun=true)
-    public void tearDownClass() throws Exception {
-        try {
-            if (machine != null) loc.release(machine);
-            if (mgmt != null) Entities.destroyAll(mgmt);
-        } catch (Throwable t) {
-            LOG.error("Caught exception in tearDown method", t);
-        } finally {
-            mgmt = null;
-        }
-    }
-
-    @Test(groups="Live")
-    public void testExecScript() throws Exception {
-        WinRmToolResponse response = machine.executeScript("echo true");
-        assertEquals(response.getStatusCode(), 0);
-        assertEquals(response.getStdErr(), "");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/location/basic/WinRmMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/location/basic/WinRmMachineLocationTest.java b/software/base/src/test/java/brooklyn/location/basic/WinRmMachineLocationTest.java
deleted file mode 100644
index de9db6c..0000000
--- a/software/base/src/test/java/brooklyn/location/basic/WinRmMachineLocationTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import org.testng.annotations.Test;
-
-import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.location.LocationSpec;
-import brooklyn.util.net.Networking;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class WinRmMachineLocationTest extends BrooklynAppUnitTestSupport {
-
-    @Test
-    public void testConfigurePrivateAddresses() throws Exception {
-        WinRmMachineLocation host = mgmt.getLocationManager().createLocation(LocationSpec.create(WinRmMachineLocation.class)
-                .configure("address", Networking.getLocalHost())
-                .configure(WinRmMachineLocation.PRIVATE_ADDRESSES, ImmutableList.of("1.2.3.4"))
-                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
-
-        assertEquals(host.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java b/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
index 003fb8e..fac6ee4 100644
--- a/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
+++ b/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
@@ -40,7 +40,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.proxying.EntityProxy;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.management.internal.UsageListener.ApplicationMetadata;
 import brooklyn.management.usage.ApplicationUsage.ApplicationEvent;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java b/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java
index 26f20bc..fb047ef 100644
--- a/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java
+++ b/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java
@@ -34,11 +34,11 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.SoftwareProcessEntityTest;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.internal.UsageListener.LocationMetadata;
 import brooklyn.management.usage.LocationUsage.LocationEvent;
 import brooklyn.test.Asserts;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java b/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java
index 9812d45..ea3dedb 100644
--- a/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java
+++ b/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java
@@ -32,7 +32,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.management.internal.UsageManager;
 import brooklyn.test.Asserts;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
new file mode 100644
index 0000000..fce5c94
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+import brooklyn.entity.AbstractEc2LiveTest;
+import brooklyn.entity.basic.EmptySoftwareProcess;
+import brooklyn.entity.trait.Startable;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.OsDetails;
+import brooklyn.util.collections.MutableMap;
+
+// This test really belongs in brooklyn-location but depends on AbstractEc2LiveTest in brooklyn-software-base
+public class MachineDetailsEc2LiveTest extends AbstractEc2LiveTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsEc2LiveTest.class);
+    private static final int TIMEOUT_MS = 1000 * 60 * 10; // ten minutes
+
+    @Override
+    protected void doTest(Location loc) throws Exception {
+        Entity testEntity = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
+        app.start(ImmutableList.of(loc));
+        EntityTestUtils.assertAttributeEqualsEventually(MutableMap.of("timeout", TIMEOUT_MS),
+                testEntity, Startable.SERVICE_UP, true);
+
+        SshMachineLocation sshLoc = Locations.findUniqueSshMachineLocation(testEntity.getLocations()).get();
+        MachineDetails machine = app.getExecutionContext()
+                .submit(BasicMachineDetails.taskForSshMachineLocation(sshLoc))
+                .getUnchecked();
+        LOG.info("Found the following at {}: {}", loc, machine);
+        assertNotNull(machine);
+        OsDetails details = machine.getOsDetails();
+        assertNotNull(details);
+        assertNotNull(details.getArch());
+        assertNotNull(details.getName());
+        assertNotNull(details.getVersion());
+        assertFalse(details.getArch().startsWith("architecture:"));
+        assertFalse(details.getName().startsWith("name:"));
+        assertFalse(details.getVersion().startsWith("version:"));
+    }
+}



[34/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
new file mode 100644
index 0000000..a93d3dd
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/ByonLocationResolver.java
@@ -0,0 +1,251 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationSpec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.net.HostAndPort;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Sanitizer;
+import org.apache.brooklyn.location.MachineLocation;
+import brooklyn.management.internal.LocalLocationManager;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.net.UserAndHostAndPort;
+import brooklyn.util.text.WildcardGlobs;
+import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
+
+/**
+ * Examples of valid specs:
+ *   <ul>
+ *     <li>byon:(hosts=myhost)
+ *     <li>byon:(hosts=myhost,myhost2)
+ *     <li>byon:(hosts="myhost, myhost2")
+ *     <li>byon:(hosts=myhost,myhost2, name=abc)
+ *     <li>byon:(hosts="myhost, myhost2", name="my location name")
+ *   </ul>
+ * 
+ * @author aled
+ */
+@SuppressWarnings({"rawtypes"})
+public class ByonLocationResolver extends AbstractLocationResolver {
+
+    public static final Logger log = LoggerFactory.getLogger(ByonLocationResolver.class);
+    
+    public static final String BYON = "byon";
+
+    public static final ConfigKey<String> OS_FAMILY = ConfigKeys.newStringConfigKey("osfamily", "OS Family of the machine, either windows or linux", "linux");
+
+    public static final Map<String, Class<? extends MachineLocation>> OS_TO_MACHINE_LOCATION_TYPE = ImmutableMap.<String, Class<? extends MachineLocation>>of(
+            "windows", WinRmMachineLocation.class,
+            "linux", SshMachineLocation.class);
+
+    @Override
+    public String getPrefix() {
+        return BYON;
+    }
+
+    @Override
+    protected Class<? extends Location> getLocationType() {
+        return FixedListMachineProvisioningLocation.class;
+    }
+
+    @Override
+    protected SpecParser getSpecParser() {
+        return new AbstractLocationResolver.SpecParser(getPrefix()).setExampleUsage("\"byon(hosts='addr1,addr2')\"");
+    }
+
+    @Override
+    protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, LocationRegistry registry) {
+        ConfigBag config = super.extractConfig(locationFlags, spec, registry);
+
+        Object hosts = config.getStringKey("hosts");
+        config.remove("hosts");
+        String user = (String) config.getStringKey("user");
+        Integer port = (Integer) TypeCoercions.coerce(config.getStringKey("port"), Integer.class);
+        Class<? extends MachineLocation> locationClass = OS_TO_MACHINE_LOCATION_TYPE.get(config.get(OS_FAMILY));
+
+        MutableMap<String, Object> defaultProps = MutableMap.of();
+        defaultProps.addIfNotNull("user", user);
+        defaultProps.addIfNotNull("port", port);
+
+        List<String> hostAddresses;
+        
+        if (hosts instanceof String) {
+            if (((String) hosts).isEmpty()) {
+                hostAddresses = ImmutableList.of();
+            } else {
+                hostAddresses = WildcardGlobs.getGlobsAfterBraceExpansion("{"+hosts+"}",
+                        true /* numeric */, /* no quote support though */ PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR);
+            }
+        } else if (hosts instanceof Iterable) {
+            hostAddresses = ImmutableList.copyOf((Iterable<String>)hosts);
+        } else {
+            throw new IllegalArgumentException("Invalid location '"+spec+"'; at least one host must be defined");
+        }
+        if (hostAddresses.isEmpty()) {
+            throw new IllegalArgumentException("Invalid location '"+spec+"'; at least one host must be defined");
+        }
+        
+        List<MachineLocation> machines = Lists.newArrayList();
+        for (Object host : hostAddresses) {
+            LocationSpec<? extends MachineLocation> machineSpec;
+            if (host instanceof String) {
+                machineSpec = parseMachine((String)host, locationClass, defaultProps, spec);
+            } else if (host instanceof Map) {
+                machineSpec = parseMachine((Map<String, ?>)host, locationClass, defaultProps, spec);
+            } else {
+                throw new IllegalArgumentException("Expected machine to be String or Map, but was "+host.getClass().getName()+" ("+host+")");
+            }
+            machineSpec.configureIfNotNull(LocalLocationManager.CREATE_UNMANAGED, config.get(LocalLocationManager.CREATE_UNMANAGED));
+            MachineLocation machine = managementContext.getLocationManager().createLocation(machineSpec);
+            machines.add(machine);
+        }
+        
+        config.putStringKey("machines", machines);
+
+        return config;
+    }
+    
+    protected LocationSpec<? extends MachineLocation> parseMachine(Map<String, ?> vals, Class<? extends MachineLocation> locationClass, Map<String, ?> defaults, String specForErrMsg) {
+        Map<String, Object> valSanitized = Sanitizer.sanitize(vals);
+        Map<String, Object> machineConfig = MutableMap.copyOf(vals);
+        
+        String osfamily = (String) machineConfig.remove(OS_FAMILY.getName());
+        String ssh = (String) machineConfig.remove("ssh");
+        String winrm = (String) machineConfig.remove("winrm");
+        Map<Integer, String> tcpPortMappings = (Map<Integer, String>) machineConfig.get("tcpPortMappings");
+        
+        checkArgument(ssh != null ^ winrm != null, "Must specify exactly one of 'ssh' or 'winrm' for machine: %s", valSanitized);
+        
+        UserAndHostAndPort userAndHostAndPort;
+        String host;
+        int port;
+        if (ssh != null) {
+            userAndHostAndPort = parseUserAndHostAndPort((String)ssh, 22);
+        } else {
+            userAndHostAndPort = parseUserAndHostAndPort((String)winrm, 5985);
+        }
+        
+        // If there is a tcpPortMapping defined for the connection-port, then use that for ssh/winrm machine
+        port = userAndHostAndPort.getHostAndPort().getPort();
+        if (tcpPortMappings != null && tcpPortMappings.containsKey(port)) {
+            String override = tcpPortMappings.get(port);
+            HostAndPort hostAndPortOverride = HostAndPort.fromString(override);
+            if (!hostAndPortOverride.hasPort()) {
+                throw new IllegalArgumentException("Invalid portMapping ('"+override+"') for port "+port+" in "+specForErrMsg);
+            }
+            port = hostAndPortOverride.getPort();
+            host = hostAndPortOverride.getHostText().trim();
+        } else {
+            host = userAndHostAndPort.getHostAndPort().getHostText().trim();
+        }
+        
+        machineConfig.put("address", host);
+        try {
+            InetAddress.getByName(host);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Invalid host '"+host+"' specified in '"+specForErrMsg+"': "+e);
+        }
+
+        if (userAndHostAndPort.getUser() != null) {
+            checkArgument(!vals.containsKey("user"), "Must not specify user twice for machine: %s", valSanitized);
+            machineConfig.put("user", userAndHostAndPort.getUser());
+        }
+        if (userAndHostAndPort.getHostAndPort().hasPort()) {
+            checkArgument(!vals.containsKey("port"), "Must not specify port twice for machine: %s", valSanitized);
+            machineConfig.put("port", port);
+        }
+        for (Map.Entry<String, ?> entry : defaults.entrySet()) {
+            if (!machineConfig.containsKey(entry.getKey())) {
+                machineConfig.put(entry.getKey(), entry.getValue());
+            }
+        }
+        
+        Class<? extends MachineLocation> locationClassHere = locationClass;
+        if (osfamily != null) {
+            locationClassHere = OS_TO_MACHINE_LOCATION_TYPE.get(osfamily);
+        }
+
+        return LocationSpec.create(locationClassHere).configure(machineConfig);
+    }
+
+    protected LocationSpec<? extends MachineLocation> parseMachine(String val, Class<? extends MachineLocation> locationClass, Map<String, ?> defaults, String specForErrMsg) {
+        Map<String, Object> machineConfig = Maps.newLinkedHashMap();
+        
+        UserAndHostAndPort userAndHostAndPort = parseUserAndHostAndPort(val);
+        
+        String host = userAndHostAndPort.getHostAndPort().getHostText().trim();
+        machineConfig.put("address", host);
+        try {
+            InetAddress.getByName(host.trim());
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Invalid host '"+host+"' specified in '"+specForErrMsg+"': "+e);
+        }
+        
+        if (userAndHostAndPort.getUser() != null) {
+            machineConfig.put("user", userAndHostAndPort.getUser());
+        }
+        if (userAndHostAndPort.getHostAndPort().hasPort()) {
+            machineConfig.put("port", userAndHostAndPort.getHostAndPort().getPort());
+        }
+        for (Map.Entry<String, ?> entry : defaults.entrySet()) {
+            if (!machineConfig.containsKey(entry.getKey())) {
+                machineConfig.put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        return LocationSpec.create(locationClass).configure(machineConfig);
+    }
+    
+    private UserAndHostAndPort parseUserAndHostAndPort(String val) {
+        String userPart = null;
+        String hostPart = val;
+        if (val.contains("@")) {
+            userPart = val.substring(0, val.indexOf("@"));
+            hostPart = val.substring(val.indexOf("@")+1);
+        }
+        return UserAndHostAndPort.fromParts(userPart, HostAndPort.fromString(hostPart));
+    }
+    
+    private UserAndHostAndPort parseUserAndHostAndPort(String val, int defaultPort) {
+        UserAndHostAndPort result = parseUserAndHostAndPort(val);
+        if (!result.getHostAndPort().hasPort()) {
+            result = UserAndHostAndPort.fromParts(result.getUser(), result.getHostAndPort().getHostText(), defaultPort);
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java
new file mode 100644
index 0000000..7d55d57
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/CatalogLocationResolver.java
@@ -0,0 +1,80 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationSpec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.management.ManagementContext;
+
+import brooklyn.catalog.internal.CatalogUtils;
+
+/**
+ * Given a location spec in the form {@code brooklyn.catalog:<symbolicName>:<version>}, 
+ * looks up the catalog to get its definition and creates such a location.
+ */
+public class CatalogLocationResolver implements LocationResolver {
+
+    @SuppressWarnings("unused")
+    private static final Logger log = LoggerFactory.getLogger(CatalogLocationResolver.class);
+
+    public static final String NAME = "brooklyn.catalog";
+
+    private ManagementContext managementContext;
+
+    @Override
+    public void init(ManagementContext managementContext) {
+        this.managementContext = checkNotNull(managementContext, "managementContext");
+    }
+    
+    @Override
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        String id = spec.substring(NAME.length()+1);
+        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(managementContext, id);
+        LocationSpec<?> origLocSpec = managementContext.getCatalog().createSpec((CatalogItem<Location, LocationSpec<?>>)item);
+        LocationSpec<?> locSpec = LocationSpec.create(origLocSpec)
+                .configure(locationFlags);
+        return managementContext.getLocationManager().createLocation(locSpec);
+    }
+
+    @Override
+    public String getPrefix() {
+        return NAME;
+    }
+    
+    /**
+     * accepts anything that looks like it will be a YAML catalog item (e.g. starting "brooklyn.locations")
+     */
+    @Override
+    public boolean accepts(String spec, LocationRegistry registry) {
+        if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true;
+        if (registry.getDefinedLocationByName(spec)!=null) return true;
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java
new file mode 100644
index 0000000..7277fc9
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/DefinedLocationByIdResolver.java
@@ -0,0 +1,74 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * looks up based on ID in DefinedLocations map
+ */
+public class DefinedLocationByIdResolver implements LocationResolver {
+
+    public static final Logger log = LoggerFactory.getLogger(DefinedLocationByIdResolver.class);
+
+    public static final String ID = "id";
+    
+    private volatile ManagementContext managementContext;
+
+    @Override
+    public void init(ManagementContext managementContext) {
+        this.managementContext = checkNotNull(managementContext, "managementContext");
+    }
+    
+    @SuppressWarnings({ "rawtypes" })
+    @Override
+    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        String id = spec;
+        if (spec.toLowerCase().startsWith(ID+":")) {
+            id = spec.substring( (ID+":").length() );
+        }
+        LocationDefinition ld = registry.getDefinedLocationById(id);
+        ld.getSpec();
+        return ((BasicLocationRegistry)registry).resolveLocationDefinition(ld, locationFlags, null);
+    }
+
+    @Override
+    public String getPrefix() {
+        return ID;
+    }
+    
+    /** accepts anything starting  id:xxx  or just   xxx where xxx is a defined location ID */
+    @Override
+    public boolean accepts(String spec, LocationRegistry registry) {
+        if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true;
+        if (registry.getDefinedLocationById(spec)!=null) return true;
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/DeprecatedKeysMappingBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/DeprecatedKeysMappingBuilder.java b/core/src/main/java/org/apache/brooklyn/location/basic/DeprecatedKeysMappingBuilder.java
new file mode 100644
index 0000000..88593d4
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/DeprecatedKeysMappingBuilder.java
@@ -0,0 +1,67 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+
+import brooklyn.config.ConfigKey;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.collect.ImmutableMap;
+
+/**
+* @deprecated since 0.6; for use only in converting deprecated flags; will be deleted in future version.
+*/
+public class DeprecatedKeysMappingBuilder {
+    private final ImmutableMap.Builder<String,String> builder = new ImmutableMap.Builder<String,String>();
+    private final Logger logger;
+    
+    public DeprecatedKeysMappingBuilder(Logger logger) {
+        this.logger = logger;
+    }
+
+    public DeprecatedKeysMappingBuilder camelToHyphen(ConfigKey<?> key) {
+        return camelToHyphen(key.getName());
+    }
+    
+    public DeprecatedKeysMappingBuilder camelToHyphen(String key) {
+        String hyphen = toHyphen(key);
+        if (key.equals(hyphen)) {
+            logger.warn("Invalid attempt to convert camel-case key {} to deprecated hyphen-case: both the same", hyphen);
+        } else {
+            builder.put(hyphen, key);
+        }
+        return this;
+    }
+    
+    public DeprecatedKeysMappingBuilder putAll(Map<String,String> vals) {
+        builder.putAll(vals);
+        return this;
+    }
+
+    public Map<String,String> build() {
+        return builder.build();
+    }
+    
+    private String toHyphen(String word) {
+        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, word);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
new file mode 100644
index 0000000..45bc585
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocation.java
@@ -0,0 +1,474 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static brooklyn.util.GroovyJavaMethods.truth;
+
+import java.io.Closeable;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.management.LocationManager;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocationCustomizer;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.util.collections.CollectionFunctionals;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.text.WildcardGlobs;
+import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
+
+/**
+ * A provisioner of {@link MachineLocation}s which takes a list of machines it can connect to.
+ * The collection of initial machines should be supplied in the 'machines' flag in the constructor,
+ * for example a list of machines which can be SSH'd to. 
+ * 
+ * This can be extended to have a mechanism to make more machines to be available
+ * (override provisionMore and canProvisionMore).
+ */
+public class FixedListMachineProvisioningLocation<T extends MachineLocation> extends AbstractLocation 
+implements MachineProvisioningLocation<T>, Closeable {
+
+    // TODO Synchronization looks very wrong for accessing machines/inUse 
+    // e.g. removeChild doesn't synchronize when doing machines.remove(...),
+    // and getMachines() returns the real sets risking 
+    // ConcurrentModificationException in the caller if it iterates over them etc.
+    
+    private static final Logger log = LoggerFactory.getLogger(FixedListMachineProvisioningLocation.class);
+    
+    public static final ConfigKey<Function<Iterable<? extends MachineLocation>, MachineLocation>> MACHINE_CHOOSER =
+            ConfigKeys.newConfigKey(
+                    new TypeToken<Function<Iterable<? extends MachineLocation>, MachineLocation>>() {}, 
+                    "byon.machineChooser",
+                    "For choosing which of the possible machines is chosen and returned by obtain()",
+                    CollectionFunctionals.<MachineLocation>firstElement());
+
+    public static final ConfigKey<Collection<MachineLocationCustomizer>> MACHINE_LOCATION_CUSTOMIZERS = CloudLocationConfig.MACHINE_LOCATION_CUSTOMIZERS;
+    
+    private final Object lock = new Object();
+    
+    @SetFromFlag
+    protected Set<T> machines;
+    
+    @SetFromFlag
+    protected Set<T> inUse;
+
+    @SetFromFlag
+    protected Set<T> pendingRemoval;
+    
+    @SetFromFlag
+    protected Map<T, Map<String, Object>> origConfigs;
+
+    public FixedListMachineProvisioningLocation() {
+        this(Maps.newLinkedHashMap());
+    }
+    public FixedListMachineProvisioningLocation(Map properties) {
+        super(properties);
+
+        if (isLegacyConstruction()) {
+            init();
+        }
+    }
+
+    @Override
+    public void init() {
+        super.init();
+        
+        Set<T> machinesCopy = MutableSet.of();
+        for (T location: machines) {
+            if (location==null) {
+                log.warn(""+this+" initialized with null location, removing (may be due to rebind with reference to an unmanaged location)");
+            } else {
+                Location parent = location.getParent();
+                if (parent == null) {
+                    addChild(location);
+                }
+                machinesCopy.add(location);
+            }
+        }
+        if (!machinesCopy.equals(machines)) {
+            machines = machinesCopy;
+        }
+    }
+    
+    @Override
+    public String toVerboseString() {
+        return Objects.toStringHelper(this).omitNullValues()
+                .add("id", getId()).add("name", getDisplayName())
+                .add("machinesAvailable", getAvailable()).add("machinesInUse", getInUse())
+                .toString();
+    }
+
+    @Override
+    public AbstractLocation configure(Map<?,?> properties) {
+        if (machines == null) machines = Sets.newLinkedHashSet();
+        if (inUse == null) inUse = Sets.newLinkedHashSet();
+        if (pendingRemoval == null) pendingRemoval = Sets.newLinkedHashSet();
+        if (origConfigs == null) origConfigs = Maps.newLinkedHashMap();
+        return super.configure(properties);
+    }
+    
+    @SuppressWarnings("unchecked")
+    public FixedListMachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags) {
+        // TODO shouldn't have to copy config bag as it should be inherited (but currently it is not used inherited everywhere; just most places)
+        return getManagementContext().getLocationManager().createLocation(LocationSpec.create(getClass())
+                .parent(this)
+                .configure(config().getLocalBag().getAllConfig())  // FIXME Should this just be inherited?
+                .configure(newFlags));
+    }
+
+    @Override
+    public void close() {
+        for (T machine : machines) {
+            if (machine instanceof Closeable) Streams.closeQuietly((Closeable)machine);
+        }
+    }
+    
+    public void addMachine(T machine) {
+        synchronized (lock) {
+            if (machines.contains(machine)) {
+                throw new IllegalArgumentException("Cannot add "+machine+" to "+toString()+", because already contained");
+            }
+            
+            Location existingParent = ((Location)machine).getParent();
+            if (existingParent == null) {
+                addChild(machine);
+            }
+            
+            machines.add(machine);
+        }
+    }
+    
+    public void removeMachine(T machine) {
+        synchronized (lock) {
+            if (inUse.contains(machine)) {
+                pendingRemoval.add(machine);
+            } else {
+                machines.remove(machine);
+                pendingRemoval.remove(machine);
+                if (this.equals(machine.getParent())) {
+                    removeChild((Location)machine);
+                }
+            }
+        }
+    }
+    
+    protected Set<T> getMachines() {
+        return machines;
+    }
+    
+    public Set<T> getAvailable() {
+        Set<T> a = Sets.newLinkedHashSet(machines);
+        a.removeAll(inUse);
+        return a;
+    }   
+     
+    public Set<T> getInUse() {
+        return Sets.newLinkedHashSet(inUse);
+    }   
+     
+    public Set<T> getAllMachines() {
+        return ImmutableSet.copyOf(machines);
+    }   
+     
+    @Override
+    public void addChild(Location child) {
+        super.addChild(child);
+        machines.add((T)child);
+    }
+
+    @Override
+    public boolean removeChild(Location child) {
+        if (inUse.contains(child)) {
+            throw new IllegalStateException("Child location "+child+" is in use; cannot remove from "+this);
+        }
+        machines.remove(child);
+        return super.removeChild(child);
+    }
+
+    protected boolean canProvisionMore() {
+        return false;
+    }
+    
+    protected void provisionMore(int size) {
+        provisionMore(size, ImmutableMap.of());
+    }
+
+    protected void provisionMore(int size, Map<?,?> flags) {
+        throw new IllegalStateException("more not permitted");
+    }
+
+    public T obtain() throws NoMachinesAvailableException {
+        return obtain(Maps.<String,Object>newLinkedHashMap());
+    }
+    
+    @Override
+    public T obtain(Map<?,?> flags) throws NoMachinesAvailableException {
+        T machine;
+        T desiredMachine = (T) flags.get("desiredMachine");
+        ConfigBag allflags = ConfigBag.newInstanceExtending(config().getBag()).putAll(flags);
+        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = allflags.get(MACHINE_CHOOSER);
+        
+        synchronized (lock) {
+            Set<T> a = getAvailable();
+            if (a.isEmpty()) {
+                if (canProvisionMore()) {
+                    provisionMore(1, allflags.getAllConfig());
+                    a = getAvailable();
+                }
+                if (a.isEmpty())
+                    throw new NoMachinesAvailableException("No machines available in "+toString());
+            }
+            if (desiredMachine != null) {
+                if (a.contains(desiredMachine)) {
+                    machine = desiredMachine;
+                } else {
+                    throw new IllegalStateException("Desired machine "+desiredMachine+" not available in "+toString()+"; "+
+                            (inUse.contains(desiredMachine) ? "machine in use" : "machine unknown"));
+                }
+            } else {
+                machine = (T) chooser.apply(a);
+                if (!a.contains(machine)) {
+                    throw new IllegalStateException("Machine chooser attempted to choose '"+machine+"' from outside the available set, in "+this);
+                }
+            }
+            inUse.add(machine);
+            updateMachineConfig(machine, flags);
+        }
+        
+        for (MachineLocationCustomizer customizer : getMachineCustomizers(allflags)) {
+            customizer.customize(machine);
+        }
+        
+        return machine;
+    }
+
+    @Override
+    public void release(T machine) {
+        ConfigBag machineConfig = ((ConfigurationSupportInternal)machine.config()).getBag();
+        for (MachineLocationCustomizer customizer : getMachineCustomizers(machineConfig)) {
+            customizer.preRelease(machine);
+        }
+
+        synchronized (lock) {
+            if (inUse.contains(machine) == false)
+                throw new IllegalStateException("Request to release machine "+machine+", but this machine is not currently allocated");
+            restoreMachineConfig(machine);
+            inUse.remove(machine);
+            
+            if (pendingRemoval.contains(machine)) {
+                removeMachine(machine);
+            }
+        }
+    }
+
+    @Override
+    public Map<String,Object> getProvisioningFlags(Collection<String> tags) {
+        return Maps.<String,Object>newLinkedHashMap();
+    }
+    
+    protected void updateMachineConfig(T machine, Map<?, ?> flags) {
+        if (origConfigs == null) {
+            // For backwards compatibility, where peristed state did not have this.
+            origConfigs = Maps.newLinkedHashMap();
+        }
+        Map<String, Object> strFlags = ConfigBag.newInstance(flags).getAllConfig();
+        Map<String, Object> origConfig = ((ConfigurationSupportInternal)machine.config()).getLocalBag().getAllConfig();
+        origConfigs.put(machine, origConfig);
+        requestPersist();
+        
+        ((ConfigurationSupportInternal)machine.config()).addToLocalBag(strFlags);
+    }
+    
+    protected void restoreMachineConfig(MachineLocation machine) {
+        if (origConfigs == null) {
+            // For backwards compatibility, where peristed state did not have this.
+            origConfigs = Maps.newLinkedHashMap();
+        }
+        Map<String, Object> origConfig = origConfigs.remove(machine);
+        if (origConfig == null) return;
+        requestPersist();
+        
+        Set<String> currentKeys = ((ConfigurationSupportInternal)machine.config()).getLocalBag().getAllConfig().keySet();
+        Set<String> newKeys = Sets.difference(currentKeys, origConfig.entrySet());
+        for (String key : newKeys) {
+            ((ConfigurationSupportInternal)machine.config()).removeFromLocalBag(key);
+        }
+        ((ConfigurationSupportInternal)machine.config()).addToLocalBag(origConfig);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private <K> K getConfigPreferringOverridden(ConfigKey<K> key, Map<?,?> overrides) {
+        K result = (K) overrides.get(key);
+        if (result == null) result = (K) overrides.get(key.getName());
+        if (result == null) result = getConfig(key);
+        return result;
+    }
+
+    protected Collection<MachineLocationCustomizer> getMachineCustomizers(ConfigBag setup) {
+        Collection<MachineLocationCustomizer> customizers = setup.get(MACHINE_LOCATION_CUSTOMIZERS);
+        return (customizers == null ? ImmutableList.<MachineLocationCustomizer>of() : customizers);
+    }
+
+    /**
+     * Facilitates fluent/programmatic style for constructing a fixed pool of machines.
+     * <pre>
+     * {@code
+     *   new FixedListMachineProvisioningLocation.Builder()
+     *           .user("alex")
+     *           .keyFile("/Users/alex/.ssh/id_rsa")
+     *           .addAddress("10.0.0.1")
+     *           .addAddress("10.0.0.2")
+     *           .addAddress("10.0.0.3")
+     *           .addAddressMultipleTimes("me@127.0.0.1", 5)
+     *           .build();
+     * }
+     * </pre>
+     */
+    public static class Builder {
+        LocationManager lm;
+        String user;
+        String privateKeyPassphrase;
+        String privateKeyFile;
+        String privateKeyData;
+        File localTempDir;
+        List machines = Lists.newArrayList();
+
+        public Builder(LocationManager lm) {
+            this.lm = lm;
+        }
+        public Builder user(String user) {
+            this.user = user;
+            return this;
+        }
+        public Builder keyPassphrase(String keyPassphrase) {
+            this.privateKeyPassphrase = keyPassphrase;
+            return this; 
+        }
+        public Builder keyFile(String keyFile) {
+            this.privateKeyFile = keyFile;
+            return this; 
+        }
+        public Builder keyData(String keyData) {
+            this.privateKeyData = keyData;
+            return this;
+        }
+        public Builder localTempDir(File val) {
+            this.localTempDir = val;
+            return this;
+        }
+        /** adds the locations; user and keyfile set in the builder are _not_ applied to the machine
+         * (use add(String address) for that)
+         */
+        public Builder add(SshMachineLocation location) {
+            machines.add(location);
+            return this;
+        }
+        public Builder addAddress(String address) {
+            return addAddresses(address);
+        }
+        public Builder addAddressMultipleTimes(String address, int n) {
+            for (int i=0; i<n; i++)
+                addAddresses(address);
+            return this;
+        }
+        public Builder addAddresses(String address1, String ...others) {
+            List<String> addrs = new ArrayList<String>();
+            addrs.addAll(WildcardGlobs.getGlobsAfterBraceExpansion("{"+address1+"}",
+                    true /* numeric */, /* no quote support though */ PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR));
+            for (String address: others) 
+                addrs.addAll(WildcardGlobs.getGlobsAfterBraceExpansion("{"+address+"}",
+                        true /* numeric */, /* no quote support though */ PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR));
+            for (String addr: addrs)
+                add(createMachine(addr)); 
+            return this;
+        }
+        protected SshMachineLocation createMachine(String addr) {
+            if (lm==null)
+                return new SshMachineLocation(makeConfig(addr));
+            else
+                return lm.createLocation(makeConfig(addr), SshMachineLocation.class);
+        }
+        private Map makeConfig(String address) {
+            String user = this.user;
+            if (address.contains("@")) {
+                user = address.substring(0, address.indexOf("@"));
+                address = address.substring(address.indexOf("@")+1);
+            }
+            Map config = MutableMap.of("address", address);
+            if (truth(user)) {
+                config.put("user", user);
+                config.put("sshconfig.user", user);
+            }
+            if (truth(privateKeyPassphrase)) config.put("sshconfig.privateKeyPassphrase", privateKeyPassphrase);
+            if (truth(privateKeyFile)) config.put("sshconfig.privateKeyFile", privateKeyFile);
+            if (truth(privateKeyData)) config.put("sshconfig.privateKey", privateKeyData);
+            if (truth(localTempDir)) config.put("localTempDir", localTempDir);
+            return config;
+        }
+        @SuppressWarnings("unchecked")
+        public FixedListMachineProvisioningLocation<SshMachineLocation> build() {
+            if (lm==null)
+                return new FixedListMachineProvisioningLocation<SshMachineLocation>(MutableMap.builder()
+                    .putIfNotNull("machines", machines)
+                    .putIfNotNull("user", user)
+                    .putIfNotNull("privateKeyPassphrase", privateKeyPassphrase)
+                    .putIfNotNull("privateKeyFile", privateKeyFile)
+                    .putIfNotNull("privateKeyData", privateKeyData)
+                    .putIfNotNull("localTempDir", localTempDir)
+                    .build());
+            else
+                return lm.createLocation(MutableMap.builder()
+                    .putIfNotNull("machines", machines)
+                    .putIfNotNull("user", user)
+                    .putIfNotNull("privateKeyPassphrase", privateKeyPassphrase)
+                    .putIfNotNull("privateKeyFile", privateKeyFile)
+                    .putIfNotNull("privateKeyData", privateKeyData)
+                    .putIfNotNull("localTempDir", localTempDir)
+                    .build(), 
+                FixedListMachineProvisioningLocation.class);
+        }        
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/HasSubnetHostname.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/HasSubnetHostname.java b/core/src/main/java/org/apache/brooklyn/location/basic/HasSubnetHostname.java
new file mode 100644
index 0000000..e9fbece
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/HasSubnetHostname.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.basic;
+
+import com.google.common.annotations.Beta;
+
+@Beta
+public interface HasSubnetHostname {
+
+    /** returns a hostname for use internally within a subnet / VPC */
+    @Beta
+    String getSubnetHostname();
+
+    /** returns an IP for use internally within a subnet / VPC */
+    String getSubnetIp();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java
new file mode 100644
index 0000000..0e5225b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.AbstractLocationResolver.SpecParser.ParsedSpec;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.guava.Maybe.Absent;
+import brooklyn.util.text.KeyValueParser;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public class HostLocationResolver extends AbstractLocationResolver {
+    
+    private static final String HOST = "host";
+    
+    @SuppressWarnings("rawtypes")
+    @Override
+    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        // Extract args from spec
+        ParsedSpec parsedSpec = specParser.parse(spec);
+        Map<String, String> argsMap = parsedSpec.argsMap;
+        if (argsMap.isEmpty()) {
+            throw new IllegalArgumentException("Invalid host spec (no host supplied): "+spec);
+        } else if (argsMap.size() == 1 && Iterables.get(argsMap.values(), 0) == null) {
+            // only given ip or hostname
+            argsMap = ImmutableMap.of("hosts", Iterables.get(argsMap.keySet(), 0));
+        } else if (!(argsMap.containsKey("host") || argsMap.containsKey("hosts"))) {
+            throw new IllegalArgumentException("Invalid host spec (no host supplied): "+spec);
+        }
+
+        // Find generic applicable properties
+        Map globalProperties = registry.getProperties();
+        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
+        Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties().getLocationProperties(null, namedLocation, globalProperties);
+        ConfigBag flags = ConfigBag.newInstance(locationFlags).putIfAbsent(filteredProperties);
+        flags.remove(LocationInternal.NAMED_SPEC_NAME);
+
+        // Generate target spec
+        String target = "byon("+KeyValueParser.toLine(argsMap)+")";
+        Maybe<Location> testResolve = managementContext.getLocationRegistry().resolve(target, false, null);
+        if (!testResolve.isPresent()) {
+            throw new IllegalArgumentException("Invalid target location '" + target + "' for location '"+HOST+"': "+
+                Exceptions.collapseText( ((Absent<?>)testResolve).getException() ), ((Absent<?>)testResolve).getException());
+        }
+        
+        return managementContext.getLocationManager().createLocation(LocationSpec.create(SingleMachineProvisioningLocation.class)
+                .configure("location", target)
+                .configure("locationFlags", flags.getAllConfig())
+                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+    }
+    
+    @Override
+    public String getPrefix() {
+        return HOST;
+    }
+    
+    @Override
+    protected Class<? extends Location> getLocationType() {
+        return SingleMachineProvisioningLocation.class;
+    }
+
+    @Override
+    protected SpecParser getSpecParser() {
+        return new SpecParser(getPrefix()).setExampleUsage("\"host(1.1.1.1)\" or \"host(host=1.1.1.1,name=myname)\"");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java
new file mode 100644
index 0000000..47c8089
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java
@@ -0,0 +1,74 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.Location;
+import brooklyn.util.config.ConfigBag;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+
+/**
+ * Examples of valid specs:
+ *   <ul>
+ *     <li>localhost
+ *     <li>localhost()
+ *     <li>localhost(name=abc)
+ *     <li>localhost(name="abc")
+ *   </ul>
+ * 
+ * @author alex, aled
+ */
+public class LocalhostLocationResolver extends AbstractLocationResolver implements LocationResolver.EnableableLocationResolver {
+
+    public static final String LOCALHOST = "localhost";
+
+    @Override
+    public String getPrefix() {
+        return LOCALHOST;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return LocationConfigUtils.isEnabled(managementContext, "brooklyn.location.localhost");
+    }
+
+    @Override
+    protected Class<? extends Location> getLocationType() {
+        return LocalhostMachineProvisioningLocation.class;
+    }
+
+    @Override
+    protected SpecParser getSpecParser() {
+        return new AbstractLocationResolver.SpecParser(getPrefix()).setExampleUsage("\"localhost\" or \"localhost(displayName=abc)\"");
+    }
+
+    @Override
+    protected Map<String, Object> getFilteredLocationProperties(String provider, String namedLocation, Map<String, ?> globalProperties) {
+        return new LocalhostPropertiesFromBrooklynProperties().getLocationProperties("localhost", namedLocation, globalProperties);
+    }
+
+    @Override
+    protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, LocationRegistry registry) {
+        ConfigBag config = super.extractConfig(locationFlags, spec, registry);
+        config.putAsStringKeyIfAbsent("name", "localhost");
+        return config;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
new file mode 100644
index 0000000..44b95b6
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
@@ -0,0 +1,347 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static brooklyn.util.GroovyJavaMethods.elvis;
+import static brooklyn.util.GroovyJavaMethods.truth;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.location.AddressableLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import brooklyn.entity.basic.BrooklynConfigKeys;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.rebind.persister.FileBasedObjectStore;
+import brooklyn.entity.rebind.persister.LocationWithObjectStore;
+import brooklyn.entity.rebind.persister.PersistenceObjectStore;
+import brooklyn.util.BrooklynNetworkUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.internal.ssh.process.ProcessTool;
+import brooklyn.util.mutex.MutexSupport;
+import brooklyn.util.mutex.WithMutexes;
+import brooklyn.util.net.Networking;
+import brooklyn.util.os.Os;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.time.Duration;
+import brooklyn.util.time.Time;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+/**
+ * An implementation of {@link MachineProvisioningLocation} that can provision a {@link SshMachineLocation} for the
+ * local host.
+ *
+ * By default you can only obtain a single SshMachineLocation for the localhost. Optionally, you can "overload"
+ * and choose to allow localhost to be provisioned multiple times, which may be useful in some testing scenarios.
+ */
+public class LocalhostMachineProvisioningLocation extends FixedListMachineProvisioningLocation<SshMachineLocation> implements AddressableLocation, LocationWithObjectStore {
+
+    public static final Logger LOG = LoggerFactory.getLogger(LocalhostMachineProvisioningLocation.class);
+    
+    public static final ConfigKey<Boolean> SKIP_ON_BOX_BASE_DIR_RESOLUTION = ConfigKeys.newConfigKeyWithDefault(
+            BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, 
+            true);
+    
+    @SetFromFlag("count")
+    int initialCount;
+
+    @SetFromFlag
+    Boolean canProvisionMore;
+    
+    @SetFromFlag
+    InetAddress address;
+
+    private static Set<Integer> portsInUse = Sets.newLinkedHashSet();
+
+    private static HostGeoInfo cachedHostGeoInfo;
+    
+    @VisibleForTesting
+    public static void clearStaticData() {
+        portsInUse.clear();
+        cachedHostGeoInfo = null;
+    }
+        
+    /**
+     * Construct a new instance.
+     *
+     * The constructor recognises the following properties:
+     * <ul>
+     * <li>count - number of localhost machines to make available
+     * </ul>
+     */
+    public LocalhostMachineProvisioningLocation() {
+        this(Maps.newLinkedHashMap());
+    }
+    /**
+     * @param properties the properties of the new instance.
+     * @deprecated since 0.6
+     * @see #LocalhostMachineProvisioningLocation()
+     */
+    public LocalhostMachineProvisioningLocation(Map properties) {
+        super(properties);
+    }
+    public LocalhostMachineProvisioningLocation(String name) {
+        this(name, 0);
+    }
+    public LocalhostMachineProvisioningLocation(String name, int count) {
+        this(MutableMap.of("name", name, "count", count));
+    }
+    
+    public static LocationSpec<LocalhostMachineProvisioningLocation> spec() {
+        return LocationSpec.create(LocalhostMachineProvisioningLocation.class);
+    }
+    
+    public LocalhostMachineProvisioningLocation configure(Map<?,?> flags) {
+        super.configure(flags);
+        
+        if (!truth(getDisplayName())) { setDisplayName("localhost"); }
+        if (!truth(address)) address = getLocalhostInetAddress();
+        // TODO should try to confirm this machine is accessible on the given address ... but there's no 
+        // immediate convenience in java so early-trapping of that particular error is deferred
+        
+        if (canProvisionMore==null) {
+            if (initialCount>0) canProvisionMore = false;
+            else canProvisionMore = true;
+        }
+        if (getHostGeoInfo()==null) {
+            if (cachedHostGeoInfo==null)
+                cachedHostGeoInfo = HostGeoInfo.fromLocation(this);
+            setHostGeoInfo(cachedHostGeoInfo);
+        }
+        if (initialCount > getMachines().size()) {
+            provisionMore(initialCount - getMachines().size());
+        }
+        
+        if (getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR)==null && (getManagementContext()==null || getManagementContext().getConfig().getConfig(BrooklynConfigKeys.ONBOX_BASE_DIR)==null)) {
+            setConfig(BrooklynConfigKeys.ONBOX_BASE_DIR, "/tmp/brooklyn-"+Os.user());
+        }
+        
+        return this;
+    }
+    
+    public static InetAddress getLocalhostInetAddress() {
+        return BrooklynNetworkUtils.getLocalhostInetAddress();
+    }
+
+    @Override
+    public InetAddress getAddress() {
+        return address;
+    }
+    
+    @Override
+    public boolean canProvisionMore() {
+        return canProvisionMore;
+    }
+    
+    @Override
+    protected void provisionMore(int size, Map<?,?> flags) {
+        for (int i=0; i<size; i++) {
+            Map<Object,Object> flags2 = MutableMap.<Object,Object>builder()
+                    .putAll(flags)
+                    .put("address", elvis(address, Networking.getLocalHost()))
+                    .put("mutexSupport", LocalhostMachine.mutexSupport)
+                    .build();
+            
+            // copy inherited keys for ssh; 
+            // shouldn't be necessary but not sure that all contexts traverse the hierarchy
+            // NOTE: changed Nov 2013 to copy only those ssh config keys actually set, rather than all of them
+            // TODO should take the plunge and try removing this altogether!
+            // (or alternatively switch to copying all ancestor keys)
+            for (HasConfigKey<?> k: SshMachineLocation.ALL_SSH_CONFIG_KEYS) {
+                if (config().getRaw(k).isPresent())
+                    flags2.put(k, getConfig(k));
+            }
+            
+            if (isManaged()) {
+                addChild(LocationSpec.create(LocalhostMachine.class).configure(flags2));
+            } else {
+                addChild(new LocalhostMachine(flags2)); // TODO legacy way
+            }
+       }
+    }
+
+    public static synchronized boolean obtainSpecificPort(InetAddress localAddress, int portNumber) {
+        if (portsInUse.contains(portNumber)) {
+            return false;
+        } else {
+            //see if it is available?
+            if (!checkPortAvailable(localAddress, portNumber)) {
+                return false;
+            }
+            portsInUse.add(portNumber);
+            return true;
+        }
+    }
+    /** checks the actual availability of the port on localhost, ie by binding to it; cf {@link Networking#isPortAvailable(int)} */
+    public static boolean checkPortAvailable(InetAddress localAddress, int portNumber) {
+        if (portNumber<1024) {
+            if (LOG.isDebugEnabled()) LOG.debug("Skipping system availability check for privileged localhost port "+portNumber);
+            return true;
+        }
+        return Networking.isPortAvailable(localAddress, portNumber);
+    }
+    public static int obtainPort(PortRange range) {
+        return obtainPort(getLocalhostInetAddress(), range);
+    }
+    public static int obtainPort(InetAddress localAddress, PortRange range) {
+        for (int p: range)
+            if (obtainSpecificPort(localAddress, p)) return p;
+        if (LOG.isDebugEnabled()) LOG.debug("unable to find port in {} on {}; returning -1", range, localAddress);
+        return -1;
+    }
+
+    public static synchronized void releasePort(InetAddress localAddress, int portNumber) {
+        portsInUse.remove((Object) portNumber);
+    }
+
+    public void release(SshMachineLocation machine) {
+        LocalhostMachine localMachine = (LocalhostMachine) machine;
+        Set<Integer> portsObtained = Sets.newLinkedHashSet();
+        synchronized (localMachine.portsObtained) {
+            portsObtained.addAll(localMachine.portsObtained);
+        }
+        
+        super.release(machine);
+        
+        for (int p: portsObtained)
+            releasePort(null, p);
+    }
+    
+    public static class LocalhostMachine extends SshMachineLocation implements HasSubnetHostname {
+        // declaring this here (as well as on LocalhostMachineProvisioningLocation) because:
+        //  1. machine.getConfig(key) will not inherit default value of machine.getParent()'s key
+        //  2. things might instantiate a `LocalhostMachine` without going through LocalhostMachineProvisioningLocation
+        //     so not sufficient for LocalhostMachineProvisioningLocation to just push its config value into
+        //     the LocalhostMachine instance.
+        public static final ConfigKey<Boolean> SKIP_ON_BOX_BASE_DIR_RESOLUTION = ConfigKeys.newConfigKeyWithDefault(
+                BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, 
+                true);
+
+        private static final WithMutexes mutexSupport = new MutexSupport();
+        
+        private final Set<Integer> portsObtained = Sets.newLinkedHashSet();
+
+        public LocalhostMachine() {
+            super();
+        }
+        /** @deprecated since 0.6.0 use no-arg constructor (and spec) then configure */
+        public LocalhostMachine(Map properties) {
+            super(MutableMap.builder().putAll(properties).put("mutexSupport", mutexSupport).build());
+        }
+        
+        @Override
+        protected WithMutexes getMutexSupport() {
+            return mutexSupport;
+        }
+        
+        public boolean obtainSpecificPort(int portNumber) {
+            if (!isSudoAllowed() && portNumber <= 1024)
+                return false;
+            return LocalhostMachineProvisioningLocation.obtainSpecificPort(getAddress(), portNumber);
+        }
+        
+        public int obtainPort(PortRange range) {
+            int r = LocalhostMachineProvisioningLocation.obtainPort(getAddress(), range);
+            synchronized (portsObtained) {
+                if (r>0) portsObtained.add(r);
+            }
+            LOG.debug("localhost.obtainPort("+range+"), returning "+r);
+            return r;
+        }
+        
+        @Override
+        public void releasePort(int portNumber) {
+            synchronized (portsObtained) {
+                portsObtained.remove((Object)portNumber);
+            }
+            LocalhostMachineProvisioningLocation.releasePort(getAddress(), portNumber);
+        }
+        
+        @Override
+        public OsDetails getOsDetails() {
+            return BasicOsDetails.Factory.newLocalhostInstance();
+        }
+        
+        @Override
+        public LocalhostMachine configure(Map<?,?> properties) {
+            if (address==null || !properties.containsKey("address"))
+                address = Networking.getLocalHost();
+            super.configure(properties);
+            return this;
+        }
+        @Override
+        public String getSubnetHostname() {
+           return Networking.getLocalHost().getHostName();
+        }
+        @Override
+        public String getSubnetIp() {
+            return Networking.getLocalHost().getHostAddress();
+        }
+    }
+
+    private static class SudoChecker {
+        static volatile long lastSudoCheckTime = -1;
+        static boolean lastSudoResult = false;
+        public static boolean isSudoAllowed() {
+            if (Time.hasElapsedSince(lastSudoCheckTime, Duration.FIVE_MINUTES))
+                checkIfNeeded();                    
+            return lastSudoResult;
+        }
+        private static synchronized void checkIfNeeded() {
+            if (Time.hasElapsedSince(lastSudoCheckTime, Duration.FIVE_MINUTES)) {
+                try {
+                    lastSudoResult = new ProcessTool().execCommands(MutableMap.<String,Object>of(), Arrays.asList(
+                            BashCommands.sudo("date"))) == 0;
+                } catch (Exception e) {
+                    lastSudoResult = false;
+                    LOG.debug("Error checking sudo at localhost: "+e, e);
+                }
+                lastSudoCheckTime = System.currentTimeMillis();
+            }
+        }
+    }
+
+    public static boolean isSudoAllowed() {
+        return SudoChecker.isSudoAllowed();
+    }
+
+    @Override
+    public PersistenceObjectStore newPersistenceObjectStore(String container) {
+        File basedir = new File(container);
+        if (basedir.isFile()) throw new IllegalArgumentException("Destination directory must not be a file");
+        return new FileBasedObjectStore(basedir);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostPropertiesFromBrooklynProperties.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostPropertiesFromBrooklynProperties.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostPropertiesFromBrooklynProperties.java
new file mode 100644
index 0000000..1830ddd
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostPropertiesFromBrooklynProperties.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.base.Strings;
+
+/**
+ * @author aledsage
+ **/
+public class LocalhostPropertiesFromBrooklynProperties extends LocationPropertiesFromBrooklynProperties {
+
+    // TODO Once delete support for deprecated "location.localhost.*" then can get rid of this class, and use
+    // LocationPropertiesFromBrooklynProperties directly
+    
+    @SuppressWarnings("unused")
+    private static final Logger LOG = LoggerFactory.getLogger(LocalhostPropertiesFromBrooklynProperties.class);
+
+    @Override
+    public Map<String, Object> getLocationProperties(String provider, String namedLocation, Map<String, ?> properties) {
+        if (Strings.isNullOrEmpty(namedLocation) && Strings.isNullOrEmpty(provider)) {
+            throw new IllegalArgumentException("Neither cloud provider/API nor location name have been specified correctly");
+        }
+
+        ConfigBag result = ConfigBag.newInstance();
+        
+        result.putAll(transformDeprecated(getGenericLocationSingleWordProperties(properties)));
+        result.putAll(transformDeprecated(getMatchingSingleWordProperties("brooklyn.location.", properties)));
+        result.putAll(transformDeprecated(getMatchingProperties("brooklyn.location.localhost.", "brooklyn.localhost.", properties)));
+        if (!Strings.isNullOrEmpty(namedLocation)) result.putAll(transformDeprecated(getNamedLocationProperties(namedLocation, properties)));
+        setLocalTempDir(properties, result);
+        
+        return result.getAllConfigRaw();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocationConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationConfigKeys.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationConfigKeys.java
new file mode 100644
index 0000000..05e15f9
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationConfigKeys.java
@@ -0,0 +1,79 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.io.File;
+import java.util.Set;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.util.os.Os;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.reflect.TypeToken;
+
+public class LocationConfigKeys {
+
+    public static final ConfigKey<String> LOCATION_ID = ConfigKeys.newStringConfigKey("id");
+    public static final ConfigKey<String> DISPLAY_NAME = ConfigKeys.newStringConfigKey("displayName");
+    public static final ConfigKey<Boolean> ENABLED = ConfigKeys.newBooleanConfigKey("enabled", "Whether the location is enabled for listing and use "
+        + "(only supported for selected locations)", true);
+    
+    public static final ConfigKey<String> ACCESS_IDENTITY = ConfigKeys.newStringConfigKey("identity"); 
+    public static final ConfigKey<String> ACCESS_CREDENTIAL = ConfigKeys.newStringConfigKey("credential"); 
+
+    public static final ConfigKey<Double> LATITUDE = new BasicConfigKey<Double>(Double.class, "latitude"); 
+    public static final ConfigKey<Double> LONGITUDE = new BasicConfigKey<Double>(Double.class, "longitude"); 
+
+    public static final ConfigKey<String> CLOUD_PROVIDER = ConfigKeys.newStringConfigKey("provider");
+    public static final ConfigKey<String> CLOUD_ENDPOINT = ConfigKeys.newStringConfigKey("endpoint");
+    public static final ConfigKey<String> CLOUD_REGION_ID = ConfigKeys.newStringConfigKey("region");
+    public static final ConfigKey<String> CLOUD_AVAILABILITY_ZONE_ID = ConfigKeys.newStringConfigKey("availabilityZone");
+
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Set<String>> ISO_3166 = ConfigKeys.newConfigKey(new TypeToken<Set<String>>() {}, "iso3166", "ISO-3166 or ISO-3166-2 location codes"); 
+
+    public static final ConfigKey<String> USER = ConfigKeys.newStringConfigKey("user", 
+            "user account for normal access to the remote machine, defaulting to local user", System.getProperty("user.name"));
+    
+    public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password", "password to use for ssh; note some images do not allow password-based ssh access");
+    public static final ConfigKey<String> PUBLIC_KEY_FILE = ConfigKeys.newStringConfigKey("publicKeyFile", "ssh public key file to use; if blank will infer from privateKeyFile by appending \".pub\"");
+    public static final ConfigKey<String> PUBLIC_KEY_DATA = ConfigKeys.newStringConfigKey("publicKeyData", "ssh public key string to use (takes precedence over publicKeyFile)");
+    public static final ConfigKey<String> PRIVATE_KEY_FILE = ConfigKeys.newStringConfigKey("privateKeyFile", "a '" + File.pathSeparator + "' separated list of ssh private key files; uses first in list that can be read",
+                                                                                           Os.fromHome(".ssh/id_rsa") + File.pathSeparator + Os.fromHome(".ssh/id_dsa"));
+    public static final ConfigKey<String> PRIVATE_KEY_DATA = ConfigKeys.newStringConfigKey("privateKeyData", "ssh private key string to use (takes precedence over privateKeyFile)");
+    public static final ConfigKey<String> PRIVATE_KEY_PASSPHRASE = ConfigKeys.newStringConfigKey("privateKeyPassphrase");
+
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PUBLIC_KEY_FILE = ConfigKeys.convert(PUBLIC_KEY_FILE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PUBLIC_KEY_DATA = ConfigKeys.convert(PUBLIC_KEY_DATA, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_FILE = ConfigKeys.convert(PRIVATE_KEY_FILE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_DATA = ConfigKeys.convert(PRIVATE_KEY_DATA, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_PASSPHRASE = ConfigKeys.convert(PRIVATE_KEY_PASSPHRASE, CaseFormat.LOWER_CAMEL, CaseFormat.LOWER_HYPHEN);
+
+    public static final ConfigKey<Object> CALLER_CONTEXT = new BasicConfigKey<Object>(Object.class, "callerContext",
+            "An object whose toString is used for logging, to indicate wherefore a VM is being created");
+    public static final ConfigKey<String> CLOUD_MACHINE_NAMER_CLASS = ConfigKeys.newStringConfigKey("cloudMachineNamer", "fully qualified class name of a class that extends CloudMachineNamer and has a single-parameter constructor that takes a ConfigBag");
+    
+}


[15/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java
new file mode 100644
index 0000000..9fce742
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java
@@ -0,0 +1,280 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+
+import org.apache.brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension;
+import org.jclouds.Constants;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.domain.LoginCredentials;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.event.basic.BasicConfigKey;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.PortForwardManager;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.util.internal.ssh.SshTool;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.reflect.TypeToken;
+
+public interface JcloudsLocationConfig extends CloudLocationConfig {
+
+    public static final ConfigKey<String> CLOUD_PROVIDER = LocationConfigKeys.CLOUD_PROVIDER;
+
+    public static final ConfigKey<Boolean> RUN_AS_ROOT = ConfigKeys.newBooleanConfigKey("runAsRoot", 
+            "Whether to run initial setup as root (default true)", null);
+    public static final ConfigKey<String> LOGIN_USER = ConfigKeys.newStringConfigKey("loginUser",
+            "Override the user who logs in initially to perform setup " +
+            "(otherwise it is detected from the cloud or known defaults in cloud or VM OS)", null);
+    public static final ConfigKey<String> LOGIN_USER_PASSWORD = ConfigKeys.newStringConfigKey("loginUser.password",
+            "Custom password for the user who logs in initially", null);
+    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_DATA = ConfigKeys.newStringConfigKey("loginUser.privateKeyData",
+            "Custom private key for the user who logs in initially", null);   
+    public static final ConfigKey<String> KEY_PAIR = ConfigKeys.newStringConfigKey("keyPair",
+            "Custom keypair name to be re-used", null);
+    public static final ConfigKey<Boolean> AUTO_GENERATE_KEYPAIRS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-generate-keypairs",
+            "Whether to generate keypairs for Nova");
+    /**
+     * @deprecated since 0.7.0 Use {@link #AUTO_ASSIGN_FLOATING_IP} instead
+     */
+    public static final ConfigKey<Boolean> AUTO_CREATE_FLOATING_IPS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-create-floating-ips",
+            "Whether to generate floating ips for Nova");
+    public static final ConfigKey<Boolean> AUTO_ASSIGN_FLOATING_IP = ConfigKeys.newBooleanConfigKey("autoAssignFloatingIp",
+            "Whether to generate floating ips (in Nova paralance), or elastic IPs (in CloudStack parlance)");
+    // not supported in jclouds
+//    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_PASSPHRASE = ConfigKeys.newStringKey("loginUser.privateKeyPassphrase", 
+//            "Passphrase for the custom private key for the user who logs in initially", null);
+    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_FILE = ConfigKeys.newStringConfigKey("loginUser.privateKeyFile",
+            "Custom private key for the user who logs in initially", null); 
+    public static final ConfigKey<String> EXTRA_PUBLIC_KEY_DATA_TO_AUTH = ConfigKeys.newStringConfigKey("extraSshPublicKeyData",
+        "Additional public key data to add to authorized_keys", null);
+    @SuppressWarnings("serial")
+    public static final ConfigKey<List<String>> EXTRA_PUBLIC_KEY_URLS_TO_AUTH = ConfigKeys.newConfigKey(new TypeToken<List<String>>() {}, 
+        "extraSshPublicKeyUrls", "Additional public keys (files or URLs, in SSH2/RFC4716/id_rsa.pub format) to add to authorized_keys", null);
+
+    public static final ConfigKey<Boolean> DONT_CREATE_USER = ConfigKeys.newBooleanConfigKey("dontCreateUser", 
+            "Whether to skip creation of 'user' when provisioning machines (default false)", false);
+    public static final ConfigKey<Boolean> GRANT_USER_SUDO = ConfigKeys.newBooleanConfigKey("grantUserSudo",
+            "Whether to grant the created user sudo privileges. Irrelevant if dontCreateUser is true. Default: true.", true);
+    public static final ConfigKey<Boolean> DISABLE_ROOT_AND_PASSWORD_SSH = ConfigKeys.newBooleanConfigKey("disableRootAndPasswordSsh",
+        "Whether to disable direct SSH access for root and disable password-based SSH, "
+        + "if creating a user with a key-based login; "
+        + "defaults to true (set false to leave root users alone)", true);
+    public static final ConfigKey<String> CUSTOM_TEMPLATE_OPTIONS_SCRIPT_CONTENTS = ConfigKeys.newStringConfigKey("customTemplateOptionsScriptContents",
+        "A custom script to pass to jclouds as part of template options, run after AdminAccess, "
+        + "for use primarily where a command which must run as root on first login before switching to the admin user, "
+        + "e.g. to customize sudoers; may start in an odd location (e.g. /tmp/bootstrap); "
+        + "NB: most commands should be run by entities, or if VM-specific but sudo is okay, then via setup.script, not via this");
+    
+    public static final ConfigKey<LoginCredentials> CUSTOM_CREDENTIALS = new BasicConfigKey<LoginCredentials>(LoginCredentials.class,
+            "customCredentials", "Custom jclouds LoginCredentials object to be used to connect to the VM", null);
+    
+    public static final ConfigKey<String> GROUP_ID = ConfigKeys.newStringConfigKey("groupId",
+            "The Jclouds group provisioned machines should be members of. " +
+            "Users of this config key are also responsible for configuring security groups.");
+    
+    // jclouds compatibility
+    public static final ConfigKey<String> JCLOUDS_KEY_USERNAME = ConfigKeys.newStringConfigKey(
+            "userName", "Equivalent to 'user'; provided for jclouds compatibility", null);
+    public static final ConfigKey<String> JCLOUDS_KEY_ENDPOINT = ConfigKeys.newStringConfigKey(
+            Constants.PROPERTY_ENDPOINT, "Equivalent to 'endpoint'; provided for jclouds compatibility", null);
+    
+    // note causing problems on centos due to use of `sudo -n`; but required for default RHEL VM
+    /**
+     * @deprecated since 0.8.0; instead configure this on the entity. See SoftwareProcess.OPEN_IPTABLES.
+     */
+    @Deprecated
+    public static final ConfigKey<Boolean> OPEN_IPTABLES = ConfigKeys.newBooleanConfigKey("openIptables", 
+            "[DEPRECATED - use openIptables on SoftwareProcess entity] Whether to open the INBOUND_PORTS via iptables rules; " +
+            "if true then ssh in to run iptables commands, as part of machine provisioning", false);
+
+    /**
+     * @deprecated since 0.8.0; instead configure this on the entity. See SoftwareProcess.STOP_IPTABLES.
+     */
+    @Deprecated
+    public static final ConfigKey<Boolean> STOP_IPTABLES = ConfigKeys.newBooleanConfigKey("stopIptables", 
+            "[DEPRECATED - use stopIptables on SoftwareProcess entity] Whether to stop iptables entirely; " +
+            "if true then ssh in to stop the iptables service, as part of machine provisioning", false);
+
+    public static final ConfigKey<String> HARDWARE_ID = ConfigKeys.newStringConfigKey("hardwareId",
+            "A system-specific identifier for the hardware profile or machine type to be used when creating a VM", null);
+    
+    public static final ConfigKey<String> IMAGE_ID = ConfigKeys.newStringConfigKey("imageId", 
+            "A system-specific identifier for the VM image to be used when creating a VM", null);
+    public static final ConfigKey<String> IMAGE_NAME_REGEX = ConfigKeys.newStringConfigKey("imageNameRegex", 
+            "A regular expression to be compared against the 'name' when selecting the VM image to be used when creating a VM", null);
+    public static final ConfigKey<String> IMAGE_DESCRIPTION_REGEX = ConfigKeys.newStringConfigKey("imageDescriptionRegex", 
+            "A regular expression to be compared against the 'description' when selecting the VM image to be used when creating a VM", null);
+
+    public static final ConfigKey<String> TEMPLATE_SPEC = ConfigKeys.newStringConfigKey("templateSpec", 
+            "A jclouds 'spec' string consisting of properties and values to be used when creating a VM " +
+            "(in most cases the properties can, and should, be specified individually using other Brooklyn location config keys)", null);
+
+    public static final ConfigKey<String> DEFAULT_IMAGE_ID = ConfigKeys.newStringConfigKey("defaultImageId", 
+            "A system-specific identifier for the VM image to be used by default when creating a VM " +
+            "(if no other VM image selection criteria are supplied)", null);
+
+    public static final ConfigKey<TemplateBuilder> TEMPLATE_BUILDER = ConfigKeys.newConfigKey(TemplateBuilder.class,
+            "templateBuilder", "A TemplateBuilder instance provided programmatically, to be used when creating a VM");
+
+    public static final ConfigKey<Object> SECURITY_GROUPS = new BasicConfigKey<Object>(Object.class, "securityGroups",
+            "Security groups to be applied when creating a VM, on supported clouds " +
+            "(either a single group identifier as a String, or an Iterable<String> or String[])", null);
+
+    public static final ConfigKey<String> USER_METADATA_STRING = ConfigKeys.newStringConfigKey("userMetadataString", 
+        "Arbitrary user data, as a single string, on supported clouds (AWS)", null);
+
+    @Deprecated /** @deprecated since 0.7.0 even AWS (the only one where this was supported) does not seem to want this uuencoded;
+      use #USER_METADATA_STRING */
+    public static final ConfigKey<String> USER_DATA_UUENCODED = ConfigKeys.newStringConfigKey("userData", 
+        "Arbitrary user data, as a single string in uuencoded format, on supported clouds (AWS)", null);
+
+    public static final ConfigKey<Object> STRING_TAGS = new BasicConfigKey<Object>(Object.class, "tags", 
+            "Tags to be applied when creating a VM, on supported clouds " +
+            "(either a single tag as a String, or an Iterable<String> or String[];" +
+            "note this is not key-value pairs (e.g. what AWS calls 'tags'), for that see userMetadata)", null);
+
+    @Deprecated /** @deprecated since 0.7.0 use #STRING_TAGS */
+    public static final ConfigKey<Object> TAGS = STRING_TAGS;
+
+    public static final ConfigKey<Object> USER_METADATA_MAP = new BasicConfigKey<Object>(Object.class, "userMetadata", 
+            "Arbitrary user metadata, as a map (or String of comma-separated key=value pairs), on supported clouds; " +
+            "note often values cannot be null", null);
+    @Deprecated /** @deprecated since 0.7.0 use #USER_METADATA_MAP */
+    public static final ConfigKey<Object> USER_METADATA = USER_METADATA_MAP;
+
+    public static final ConfigKey<Boolean> INCLUDE_BROOKLYN_USER_METADATA = ConfigKeys.newBooleanConfigKey("includeBrooklynUserMetadata", 
+        "Whether to set metadata about the context of a machine, e.g. brooklyn-entity-id, brooklyn-app-name (default true)", true);
+
+    public static final ConfigKey<Boolean> MAP_DEV_RANDOM_TO_DEV_URANDOM = ConfigKeys.newBooleanConfigKey(
+            "installDevUrandom", "Map /dev/random to /dev/urandom to prevent halting on insufficient entropy", true);
+
+    /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */
+    @Deprecated
+    public static final ConfigKey<JcloudsLocationCustomizer> JCLOUDS_LOCATION_CUSTOMIZER = ConfigKeys.newConfigKey(JcloudsLocationCustomizer.class,
+            "customizer", "Optional location customizer");
+
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Collection<JcloudsLocationCustomizer>> JCLOUDS_LOCATION_CUSTOMIZERS = ConfigKeys.newConfigKey(
+            new TypeToken<Collection<JcloudsLocationCustomizer>>() {},
+            "customizers", "Optional location customizers");
+
+    /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */
+    @Deprecated
+    public static final ConfigKey<String> JCLOUDS_LOCATION_CUSTOMIZER_TYPE = ConfigKeys.newStringConfigKey(
+            "customizerType", "Optional location customizer type (to be class-loaded and constructed with no-arg constructor)");
+
+    /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */
+    @Deprecated
+    public static final ConfigKey<String> JCLOUDS_LOCATION_CUSTOMIZERS_SUPPLIER_TYPE = ConfigKeys.newStringConfigKey(
+            "customizersSupplierType", "Optional type of a Supplier<Collection<JcloudsLocationCustomizer>> " +
+            "(to be class-loaded and constructed with ConfigBag or no-arg constructor)");
+
+    public static final ConfigKey<String> LOCAL_TEMP_DIR = SshTool.PROP_LOCAL_TEMP_DIR;
+    
+    public static final ConfigKey<Integer> OVERRIDE_RAM = ConfigKeys.newIntegerConfigKey("overrideRam", "Custom ram value");    
+    
+    public static final ConfigKey<String> NETWORK_NAME = ConfigKeys.newStringConfigKey(
+        "networkName", "Network name or ID where the instance should be created (e.g. the subnet ID in AWS");
+
+    /**
+     * CUSTOM_MACHINE_SETUP_SCRIPT_URL accepts a URL location that points to a shell script. 
+     * Please have a look at locations/jclouds/src/main/resources/sample/script/setup-server.sh as an example
+     */
+    public static final ConfigKey<String> CUSTOM_MACHINE_SETUP_SCRIPT_URL = ConfigKeys.newStringConfigKey(
+            "setup.script", "Custom script to customize a node");
+    
+    @SuppressWarnings("serial")
+    public static final ConfigKey<List<String>> CUSTOM_MACHINE_SETUP_SCRIPT_URL_LIST = ConfigKeys.newConfigKey(new TypeToken<List<String>>() {},
+            "setup.scripts", "A list of scripts to customize a node");
+    
+    public static final ConfigKey<String> CUSTOM_MACHINE_SETUP_SCRIPT_VARS = ConfigKeys.newStringConfigKey(
+            "setup.script.vars", "vars to customize a setup.script i.e.: key1:value1,key2:value2");
+    
+    public static final ConfigKey<Boolean> GENERATE_HOSTNAME = ConfigKeys.newBooleanConfigKey(
+            "generate.hostname", "Use the nodename generated by jclouds", false);
+
+    public static final ConfigKey<Boolean> USE_PORT_FORWARDING = ConfigKeys.newBooleanConfigKey(
+            "portforwarding.enabled", 
+            "Whether to setup port-forwarding to subsequently access the VM (over the ssh port)",
+            false);
+    
+    @Beta
+    public static final ConfigKey<Boolean> USE_JCLOUDS_SSH_INIT = ConfigKeys.newBooleanConfigKey(
+            "useJcloudsSshInit", 
+            "Whether to use jclouds for initial ssh-based setup (i.e. as part of the 'TemplateOptions'); "
+                    + "if false will use core brooklyn ssh utilities. "
+                    + "This config is beta; its default could be changed and/or the option removed in an upcoming release.", 
+            true);
+    
+    public static final ConfigKey<JcloudsPortForwarderExtension> PORT_FORWARDER = ConfigKeys.newConfigKey(
+            JcloudsPortForwarderExtension.class, "portforwarding.forwarder", "The port-forwarder to use");
+    
+    public static final ConfigKey<PortForwardManager> PORT_FORWARDING_MANAGER = BrooklynAccessUtils
+            .PORT_FORWARDING_MANAGER;
+
+    public static final ConfigKey<Integer> MACHINE_CREATE_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
+            "machineCreateAttempts", "Number of times to retry if jclouds fails to create a VM", 1);
+
+    public static final ConfigKey<Integer> MAX_CONCURRENT_MACHINE_CREATIONS = ConfigKeys.newIntegerConfigKey(
+            "maxConcurrentMachineCreations", "Maximum number of concurrent machine-creations", Integer.MAX_VALUE);
+
+    public static final ConfigKey<Semaphore> MACHINE_CREATION_SEMAPHORE = ConfigKeys.newConfigKey(
+            Semaphore.class, "machineCreationSemaphore", "Semaphore for controlling concurrent machine creation", null);
+
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Function<Iterable<? extends Image>,Image>> IMAGE_CHOOSER = ConfigKeys.newConfigKey(
+        new TypeToken<Function<Iterable<? extends Image>,Image>>() {},
+        "imageChooser", "An image chooser function to control which images are preferred", 
+        new BrooklynImageChooser().chooser());
+
+    public static final ConfigKey<OsFamily> OS_FAMILY = ConfigKeys.newConfigKey(OsFamily.class, "osFamily", 
+        "OS family, e.g. CentOS, Debian, RHEL, Ubuntu");
+    public static final ConfigKey<String> OS_VERSION_REGEX = ConfigKeys.newStringConfigKey("osVersionRegex", 
+        "Regular expression for the OS version to load");
+
+    public static final ConfigKey<OsFamily> OS_FAMILY_OVERRIDE = ConfigKeys.newConfigKey(OsFamily.class, "osFamilyOverride", 
+            "OS family of VMs (ignores VM metadata from jclouds, and assumes this value)");
+
+    public static final ConfigKey<ComputeServiceRegistry> COMPUTE_SERVICE_REGISTRY = ConfigKeys.newConfigKey(
+            ComputeServiceRegistry.class,
+            "jclouds.computeServiceRegistry",
+            "Registry/Factory for creating jclouds ComputeService; default is almost always fine, except where tests want to customize behaviour",
+            ComputeServiceRegistryImpl.INSTANCE);
+    
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Map<String,Object>> TEMPLATE_OPTIONS = ConfigKeys.newConfigKey(
+            new TypeToken<Map<String, Object>>() {}, "templateOptions", "Additional jclouds template options");
+
+    // TODO
+    
+//  "noDefaultSshKeys" - hints that local ssh keys should not be read as defaults
+    // this would be useful when we need to indicate a password
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationCustomizer.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationCustomizer.java
new file mode 100644
index 0000000..b6cb363
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationCustomizer.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.jclouds;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.annotations.Beta;
+
+import brooklyn.util.config.ConfigBag;
+
+/**
+ * Customization hooks to allow apps to perform specific customisation at each stage of jclouds machine provisioning.
+ * For example, an app could attach an EBS volume to an EC2 node, or configure a desired availability zone.
+ * <p/>
+ * Instances will be invoked with the {@link ConfigBag} being used to obtain a machine by the
+ * {@link JcloudsLocation }if such a constructor exists. If not, the default no argument constructor
+ * will be invoked.
+ */
+@Beta
+public interface JcloudsLocationCustomizer {
+
+    /**
+     * Override to configure {@link org.jclouds.compute.domain.TemplateBuilder templateBuilder}
+     * before it is built and immutable.
+     */
+    void customize(JcloudsLocation location, ComputeService computeService, TemplateBuilder templateBuilder);
+
+    /**
+     * Override to configure a subclass of this with the built template, or to configure the built
+     * template's {@link org.jclouds.compute.options.TemplateOptions}.
+     * <p/>
+     * This method will be called before {@link #customize(JcloudsLocation, ComputeService, TemplateOptions)}.
+     */
+    void customize(JcloudsLocation location, ComputeService computeService, Template template);
+
+    /**
+     * Override to configure the {@link org.jclouds.compute.options.TemplateOptions} that will
+     * be used by {@link JcloudsLocation} to obtain machines.
+     */
+    void customize(JcloudsLocation location, ComputeService computeService, TemplateOptions templateOptions);
+
+    /**
+     * Override to configure the given machine once it has been created and started by Jclouds.
+     * <p/>
+     * If {@link JcloudsLocationConfig#WAIT_FOR_SSHABLE} is true the
+     * machine is guaranteed to be SSHable when this method is called.
+     * 
+     * @since 0.7.0; use {@link #customize(JcloudsLocation, ComputeService, JcloudsMachineLocation)}
+     */
+    @Deprecated
+    void customize(JcloudsLocation location, ComputeService computeService, JcloudsSshMachineLocation machine);
+    
+    /**
+     * Override to handle machine-related cleanup before Jclouds is called to release (destroy) the machine.
+     * 
+     * @since 0.7.0; use {@link #preRelease(JcloudsMachineLocation)}
+     */
+    @Deprecated
+    void preRelease(JcloudsSshMachineLocation machine);
+
+    /**
+     * Override to handle machine-related cleanup after Jclouds is called to release (destroy) the machine.
+     * 
+     * @since 0.7.0; use {@link #postRelesae(JcloudsMachineLocation)}
+     */
+    @Deprecated
+    void postRelease(JcloudsSshMachineLocation machine);
+
+    /**
+     * Override to configure the given machine once it has been created and started by Jclouds.
+     * <p/>
+     * If {@link JcloudsLocationConfig#WAIT_FOR_SSHABLE} is true the
+     * machine is guaranteed to be SSHable when this method is called.
+     */
+    void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine);
+    
+    /**
+     * Override to handle machine-related cleanup before Jclouds is called to release (destroy) the machine.
+     */
+    void preRelease(JcloudsMachineLocation machine);
+
+    /**
+     * Override to handle machine-related cleanup after Jclouds is called to release (destroy) the machine.
+     */
+    void postRelease(JcloudsMachineLocation machine);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
new file mode 100644
index 0000000..1ca33c2
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
@@ -0,0 +1,227 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.basic.LocationConfigUtils;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.apis.Apis;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.providers.Providers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
+import brooklyn.util.text.Strings;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+@SuppressWarnings("rawtypes")
+public class JcloudsLocationResolver implements LocationResolver {
+
+    public static final Logger log = LoggerFactory.getLogger(JcloudsLocationResolver.class);
+    
+    private static final String JCLOUDS = "jclouds";
+    
+    public static final Map<String,ProviderMetadata> PROVIDERS = getProvidersMap();
+    public static final Map<String,ApiMetadata> APIS = getApisMap();
+    
+    private static Map<String,ProviderMetadata> getProvidersMap() {
+        Map<String,ProviderMetadata> result = Maps.newLinkedHashMap();
+        for (ProviderMetadata p: Providers.all()) {
+            result.put(p.getId(), p);
+        }
+        return ImmutableMap.copyOf(result);
+    }
+
+    private static Map<String,ApiMetadata> getApisMap() {
+        Map<String,ApiMetadata> result = Maps.newLinkedHashMap();
+        for (ApiMetadata api: Apis.all()) {
+            result.put(api.getId(), api);
+        }
+        return ImmutableMap.copyOf(result);
+    }
+
+    public static final Collection<String> AWS_REGIONS = Arrays.asList(
+            // from http://docs.amazonwebservices.com/general/latest/gr/rande.html as of Apr 2012.
+            // it is suggested not to maintain this list here, instead to require aws-ec2 explicitly named.
+            "eu-west-1","us-east-1","us-west-1","us-west-2","ap-southeast-1","ap-northeast-1","sa-east-1");
+         
+    private ManagementContext managementContext;
+
+    @Override
+    public void init(ManagementContext managementContext) {
+        this.managementContext = checkNotNull(managementContext, "managementContext");
+    }
+    
+    protected class JcloudsSpecParser {
+        String providerOrApi;
+        String parameter;
+        
+        public JcloudsSpecParser parse(String spec, boolean dryrun) {
+            JcloudsSpecParser result = new JcloudsSpecParser();
+            int split = spec.indexOf(':');
+            if (split<0) {
+                if (spec.equalsIgnoreCase(getPrefix())) {
+                    if (dryrun) return null;
+                    throw new IllegalArgumentException("Cannot use '"+spec+"' as a location ID; it is insufficient. "+
+                           "Try jclouds:aws-ec2 (for example).");
+                }
+                result.providerOrApi = spec;
+                result.parameter = null;
+            } else {
+                result.providerOrApi = spec.substring(0, split);
+                result.parameter = spec.substring(split+1);
+                int numJcloudsPrefixes = 0;
+                while (result.providerOrApi.equalsIgnoreCase(getPrefix())) {
+                    //strip any number of jclouds: prefixes, for use by static "resolve" method
+                    numJcloudsPrefixes++;
+                    result.providerOrApi = result.parameter;
+                    result.parameter = null;
+                    split = result.providerOrApi.indexOf(':');
+                    if (split>=0) {
+                        result.parameter = result.providerOrApi.substring(split+1);
+                        result.providerOrApi = result.providerOrApi.substring(0, split);
+                    }
+                }
+                if (!dryrun && numJcloudsPrefixes > 1) {
+                    log.warn("Use of deprecated location spec '"+spec+"'; in future use a single \"jclouds\" prefix");
+                }
+            }
+            
+            if (result.parameter==null && AWS_REGIONS.contains(result.providerOrApi)) {
+                // treat amazon as a default
+                result.parameter = result.providerOrApi;
+                result.providerOrApi = "aws-ec2";
+                if (!dryrun)
+                    log.warn("Use of deprecated location '"+result.parameter+"'; in future refer to with explicit " +
+                            "provider '"+result.providerOrApi+":"+result.parameter+"'");
+            }
+            
+            return result;
+        }
+
+        public boolean isProvider() {
+            return PROVIDERS.containsKey(providerOrApi);
+        }
+
+        public boolean isApi() {
+            return APIS.containsKey(providerOrApi);
+        }
+        
+        public String getProviderOrApi() {
+            return providerOrApi;
+        }
+        
+        public String getParameter() {
+            return parameter;
+        }
+    }
+    
+    @Override
+    @SuppressWarnings("unchecked")
+    public JcloudsLocation newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        Map globalProperties = registry.getProperties();
+
+        JcloudsSpecParser details = new JcloudsSpecParser().parse(spec, false);
+        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
+
+        boolean isProvider = details.isProvider();
+        String providerOrApi = details.providerOrApi;
+        // gce claims to be an api ... perhaps just a bug? email sent to jclouds dev list, 28 mar 2014
+        isProvider = isProvider || "google-compute-engine".equals(providerOrApi);
+        
+        if (Strings.isEmpty(providerOrApi)) {
+            throw new IllegalArgumentException("Cloud provider/API type not specified in spec \""+spec+"\"");
+        }
+        if (!isProvider && !details.isApi()) {
+            throw new NoSuchElementException("Cloud provider/API type "+providerOrApi+" is not supported by jclouds");
+        }
+        
+        // For everything in brooklyn.properties, only use things with correct prefix (and remove that prefix).
+        // But for everything passed in via locationFlags, pass those as-is.
+        // TODO Should revisit the locationFlags: where are these actually used? Reason accepting properties without
+        //      full prefix is that the map's context is explicitly this location, rather than being generic properties.
+        Map allProperties = getAllProperties(registry, globalProperties);
+        String regionOrEndpoint = details.parameter;
+        if (regionOrEndpoint==null && isProvider) regionOrEndpoint = (String)locationFlags.get(LocationConfigKeys.CLOUD_REGION_ID.getName());
+        Map jcloudsProperties = new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties(providerOrApi, regionOrEndpoint, namedLocation, allProperties);
+        jcloudsProperties.putAll(locationFlags);
+        
+        if (regionOrEndpoint!=null) {
+            // apply the regionOrEndpoint (e.g. from the parameter) as appropriate -- but only if it has not been overridden
+            if (isProvider) {
+                // providers from ServiceLoader take a location (endpoint already configured), and optionally a region name
+                // NB blank might be supplied if spec string is "mycloud:" -- that should be respected, 
+                // whereas no parameter/regionName ie null value -- "mycloud" -- means don't set
+                if (Strings.isBlank(Strings.toString(jcloudsProperties.get(JcloudsLocationConfig.CLOUD_REGION_ID.getName()))))
+                    jcloudsProperties.put(JcloudsLocationConfig.CLOUD_REGION_ID.getName(), regionOrEndpoint);
+            } else {
+                // other "providers" are APIs so take an _endpoint_ (but not a location);
+                // see note above re null here
+                if (Strings.isBlank(Strings.toString(jcloudsProperties.get(JcloudsLocationConfig.CLOUD_ENDPOINT.getName()))))
+                    jcloudsProperties.put(JcloudsLocationConfig.CLOUD_ENDPOINT.getName(), regionOrEndpoint);
+            }
+        }
+        
+        return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationClass())
+                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, jcloudsProperties, globalProperties, namedLocation))
+                .configure(jcloudsProperties) );
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map getAllProperties(LocationRegistry registry, Map<?,?> properties) {
+        Map<Object,Object> allProperties = Maps.newHashMap();
+        if (registry!=null) allProperties.putAll(registry.getProperties());
+        allProperties.putAll(properties);
+        return allProperties;
+    }
+    
+    @Override
+    public String getPrefix() {
+        return JCLOUDS;
+    }
+
+    protected Class<? extends JcloudsLocation> getLocationClass() {
+        return JcloudsLocation.class;
+    }
+    
+    @Override
+    public boolean accepts(String spec, LocationRegistry registry) {
+        if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true)) return true;
+        JcloudsSpecParser details = new JcloudsSpecParser().parse(spec, true);
+        if (details==null) return false;
+        if (details.isProvider() || details.isApi()) return true;
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
new file mode 100644
index 0000000..2619206
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
@@ -0,0 +1,45 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import org.apache.brooklyn.location.basic.HasSubnetHostname;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+
+import org.apache.brooklyn.location.MachineLocation;
+
+public interface JcloudsMachineLocation extends MachineLocation, HasSubnetHostname {
+    
+    @Override
+    public JcloudsLocation getParent();
+    
+    public NodeMetadata getNode();
+    
+    public Template getTemplate();
+
+    public String getJcloudsId();
+
+    /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */
+    @Override
+    public String getSubnetHostname();
+
+    String getUser();
+
+    int getPort();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineNamer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineNamer.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineNamer.java
new file mode 100644
index 0000000..4f4587e
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineNamer.java
@@ -0,0 +1,44 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import org.apache.brooklyn.location.cloud.names.BasicCloudMachineNamer;
+import brooklyn.util.config.ConfigBag;
+
+public class JcloudsMachineNamer extends BasicCloudMachineNamer {
+
+    @Override
+    /** returns the max length of a VM name for the cloud specified in setup;
+     * this value is typically decremented by 9 to make room for jclouds labels */
+    public Integer getCustomMaxNameLength(ConfigBag setup) {
+        // otherwise, for some known clouds which only allow a short name, use that length
+        if ("vcloud".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) ))
+            return 24;
+        if ("abiquo".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) ))
+            return 39;
+        if ("google-compute-engine".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) ))
+            return 39;
+        if ("softlayer".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) ))
+            return 55;
+        // TODO other cloud max length rules
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsPredicates.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsPredicates.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsPredicates.java
new file mode 100644
index 0000000..565425d
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsPredicates.java
@@ -0,0 +1,53 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.domain.Location;
+
+import com.google.common.base.Predicate;
+
+public class JcloudsPredicates {
+
+    public static class NodeInLocation implements Predicate<ComputeMetadata> {
+        private String regionId;
+        private boolean matchNullLocations;
+        public NodeInLocation(String regionId, boolean matchNullLocations) {
+            this.regionId = regionId;
+            this.matchNullLocations = matchNullLocations;
+        }
+        @Override
+        public boolean apply(ComputeMetadata input) {
+            boolean exclude;
+            Location nodeLocation = input.getLocation();
+            if (nodeLocation==null) return matchNullLocations;
+            
+            exclude = true;
+            while (nodeLocation!=null && exclude) {
+                if (nodeLocation.getId().equals(regionId)) {
+                    // matching location info found
+                    exclude = false;
+                }
+                nodeLocation = nodeLocation.getParent();
+            }
+            return !exclude;
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java
new file mode 100644
index 0000000..f307041
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java
@@ -0,0 +1,159 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.basic.DeprecatedKeysMappingBuilder;
+import org.apache.brooklyn.location.basic.LocationPropertiesFromBrooklynProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigUtils;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.javalang.JavaClassNames;
+
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+
+/**
+ * <p>
+ * The properties to use for a jclouds location, loaded from brooklyn.properties file
+ * </p>
+ * 
+ * Preferred format is:
+ * 
+ * <ul>
+ * <li>
+ * brooklyn.location.named.NAME.key 
+ * </li>
+ * <li>
+ * brooklyn.location.jclouds.PROVIDER.key
+ * </li>
+ * </ul>
+ * 
+ * <p>
+ * A number of properties are also supported, listed in the {@code JcloudsLocationConfig}
+ * </p>
+ * 
+ * @author andrea
+ **/
+public class JcloudsPropertiesFromBrooklynProperties extends LocationPropertiesFromBrooklynProperties {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsPropertiesFromBrooklynProperties.class);
+
+    @SuppressWarnings("deprecation")
+    private static final Map<String, String> DEPRECATED_JCLOUDS_KEYS_MAPPING = new DeprecatedKeysMappingBuilder(LOG)
+            .putAll(LocationPropertiesFromBrooklynProperties.DEPRECATED_KEYS_MAPPING)
+            .camelToHyphen(JcloudsLocation.IMAGE_ID)
+            .camelToHyphen(JcloudsLocation.IMAGE_NAME_REGEX)
+            .camelToHyphen(JcloudsLocation.IMAGE_DESCRIPTION_REGEX)
+            .camelToHyphen(JcloudsLocation.HARDWARE_ID)
+            .build();
+
+    @Override
+    public Map<String, Object> getLocationProperties(String provider, String namedLocation, Map<String, ?> properties) {
+        throw new UnsupportedOperationException("Instead use getJcloudsProperties(String,String,String,Map)");
+    }
+    
+    /**
+     * @see LocationPropertiesFromBrooklynProperties#getLocationProperties(String, String, Map)
+     */
+    public Map<String, Object> getJcloudsProperties(String providerOrApi, String regionOrEndpoint, String namedLocation, Map<String, ?> properties) {
+        if(Strings.isNullOrEmpty(namedLocation) && Strings.isNullOrEmpty(providerOrApi)) {
+            throw new IllegalArgumentException("Neither cloud provider/API nor location name have been specified correctly");
+        }
+
+        ConfigBag jcloudsProperties = ConfigBag.newInstance();
+        String provider = getProviderName(providerOrApi, namedLocation, properties);
+        
+        // named properties are preferred over providerOrApi properties
+        jcloudsProperties.put(LocationConfigKeys.CLOUD_PROVIDER, provider);
+        jcloudsProperties.putAll(transformDeprecated(getGenericLocationSingleWordProperties(properties)));
+        jcloudsProperties.putAll(transformDeprecated(getGenericJcloudsSingleWordProperties(providerOrApi, properties)));
+        jcloudsProperties.putAll(transformDeprecated(getProviderOrApiJcloudsProperties(providerOrApi, properties)));
+        jcloudsProperties.putAll(transformDeprecated(getRegionJcloudsProperties(providerOrApi, regionOrEndpoint, properties)));
+        if (!Strings.isNullOrEmpty(namedLocation)) jcloudsProperties.putAll(transformDeprecated(getNamedJcloudsProperties(namedLocation, properties)));
+        setLocalTempDir(properties, jcloudsProperties);
+
+        return jcloudsProperties.getAllConfigRaw();
+    }
+
+    protected String getProviderName(String providerOrApi, String namedLocationName, Map<String, ?> properties) {
+        String provider = providerOrApi;
+        if (!Strings.isNullOrEmpty(namedLocationName)) {
+            String providerDefinition = (String) properties.get(String.format("brooklyn.location.named.%s", namedLocationName));
+            if (providerDefinition!=null) {
+                String provider2 = getProviderFromDefinition(providerDefinition);
+                if (provider==null) {
+                    // 0.7.0 25 Feb -- is this even needed?
+                    LOG.warn(JavaClassNames.niceClassAndMethod()+" NOT set with provider, inferring from locationName "+namedLocationName+" as "+provider2);
+                    provider = provider2;
+                } else if (!provider.equals(provider2)) {
+                    // 0.7.0 25 Feb -- previously we switched to provider2 in this case, but that was wrong when
+                    // working with chains of names; not sure why this case would ever occur (apart from tests which have been changed)
+                    // 28 Mar seen this warning many times but only in cases when NOT changing is the right behaviour 
+                    LOG.debug(JavaClassNames.niceClassAndMethod()+" NOT changing provider from "+provider+" to candidate "+provider2);
+                }
+            }
+        }
+        return provider;
+    }
+    
+    protected String getProviderFromDefinition(String definition) {
+        return Iterables.get(Splitter.on(":").split(definition), 1);
+    }
+
+    protected Map<String, Object> getGenericJcloudsSingleWordProperties(String providerOrApi, Map<String, ?> properties) {
+        if (Strings.isNullOrEmpty(providerOrApi)) return Maps.newHashMap();
+        String deprecatedPrefix = "brooklyn.jclouds.";
+        String preferredPrefix = "brooklyn.location.jclouds.";
+        return getMatchingSingleWordProperties(preferredPrefix, deprecatedPrefix, properties);
+    }
+
+    protected Map<String, Object> getProviderOrApiJcloudsProperties(String providerOrApi, Map<String, ?> properties) {
+        if (Strings.isNullOrEmpty(providerOrApi)) return Maps.newHashMap();
+        String preferredPrefix = String.format("brooklyn.location.jclouds.%s.", providerOrApi);
+        String deprecatedPrefix = String.format("brooklyn.jclouds.%s.", providerOrApi);
+        
+        return getMatchingProperties(preferredPrefix, deprecatedPrefix, properties);
+    }
+
+    protected Map<String, Object> getRegionJcloudsProperties(String providerOrApi, String regionName, Map<String, ?> properties) {
+        if (Strings.isNullOrEmpty(providerOrApi) || Strings.isNullOrEmpty(regionName)) return Maps.newHashMap();
+        String preferredPrefix = String.format("brooklyn.location.jclouds.%s@%s.", providerOrApi, regionName);
+        String deprecatedPrefix = String.format("brooklyn.jclouds.%s@%s.", providerOrApi, regionName);
+        
+        return getMatchingProperties(preferredPrefix, deprecatedPrefix, properties);
+    }
+
+    protected Map<String, Object> getNamedJcloudsProperties(String locationName, Map<String, ?> properties) {
+        if(locationName == null) return Maps.newHashMap();
+        String prefix = String.format("brooklyn.location.named.%s.", locationName);
+        return ConfigUtils.filterForPrefixAndStrip(properties, prefix).asMapWithStringKeys();
+    }
+
+    @Override
+    protected Map<String, String> getDeprecatedKeysMapping() {
+        return DEPRECATED_JCLOUDS_KEYS_MAPPING;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
new file mode 100644
index 0000000..08fd3b0
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
@@ -0,0 +1,338 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.location.HardwareDetails;
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.BasicHardwareDetails;
+import org.apache.brooklyn.location.basic.BasicMachineDetails;
+import org.apache.brooklyn.location.basic.BasicOsDetails;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.callables.RunScriptOnNode;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.options.RunScriptOptions;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.scriptbuilder.domain.InterpretableStatement;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.net.Networking;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.net.HostAndPort;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class JcloudsSshMachineLocation extends SshMachineLocation implements JcloudsMachineLocation {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsSshMachineLocation.class);
+    private static final long serialVersionUID = -443866395634771659L;
+
+    @SetFromFlag
+    JcloudsLocation jcloudsParent;
+    
+    @SetFromFlag
+    NodeMetadata node;
+    
+    @SetFromFlag
+    Template template;
+    
+    private RunScriptOnNode.Factory runScriptFactory;
+    
+    public JcloudsSshMachineLocation() {
+    }
+    
+    /**
+     * @deprecated since 0.6; use LocationSpec (which calls no-arg constructor)
+     */
+    @Deprecated
+    public JcloudsSshMachineLocation(Map<?,?> flags, JcloudsLocation jcloudsParent, NodeMetadata node) {
+        super(flags);
+        this.jcloudsParent = jcloudsParent;
+        this.node = node;
+        
+        init();
+    }
+
+    @Override
+    public void init() {
+        if (jcloudsParent != null) {
+            super.init();
+            ComputeServiceContext context = jcloudsParent.getComputeService().getContext();
+            runScriptFactory = context.utils().injector().getInstance(RunScriptOnNode.Factory.class);
+        } else {
+            // TODO Need to fix the rebind-detection, and not call init() on rebind.
+            // This will all change when locations become entities.
+            if (LOG.isDebugEnabled()) LOG.debug("Not doing init() of {} because parent not set; presuming rebinding", this);
+        }
+    }
+    
+    @Override
+    public void rebind() {
+        super.rebind();
+        ComputeServiceContext context = jcloudsParent.getComputeService().getContext();
+        runScriptFactory = context.utils().injector().getInstance(RunScriptOnNode.Factory.class);
+    }
+    
+    @Override
+    public String toVerboseString() {
+        return Objects.toStringHelper(this).omitNullValues()
+                .add("id", getId()).add("name", getDisplayName())
+                .add("user", getUser()).add("address", getAddress()).add("port", getConfig(SSH_PORT))
+                .add("node", getNode())
+                .add("jcloudsId", getJcloudsId())
+                .add("privateAddresses", node.getPrivateAddresses())
+                .add("publicAddresses", node.getPublicAddresses())
+                .add("parentLocation", getParent())
+                .add("osDetails", getOsDetails())
+                .toString();
+    }
+
+    @Override
+    public NodeMetadata getNode() {
+        return node;
+    }
+    
+    @Override
+    public Template getTemplate() {
+        return template;
+    }
+    
+    @Override
+    public JcloudsLocation getParent() {
+        return jcloudsParent;
+    }
+    
+    @Override
+    public String getHostname() {
+        return node.getHostname();
+    }
+    
+    /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */
+    @Override
+    public Set<String> getPublicAddresses() {
+        return node.getPublicAddresses();
+    }
+    
+    @Override
+    public Set<String> getPrivateAddresses() {
+        return node.getPrivateAddresses();
+    }
+
+    @Override
+    public String getSubnetHostname() {
+        String privateHostname = jcloudsParent.getPrivateHostname(node, Optional.<HostAndPort>absent(), config().getBag());
+        return privateHostname;
+    }
+
+    @Override
+    public String getSubnetIp() {
+        Optional<String> privateAddress = getPrivateAddress();
+        if (privateAddress.isPresent()) {
+            return privateAddress.get();
+        }
+
+        String hostname = jcloudsParent.getPublicHostname(node, Optional.<HostAndPort>absent(), config().getBag());
+        if (hostname != null && !Networking.isValidIp4(hostname)) {
+            try {
+                return InetAddress.getByName(hostname).getHostAddress();
+            } catch (UnknownHostException e) {
+                LOG.debug("Cannot resolve IP for hostname {} of machine {} (so returning hostname): {}", new Object[] {hostname, this, e});
+            }
+        }
+        return hostname;
+    }
+
+    protected Optional<String> getPrivateAddress() {
+        if (groovyTruth(node.getPrivateAddresses())) {
+            for (String p : node.getPrivateAddresses()) {
+                // disallow local only addresses
+                if (Networking.isLocalOnly(p)) continue;
+                // other things may be public or private, but either way, return it
+                return Optional.of(p);
+            }
+        }
+        return Optional.absent();
+    }
+    
+    @Override
+    public String getJcloudsId() {
+        return node.getId();
+    }
+    
+    /** executes the given statements on the server using jclouds ScriptBuilder,
+     * wrapping in a script which is polled periodically.
+     * the output is returned once the script completes (disadvantage compared to other methods)
+     * but the process is nohupped and the SSH session is not kept, 
+     * so very useful for long-running processes
+     */
+    public ListenableFuture<ExecResponse> submitRunScript(String ...statements) {
+        return submitRunScript(new InterpretableStatement(statements));
+    }
+    public ListenableFuture<ExecResponse> submitRunScript(Statement script) {
+        return submitRunScript(script, new RunScriptOptions());            
+    }
+    public ListenableFuture<ExecResponse> submitRunScript(Statement script, RunScriptOptions options) {
+        return runScriptFactory.submit(node, script, options);
+    }
+    /** uses submitRunScript to execute the commands, and throws error if it fails or returns non-zero */
+    public void execRemoteScript(String ...commands) {
+        try {
+            ExecResponse result = submitRunScript(commands).get();
+            if (result.getExitStatus()!=0)
+                throw new IllegalStateException("Error running remote commands (code "+result.getExitStatus()+"): "+commands);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw Throwables.propagate(e);
+        } catch (ExecutionException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    /**
+     * Retrieves the password for this VM, if one exists. The behaviour/implementation is different for different clouds.
+     * e.g. on Rackspace, the password for a windows VM is available immediately; on AWS-EC2, for a Windows VM you need 
+     * to poll repeatedly until the password is available which can take up to 15 minutes.
+     */
+    public String waitForPassword() {
+        // TODO Hacky; don't want aws specific stuff here but what to do?!
+        if (jcloudsParent.getProvider().equals("aws-ec2")) {
+            try {
+                return JcloudsUtil.waitForPasswordOnAws(jcloudsParent.getComputeService(), node, 15, TimeUnit.MINUTES);
+            } catch (TimeoutException e) {
+                throw Throwables.propagate(e);
+            }
+        } else {
+            LoginCredentials credentials = node.getCredentials();
+            return (credentials != null) ? credentials.getPassword() : null;
+        }
+    }
+
+    @Override
+    protected MachineDetails inferMachineDetails() {
+        Optional<String> name = Optional.absent();
+        Optional<String> version = Optional.absent();
+        Optional<String> architecture = Optional.absent();
+
+        OperatingSystem os = node.getOperatingSystem();
+        if (os == null && getTemplate() != null && getTemplate().getImage() != null)
+            // some nodes (eg cloudstack, gce) might not get OS available on the node,
+            // so also try taking it from the template if available
+            os = getTemplate().getImage().getOperatingSystem();
+
+        if (os != null) {
+            // Note using family rather than name. Name is often unset.
+            name = Optional.fromNullable(os.getFamily() != null && !OsFamily.UNRECOGNIZED.equals(os.getFamily()) ? os.getFamily().toString() : null);
+            version = Optional.fromNullable(!Strings.isBlank(os.getVersion()) ? os.getVersion() : null);
+            // Using is64Bit rather then getArch because getArch often returns "paravirtual"
+            architecture = Optional.fromNullable(os.is64Bit() ? BasicOsDetails.OsArchs.X_86_64 : BasicOsDetails.OsArchs.I386);
+        }
+
+        Hardware hardware = node.getHardware();
+        Optional<Integer> ram = hardware==null ? Optional.<Integer>absent() : Optional.fromNullable(hardware.getRam());
+        Optional<Integer> cpus = hardware==null ? Optional.<Integer>absent() : Optional.fromNullable(hardware.getProcessors() != null ? hardware.getProcessors().size() : null);
+
+        // Skip superclass' SSH to machine if all data is present, otherwise defer to super
+        if (name.isPresent() && version.isPresent() && architecture.isPresent() && ram.isPresent() && cpus.isPresent()) {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Gathered machine details from Jclouds, skipping SSH test on {}", this);
+            }
+            OsDetails osD = new BasicOsDetails(name.get(), architecture.get(), version.get());
+            HardwareDetails hwD = new BasicHardwareDetails(cpus.get(), ram.get());
+            return new BasicMachineDetails(hwD, osD);
+        } else if ("false".equalsIgnoreCase(getConfig(JcloudsLocation.WAIT_FOR_SSHABLE))) {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Machine details for {} missing from Jclouds, but skipping SSH test because waitForSshable=false. name={}, version={}, " +
+                        "arch={}, ram={}, #cpus={}",
+                        new Object[]{this, name, version, architecture, ram, cpus});
+            }
+            OsDetails osD = new BasicOsDetails(name.orNull(), architecture.orNull(), version.orNull());
+            HardwareDetails hwD = new BasicHardwareDetails(cpus.orNull(), ram.orNull());
+            return new BasicMachineDetails(hwD, osD);
+        } else {
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("Machine details for {} missing from Jclouds, using SSH test instead. name={}, version={}, " +
+                                "arch={}, ram={}, #cpus={}",
+                        new Object[]{this, name, version, architecture, ram, cpus});
+            }
+            return super.inferMachineDetails();
+        }
+    }
+
+    @Override
+    public Map<String, String> toMetadataRecord() {
+        Hardware hardware = node.getHardware();
+        List<? extends Processor> processors = (hardware != null) ? hardware.getProcessors() : null;
+        
+        ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+        builder.putAll(super.toMetadataRecord());
+        putIfNotNull(builder, "provider", getParent().getProvider());
+        putIfNotNull(builder, "account", getParent().getIdentity());
+        putIfNotNull(builder, "serverId", node.getProviderId());
+        putIfNotNull(builder, "imageId", node.getImageId());
+        putIfNotNull(builder, "instanceTypeName", (hardware != null ? hardware.getName() : null));
+        putIfNotNull(builder, "instanceTypeId", (hardware != null ? hardware.getProviderId() : null));
+        putIfNotNull(builder, "ram", "" + (hardware != null ? hardware.getRam() : null));
+        putIfNotNull(builder, "cpus", "" + (processors != null ? processors.size() : null));
+        
+        try {
+            OsDetails osDetails = getOsDetails();
+            putIfNotNull(builder, "osName", osDetails.getName());
+            putIfNotNull(builder, "osArch", osDetails.getArch());
+            putIfNotNull(builder, "is64bit", osDetails.is64bit() ? "true" : "false");
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            LOG.warn("Unable to get OS Details for "+node+"; continuing", e);
+        }
+        
+        return builder.build();
+    }
+    
+    private void putIfNotNull(ImmutableMap.Builder<String, String> builder, String key, @Nullable String value) {
+        if (value != null) builder.put(key, value);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsUtil.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsUtil.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsUtil.java
new file mode 100644
index 0000000..e3026df
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsUtil.java
@@ -0,0 +1,448 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideLoginCredentials;
+import static org.jclouds.compute.util.ComputeServiceUtils.execHttpResponse;
+import static org.jclouds.scriptbuilder.domain.Statements.appendFile;
+import static org.jclouds.scriptbuilder.domain.Statements.exec;
+import static org.jclouds.scriptbuilder.domain.Statements.interpret;
+import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.annotation.Nullable;
+
+import org.jclouds.Constants;
+import org.jclouds.ContextBuilder;
+import org.jclouds.aws.ec2.AWSEC2Api;
+import org.jclouds.blobstore.BlobStoreContext;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.RunScriptOnNodesException;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.options.RunScriptOptions;
+import org.jclouds.compute.predicates.OperatingSystemPredicates;
+import org.jclouds.docker.DockerApi;
+import org.jclouds.docker.domain.Container;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey;
+import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData;
+import org.jclouds.ec2.domain.PasswordData;
+import org.jclouds.ec2.features.WindowsApi;
+import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.jclouds.ssh.SshClient;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.jclouds.util.Predicates2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Charsets;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.io.Files;
+import com.google.inject.Module;
+
+import brooklyn.entity.basic.Sanitizer;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.net.Protocol;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.ssh.IptablesCommands;
+import brooklyn.util.ssh.IptablesCommands.Chain;
+import brooklyn.util.ssh.IptablesCommands.Policy;
+
+public class JcloudsUtil implements JcloudsLocationConfig {
+
+    // TODO Review what utility methods are needed, and what is now supported in jclouds 1.1
+
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsUtil.class);
+
+    /**
+     * @deprecated since 0.7; see {@link BashCommands}
+     */
+    @Deprecated
+    public static String APT_INSTALL = "apt-get install -f -y -qq --force-yes";
+
+    /**
+     * @deprecated since 0.7; see {@link BashCommands}
+     */
+    @Deprecated
+    public static String installAfterUpdatingIfNotPresent(String cmd) {
+       String aptInstallCmd = APT_INSTALL + " " + cmd;
+       return String.format("which %s || (%s || (apt-get update && %s))", cmd, aptInstallCmd, aptInstallCmd);
+    }
+
+    /**
+     * @deprecated since 0.7
+     */
+    @Deprecated
+    public static Predicate<NodeMetadata> predicateMatchingById(final NodeMetadata node) {
+        return predicateMatchingById(node.getId());
+    }
+
+    /**
+     * @deprecated since 0.7
+     */
+    @Deprecated
+    public static Predicate<NodeMetadata> predicateMatchingById(final String id) {
+        Predicate<NodeMetadata> nodePredicate = new Predicate<NodeMetadata>() {
+            @Override public boolean apply(NodeMetadata arg0) {
+                return id.equals(arg0.getId());
+            }
+            @Override public String toString() {
+                return "node.id=="+id;
+            }
+        };
+        return nodePredicate;
+    }
+
+    /**
+     * @deprecated since 0.7; see {@link IptablesCommands}
+     */
+    @Deprecated
+    public static Statement authorizePortInIpTables(int port) {
+        // TODO gogrid rules only allow ports 22, 3389, 80 and 443.
+        // the first rule will be ignored, so we have to apply this
+        // directly
+        return Statements.newStatementList(// just in case iptables are being used, try to open 8080
+                exec("iptables -I INPUT 1 -p tcp --dport " + port + " -j ACCEPT"),//
+                exec("iptables -I RH-Firewall-1-INPUT 1 -p tcp --dport " + port + " -j ACCEPT"),//
+                exec("iptables-save"));
+    }
+
+    /**
+     * @throws RunScriptOnNodesException
+     * @throws IllegalStateException     If do not find exactly one matching node
+     *
+     * @deprecated since 0.7
+     */
+    @Deprecated
+    public static ExecResponse runScriptOnNode(ComputeService computeService, NodeMetadata node, Statement statement, String scriptName) throws RunScriptOnNodesException {
+        // TODO Includes workaround for NodeMetadata's equals/hashcode method being wrong.
+
+        Map<? extends NodeMetadata, ExecResponse> scriptResults = computeService.runScriptOnNodesMatching(
+                JcloudsUtil.predicateMatchingById(node),
+                statement,
+                new RunScriptOptions().nameTask(scriptName));
+        if (scriptResults.isEmpty()) {
+            throw new IllegalStateException("No matching node found when executing script "+scriptName+": expected="+node);
+        } else if (scriptResults.size() > 1) {
+            throw new IllegalStateException("Multiple nodes matched predicate: id="+node.getId()+"; expected="+node+"; actual="+scriptResults.keySet());
+        } else {
+            return Iterables.getOnlyElement(scriptResults.values());
+        }
+    }
+
+    /**
+     * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)}
+     */
+    @Deprecated
+    public static final Statement APT_RUN_SCRIPT = newStatementList(//
+          exec(installAfterUpdatingIfNotPresent("curl")),//
+          exec("(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||"),//
+          execHttpResponse(URI.create("http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install")),//
+          exec(new StringBuilder()//
+                .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
+                // jeos hasn't enough room!
+                .append("rm -rf /var/cache/apt /usr/lib/vmware-tools\n")//
+                .append("echo \"export PATH=\\\"$JAVA_HOME/bin/:$PATH\\\"\" >> /root/.bashrc")//
+                .toString()));
+
+    /**
+     * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)}
+     */
+    @Deprecated
+    public static final Statement YUM_RUN_SCRIPT = newStatementList(
+          exec("which curl ||yum --nogpgcheck -y install curl"),//
+          exec("(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||"),//
+          execHttpResponse(URI.create("http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install")),//
+          exec(new StringBuilder()//
+                .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n") //
+                .append("echo \"export PATH=\\\"$JAVA_HOME/bin/:$PATH\\\"\" >> /root/.bashrc")//
+                .toString()));
+
+    /**
+     * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)}
+     */
+    @Deprecated
+    public static final Statement ZYPPER_RUN_SCRIPT = exec(new StringBuilder()//
+          .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
+          .append("which curl || zypper install curl\n")//
+          .append("(which java && java -fullversion 2>&1|egrep -q 1.6 ) || zypper install java-1.6.0-openjdk\n")//
+          .toString());
+
+    // Code taken from RunScriptData
+    /**
+     * @deprecated since 0.7; see {@link BashCommands#installJava7()} and {@link BashCommands#INSTALL_CURL}
+     */
+    @Deprecated
+    public static Statement installJavaAndCurl(OperatingSystem os) {
+       if (os == null || OperatingSystemPredicates.supportsApt().apply(os))
+          return APT_RUN_SCRIPT;
+       else if (OperatingSystemPredicates.supportsYum().apply(os))
+          return YUM_RUN_SCRIPT;
+       else if (OperatingSystemPredicates.supportsZypper().apply(os))
+          return ZYPPER_RUN_SCRIPT;
+       else
+          throw new IllegalArgumentException("don't know how to handle" + os.toString());
+    }
+
+    /**
+     * @deprecated since 0.7; see {@link ComputeServiceRegistry#findComputeService(ConfigBag, boolean)}
+     */
+    @Deprecated
+    public static ComputeService findComputeService(ConfigBag conf) {
+        return ComputeServiceRegistryImpl.INSTANCE.findComputeService(conf, true);
+    }
+
+    /**
+     * @deprecated since 0.7; see {@link ComputeServiceRegistry#findComputeService(ConfigBag, boolean)}
+     */
+    @Deprecated
+    public static ComputeService findComputeService(ConfigBag conf, boolean allowReuse) {
+        return ComputeServiceRegistryImpl.INSTANCE.findComputeService(conf, allowReuse);
+    }
+
+    /**
+     * Returns the jclouds modules we typically install
+     *
+     * @deprecated since 0.7; see {@link ComputeServiceRegistry}
+     */
+    @Deprecated
+    public static ImmutableSet<Module> getCommonModules() {
+        return ImmutableSet.<Module> of(
+                new SshjSshClientModule(),
+                new SLF4JLoggingModule(),
+                new BouncyCastleCryptoModule());
+    }
+
+    /**
+     *  Temporary constructor to address https://issues.apache.org/jira/browse/JCLOUDS-615.
+     *  <p>
+     *  See https://issues.apache.org/jira/browse/BROOKLYN-6 .
+     *  When https://issues.apache.org/jira/browse/JCLOUDS-615 is fixed in the jclouds we use,
+     *  we can remove the useSoftlayerFix argument.
+     *  <p>
+     *  (Marked Beta as that argument will likely be removed.)
+     *
+     *  @since 0.7.0 */
+    @Beta
+    public static BlobStoreContext newBlobstoreContext(String provider, @Nullable String endpoint, String identity, String credential) {
+        Properties overrides = new Properties();
+        // * Java 7,8 bug workaround - sockets closed by GC break the internal bookkeeping
+        //   of HttpUrlConnection, leading to invalid handling of the "HTTP/1.1 100 Continue"
+        //   response. Coupled with a bug when using SSL sockets reads will block
+        //   indefinitely even though a read timeout is explicitly set.
+        // * Java 6 ignores the header anyways as it is included in its restricted headers black list.
+        // * Also there's a bug in SL object store which still expects Content-Length bytes
+        //   even when it responds with a 408 timeout response, leading to incorrectly
+        //   interpreting the next request (triggered by above problem).
+        overrides.setProperty(Constants.PROPERTY_STRIP_EXPECT_HEADER, "true");
+
+        ContextBuilder contextBuilder = ContextBuilder.newBuilder(provider).credentials(identity, credential);
+        contextBuilder.modules(MutableList.copyOf(JcloudsUtil.getCommonModules()));
+        if (!brooklyn.util.text.Strings.isBlank(endpoint)) {
+            contextBuilder.endpoint(endpoint);
+        }
+        contextBuilder.overrides(overrides);
+        BlobStoreContext context = contextBuilder.buildView(BlobStoreContext.class);
+        return context;
+    }
+
+    /**
+     * @deprecated since 0.7
+     */
+    @Deprecated
+    protected static String getDeprecatedProperty(ConfigBag conf, String key) {
+        if (conf.containsKey(key)) {
+            LOG.warn("Jclouds using deprecated brooklyn-jclouds property "+key+": "+Sanitizer.sanitize(conf.getAllConfig()));
+            return (String) conf.getStringKey(key);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @deprecated since 0.7
+     */
+    @Deprecated
+    // Do this so that if there's a problem with our USERNAME's ssh key, we can still get in to check
+    // TODO Once we're really confident there are not going to be regular problems, then delete this
+    public static Statement addAuthorizedKeysToRoot(File publicKeyFile) throws IOException {
+        String publicKey = Files.toString(publicKeyFile, Charsets.UTF_8);
+        return addAuthorizedKeysToRoot(publicKey);
+    }
+
+    /**
+     * @deprecated since 0.7
+     */
+    @Deprecated
+    public static Statement addAuthorizedKeysToRoot(String publicKey) {
+        return newStatementList(
+                appendFile("/root/.ssh/authorized_keys", Splitter.on('\n').split(publicKey)),
+                interpret("chmod 600 /root/.ssh/authorized_keys"));
+    }
+
+    public static String getFirstReachableAddress(ComputeServiceContext context, NodeMetadata node) {
+        // To pick the address, it relies on jclouds `sshForNode().apply(Node)` to check all IPs of node (private+public),
+        // to find one that is reachable. It does `openSocketFinder.findOpenSocketOnNode(node, node.getLoginPort(), ...)`.
+        // This keeps trying for time org.jclouds.compute.reference.ComputeServiceConstants.Timeouts.portOpen.
+        // TODO Want to configure this timeout here.
+        //
+        // TODO We could perhaps instead just set `templateOptions.blockOnPort(loginPort, 120)`, but need
+        // to be careful to only set that if config WAIT_FOR_SSHABLE is true. For some advanced networking examples
+        // (e.g. using DNAT on CloudStack), the brooklyn machine won't be able to reach the VM until some additional
+        // setup steps have been done. See links from Andrea:
+        //     https://github.com/jclouds/jclouds/pull/895
+        //     https://issues.apache.org/jira/browse/WHIRR-420
+        //     jclouds.ssh.max-retries
+        //     jclouds.ssh.retry-auth
+
+        SshClient client;
+        try {
+            client = context.utils().sshForNode().apply(node);
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            /* i've seen: java.lang.IllegalStateException: Optional.get() cannot be called on an absent value
+             * from org.jclouds.crypto.ASN1Codec.createASN1Sequence(ASN1Codec.java:86), if the ssh key has a passphrase, against AWS.
+             *
+             * others have reported: java.lang.IllegalArgumentException: DER length more than 4 bytes
+             * when using a key with a passphrase (perhaps from other clouds?); not sure if that's this callpath or a different one.
+             */
+            throw new IllegalStateException("Unable to connect SshClient to "+node+"; check that the node is accessible and that the SSH key exists and is correctly configured, including any passphrase defined", e);
+        }
+        return client.getHostAddress();
+    }
+
+    // Suggest at least 15 minutes for timeout
+    public static String waitForPasswordOnAws(ComputeService computeService, final NodeMetadata node, long timeout, TimeUnit timeUnit) throws TimeoutException {
+        ComputeServiceContext computeServiceContext = computeService.getContext();
+        AWSEC2Api ec2Client = computeServiceContext.unwrapApi(AWSEC2Api.class);
+        final WindowsApi client = ec2Client.getWindowsApi().get();
+        final String region = node.getLocation().getParent().getId();
+
+        // The Administrator password will take some time before it is ready - Amazon says sometimes 15 minutes.
+        // So we create a predicate that tests if the password is ready, and wrap it in a retryable predicate.
+        Predicate<String> passwordReady = new Predicate<String>() {
+            @Override public boolean apply(String s) {
+                if (Strings.isNullOrEmpty(s)) return false;
+                PasswordData data = client.getPasswordDataInRegion(region, s);
+                if (data == null) return false;
+                return !Strings.isNullOrEmpty(data.getPasswordData());
+            }
+        };
+
+        LOG.info("Waiting for password, for "+node.getProviderId()+":"+node.getId());
+        Predicate<String> passwordReadyRetryable = Predicates2.retry(passwordReady, timeUnit.toMillis(timeout), 10*1000, TimeUnit.MILLISECONDS);
+        boolean ready = passwordReadyRetryable.apply(node.getProviderId());
+        if (!ready) throw new TimeoutException("Password not available for "+node+" in region "+region+" after "+timeout+" "+timeUnit.name());
+
+        // Now pull together Amazon's encrypted password blob, and the private key that jclouds generated
+        PasswordDataAndPrivateKey dataAndKey = new PasswordDataAndPrivateKey(
+                client.getPasswordDataInRegion(region, node.getProviderId()),
+                node.getCredentials().getPrivateKey());
+
+        // And apply it to the decryption function
+        WindowsLoginCredentialsFromEncryptedData f = computeServiceContext.utils().injector().getInstance(WindowsLoginCredentialsFromEncryptedData.class);
+        LoginCredentials credentials = f.apply(dataAndKey);
+
+        return credentials.getPassword();
+    }
+
+    public static Map<Integer, Integer> dockerPortMappingsFor(JcloudsLocation docker, String containerId) {
+        ComputeServiceContext context = null;
+        try {
+            Properties properties = new Properties();
+            properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
+            properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
+            context = ContextBuilder.newBuilder("docker")
+                    .endpoint(docker.getEndpoint())
+                    .credentials(docker.getIdentity(), docker.getCredential())
+                    .overrides(properties)
+                    .modules(ImmutableSet.<Module>of(new SLF4JLoggingModule(), new SshjSshClientModule()))
+                    .build(ComputeServiceContext.class);
+            DockerApi api = context.unwrapApi(DockerApi.class);
+            Container container = api.getContainerApi().inspectContainer(containerId);
+            Map<Integer, Integer> portMappings = Maps.newLinkedHashMap();
+            Map<String, List<Map<String, String>>> ports = container.networkSettings().ports();
+            if (ports == null) ports = ImmutableMap.<String, List<Map<String,String>>>of();
+
+            LOG.debug("Docker will forward these ports {}", ports);
+            for (Map.Entry<String, List<Map<String, String>>> entrySet : ports.entrySet()) {
+                String containerPort = Iterables.get(Splitter.on("/").split(entrySet.getKey()), 0);
+                String hostPort = Iterables.getOnlyElement(Iterables.transform(entrySet.getValue(),
+                        new Function<Map<String, String>, String>() {
+                            @Override
+                            public String apply(Map<String, String> hostIpAndPort) {
+                                return hostIpAndPort.get("HostPort");
+                            }
+                        }));
+                portMappings.put(Integer.parseInt(containerPort), Integer.parseInt(hostPort));
+            }
+            return portMappings;
+        } finally {
+            if (context != null) {
+                context.close();
+            }
+        }
+    }
+
+    /**
+     * @deprecated since 0.7
+     */
+    @Deprecated
+    public static void mapSecurityGroupRuleToIpTables(ComputeService computeService, NodeMetadata node,
+            LoginCredentials credentials, String networkInterface, Iterable<Integer> ports) {
+        for (Integer port : ports) {
+            String insertIptableRule = IptablesCommands.insertIptablesRule(Chain.INPUT, networkInterface,
+                    Protocol.TCP, port, Policy.ACCEPT);
+            Statement statement = Statements.newStatementList(exec(insertIptableRule));
+            ExecResponse response = computeService.runScriptOnNode(node.getId(), statement,
+                    overrideLoginCredentials(credentials).runAsRoot(false));
+            if (response.getExitStatus() != 0) {
+                String msg = String.format("Cannot insert the iptables rule for port %d. Error: %s", port,
+                        response.getError());
+                LOG.error(msg);
+                throw new RuntimeException(msg);
+            }
+        }
+    }
+
+}



[36/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/ResourceUtils.java b/core/src/main/java/brooklyn/util/ResourceUtils.java
index a39f363..cb350af 100644
--- a/core/src/main/java/brooklyn/util/ResourceUtils.java
+++ b/core/src/main/java/brooklyn/util/ResourceUtils.java
@@ -53,7 +53,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
 import brooklyn.catalog.internal.CatalogUtils;
 import brooklyn.internal.BrooklynInitialization;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/file/ArchiveTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/file/ArchiveTasks.java b/core/src/main/java/brooklyn/util/file/ArchiveTasks.java
index 9c6ed2f..b183f62 100644
--- a/core/src/main/java/brooklyn/util/file/ArchiveTasks.java
+++ b/core/src/main/java/brooklyn/util/file/ArchiveTasks.java
@@ -23,7 +23,7 @@ import java.util.Map;
 import org.apache.brooklyn.api.management.TaskAdaptable;
 import org.apache.brooklyn.api.management.TaskFactory;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.net.Urls;
 import brooklyn.util.task.Tasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/file/ArchiveUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/file/ArchiveUtils.java b/core/src/main/java/brooklyn/util/file/ArchiveUtils.java
index e8233c2..d072b70 100644
--- a/core/src/main/java/brooklyn/util/file/ArchiveUtils.java
+++ b/core/src/main/java/brooklyn/util/file/ArchiveUtils.java
@@ -31,7 +31,7 @@ import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java b/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java
index 31f654c..bd9e96e 100644
--- a/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java
+++ b/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskFactory.java
@@ -22,7 +22,7 @@ import org.apache.brooklyn.api.management.TaskFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.config.ConfigBag;
 
 // cannot be (cleanly) instantiated due to nested generic self-referential type; however trivial subclasses do allow it 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java b/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java
index 1d265dc..9553b4f 100644
--- a/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java
+++ b/core/src/main/java/brooklyn/util/task/ssh/SshFetchTaskWrapper.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.api.management.TaskWrapper;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java b/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java
index 381341a..e2c5502 100644
--- a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java
+++ b/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskFactory.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.api.management.TaskFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.stream.KnownSizeInputStream;
 import brooklyn.util.stream.ReaderInputStream;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java b/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java
index ec99dc8..185e819 100644
--- a/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java
+++ b/core/src/main/java/brooklyn/util/task/ssh/SshPutTaskStub.java
@@ -20,7 +20,7 @@ package brooklyn.util.task.ssh;
 
 import java.io.InputStream;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.config.ConfigBag;
 
 import com.google.common.base.Supplier;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java b/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
index bf01bfe..b13b43c 100644
--- a/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
+++ b/core/src/main/java/brooklyn/util/task/ssh/SshTasks.java
@@ -35,10 +35,10 @@ import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigUtils;
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.internal.ssh.SshTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.java b/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.java
index c78ce5d..86764f3 100644
--- a/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.java
+++ b/core/src/main/java/brooklyn/util/task/ssh/internal/AbstractSshExecTaskFactory.java
@@ -20,7 +20,7 @@ package brooklyn.util.task.ssh.internal;
 
 import com.google.common.base.Preconditions;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.system.ProcessTaskFactory;
 import brooklyn.util.task.system.ProcessTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java b/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java
index a7c6994..efc14db 100644
--- a/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java
+++ b/core/src/main/java/brooklyn/util/task/ssh/internal/PlainSshExecTaskFactory.java
@@ -20,8 +20,7 @@ package brooklyn.util.task.ssh.internal;
 
 import java.util.List;
 
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.config.ConfigBag;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.task.system.ProcessTaskWrapper;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java b/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java
index f43e47a..407111c 100644
--- a/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java
+++ b/core/src/main/java/brooklyn/util/task/system/ProcessTaskFactory.java
@@ -23,7 +23,7 @@ import java.util.Map;
 import org.apache.brooklyn.api.management.TaskFactory;
 
 import brooklyn.config.ConfigKey;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.task.system.ProcessTaskStub.ScriptReturnType;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java b/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java
index 9fd19e7..df37691 100644
--- a/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java
+++ b/core/src/main/java/brooklyn/util/task/system/ProcessTaskStub.java
@@ -22,7 +22,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java b/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java
index 5aa84c0..e41a9a9 100644
--- a/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java
+++ b/core/src/main/java/brooklyn/util/task/system/internal/AbstractProcessTaskFactory.java
@@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.stream.Streams;
 import brooklyn.util.task.TaskBuilder;
 import brooklyn.util.task.system.ProcessTaskFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/system/internal/ExecWithLoggingHelpers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/internal/ExecWithLoggingHelpers.java b/core/src/main/java/brooklyn/util/task/system/internal/ExecWithLoggingHelpers.java
index f39d7b6..c2b8907 100644
--- a/core/src/main/java/brooklyn/util/task/system/internal/ExecWithLoggingHelpers.java
+++ b/core/src/main/java/brooklyn/util/task/system/internal/ExecWithLoggingHelpers.java
@@ -28,7 +28,7 @@ import java.util.Map;
 import org.slf4j.Logger;
 
 import brooklyn.config.ConfigKey;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.flags.TypeCoercions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/task/system/internal/SystemProcessTaskFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/system/internal/SystemProcessTaskFactory.java b/core/src/main/java/brooklyn/util/task/system/internal/SystemProcessTaskFactory.java
index 9b40c7f..e6eb831 100644
--- a/core/src/main/java/brooklyn/util/task/system/internal/SystemProcessTaskFactory.java
+++ b/core/src/main/java/brooklyn/util/task/system/internal/SystemProcessTaskFactory.java
@@ -23,7 +23,7 @@ import java.io.File;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.internal.ssh.ShellTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/text/TemplateProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/text/TemplateProcessor.java b/core/src/main/java/brooklyn/util/text/TemplateProcessor.java
index 8fdaebb..f936e93 100644
--- a/core/src/main/java/brooklyn/util/text/TemplateProcessor.java
+++ b/core/src/main/java/brooklyn/util/text/TemplateProcessor.java
@@ -37,7 +37,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java b/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java
new file mode 100644
index 0000000..eebee14
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/access/BrooklynAccessUtils.java
@@ -0,0 +1,143 @@
+/*
+ * 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.apache.brooklyn.location.access;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.location.Location;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.event.basic.BasicConfigKey;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SupportsPortForwarding;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.net.Cidr;
+import brooklyn.util.task.DynamicTasks;
+import brooklyn.util.task.Tasks;
+import brooklyn.util.task.ssh.SshTasks;
+import brooklyn.util.task.system.ProcessTaskWrapper;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Supplier;
+import com.google.common.net.HostAndPort;
+
+public class BrooklynAccessUtils {
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynAccessUtils.class);
+    
+    public static final ConfigKey<PortForwardManager> PORT_FORWARDING_MANAGER = new BasicConfigKey<PortForwardManager>(
+            PortForwardManager.class, "brooklyn.portforwarding.manager", "A port-forwarding manager to use at an entity "
+                + "or a location, where supported; note this should normally be a serializable client instance to prevent "
+                + "the creation of multiple disconnected instances via config duplication");
+    
+    public static final ConfigKey<Cidr> MANAGEMENT_ACCESS_CIDR = new BasicConfigKey<Cidr>(
+            Cidr.class, "brooklyn.portforwarding.management.cidr", "CIDR to enable by default for port-forwarding for management",
+            null);  // TODO should be a list
+
+    public static HostAndPort getBrooklynAccessibleAddress(Entity entity, int port) {
+        String host;
+        
+        // look up port forwarding
+        PortForwardManager pfw = entity.getConfig(PORT_FORWARDING_MANAGER);
+        if (pfw!=null) {
+            Collection<Location> ll = entity.getLocations();
+            Maybe<SupportsPortForwarding> machine = Machines.findUniqueElement(ll, SupportsPortForwarding.class);
+            if (machine.isPresent()) {
+                synchronized (BrooklynAccessUtils.class) {
+                    // TODO finer-grained synchronization
+                    
+                    HostAndPort hp = pfw.lookup((MachineLocation)machine.get(), port);
+                    if (hp!=null) return hp;
+                    
+                    Location l = (Location) machine.get();
+                    if (l instanceof SupportsPortForwarding) {
+                        Cidr source = entity.getConfig(MANAGEMENT_ACCESS_CIDR);
+                        if (source!=null) {
+                            log.debug("BrooklynAccessUtils requesting new port-forwarding rule to access "+port+" on "+entity+" (at "+l+", enabled for "+source+")");
+                            // TODO discuss, is this the best way to do it
+                            // (will probably _create_ the port forwarding rule!)
+                            hp = ((SupportsPortForwarding) l).getSocketEndpointFor(source, port);
+                            if (hp!=null) return hp;
+                        } else {
+                            log.warn("No "+MANAGEMENT_ACCESS_CIDR.getName()+" configured for "+entity+", so cannot forward port "+port+" " +
+                                    "even though "+PORT_FORWARDING_MANAGER.getName()+" was supplied");
+                        }
+                    }
+                }
+            }
+        }
+        
+        host = entity.getAttribute(Attributes.HOSTNAME);
+        if (host!=null) return HostAndPort.fromParts(host, port);
+        
+        throw new IllegalStateException("Cannot find way to access port "+port+" on "+entity+" from Brooklyn (no host.name)");
+    }
+
+    /** attempts to resolve hostnameTarget from origin
+     * @return null if it definitively can't be resolved,  
+     * best-effort IP address if possible, or blank if we could not run ssh or make sense of the output */
+    public static String getResolvedAddress(Entity entity, SshMachineLocation origin, String hostnameTarget) {
+        ProcessTaskWrapper<Integer> task = SshTasks.newSshExecTaskFactory(origin, "ping -c 1 -t 1 "+hostnameTarget)
+            .summary("checking resolution of "+hostnameTarget).allowingNonZeroExitCode().newTask();
+        DynamicTasks.queueIfPossible(task).orSubmitAndBlock(entity).asTask().blockUntilEnded();
+        if (task.asTask().isError()) {
+            log.warn("ping could not be run, at "+entity+" / "+origin+": "+Tasks.getError(task.asTask()));
+            return "";
+        }
+        if (task.getExitCode()==null || task.getExitCode()!=0) {
+            if (task.getExitCode()!=null && task.getExitCode()<10) {
+                // small number means ping failed to resolve or ping the hostname
+                log.debug("not able to resolve "+hostnameTarget+" from "+origin+" for "+entity+" because exit code was "+task.getExitCode());
+                return null;
+            }
+            // large number means ping probably did not run
+            log.warn("ping not run as expected, at "+entity+" / "+origin+" (code "+task.getExitCode()+"):\n"+task.getStdout().trim()+" --- "+task.getStderr().trim());
+            return "";
+        }
+        String out = task.getStdout();
+        try {
+            String line1 = Strings.getFirstLine(out);
+            String ip = Strings.getFragmentBetween(line1, "(", ")");
+            if (Strings.isNonBlank(ip)) 
+                return ip;
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            /* ignore non-parseable output */ 
+        }
+        if (out.contains("127.0.0.1")) return "127.0.0.1";
+        return "";
+    }
+
+    public static Supplier<String> resolvedAddressSupplier(final Entity entity, final SshMachineLocation origin, final String hostnameTarget) {
+        return new Supplier<String>() {
+            @Override
+            public String get() {
+                return getResolvedAddress(entity, origin, hostnameTarget);
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java
new file mode 100644
index 0000000..922231b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManager.java
@@ -0,0 +1,327 @@
+/*
+ * 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.apache.brooklyn.location.access;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import org.apache.brooklyn.location.Location;
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.net.HostAndPort;
+
+import java.util.Collection;
+
+/**
+ * Acts as a registry for existing port mappings (e.g. the public endpoints for accessing specific
+ * ports on private VMs). This could be using DNAT, or iptables port-forwarding, or Docker port-mapping 
+ * via the host, or any other port mapping approach.
+ * 
+ * Also controls the allocation of ports via {@link #acquirePublicPort(String)}
+ * (e.g. for port-mapping with DNAT, then which port to use for the public side).
+ * 
+ * Implementations typically will not know anything about what the firewall/IP actually is, they just 
+ * handle a unique identifier for it.
+ * 
+ * To use, see {@link PortForwardManagerLocationResolver}, with code such as 
+ * {@code managementContext.getLocationRegistry().resolve("portForwardManager(scope=global)")}.
+ * 
+ * @see PortForwardManagerImpl for implementation notes and considerations.
+ */
+@Beta
+public interface PortForwardManager extends Location {
+
+    @Beta
+    class AssociationMetadata {
+        private final String publicIpId;
+        private final HostAndPort publicEndpoint;
+        private final Location location;
+        private final int privatePort;
+
+        /**
+         * Users are discouraged from calling this constructor; the signature may change in future releases.
+         * Instead, instances will be created automatically by Brooklyn to be passed to the
+         * {@link AssociationListener#onAssociationCreated(AssociationMetadata)} method.
+         */
+        public AssociationMetadata(String publicIpId, HostAndPort publicEndpoint, Location location, int privatePort) {
+            this.publicIpId = publicIpId;
+            this.publicEndpoint = publicEndpoint;
+            this.location = location;
+            this.privatePort = privatePort;
+        }
+
+        public String getPublicIpId() {
+            return publicIpId;
+        }
+
+        public HostAndPort getPublicEndpoint() {
+            return publicEndpoint;
+        }
+
+        public Location getLocation() {
+            return location;
+        }
+
+        public int getPrivatePort() {
+            return privatePort;
+        }
+
+        public String toString() {
+            return Objects.toStringHelper(this)
+                    .add("publicIpId", publicIpId)
+                    .add("publicEndpoint", publicEndpoint)
+                    .add("location", location)
+                    .add("privatePort", privatePort)
+                    .toString();
+        }
+    }
+
+    @Beta
+    interface AssociationListener {
+        void onAssociationCreated(AssociationMetadata metadata);
+        void onAssociationDeleted(AssociationMetadata metadata);
+    }
+
+    /**
+     * The intention is that there is one PortForwardManager instance per "scope". If you 
+     * use global, then it will be a shared instance (for that management context). If you 
+     * pass in your own name (e.g. "docker-fjie3") then it will shared with just any other
+     * places that use that same location spec (e.g. {@code portForwardManager(scope=docker-fjie3)}).
+     */
+    // TODO Note: using name "scope" rather than "brooklyn.portForwardManager.scope" so that location spec 
+    // "portForwardManager(scope=global)" works, rather than having to do 
+    // portForwardManager(brooklyn.portForwardManager.scope=global).
+    // The config being read by the PortForwardManagerLocationResolver doesn't respect @SetFromFlag("scope").
+    public static final ConfigKey<String> SCOPE = ConfigKeys.newStringConfigKey(
+            "scope",
+            "The scope that this applies to, defaulting to global",
+            "global");
+
+    @Beta
+    public static final ConfigKey<Integer> PORT_FORWARD_MANAGER_STARTING_PORT = ConfigKeys.newIntegerConfigKey(
+            "brooklyn.portForwardManager.startingPort",
+            "The starting port for assigning port numbers, such as for DNAT",
+            11000);
+
+    public String getScope();
+
+    /**
+     * Reserves a unique public port on the given publicIpId.
+     * <p>
+     * Often followed by {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
+     * to enable {@link #lookup(String, int)} or {@link #lookup(Location, int)} respectively.
+     */
+    public int acquirePublicPort(String publicIpId);
+
+    /**
+     * Records a location and private port against a public endpoint (ip and port),
+     * to support {@link #lookup(Location, int)}.
+     * <p>
+     * Superfluous if {@link #acquirePublicPort(String, Location, int)} was used,
+     * but strongly recommended if {@link #acquirePublicPortExplicit(String, int)} was used
+     * e.g. if the location is not known ahead of time.
+     */
+    public void associate(String publicIpId, HostAndPort publicEndpoint, Location l, int privatePort);
+
+    /**
+     * Records a mapping for publicIpId:privatePort to a public endpoint, such that it can
+     * subsequently be looked up using {@link #lookup(String, int)}.
+     */
+    public void associate(String publicIpId, HostAndPort publicEndpoint, int privatePort);
+
+    /**
+     * Registers a listener, which will be notified each time a new port mapping is associated. See {@link #associate(String, HostAndPort, int)}
+     * and {@link #associate(String, HostAndPort, Location, int)}.
+     */
+    @Beta
+    public void addAssociationListener(AssociationListener listener, Predicate<? super AssociationMetadata> filter);
+
+    @Beta
+    public void removeAssociationListener(AssociationListener listener);
+    
+    /**
+     * Returns the public ip hostname and public port for use contacting the given endpoint.
+     * <p>
+     * Will return null if:
+     * <ul>
+     * <li>No publicPort is associated with this location and private port.
+     * <li>No publicIpId is associated with this location and private port.
+     * <li>No publicIpHostname is recorded against the associated publicIpId.
+     * </ul>
+     * Conceivably this may have to be access-location specific.
+     *
+     * @see #recordPublicIpHostname(String, String)
+     */
+    public HostAndPort lookup(Location l, int privatePort);
+
+    /**
+     * Returns the public endpoint (host and port) for use contacting the given endpoint.
+     * 
+     * Expects a previous call to {@link #associate(String, HostAndPort, int)}, to register
+     * the endpoint.
+     * 
+     * Will return null if there has not been a public endpoint associated with this pairing.
+     */
+    public HostAndPort lookup(String publicIpId, int privatePort);
+
+    /** 
+     * Clears the given port mapping, returning true if there was a match.
+     */
+    public boolean forgetPortMapping(String publicIpId, int publicPort);
+    
+    /** 
+     * Clears the port mappings associated with the given location, returning true if there were any matches.
+     */
+    public boolean forgetPortMappings(Location location);
+    
+    /** 
+     * Clears the port mappings associated with the given publicIpId, returning true if there were any matches.
+     */
+    public boolean forgetPortMappings(String publicIpId);
+    
+    public String toVerboseString();
+
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Deprecated
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Reserves a unique public port for the purpose of forwarding to the given target,
+     * associated with a given location for subsequent lookup purpose.
+     * <p>
+     * If already allocated, returns the previously allocated.
+     * 
+     * @deprecated since 0.7.0; use {@link #acquirePublicPort(String)}, and then use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
+     */
+    @Deprecated
+    public int acquirePublicPort(String publicIpId, Location l, int privatePort);
+
+    /** 
+     * Returns old mapping if it existed, null if it is new.
+     * 
+     * @deprecated since 0.7.0; use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
+     */
+    @Deprecated
+    public PortMapping acquirePublicPortExplicit(String publicIpId, int port);
+
+    /**
+     * Records a location and private port against a publicIp and public port,
+     * to support {@link #lookup(Location, int)}.
+     * <p>
+     * Superfluous if {@link #acquirePublicPort(String, Location, int)} was used,
+     * but strongly recommended if {@link #acquirePublicPortExplicit(String, int)} was used
+     * e.g. if the location is not known ahead of time.
+     * 
+     * @deprecated Use {@link #associate(String, HostAndPort, Location, int)}
+     */
+    @Deprecated
+    public void associate(String publicIpId, int publicPort, Location l, int privatePort);
+
+    /**
+     * Records a public hostname or address to be associated with the given publicIpId for lookup purposes.
+     * <p>
+     * Conceivably this may have to be access-location specific.
+     * 
+     * @deprecated Use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
+     */
+    @Deprecated
+    public void recordPublicIpHostname(String publicIpId, String hostnameOrPublicIpAddress);
+
+    /**
+     * Returns a recorded public hostname or address.
+     * 
+     * @deprecated Use {@link #lookup(String, int)} or {@link #lookup(Location, int)}
+     */
+    @Deprecated
+    public String getPublicIpHostname(String publicIpId);
+    
+    /**
+     * Clears a previous call to {@link #recordPublicIpHostname(String, String)}.
+     * 
+     * @deprecated Use {@link #forgetPortMapping(String, int)} or {@link #forgetPortMappings(Location)}
+     */
+    @Deprecated
+    public boolean forgetPublicIpHostname(String publicIpId);
+
+    /**
+     * Returns true if this implementation is a client which is immutable/safe for serialization
+     * i.e. it delegates to something on an entity or location elsewhere.
+     * 
+     * @deprecated since 0.7.0; no need to separate client-proxy from impl
+     */
+    @Deprecated
+    public boolean isClient();
+    
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Deprecated; just internal
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /** 
+     * Returns the port mapping for a given publicIpId and public port.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Deprecated
+    public PortMapping getPortMappingWithPublicSide(String publicIpId, int publicPort);
+
+    /** 
+     * Returns the subset of port mappings associated with a given public IP ID.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Deprecated
+    public Collection<PortMapping> getPortMappingWithPublicIpId(String publicIpId);
+
+    /** 
+     * @see {@link #forgetPortMapping(String, int)} and {@link #forgetPortMappings(Location)}
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Deprecated
+    public boolean forgetPortMapping(PortMapping m);
+
+    /**
+     * Returns the public host and port for use accessing the given mapping.
+     * <p>
+     * Conceivably this may have to be access-location specific.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Deprecated
+    public HostAndPort getPublicHostAndPort(PortMapping m);
+
+    /** 
+     * Returns the subset of port mappings associated with a given location.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Deprecated
+    public Collection<PortMapping> getLocationPublicIpIds(Location l);
+        
+    /** 
+     * Returns the mapping to a given private port, or null if none.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Deprecated
+    public PortMapping getPortMappingWithPrivateSide(Location l, int privatePort);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerAuthority.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerAuthority.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerAuthority.java
new file mode 100644
index 0000000..da7d098
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerAuthority.java
@@ -0,0 +1,47 @@
+/*
+ * 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.apache.brooklyn.location.access;
+
+
+import org.apache.brooklyn.api.entity.Entity;
+
+import brooklyn.entity.basic.EntityInternal;
+
+/**
+ * @deprecated since 0.7.0; use {@link PortForwardManagerImpl}
+ */
+@Deprecated
+public class PortForwardManagerAuthority extends PortForwardManagerImpl {
+    private Entity owningEntity;
+
+    public PortForwardManagerAuthority() {
+    }
+
+    public PortForwardManagerAuthority(Entity owningEntity) {
+        this.owningEntity = owningEntity;
+    }
+
+    protected void onChanged() {
+        if (owningEntity != null) {
+            ((EntityInternal) owningEntity).requestPersist();
+        } else {
+            super.onChanged();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java
new file mode 100644
index 0000000..09aea72
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerClient.java
@@ -0,0 +1,406 @@
+/*
+ * 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.apache.brooklyn.location.access;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.event.AttributeSensor;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import org.apache.brooklyn.location.Location;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.net.HostAndPort;
+
+/**
+ * @deprecated since 0.7.0; just use the {@link PortForwardManager}, or a direct reference to its impl {@link PortForwardManagerImpl}
+ */
+@Deprecated
+public class PortForwardManagerClient implements PortForwardManager {
+
+    private static final long serialVersionUID = -295204304305332895L;
+    
+    protected final Supplier<PortForwardManager> delegateSupplier;
+    private transient volatile PortForwardManager _delegate;
+    
+    protected PortForwardManagerClient(Supplier<PortForwardManager> supplier) {
+        this.delegateSupplier = supplier;
+    }
+    
+    /** creates an instance given a supplier; 
+     * the supplier should be brooklyn-persistable, that is to say
+     * references should be in terms of entities/locations 
+     * which can retrieve an authoritative source even under cloning */
+    public static PortForwardManager fromSupplier(Supplier<PortForwardManager> supplier) {
+        return new PortForwardManagerClient(supplier);
+    }
+
+    /** creates an instance given an entity and an interface method it implements to retrieve the PortForwardManager */ 
+    public static PortForwardManager fromMethodOnEntity(final Entity entity, final String getterMethodOnEntity) {
+        Preconditions.checkNotNull(entity);
+        Preconditions.checkNotNull(getterMethodOnEntity);
+        return new PortForwardManagerClient(new Supplier<PortForwardManager>() {
+            @Override
+            public PortForwardManager get() {
+                PortForwardManager result;
+                try {
+                    result = (PortForwardManager) entity.getClass().getMethod(getterMethodOnEntity).invoke(entity);
+                } catch (Exception e) {
+                    Exceptions.propagateIfFatal(e);
+                    throw new IllegalStateException("Cannot invoke "+getterMethodOnEntity+" on "+entity+" ("+entity.getClass()+"): "+e, e);
+                }
+                if (result==null)
+                    throw new IllegalStateException("No PortForwardManager available via "+getterMethodOnEntity+" on "+entity+" (returned null)");
+                return result;
+            }
+        });
+    }
+
+    /** creates an instance given an entity and {@link AttributeSensor} to retrieve the PortForwardManager */ 
+    public static PortForwardManager fromAttributeOnEntity(final Entity entity, final AttributeSensor<PortForwardManager> attributeOnEntity) {
+        Preconditions.checkNotNull(entity);
+        Preconditions.checkNotNull(attributeOnEntity);
+        return new PortForwardManagerClient(new Supplier<PortForwardManager>() {
+            @Override
+            public PortForwardManager get() {
+                PortForwardManager result = entity.getAttribute(attributeOnEntity);
+                if (result==null)
+                    throw new IllegalStateException("No PortForwardManager available via "+attributeOnEntity+" on "+entity+" (returned null)");
+                return result;
+            }
+        });
+    }
+    
+    protected PortForwardManager getDelegate() {
+        if (_delegate==null) {
+            _delegate = delegateSupplier.get();
+        }
+        return _delegate;
+    }
+
+    @Override
+    public int acquirePublicPort(String publicIpId) {
+        return getDelegate().acquirePublicPort(publicIpId);
+    }
+
+    @Override
+    public void associate(String publicIpId, HostAndPort publicEndpoint, Location l, int privatePort) {
+        getDelegate().associate(publicIpId, publicEndpoint, l, privatePort);
+    }
+
+    @Override
+    public void associate(String publicIpId, HostAndPort publicEndpoint, int privatePort) {
+        getDelegate().associate(publicIpId, publicEndpoint, privatePort);
+    }
+
+    @Override
+    public HostAndPort lookup(Location l, int privatePort) {
+        return getDelegate().lookup(l, privatePort);
+    }
+
+    @Override
+    public HostAndPort lookup(String publicIpId, int privatePort) {
+        return getDelegate().lookup(publicIpId, privatePort);
+    }
+
+    @Override
+    public boolean forgetPortMapping(String publicIpId, int publicPort) {
+        return getDelegate().forgetPortMapping(publicIpId, publicPort);
+    }
+
+    @Override
+    public boolean forgetPortMappings(Location location) {
+        return getDelegate().forgetPortMappings(location);
+    }
+
+    @Override
+    public boolean forgetPortMappings(String publicIpId) {
+        return getDelegate().forgetPortMappings(publicIpId);
+    }
+
+    @Override
+    public String getId() {
+        return getDelegate().getId();
+    }
+
+    @Override
+    public String getScope() {
+        return getDelegate().getScope();
+    }
+
+    @Override
+    public void addAssociationListener(AssociationListener listener, Predicate<? super AssociationMetadata> filter) {
+        getDelegate().addAssociationListener(listener, filter);
+    }
+
+    @Override
+    public void removeAssociationListener(AssociationListener listener) {
+        getDelegate().removeAssociationListener(listener);
+    }
+
+    @Override
+    public String toVerboseString() {
+        return getClass().getName()+"[wrapping="+getDelegate().toVerboseString()+"]";
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Deprecated
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Reserves a unique public port for the purpose of forwarding to the given target,
+     * associated with a given location for subsequent lookup purpose.
+     * <p>
+     * If already allocated, returns the previously allocated.
+     * 
+     * @deprecated since 0.7.0; use {@link #acquirePublicPort(String)}, and then use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
+     */
+    @Override
+    @Deprecated
+    public int acquirePublicPort(String publicIpId, Location l, int privatePort) {
+        return getDelegate().acquirePublicPort(publicIpId, l, privatePort);
+    }
+
+    /** 
+     * Returns old mapping if it existed, null if it is new.
+     * 
+     * @deprecated since 0.7.0; use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
+     */
+    @Override
+    @Deprecated
+    public PortMapping acquirePublicPortExplicit(String publicIpId, int publicPort) {
+        return getDelegate().acquirePublicPortExplicit(publicIpId, publicPort);
+    }
+
+    /**
+     * Records a location and private port against a publicIp and public port,
+     * to support {@link #lookup(Location, int)}.
+     * <p>
+     * Superfluous if {@link #acquirePublicPort(String, Location, int)} was used,
+     * but strongly recommended if {@link #acquirePublicPortExplicit(String, int)} was used
+     * e.g. if the location is not known ahead of time.
+     * 
+     * @deprecated Use {@link #associate(String, HostAndPort, Location, int)}
+     */
+    @Override
+    @Deprecated
+    public void associate(String publicIpId, int publicPort, Location l, int privatePort) {
+        getDelegate().associate(publicIpId, publicPort, l, privatePort);
+    }
+
+    /**
+     * Records a public hostname or address to be associated with the given publicIpId for lookup purposes.
+     * <p>
+     * Conceivably this may have to be access-location specific.
+     * 
+     * @deprecated Use {@link #associate(String, HostAndPort, int)} or {@link #associate(String, HostAndPort, Location, int)}
+     */
+    @Override
+    @Deprecated
+    public void recordPublicIpHostname(String publicIpId, String hostnameOrPublicIpAddress) {
+        getDelegate().recordPublicIpHostname(publicIpId, hostnameOrPublicIpAddress);
+    }
+
+    /**
+     * Returns a recorded public hostname or address.
+     * 
+     * @deprecated Use {@link #lookup(String, int)} or {@link #lookup(Location, int)}
+     */
+    @Override
+    @Deprecated
+    public String getPublicIpHostname(String publicIpId) {
+        return getDelegate().getPublicIpHostname(publicIpId);
+    }
+    
+    /**
+     * Clears a previous call to {@link #recordPublicIpHostname(String, String)}.
+     * 
+     * @deprecated Use {@link #forgetPortMapping(String, int)} or {@link #forgetPortMapping(Location, int)}
+     */
+    @Override
+    @Deprecated
+    public boolean forgetPublicIpHostname(String publicIpId) {
+        return getDelegate().forgetPublicIpHostname(publicIpId);
+    }
+
+    @Override
+    @Deprecated
+    public boolean isClient() {
+        return true;
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Deprecated; just internal
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /** 
+     * Returns the port mapping for a given publicIpId and public port.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Override
+    @Deprecated
+    public PortMapping getPortMappingWithPublicSide(String publicIpId, int publicPort) {
+        return getDelegate().getPortMappingWithPublicSide(publicIpId, publicPort);
+    }
+
+    /** 
+     * Returns the subset of port mappings associated with a given public IP ID.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Override
+    @Deprecated
+    public Collection<PortMapping> getPortMappingWithPublicIpId(String publicIpId) {
+        return getDelegate().getPortMappingWithPublicIpId(publicIpId);
+    }
+
+    /** 
+     * @see #forgetPortMapping(String, int)
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Override
+    @Deprecated
+    public boolean forgetPortMapping(PortMapping m) {
+        return getDelegate().forgetPortMapping(m);
+    }
+
+    /**
+     * Returns the public host and port for use accessing the given mapping.
+     * <p>
+     * Conceivably this may have to be access-location specific.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Override
+    @Deprecated
+    public HostAndPort getPublicHostAndPort(PortMapping m) {
+        return getDelegate().getPublicHostAndPort(m);
+    }
+
+    /** 
+     * Returns the subset of port mappings associated with a given location.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Override
+    @Deprecated
+    public Collection<PortMapping> getLocationPublicIpIds(Location l) {
+        return getDelegate().getLocationPublicIpIds(l);
+    }
+        
+    /** 
+     * Returns the mapping to a given private port, or null if none.
+     * 
+     * @deprecated since 0.7.0; this method will be internal only
+     */
+    @Override
+    @Deprecated
+    public PortMapping getPortMappingWithPrivateSide(Location l, int privatePort) {
+        return getDelegate().getPortMappingWithPrivateSide(l, privatePort);
+    }
+    
+    @Override
+    public String toString() {
+        return getClass().getName()+"[id="+getId()+"]";
+    }
+
+    @Override
+    public String getDisplayName() {
+        return getDelegate().getDisplayName();
+    }
+
+    @Override
+    public Location getParent() {
+        return getDelegate().getParent();
+    }
+
+    @Override
+    public Collection<Location> getChildren() {
+        return getDelegate().getChildren();
+    }
+
+    @Override
+    public void setParent(Location newParent) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean containsLocation(Location potentialDescendent) {
+        return getDelegate().containsLocation(potentialDescendent);
+    }
+
+    @Override
+    public <T> T getConfig(ConfigKey<T> key) {
+        return getDelegate().getConfig(key);
+    }
+
+    @Override
+    public <T> T getConfig(HasConfigKey<T> key) {
+        return getDelegate().getConfig(key);
+    }
+
+    @Override
+    public boolean hasConfig(ConfigKey<?> key, boolean includeInherited) {
+        return getDelegate().hasConfig(key, includeInherited);
+    }
+
+    @Override
+    public Map<String, Object> getAllConfig(boolean includeInherited) {
+        return getDelegate().getAllConfig(includeInherited);
+    }
+
+    @Override
+    public boolean hasExtension(Class<?> extensionType) {
+        return getDelegate().hasExtension(extensionType);
+    }
+
+    @Override
+    public <T> T getExtension(Class<T> extensionType) {
+        return getDelegate().getExtension(extensionType);
+    }
+
+    @Override
+    public String getCatalogItemId() {
+        return getDelegate().getCatalogItemId();
+    }
+
+    @Override
+    public TagSupport tags() {
+        return getDelegate().tags();
+    }
+
+    @Override
+    public <T> T setConfig(ConfigKey<T> key, T val) {
+        return getDelegate().setConfig(key, val);
+    }
+
+    @Override
+    public ConfigurationSupport config() {
+        return getDelegate().config();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java
new file mode 100644
index 0000000..6493f30
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerImpl.java
@@ -0,0 +1,506 @@
+/*
+ * 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.apache.brooklyn.location.access;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.api.entity.rebind.RebindContext;
+import org.apache.brooklyn.api.entity.rebind.RebindSupport;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.mementos.LocationMemento;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.rebind.BasicLocationRebindSupport;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.net.HostAndPort;
+
+/**
+ * 
+ * @author aled
+ *
+ * TODO This implementation is not efficient, and currently has a cap of about 50000 rules.
+ * Need to improve the efficiency and scale.
+ * A quick win could be to use a different portReserved counter for each publicIpId,
+ * when calling acquirePublicPort?
+ * 
+ * TODO Callers need to be more careful in acquirePublicPort for which ports are actually in use.
+ * If multiple apps sharing the same public-ip (e.g. in the same vcloud-director vOrg) then they 
+ * must not allocate the same public port (e.g. ensure they share the same PortForwardManager
+ * by using the same scope in 
+ * {@code managementContext.getLocationRegistry().resolve("portForwardManager(scope=global)")}.
+ * However, this still doesn't check if the port is *actually* available. For example, if a
+ * different Brooklyn instance is also deploying there then we can get port conflicts, or if 
+ * some ports in that range are already in use (e.g. due to earlier dev/test runs) then this
+ * will not be respected. Callers should probably figure out the port number themselves, but
+ * that also leads to concurrency issues.
+ * 
+ * TODO The publicIpId means different things to different callers:
+ * <ul>
+ *   <li> In acquirePublicPort() it is (often?) an identifier of the actual public ip.
+ *   <li> In later calls to associate(), it is (often?) an identifier for the target machine
+ *        such as the jcloudsMachine.getJcloudsId().
+ * </ul>
+ */
+@SuppressWarnings("serial")
+public class PortForwardManagerImpl extends AbstractLocation implements PortForwardManager {
+
+    private static final Logger log = LoggerFactory.getLogger(PortForwardManagerImpl.class);
+    
+    protected final Map<String,PortMapping> mappings = new LinkedHashMap<String,PortMapping>();
+
+    private final Map<AssociationListener, Predicate<? super AssociationMetadata>> associationListeners = new ConcurrentHashMap<AssociationListener, Predicate<? super AssociationMetadata>>();
+
+    @Deprecated
+    protected final Map<String,String> publicIpIdToHostname = new LinkedHashMap<String,String>();
+    
+    // horrible hack -- see javadoc above
+    private final AtomicInteger portReserved = new AtomicInteger(11000);
+
+    private final Object mutex = new Object();
+    
+    public PortForwardManagerImpl() {
+        super();
+        if (isLegacyConstruction()) {
+            log.warn("Deprecated construction of "+PortForwardManagerImpl.class.getName()+"; instead use location resolver");
+        }
+    }
+    
+    @Override
+    public void init() {
+        super.init();
+        Integer portStartingPoint;
+        Object rawPort = getAllConfigBag().getStringKey(PORT_FORWARD_MANAGER_STARTING_PORT.getName());
+        if (rawPort != null) {
+            portStartingPoint = getConfig(PORT_FORWARD_MANAGER_STARTING_PORT);
+        } else {
+            portStartingPoint = getManagementContext().getConfig().getConfig(PORT_FORWARD_MANAGER_STARTING_PORT);
+        }
+        portReserved.set(portStartingPoint);
+        log.debug(this+" set initial port to "+portStartingPoint);
+    }
+
+    // TODO Need to use attributes for these so they are persisted (once a location is an entity),
+    // rather than this deprecated approach of custom fields.
+    @Override
+    public RebindSupport<LocationMemento> getRebindSupport() {
+        return new BasicLocationRebindSupport(this) {
+            @Override public LocationMemento getMemento() {
+                Map<String, PortMapping> mappingsCopy;
+                Map<String,String> publicIpIdToHostnameCopy;
+                synchronized (mutex) {
+                    mappingsCopy = MutableMap.copyOf(mappings);
+                    publicIpIdToHostnameCopy = MutableMap.copyOf(publicIpIdToHostname);
+                }
+                return getMementoWithProperties(MutableMap.<String,Object>of(
+                        "mappings", mappingsCopy, 
+                        "portReserved", portReserved.get(), 
+                        "publicIpIdToHostname", publicIpIdToHostnameCopy));
+            }
+            @Override
+            protected void doReconstruct(RebindContext rebindContext, LocationMemento memento) {
+                super.doReconstruct(rebindContext, memento);
+                mappings.putAll( Preconditions.checkNotNull((Map<String, PortMapping>) memento.getCustomField("mappings"), "mappings was not serialized correctly"));
+                portReserved.set( (Integer)memento.getCustomField("portReserved"));
+                publicIpIdToHostname.putAll( Preconditions.checkNotNull((Map<String, String>)memento.getCustomField("publicIpIdToHostname"), "publicIpIdToHostname was not serialized correctly") );
+            }
+        };
+    }
+    
+    @Override
+    public int acquirePublicPort(String publicIpId) {
+        int port;
+        synchronized (mutex) {
+            // far too simple -- see javadoc above
+            port = getNextPort();
+            
+            // TODO When delete deprecated code, stop registering PortMapping until associate() is called
+            PortMapping mapping = new PortMapping(publicIpId, port, null, -1);
+            log.debug(this+" allocating public port "+port+" on "+publicIpId+" (no association info yet)");
+            
+            mappings.put(makeKey(publicIpId, port), mapping);
+        }
+        onChanged();
+        return port;
+    }
+
+    protected int getNextPort() {
+        // far too simple -- see javadoc above
+        return portReserved.getAndIncrement();
+    }
+    
+    @Override
+    public void associate(String publicIpId, HostAndPort publicEndpoint, Location l, int privatePort) {
+        associateImpl(publicIpId, publicEndpoint, l, privatePort);
+        emitAssociationCreatedEvent(publicIpId, publicEndpoint, l, privatePort);
+    }
+
+    @Override
+    public void associate(String publicIpId, HostAndPort publicEndpoint, int privatePort) {
+        associateImpl(publicIpId, publicEndpoint, null, privatePort);
+        emitAssociationCreatedEvent(publicIpId, publicEndpoint, null, privatePort);
+    }
+
+    protected void associateImpl(String publicIpId, HostAndPort publicEndpoint, Location l, int privatePort) {
+        synchronized (mutex) {
+            String publicIp = publicEndpoint.getHostText();
+            int publicPort = publicEndpoint.getPort();
+            recordPublicIpHostname(publicIpId, publicIp);
+            PortMapping mapping = new PortMapping(publicIpId, publicEndpoint, l, privatePort);
+            PortMapping oldMapping = getPortMappingWithPublicSide(publicIpId, publicPort);
+            log.debug(this+" associating public "+publicEndpoint+" on "+publicIpId+" with private port "+privatePort+" at "+l+" ("+mapping+")"
+                    +(oldMapping == null ? "" : " (overwriting "+oldMapping+" )"));
+            mappings.put(makeKey(publicIpId, publicPort), mapping);
+        }
+        onChanged();
+    }
+
+    private void emitAssociationCreatedEvent(String publicIpId, HostAndPort publicEndpoint, Location location, int privatePort) {
+        AssociationMetadata metadata = new AssociationMetadata(publicIpId, publicEndpoint, location, privatePort);
+        for (Map.Entry<AssociationListener, Predicate<? super AssociationMetadata>> entry : associationListeners.entrySet()) {
+            if (entry.getValue().apply(metadata)) {
+                try {
+                    entry.getKey().onAssociationCreated(metadata);
+                } catch (Exception e) {
+                    Exceptions.propagateIfFatal(e);
+                    log.warn("Exception thrown when emitting association creation event " + metadata, e);
+                }
+            }
+        }
+    }
+
+    @Override
+    public HostAndPort lookup(Location l, int privatePort) {
+        synchronized (mutex) {
+            for (PortMapping m: mappings.values()) {
+                if (l.equals(m.target) && privatePort == m.privatePort)
+                    return getPublicHostAndPort(m);
+            }
+        }
+        return null;
+    }
+    
+    @Override
+    public HostAndPort lookup(String publicIpId, int privatePort) {
+        synchronized (mutex) {
+            for (PortMapping m: mappings.values()) {
+                if (publicIpId.equals(m.publicIpId) && privatePort==m.privatePort)
+                    return getPublicHostAndPort(m);
+            }
+        }
+        return null;
+    }
+    
+    @Override
+    public boolean forgetPortMapping(String publicIpId, int publicPort) {
+        PortMapping old;
+        synchronized (mutex) {
+            old = mappings.remove(makeKey(publicIpId, publicPort));
+            if (old != null) {
+                emitAssociationDeletedEvent(associationMetadataFromPortMapping(old));
+            }
+            log.debug("cleared port mapping for "+publicIpId+":"+publicPort+" - "+old);
+        }
+        if (old != null) onChanged();
+        return (old != null);
+    }
+    
+    @Override
+    public boolean forgetPortMappings(Location l) {
+        List<PortMapping> result = Lists.newArrayList();
+        synchronized (mutex) {
+            for (Iterator<PortMapping> iter = mappings.values().iterator(); iter.hasNext();) {
+                PortMapping m = iter.next();
+                if (l.equals(m.target)) {
+                    iter.remove();
+                    result.add(m);
+                    emitAssociationDeletedEvent(associationMetadataFromPortMapping(m));
+                }
+            }
+        }
+        if (log.isDebugEnabled()) log.debug("cleared all port mappings for "+l+" - "+result);
+        if (!result.isEmpty()) {
+            onChanged();
+        }
+        return !result.isEmpty();
+    }
+    
+    @Override
+    public boolean forgetPortMappings(String publicIpId) {
+        List<PortMapping> result = Lists.newArrayList();
+        synchronized (mutex) {
+            for (Iterator<PortMapping> iter = mappings.values().iterator(); iter.hasNext();) {
+                PortMapping m = iter.next();
+                if (publicIpId.equals(m.publicIpId)) {
+                    iter.remove();
+                    result.add(m);
+                    emitAssociationDeletedEvent(associationMetadataFromPortMapping(m));
+                }
+            }
+        }
+        if (log.isDebugEnabled()) log.debug("cleared all port mappings for "+publicIpId+" - "+result);
+        if (!result.isEmpty()) {
+            onChanged();
+        }
+        return !result.isEmpty();
+    }
+
+    private void emitAssociationDeletedEvent(AssociationMetadata metadata) {
+        for (Map.Entry<AssociationListener, Predicate<? super AssociationMetadata>> entry : associationListeners.entrySet()) {
+            if (entry.getValue().apply(metadata)) {
+                try {
+                    entry.getKey().onAssociationDeleted(metadata);
+                } catch (Exception e) {
+                    Exceptions.propagateIfFatal(e);
+                    log.warn("Exception thrown when emitting association creation event " + metadata, e);
+                }
+            }
+        }
+    }
+    
+    @Override
+    protected ToStringHelper string() {
+        int size;
+        synchronized (mutex) {
+            size = mappings.size();
+        }
+        return super.string().add("scope", getScope()).add("mappingsSize", size);
+    }
+
+    @Override
+    public String toVerboseString() {
+        String mappingsStr;
+        synchronized (mutex) {
+            mappingsStr = mappings.toString();
+        }
+        return string().add("mappings", mappingsStr).toString();
+    }
+
+    @Override
+    public String getScope() {
+        return checkNotNull(getConfig(SCOPE), "scope");
+    }
+
+    @Override
+    public boolean isClient() {
+        return false;
+    }
+
+    @Override
+    public void addAssociationListener(AssociationListener listener, Predicate<? super AssociationMetadata> filter) {
+        associationListeners.put(listener, filter);
+    }
+
+    @Override
+    public void removeAssociationListener(AssociationListener listener) {
+        associationListeners.remove(listener);
+    }
+
+    protected String makeKey(String publicIpId, int publicPort) {
+        return publicIpId+":"+publicPort;
+    }
+
+    private AssociationMetadata associationMetadataFromPortMapping(PortMapping portMapping) {
+        String publicIpId = portMapping.getPublicEndpoint().getHostText();
+        HostAndPort publicEndpoint = portMapping.getPublicEndpoint();
+        Location location = portMapping.getTarget();
+        int privatePort = portMapping.getPrivatePort();
+        return new AssociationMetadata(publicIpId, publicEndpoint, location, privatePort);
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Internal state, for generating memento
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public List<PortMapping> getPortMappings() {
+        synchronized (mutex) {
+            return ImmutableList.copyOf(mappings.values());
+        }
+    }
+    
+    public Map<String, Integer> getPortCounters() {
+        return ImmutableMap.of("global", portReserved.get());
+    }
+
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Deprecated
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    @Deprecated
+    public PortMapping acquirePublicPortExplicit(String publicIpId, int port) {
+        PortMapping mapping = new PortMapping(publicIpId, port, null, -1);
+        log.debug("assigning explicit public port "+port+" at "+publicIpId);
+        PortMapping result;
+        synchronized (mutex) {
+            result = mappings.put(makeKey(publicIpId, port), mapping);
+        }
+        onChanged();
+        return result;
+    }
+
+    @Override
+    @Deprecated
+    public boolean forgetPortMapping(PortMapping m) {
+        return forgetPortMapping(m.publicIpId, m.publicPort);
+    }
+
+    @Override
+    @Deprecated
+    public void recordPublicIpHostname(String publicIpId, String hostnameOrPublicIpAddress) {
+        log.debug("recording public IP "+publicIpId+" associated with "+hostnameOrPublicIpAddress);
+        synchronized (mutex) {
+            String old = publicIpIdToHostname.put(publicIpId, hostnameOrPublicIpAddress);
+            if (old!=null && !old.equals(hostnameOrPublicIpAddress))
+                log.warn("Changing hostname recorded against public IP "+publicIpId+"; from "+old+" to "+hostnameOrPublicIpAddress);
+        }
+        onChanged();
+    }
+
+    @Override
+    @Deprecated
+    public String getPublicIpHostname(String publicIpId) {
+        synchronized (mutex) {
+            return publicIpIdToHostname.get(publicIpId);
+        }
+    }
+    
+    @Override
+    @Deprecated
+    public boolean forgetPublicIpHostname(String publicIpId) {
+        log.debug("forgetting public IP "+publicIpId+" association");
+        boolean result;
+        synchronized (mutex) {
+            result = (publicIpIdToHostname.remove(publicIpId) != null);
+        }
+        onChanged();
+        return result;
+    }
+
+    @Override
+    @Deprecated
+    public int acquirePublicPort(String publicIpId, Location l, int privatePort) {
+        int publicPort;
+        synchronized (mutex) {
+            PortMapping old = getPortMappingWithPrivateSide(l, privatePort);
+            // only works for 1 public IP ID per location (which is the norm)
+            if (old!=null && old.publicIpId.equals(publicIpId)) {
+                log.debug("request to acquire public port at "+publicIpId+" for "+l+":"+privatePort+", reusing old assignment "+old);
+                return old.getPublicPort();
+            }
+            
+            publicPort = acquirePublicPort(publicIpId);
+            log.debug("request to acquire public port at "+publicIpId+" for "+l+":"+privatePort+", allocating "+publicPort);
+            associateImpl(publicIpId, publicPort, l, privatePort);
+        }
+        onChanged();
+        return publicPort;
+    }
+
+    @Override
+    @Deprecated
+    public void associate(String publicIpId, int publicPort, Location l, int privatePort) {
+        synchronized (mutex) {
+            associateImpl(publicIpId, publicPort, l, privatePort);
+        }
+        onChanged();
+    }
+
+    protected void associateImpl(String publicIpId, int publicPort, Location l, int privatePort) {
+        synchronized (mutex) {
+            PortMapping mapping = new PortMapping(publicIpId, publicPort, l, privatePort);
+            PortMapping oldMapping = getPortMappingWithPublicSide(publicIpId, publicPort);
+            log.debug("associating public port "+publicPort+" on "+publicIpId+" with private port "+privatePort+" at "+l+" ("+mapping+")"
+                    +(oldMapping == null ? "" : " (overwriting "+oldMapping+" )"));
+            mappings.put(makeKey(publicIpId, publicPort), mapping);
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    // Internal only; make protected when deprecated interface method removed
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public HostAndPort getPublicHostAndPort(PortMapping m) {
+        if (m.publicEndpoint == null) {
+            String hostname = getPublicIpHostname(m.publicIpId);
+            if (hostname==null)
+                throw new IllegalStateException("No public hostname associated with "+m.publicIpId+" (mapping "+m+")");
+            return HostAndPort.fromParts(hostname, m.publicPort);
+        } else {
+            return m.publicEndpoint;
+        }
+    }
+
+    @Override
+    public PortMapping getPortMappingWithPublicSide(String publicIpId, int publicPort) {
+        synchronized (mutex) {
+            return mappings.get(makeKey(publicIpId, publicPort));
+        }
+    }
+
+    @Override
+    public Collection<PortMapping> getPortMappingWithPublicIpId(String publicIpId) {
+        List<PortMapping> result = new ArrayList<PortMapping>();
+        synchronized (mutex) {
+            for (PortMapping m: mappings.values())
+                if (publicIpId.equals(m.publicIpId)) result.add(m);
+        }
+        return result;
+    }
+
+    /** returns the subset of port mappings associated with a given location */
+    @Override
+    public Collection<PortMapping> getLocationPublicIpIds(Location l) {
+        List<PortMapping> result = new ArrayList<PortMapping>();
+        synchronized (mutex) {
+            for (PortMapping m: mappings.values())
+                if (l.equals(m.getTarget())) result.add(m);
+        }
+        return result;
+    }
+
+    @Override
+    public PortMapping getPortMappingWithPrivateSide(Location l, int privatePort) {
+        synchronized (mutex) {
+            for (PortMapping m: mappings.values())
+                if (l.equals(m.getTarget()) && privatePort==m.privatePort) return m;
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java
new file mode 100644
index 0000000..dcb9048
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolver.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.access;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocationConfigUtils;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.basic.LocationPredicates;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.location.basic.AbstractLocationResolver;
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class PortForwardManagerLocationResolver extends AbstractLocationResolver {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PortForwardManagerLocationResolver.class);
+
+    public static final String PREFIX = "portForwardManager";
+
+    @Override
+    public String getPrefix() {
+        return PREFIX;
+    }
+
+    @Override
+    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        ConfigBag config = extractConfig(locationFlags, spec, registry);
+        Map globalProperties = registry.getProperties();
+        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
+        String scope = config.get(PortForwardManager.SCOPE);
+
+        Optional<Location> result = Iterables.tryFind(managementContext.getLocationManager().getLocations(), 
+                Predicates.and(
+                        Predicates.instanceOf(PortForwardManager.class), 
+                        LocationPredicates.configEqualTo(PortForwardManager.SCOPE, scope)));
+        
+        if (result.isPresent()) {
+            return result.get();
+        } else {
+            PortForwardManager loc = managementContext.getLocationManager().createLocation(LocationSpec.create(PortForwardManagerImpl.class)
+                    .configure(config.getAllConfig())
+                    .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+            
+            if (LOG.isDebugEnabled()) LOG.debug("Created "+loc+" for scope "+scope);
+            return loc;
+        }
+    }
+
+    @Override
+    protected Class<? extends Location> getLocationType() {
+        return PortForwardManager.class;
+    }
+
+    @Override
+    protected SpecParser getSpecParser() {
+        return new AbstractLocationResolver.SpecParser(getPrefix()).setExampleUsage("\"portForwardManager\" or \"portForwardManager(scope=global)\"");
+    }
+    
+    @Override
+    protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, LocationRegistry registry) {
+        ConfigBag config = super.extractConfig(locationFlags, spec, registry);
+        config.putAsStringKeyIfAbsent("name", "localhost");
+        return config;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java b/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java
new file mode 100644
index 0000000..086b67c
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/access/PortMapping.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.access;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.location.Location;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.net.HostAndPort;
+
+public class PortMapping {
+
+    final String publicIpId;
+    final HostAndPort publicEndpoint;
+    final int publicPort;
+
+    final Location target;
+    final int privatePort;
+    // TODO CIDR's ?
+
+    public PortMapping(String publicIpId, HostAndPort publicEndpoint, Location target, int privatePort) {
+        this.publicIpId = checkNotNull(publicIpId, "publicIpId");
+        this.publicEndpoint = checkNotNull(publicEndpoint, "publicEndpoint");
+        this.publicPort = publicEndpoint.getPort();
+        this.target = target;
+        this.privatePort = privatePort;
+    }
+    
+    public PortMapping(String publicIpId, int publicPort, Location target, int privatePort) {
+        this.publicIpId = checkNotNull(publicIpId, "publicIpId");
+        this.publicEndpoint = null;
+        this.publicPort = publicPort;
+        this.target = target;
+        this.privatePort = privatePort;
+    }
+
+    // In a release after 0.7.0, this will no longer be @Nullable
+    @Beta
+    @Nullable
+    public HostAndPort getPublicEndpoint() {
+        return publicEndpoint;
+    }
+
+    public int getPublicPort() {
+        return publicPort;
+    }
+
+    public Location getTarget() {
+        return target;
+    }
+    
+    public int getPrivatePort() {
+        return privatePort;
+    }
+    
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(this)
+                .add("publicIpId", publicIpId+":"+publicPort)
+                .add("publicEndpoint", (publicEndpoint == null ? publicPort : publicEndpoint))
+                .add("targetLocation", target)
+                .add("targetPort", privatePort)
+                .toString();
+    }
+    
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof PortMapping)) return false;
+        PortMapping opm = (PortMapping)obj;
+        return Objects.equal(publicIpId, opm.publicIpId) &&
+            Objects.equal(publicPort, opm.publicPort) &&
+            Objects.equal(target, opm.target) &&
+            Objects.equal(privatePort, opm.privatePort);
+    }
+    
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(publicIpId, publicPort, target, privatePort);
+    }
+    
+}
\ No newline at end of file


[30/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/geo/MaxMind2HostGeoLookup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/geo/MaxMind2HostGeoLookup.java b/core/src/main/java/org/apache/brooklyn/location/geo/MaxMind2HostGeoLookup.java
new file mode 100644
index 0000000..f907329
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/geo/MaxMind2HostGeoLookup.java
@@ -0,0 +1,115 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.internal.BrooklynSystemProperties;
+import brooklyn.util.net.Networking;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Lists;
+import com.maxmind.geoip2.DatabaseReader;
+import com.maxmind.geoip2.model.CityResponse;
+import com.maxmind.geoip2.record.Subdivision;
+
+public class MaxMind2HostGeoLookup implements HostGeoLookup {
+
+    public static final Logger log = LoggerFactory.getLogger(MaxMind2HostGeoLookup.class);
+    
+    static final String MAXMIND_DB_URL = "http://dev.maxmind.com/geoip/geoip2/geolite2/#Downloads";
+    // TODO this should be configurable from system property or brooklyn.properties
+    // TODO and should use properties BrooklynServerConfig.MGMT_BASE_DIR (but hard to get mgmt properties here!)
+    static final String MAXMIND_DB_PATH = System.getProperty("user.home")+"/"+".brooklyn/"+"GeoLite2-City.mmdb";
+    
+    static boolean lookupFailed = false;
+    static DatabaseReader databaseReader = null;
+    
+    public static synchronized DatabaseReader getDatabaseReader() {
+        if (databaseReader!=null) return databaseReader;
+        try {
+            File f = new File(MAXMIND_DB_PATH);
+            databaseReader = new DatabaseReader.Builder(f).build();
+        } catch (IOException e) {
+            lookupFailed = true;
+            log.debug("MaxMind geo lookup unavailable; either download and unpack the latest "+
+                    "binary from "+MAXMIND_DB_URL+" into "+MAXMIND_DB_PATH+", "+
+                    "or specify a different HostGeoLookup implementation with the key "+
+                    BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getPropertyName()+" (error trying to read: "+e+")");
+        }
+        return databaseReader;
+    }
+    
+    public HostGeoInfo getHostGeoInfo(InetAddress address) throws MalformedURLException, IOException {
+        if (lookupFailed) return null;
+        
+        DatabaseReader ll = getDatabaseReader();
+        if (ll==null) return null;
+        
+        InetAddress extAddress = address;
+        if (Networking.isPrivateSubnet(extAddress)) extAddress = InetAddress.getByName(LocalhostExternalIpLoader.getLocalhostIpQuicklyOrDefault());
+        
+        try {
+            CityResponse l = ll.city(extAddress);
+            if (l==null) {
+                if (log.isDebugEnabled()) log.debug("Geo info failed to find location for address {}, using {}", extAddress, ll);
+                return null;
+            }
+            
+            StringBuilder name = new StringBuilder();
+            
+            if (l.getCity()!=null && l.getCity().getName()!=null) name.append(l.getCity().getName());
+            
+            if (l.getSubdivisions()!=null) {
+                for (Subdivision subd: Lists.reverse(l.getSubdivisions())) {
+                    if (name.length()>0) name.append(", ");
+                    // prefer e.g. USA state codes over state names
+                    if (!Strings.isBlank(subd.getIsoCode())) 
+                        name.append(subd.getIsoCode());
+                    else
+                        name.append(subd.getName());
+                }
+            }
+            
+            if (l.getCountry()!=null) {
+                if (name.length()==0) {
+                    name.append(l.getCountry().getName());
+                } else {
+                    name.append(" ("); name.append(l.getCountry().getIsoCode()); name.append(")");
+                }
+            }
+
+            
+            HostGeoInfo geo = new HostGeoInfo(address.getHostName(), name.toString(), l.getLocation().getLatitude(), l.getLocation().getLongitude());
+            log.debug("Geo info lookup (MaxMind DB) for "+address+" returned: "+geo);
+            return geo;
+        } catch (Exception e) {
+            if (log.isDebugEnabled())
+                log.debug("Geo info lookup failed: "+e);
+            throw Throwables.propagate(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/geo/UtraceHostGeoLookup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/geo/UtraceHostGeoLookup.java b/core/src/main/java/org/apache/brooklyn/location/geo/UtraceHostGeoLookup.java
new file mode 100644
index 0000000..9b2537c
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/geo/UtraceHostGeoLookup.java
@@ -0,0 +1,210 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+import groovy.util.Node;
+import groovy.util.NodeList;
+import groovy.util.XmlParser;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.javalang.JavaClassNames;
+import brooklyn.util.net.Networking;
+import brooklyn.util.time.Duration;
+import brooklyn.util.time.Durations;
+
+import com.google.common.base.Throwables;
+
+public class UtraceHostGeoLookup implements HostGeoLookup {
+
+
+    /*
+     * 
+http://xml.utrace.de/?query=88.198.156.18 
+(IP address or hostname)
+
+The XML result is as follows:
+
+<?xml version="1.0" encoding="iso-8869-1"?>
+<results>
+<result>
+<ip>88.198.156.18</ip>
+<host>utrace.de</host>
+<isp>Hetzner Online AG</isp>
+<org>Pagedesign GmbH</org>
+<region>Hamburg</region>
+<countrycode>DE</countrycode>
+<latitude>53.5499992371</latitude>
+<longitude>10</longitude>
+<queries>10</queries>
+</result>
+</results>
+
+Note the queries count field -- you are permitted 100 per day.
+Beyond this you get blacklisted and requests may time out, or return none.
+(This may last for several days once blacklisting, not sure how long.)
+     */
+    
+    /** after failures, subsequent retries within this time interval are blocked */
+    private static final Duration RETRY_INTERVAL = Duration.FIVE_MINUTES;
+    /** requests taking longer than this period are deemed to have timed out and failed;
+     * set reasonably low so that if we are blacklisted for making too many requests,
+     * the call to get geo info does not take very long */
+    private static final Duration REQUEST_TIMEOUT = Duration.seconds(3);
+    
+    public static final Logger log = LoggerFactory.getLogger(UtraceHostGeoLookup.class);
+    
+    public String getLookupUrlForPublicIp(String ip) {
+        return "http://xml.utrace.de/?query="+ip.trim();
+    }
+
+    /**
+     * @deprecated since 0.7.0. Use {@link LocalhostExternalIpLoader} instead.
+     */
+    @Deprecated
+    public static String getLocalhostExternalIp() {
+        return LocalhostExternalIpLoader.getLocalhostIpWithin(Duration.seconds(2));
+    }
+    
+    /**
+     * @deprecated since 0.7.0. Use {@link LocalhostExternalIpLoader} instead.
+     */
+    @Deprecated
+    public static String getLocalhostExternalIpImpl() {
+        return LocalhostExternalIpLoader.getLocalhostIpWithin(Duration.seconds(2));
+    }
+    
+    public String getLookupUrlForLocalhost() {
+        return getLookupUrlForPublicIp(LocalhostExternalIpLoader.getLocalhostIpQuicklyOrDefault());
+    }
+
+    /** returns URL to get properties for the given address (assuming localhost if address is on a subnet) */
+    public String getLookupUrlFor(InetAddress address) {
+        if (Networking.isPrivateSubnet(address)) return getLookupUrlForLocalhost();
+        return getLookupUrlForPublicIp(address.getHostAddress());
+    }
+    
+    private static boolean LOGGED_GEO_LOOKUP_UNAVAILABLE = false;
+    private static long LAST_FAILURE_UTC = -1;
+    
+    /** does the {@link #retrieveHostGeoInfo(InetAddress)}, but in the background with a default timeout */
+    public HostGeoInfo getHostGeoInfo(InetAddress address) throws MalformedURLException, IOException {
+        if (Duration.sinceUtc(LAST_FAILURE_UTC).compareTo(RETRY_INTERVAL) < 0) {
+            // wait at least 60s since a failure
+            return null;
+        }
+        return getHostGeoInfo(address, REQUEST_TIMEOUT);
+    }
+    
+    /** does a {@link #retrieveHostGeoInfo(InetAddress)} with a timeout (returning null, interrupting, and setting failure time) */
+    public HostGeoInfo getHostGeoInfo(final InetAddress address, Duration timeout) throws MalformedURLException, IOException {
+        final AtomicReference<HostGeoInfo> result = new AtomicReference<HostGeoInfo>();
+        Thread lt = new Thread() {
+            public void run() {
+                try {
+                    result.set(retrieveHostGeoInfo(address));
+                } catch (Exception e) {
+                    log.warn("Error computing geo info for "+address+"; internet issues or too many requests to (free) servers for "+JavaClassNames.simpleClassName(UtraceHostGeoLookup.this)+": "+e);
+                    log.debug("Detail of host geo error: "+e, e);
+                }
+            }
+        };
+        lt.start();
+
+        try {
+            Durations.join(lt, timeout);
+        } catch (InterruptedException e) {
+            throw Exceptions.propagate(e);
+        }
+        
+        if (lt.isAlive()) {
+            // interrupt and set the failure time so that subsequent attempts do not face this timeout
+            lt.interrupt();
+            LAST_FAILURE_UTC = System.currentTimeMillis();
+            log.debug("Geo info lookup for "+address+" timed out after "+timeout);
+        }
+        
+        return result.get();
+    }
+    
+    public HostGeoInfo retrieveHostGeoInfo(InetAddress address) throws MalformedURLException, IOException {
+        String url = getLookupUrlFor(address);
+        if (log.isDebugEnabled())
+            log.debug("Geo info lookup for "+address+" at "+url);
+        Node xml;
+        try {
+            xml = new XmlParser().parse(getLookupUrlFor(address));
+        } catch (Exception e) {
+            LAST_FAILURE_UTC = System.currentTimeMillis();
+            if (log.isDebugEnabled())
+                log.debug("Geo info lookup for "+address+" failed: "+e);
+            if (!LOGGED_GEO_LOOKUP_UNAVAILABLE) {
+                LOGGED_GEO_LOOKUP_UNAVAILABLE = true;
+                log.info("Geo info lookup unavailable (for "+address+"; cause "+e+")");
+            }
+            return null;
+        }
+        try {
+            String org = getXmlResultsField(xml, "org").trim();
+            if (org.isEmpty()) org = getXmlResultsField(xml, "isp").trim();
+            String region = getXmlResultsField(xml, "region").trim();
+            if (!org.isEmpty()) {
+                if (!region.isEmpty()) region = org+", "+region;
+                else region = org;
+            }
+            if (region.isEmpty()) region = getXmlResultsField(xml, "isp").trim();
+            if (region.isEmpty()) region = address.toString();
+            HostGeoInfo geo = new HostGeoInfo(address.getHostName(), 
+                    region+
+                    " ("+getXmlResultsField(xml, "countrycode")+")", 
+                    Double.parseDouble(""+getXmlResultsField(xml, "latitude")), 
+                    Double.parseDouble(""+getXmlResultsField(xml, "longitude")));
+            log.info("Geo info lookup for "+address+" returned: "+geo);
+            return geo;
+        } catch (Exception e) {
+            if (log.isDebugEnabled())
+                log.debug("Geo info lookup failed, for "+address+" at "+url+", due to "+e+"; response is "+xml);
+            throw Throwables.propagate(e);
+        }
+    }
+    
+    @Nullable
+    private static Node getFirstChild(Node xml, String field) {
+        if (xml==null) return null;
+        NodeList nl = (NodeList)xml.get(field);
+        if (nl==null || nl.isEmpty()) return null;
+        return (Node)nl.get(0);
+    }
+    @Nonnull
+    private static String getXmlResultsField(Node xml, String field) {
+        Node f1 = getFirstChild(getFirstChild(xml, "result"), field);
+        if (f1==null) return "";
+        return f1.text();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java b/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java
new file mode 100644
index 0000000..e90f757
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.paas;
+
+import org.apache.brooklyn.location.Location;
+
+/**
+ * {@link Location} representing an application container on a PaaS provider.
+ */
+public interface PaasLocation extends Location {
+    
+    String getPaasProviderName();
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver b/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
deleted file mode 100644
index fd14323..0000000
--- a/core/src/main/resources/META-INF/services/brooklyn.location.LocationResolver
+++ /dev/null
@@ -1,9 +0,0 @@
-brooklyn.location.basic.DefinedLocationByIdResolver
-brooklyn.location.basic.NamedLocationResolver
-brooklyn.location.basic.CatalogLocationResolver
-brooklyn.location.basic.LocalhostLocationResolver
-brooklyn.location.basic.ByonLocationResolver
-brooklyn.location.basic.SingleMachineLocationResolver
-brooklyn.location.basic.HostLocationResolver
-brooklyn.location.basic.MultiLocationResolver
-brooklyn.location.access.PortForwardManagerLocationResolver
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver b/core/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
new file mode 100644
index 0000000..721b7e7
--- /dev/null
+++ b/core/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
@@ -0,0 +1,9 @@
+org.apache.brooklyn.location.basic.DefinedLocationByIdResolver
+org.apache.brooklyn.location.basic.NamedLocationResolver
+org.apache.brooklyn.location.basic.CatalogLocationResolver
+org.apache.brooklyn.location.basic.LocalhostLocationResolver
+org.apache.brooklyn.location.basic.ByonLocationResolver
+org.apache.brooklyn.location.basic.SingleMachineLocationResolver
+org.apache.brooklyn.location.basic.HostLocationResolver
+org.apache.brooklyn.location.basic.MultiLocationResolver
+org.apache.brooklyn.location.access.PortForwardManagerLocationResolver
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/resources/brooklyn/location/basic/os-details.sh
----------------------------------------------------------------------
diff --git a/core/src/main/resources/brooklyn/location/basic/os-details.sh b/core/src/main/resources/brooklyn/location/basic/os-details.sh
deleted file mode 100755
index d6f84c3..0000000
--- a/core/src/main/resources/brooklyn/location/basic/os-details.sh
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/bin/bash
-#
-# 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.
-#
-# /etc/os-release is the new-ish standard for specifying OS details.
-# See http://www.freedesktop.org/software/systemd/man/os-release.html.
-# There are a multitude of system-dependent files we can check (see list 
-# at http://linuxmafia.com/faq/Admin/release-files.html). We can support 
-# them as we need.
-
-# Survey of CentOS 6.5, Debian Jessie, Fedora 17, OSX and Ubuntu 12.04 suggests
-# uname -m is the most reliable flag for architecture
-ARCHITECTURE=$(uname -m)
-
-# Tests for existence of commands
-function exists {
-    command -v $1 >/dev/null 2>&1
-}
-
-# OS info
-if [ -f /etc/os-release ]; then
-    source /etc/os-release
-elif [ -f /etc/redhat-release ]; then
-    # Example: Red Hat Enterprise Linux Server release 6.3 (Santiago)
-    # Match everything up to ' release'
-    NAME=$(cat /etc/redhat-release | sed 's/ release.*//')
-    # Match everything between 'release ' and the next space
-    VERSION_ID=$(cat /etc/redhat-release | sed 's/.*release \([^ ]*\).*/\1/')
-elif exists lsb_release; then
-    NAME=$(lsb_release -s -i)
-    VERSION_ID=$(lsb_release -s -r)
-elif exists sw_vers; then
-    # sw_vers is an OSX command
-    NAME=$(sw_vers -productName)
-    VERSION_ID=$(sw_vers -productVersion)
-fi
-
-# Debian os-release doesn't set versions, and Debian 6 doesn't have os-release or lsb_release
-if [ -z $VERSION_ID ] && [ -f /etc/debian_version ]; then
-    NAME=Debian
-    VERSION_ID=$(cat /etc/debian_version)
-fi
-
-# Suse doesn't have os-release or lsb_release
-if [ -z $VERSION_ID ] && [ -f /etc/SuSE-release  ]; then
-    NAME=Suse
-    VERSION_MAJOR=$(cat /etc/SuSE-release | grep VERSION | sed 's/VERSION \= //')
-    VERSION_PATCH=$(cat /etc/SuSE-release | grep PATCHLEVEL | sed 's/PATCHLEVEL \= //')
-    if [ -z $VERSION_PATCH ]; then
-        VERSION_ID=${VERSION_MAJOR}
-    else
-        VERSION_ID=${VERSION_MAJOR}.${VERSION_PATCH}
-    fi
-fi
-
-# Hardware info
-# Is the loss of precision converting bytes and kilobytes to megabytes acceptable?
-# We can do floating point calculations with precision with the bc program, but it
-# isn't available by default on all systems.
-if exists sw_vers; then
-    # sysctl outputs total in bytes, linux meminfo uses kilobytes
-    bytes=$(sysctl -n hw.memsize)
-    RAM=$((bytes/1048576))
-    CPU_COUNT=$(sysctl -n hw.ncpu)
-else
-    # e.g. "MemTotal:        1019352 kB" -> "1019352"
-    # grep -o '[0-9]*' would be simpler than the sed command but I've observed it match
-    # nothing on Centos 5.6 instances.
-    kilobytes=$(grep MemTotal /proc/meminfo | sed 's/^MemTotal:[ ]*\([0-9]*\) kB/\1/')
-    RAM=$((kilobytes/1024))
-    CPU_COUNT=$(grep processor /proc/cpuinfo | wc -l)
-fi
-
-echo "name:$NAME"
-echo "version:$VERSION_ID"
-echo "architecture:$ARCHITECTURE"
-echo "ram:$RAM"
-echo "cpus:$CPU_COUNT"

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/resources/brooklyn/location/geo/external-ip-address-resolvers.txt
----------------------------------------------------------------------
diff --git a/core/src/main/resources/brooklyn/location/geo/external-ip-address-resolvers.txt b/core/src/main/resources/brooklyn/location/geo/external-ip-address-resolvers.txt
deleted file mode 100644
index bc3c26e..0000000
--- a/core/src/main/resources/brooklyn/location/geo/external-ip-address-resolvers.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-# 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.
-
-http://jsonip.com/
-http://myip.dnsomatic.com/
-http://checkip.dyndns.org/
-http://www.telize.com/ip
-http://wtfismyip.com/text
-http://whatismyip.akamai.com/
-http://myip.wampdeveloper.com/
-http://icanhazip.com/

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/resources/org/apache/brooklyn/location/basic/os-details.sh
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/brooklyn/location/basic/os-details.sh b/core/src/main/resources/org/apache/brooklyn/location/basic/os-details.sh
new file mode 100755
index 0000000..d6f84c3
--- /dev/null
+++ b/core/src/main/resources/org/apache/brooklyn/location/basic/os-details.sh
@@ -0,0 +1,93 @@
+#!/bin/bash
+#
+# 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.
+#
+# /etc/os-release is the new-ish standard for specifying OS details.
+# See http://www.freedesktop.org/software/systemd/man/os-release.html.
+# There are a multitude of system-dependent files we can check (see list 
+# at http://linuxmafia.com/faq/Admin/release-files.html). We can support 
+# them as we need.
+
+# Survey of CentOS 6.5, Debian Jessie, Fedora 17, OSX and Ubuntu 12.04 suggests
+# uname -m is the most reliable flag for architecture
+ARCHITECTURE=$(uname -m)
+
+# Tests for existence of commands
+function exists {
+    command -v $1 >/dev/null 2>&1
+}
+
+# OS info
+if [ -f /etc/os-release ]; then
+    source /etc/os-release
+elif [ -f /etc/redhat-release ]; then
+    # Example: Red Hat Enterprise Linux Server release 6.3 (Santiago)
+    # Match everything up to ' release'
+    NAME=$(cat /etc/redhat-release | sed 's/ release.*//')
+    # Match everything between 'release ' and the next space
+    VERSION_ID=$(cat /etc/redhat-release | sed 's/.*release \([^ ]*\).*/\1/')
+elif exists lsb_release; then
+    NAME=$(lsb_release -s -i)
+    VERSION_ID=$(lsb_release -s -r)
+elif exists sw_vers; then
+    # sw_vers is an OSX command
+    NAME=$(sw_vers -productName)
+    VERSION_ID=$(sw_vers -productVersion)
+fi
+
+# Debian os-release doesn't set versions, and Debian 6 doesn't have os-release or lsb_release
+if [ -z $VERSION_ID ] && [ -f /etc/debian_version ]; then
+    NAME=Debian
+    VERSION_ID=$(cat /etc/debian_version)
+fi
+
+# Suse doesn't have os-release or lsb_release
+if [ -z $VERSION_ID ] && [ -f /etc/SuSE-release  ]; then
+    NAME=Suse
+    VERSION_MAJOR=$(cat /etc/SuSE-release | grep VERSION | sed 's/VERSION \= //')
+    VERSION_PATCH=$(cat /etc/SuSE-release | grep PATCHLEVEL | sed 's/PATCHLEVEL \= //')
+    if [ -z $VERSION_PATCH ]; then
+        VERSION_ID=${VERSION_MAJOR}
+    else
+        VERSION_ID=${VERSION_MAJOR}.${VERSION_PATCH}
+    fi
+fi
+
+# Hardware info
+# Is the loss of precision converting bytes and kilobytes to megabytes acceptable?
+# We can do floating point calculations with precision with the bc program, but it
+# isn't available by default on all systems.
+if exists sw_vers; then
+    # sysctl outputs total in bytes, linux meminfo uses kilobytes
+    bytes=$(sysctl -n hw.memsize)
+    RAM=$((bytes/1048576))
+    CPU_COUNT=$(sysctl -n hw.ncpu)
+else
+    # e.g. "MemTotal:        1019352 kB" -> "1019352"
+    # grep -o '[0-9]*' would be simpler than the sed command but I've observed it match
+    # nothing on Centos 5.6 instances.
+    kilobytes=$(grep MemTotal /proc/meminfo | sed 's/^MemTotal:[ ]*\([0-9]*\) kB/\1/')
+    RAM=$((kilobytes/1024))
+    CPU_COUNT=$(grep processor /proc/cpuinfo | wc -l)
+fi
+
+echo "name:$NAME"
+echo "version:$VERSION_ID"
+echo "architecture:$ARCHITECTURE"
+echo "ram:$RAM"
+echo "cpus:$CPU_COUNT"

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/resources/org/apache/brooklyn/location/geo/external-ip-address-resolvers.txt
----------------------------------------------------------------------
diff --git a/core/src/main/resources/org/apache/brooklyn/location/geo/external-ip-address-resolvers.txt b/core/src/main/resources/org/apache/brooklyn/location/geo/external-ip-address-resolvers.txt
new file mode 100644
index 0000000..bc3c26e
--- /dev/null
+++ b/core/src/main/resources/org/apache/brooklyn/location/geo/external-ip-address-resolvers.txt
@@ -0,0 +1,25 @@
+# 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.
+
+http://jsonip.com/
+http://myip.dnsomatic.com/
+http://checkip.dyndns.org/
+http://www.telize.com/ip
+http://wtfismyip.com/text
+http://whatismyip.akamai.com/
+http://myip.wampdeveloper.com/
+http://icanhazip.com/

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy b/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
index 93c4884..ac1df97 100644
--- a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
+++ b/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
@@ -25,16 +25,13 @@ import org.slf4j.LoggerFactory
 import org.testng.annotations.AfterMethod
 import org.testng.annotations.BeforeMethod
 import org.testng.annotations.Test
-
-import brooklyn.entity.basic.ApplicationBuilder
 import brooklyn.entity.basic.BasicGroup
 import brooklyn.entity.basic.Entities
 import org.apache.brooklyn.api.entity.proxying.EntitySpec
 import org.apache.brooklyn.api.event.AttributeSensor
 import brooklyn.event.basic.BasicAttributeSensor
-import brooklyn.location.basic.SimulatedLocation
+import org.apache.brooklyn.location.basic.SimulatedLocation
 import org.apache.brooklyn.test.TestUtils
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication
 import org.apache.brooklyn.test.entity.TestEntity
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java b/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java
index e539631..666e898 100644
--- a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java
+++ b/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java
@@ -34,8 +34,8 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy b/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy
index cf9fdc1..7a0fa1c 100644
--- a/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy
+++ b/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy
@@ -28,12 +28,11 @@ import org.testng.annotations.BeforeMethod
 import org.testng.annotations.Test
 
 import brooklyn.enricher.basic.SensorTransformingEnricher
-import brooklyn.entity.basic.ApplicationBuilder
 import brooklyn.entity.basic.Entities
 import org.apache.brooklyn.api.entity.proxying.EntitySpec
 import org.apache.brooklyn.api.event.AttributeSensor
 import brooklyn.event.basic.BasicAttributeSensor
-import brooklyn.location.basic.SimulatedLocation
+import org.apache.brooklyn.location.basic.SimulatedLocation
 import org.apache.brooklyn.test.TestUtils
 import org.apache.brooklyn.test.entity.TestApplication
 import org.apache.brooklyn.test.entity.TestEntity

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/enricher/TransformingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/TransformingEnricherTest.java b/core/src/test/java/brooklyn/enricher/TransformingEnricherTest.java
index 9e3319e..06b6ac8 100644
--- a/core/src/test/java/brooklyn/enricher/TransformingEnricherTest.java
+++ b/core/src/test/java/brooklyn/enricher/TransformingEnricherTest.java
@@ -29,7 +29,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.math.MathFunctions;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java b/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
index d265a73..485504e 100644
--- a/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
+++ b/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
@@ -38,7 +38,7 @@ import brooklyn.entity.basic.BasicParameterType;
 import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.EffectorUtils;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/SetFromFlagTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/SetFromFlagTest.java b/core/src/test/java/brooklyn/entity/SetFromFlagTest.java
index fa33ec8..e28038f 100644
--- a/core/src/test/java/brooklyn/entity/SetFromFlagTest.java
+++ b/core/src/test/java/brooklyn/entity/SetFromFlagTest.java
@@ -26,8 +26,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.flags.SetFromFlag;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java b/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java
index de330ee..b78562e 100644
--- a/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java
@@ -34,8 +34,8 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 
 /**
  * Tests the deprecated use of AbstractAppliation, where its constructor is called directly.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java b/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java
index 6689740..96c7589 100644
--- a/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java
@@ -25,7 +25,6 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -34,7 +33,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableMap;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java b/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
index ef49562..cbd1c8b 100644
--- a/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
@@ -41,10 +41,10 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.Locations.LocationsFilter;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.Locations.LocationsFilter;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableSet;
 
 public class BasicStartableTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java b/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java
index 1f9c706..228a6fe 100644
--- a/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java
@@ -34,8 +34,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
index 6cd57b8..888e2e5 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
@@ -31,8 +31,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableSet;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageLegacyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageLegacyTest.java b/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageLegacyTest.java
index 1304d36..fec12e3 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageLegacyTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageLegacyTest.java
@@ -32,7 +32,7 @@ import org.testng.annotations.Test;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.time.Time;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageTest.java b/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageTest.java
index bac3da9..ff4d83e 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityConfigMapUsageTest.java
@@ -36,7 +36,7 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java b/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java
index db563b6..8597942 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java
@@ -27,7 +27,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java b/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java
index b0c6e93..77ad89a 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java
@@ -29,7 +29,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java b/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java
index 0636a0a..8b47dd2 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java
@@ -28,7 +28,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.trait.Changeable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.text.StringPredicates;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java b/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java
index 92f65c8..849aeac 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitySpecTest.java
@@ -37,7 +37,7 @@ import brooklyn.config.ConfigKey;
 import brooklyn.enricher.basic.AbstractEnricher;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.test.Asserts;
 import brooklyn.util.flags.SetFromFlag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.java b/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.java
index 6b0a91b..5525d1b 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.java
@@ -31,7 +31,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.event.basic.BasicSensorEvent;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java b/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java
index ed23cad..edd1665 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java
@@ -27,9 +27,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.Location;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy b/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy
index cd90553..a52e7d5 100644
--- a/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy
+++ b/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy
@@ -34,7 +34,7 @@ import brooklyn.event.basic.DependentConfiguration
 import brooklyn.event.basic.ListConfigKey.ListModifications
 import brooklyn.event.basic.MapConfigKey.MapModifications
 import brooklyn.event.basic.SetConfigKey.SetModifications
-import brooklyn.location.basic.SimulatedLocation
+import org.apache.brooklyn.location.basic.SimulatedLocation
 import org.apache.brooklyn.test.entity.TestApplication
 import org.apache.brooklyn.test.entity.TestEntity
 import brooklyn.util.collections.MutableMap

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java b/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
index 81967ba..e08cf97 100644
--- a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
@@ -35,7 +35,7 @@ import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.QuorumCheck.QuorumChecks;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/BasicEntityDriverManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/BasicEntityDriverManagerTest.java b/core/src/test/java/brooklyn/entity/drivers/BasicEntityDriverManagerTest.java
index c57b9cd..71eaac9 100644
--- a/core/src/test/java/brooklyn/entity/drivers/BasicEntityDriverManagerTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/BasicEntityDriverManagerTest.java
@@ -29,8 +29,8 @@ import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MyDriver;
 import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MyDriverDependentEntity;
 import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MySshDriver;
 import brooklyn.entity.drivers.RegistryEntityDriverFactoryTest.MyOtherSshDriver;
-import brooklyn.location.basic.SimulatedLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 
 public class BasicEntityDriverManagerTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/EntityDriverRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/EntityDriverRegistryTest.java b/core/src/test/java/brooklyn/entity/drivers/EntityDriverRegistryTest.java
index aa57db3..7ebceda 100644
--- a/core/src/test/java/brooklyn/entity/drivers/EntityDriverRegistryTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/EntityDriverRegistryTest.java
@@ -31,7 +31,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MyDriver;
 import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MyDriverDependentEntity;
 import brooklyn.entity.drivers.RegistryEntityDriverFactoryTest.MyOtherSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 
 public class EntityDriverRegistryTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java b/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java
index f6b6f8c..2eb6a29 100644
--- a/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java
@@ -19,9 +19,9 @@
 package brooklyn.entity.drivers;
 
 import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.paas.PaasLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.paas.PaasLocation;
 import brooklyn.test.location.TestPaasLocation;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java b/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java
index 39e4feb..7b45974 100644
--- a/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java
@@ -30,9 +30,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MyDriver;
 import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MyDriverDependentEntity;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 
 public class RegistryEntityDriverFactoryTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
index c11f4aa..5be9551 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
@@ -34,8 +34,8 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
index 8ec4d3c..07f9f14 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
@@ -35,8 +35,8 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java
index 02da899..dc36f8c 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java
@@ -35,8 +35,8 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java
index 53ab2d1..344e16b 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java
@@ -31,8 +31,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 
 import com.google.common.base.Functions;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java b/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java
index c190790..02154f7 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java
@@ -22,7 +22,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class MyEntityDriver implements EntityDriver {
     private final Entity entity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/effector/EffectorBasicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/effector/EffectorBasicTest.java b/core/src/test/java/brooklyn/entity/effector/EffectorBasicTest.java
index 5d561bc..ce3dffc 100644
--- a/core/src/test/java/brooklyn/entity/effector/EffectorBasicTest.java
+++ b/core/src/test/java/brooklyn/entity/effector/EffectorBasicTest.java
@@ -37,7 +37,7 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.FailingEntity;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java b/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
index 5e16db6..1418868 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
@@ -63,8 +63,8 @@ import org.apache.brooklyn.test.entity.TestEntityImpl;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.trait.Changeable;
 import brooklyn.entity.trait.FailingEntity;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java b/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java
index 5289855..064f2ac 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java
@@ -40,12 +40,12 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.group.zoneaware.ProportionalZoneFailureDetector;
 import brooklyn.entity.trait.FailingEntity;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.basic.SimulatedLocation;
-import brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
-import brooklyn.location.cloud.AvailabilityZoneExtension;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
+import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
 import brooklyn.test.Asserts;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java b/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java
index 4e3098d..0ce3faf 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java
@@ -49,9 +49,9 @@ import brooklyn.entity.basic.BasicEntity;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/DynamicMultiGroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicMultiGroupTest.java b/core/src/test/java/brooklyn/entity/group/DynamicMultiGroupTest.java
index 7f4fb56..55a8c97 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicMultiGroupTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicMultiGroupTest.java
@@ -45,12 +45,11 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
 
 public class DynamicMultiGroupTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java b/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java
index 9d34ebe..b0821e5 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java
@@ -31,8 +31,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/GroupTest.java b/core/src/test/java/brooklyn/entity/group/GroupTest.java
index ea5e562..ab73812 100644
--- a/core/src/test/java/brooklyn/entity/group/GroupTest.java
+++ b/core/src/test/java/brooklyn/entity/group/GroupTest.java
@@ -35,8 +35,8 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 
 public class GroupTest extends BrooklynAppUnitTestSupport {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java b/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java
index dd5ce7f..65ab601 100644
--- a/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java
+++ b/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java
@@ -38,8 +38,8 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java b/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java
index e86c662..b96310e 100644
--- a/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java
+++ b/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java
@@ -28,8 +28,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java b/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java
index e021f10..975db33 100644
--- a/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java
+++ b/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java
@@ -27,9 +27,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java b/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java
index f24886f..367952b 100644
--- a/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java
+++ b/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java
@@ -30,8 +30,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Ticker;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/hello/LocalEntitiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/hello/LocalEntitiesTest.java b/core/src/test/java/brooklyn/entity/hello/LocalEntitiesTest.java
index 18b1ea3..91fc9aa 100644
--- a/core/src/test/java/brooklyn/entity/hello/LocalEntitiesTest.java
+++ b/core/src/test/java/brooklyn/entity/hello/LocalEntitiesTest.java
@@ -48,7 +48,7 @@ import org.testng.collections.Lists;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.time.Time;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
index fe15c77..ff37f74 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindCatalogItemTest.java
@@ -47,7 +47,7 @@ import brooklyn.catalog.internal.CatalogDto;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.config.BrooklynServerConfig;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.policy.basic.AbstractPolicy;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
index 18857d8..5e9f9d9 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
@@ -49,8 +49,8 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.flags.SetFromFlag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
index 84c61bc..cf246d1 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
@@ -69,9 +69,9 @@ import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.BasicSensorEvent;
 import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocationConfigTest.MyLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocationConfigTest.MyLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
index ba7fee9..6935a48 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
@@ -49,9 +49,9 @@ import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshValueFunctions;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.internal.BrooklynGarbageCollector;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
index a69de14..aac9b21 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
@@ -30,9 +30,9 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
index 721cea0..c245d85 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
@@ -38,11 +38,10 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.RebindEntityTest.MyEntity;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.AbstractLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.flags.SetFromFlag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
index 6020618..0223324 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
@@ -42,8 +42,8 @@ import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.rebind.RebindEnricherTest.MyEnricher;
-import brooklyn.location.Location;
-import brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.Locations;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java
index d83db50..89c4875 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java
@@ -28,9 +28,9 @@ import org.slf4j.LoggerFactory;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java b/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java
index 0dac5e5..c7b02d8 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java
@@ -49,7 +49,7 @@ import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
 import brooklyn.entity.rebind.persister.FileBasedObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java b/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
index ef47a5b..f6860fc 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java b/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java
index e87db3b..6806e42 100644
--- a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java
+++ b/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java
@@ -47,9 +47,9 @@ import brooklyn.entity.rebind.PersistenceExceptionHandlerImpl;
 import brooklyn.entity.rebind.RebindContextImpl;
 import brooklyn.entity.rebind.RebindTestUtils;
 import brooklyn.entity.rebind.RecordingRebindExceptionHandler;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.test.policy.TestPolicy;
 
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java b/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java
index 3efd123..3d4acd4 100644
--- a/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java
@@ -32,6 +32,8 @@ import java.util.Set;
 
 import brooklyn.management.osgi.OsgiTestResources;
 
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.mementos.BrooklynMementoPersister.LookupContext;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
@@ -56,8 +58,8 @@ import brooklyn.catalog.internal.CatalogItemDtoAbstract;
 import brooklyn.catalog.internal.CatalogTestUtils;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
 import brooklyn.management.osgi.OsgiVersionMoreEntityTest;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
@@ -176,7 +178,7 @@ public class XmlMementoSerializerTest {
         ManagementContext managementContext = app.getManagementContext();
         try {
             @SuppressWarnings("deprecation")
-            final Location loc = managementContext.getLocationManager().createLocation(LocationSpec.create(brooklyn.location.basic.SimulatedLocation.class));
+            final Location loc = managementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
             serializer.setLookupContext(new LookupContextImpl(managementContext,
                     ImmutableList.<Entity>of(), ImmutableList.of(loc), ImmutableList.<Policy>of(),
                     ImmutableList.<Enricher>of(), ImmutableList.<Feed>of(), ImmutableList.<CatalogItem<?, ?>>of(), true));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java b/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java
index ab80fd3..71cf3f7 100644
--- a/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java
+++ b/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.test.entity.TestEntityImpl;
 import org.testng.Assert;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.task.Tasks;
 



[09/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java b/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java
index 3dba382..fe77f5e 100644
--- a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java
@@ -33,12 +33,11 @@ import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.policy.os.CreateUserPolicy;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.text.Identifiers;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java b/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java
index a89e089..4184163 100644
--- a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java
@@ -37,9 +37,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.policy.os.CreateUserPolicy;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.internal.ssh.SshTool;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
new file mode 100644
index 0000000..b5f4dab
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsLiveTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.exceptions.CompoundRuntimeException;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+
+public class AbstractJcloudsLiveTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractJcloudsLiveTest.class);
+
+    public static final String BROOKLYN_PROPERTIES_PREFIX = "brooklyn.location.jclouds.";
+    public static final String BROOKLYN_PROPERTIES_LEGACY_PREFIX = "brooklyn.jclouds.";
+    
+    public static final String AWS_EC2_PROVIDER = "aws-ec2";
+    public static final String AWS_EC2_MICRO_HARDWARE_ID = "t1.micro";
+    public static final String AWS_EC2_SMALL_HARDWARE_ID = "m1.small";
+    public static final String AWS_EC2_EUWEST_REGION_NAME = "eu-west-1";
+    public static final String AWS_EC2_USEAST_REGION_NAME = "us-east-1";
+
+    public static final String RACKSPACE_PROVIDER = "rackspace-cloudservers-uk";
+    
+    public static final String SOFTLAYER_PROVIDER = "softlayer";
+    public static final String SOFTLAYER_AMS01_REGION_NAME = "ams01";
+    
+    protected BrooklynProperties brooklynProperties;
+    protected LocalManagementContext managementContext;
+    
+    protected List<JcloudsSshMachineLocation> machines;
+    protected JcloudsLocation jcloudsLocation;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        machines = Lists.newCopyOnWriteArrayList();
+        managementContext = newManagementContext();
+        
+        // Don't let any defaults from brooklyn.properties (except credentials) interfere with test
+        brooklynProperties = managementContext.getBrooklynProperties();
+        stripBrooklynProperties(brooklynProperties);
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        List<Exception> exceptions = Lists.newArrayList();
+        try {
+            if (machines != null) {
+                for (JcloudsSshMachineLocation machine : machines) {
+                    try {
+                        releaseMachine(machine);
+                    } catch (Exception e) {
+                        LOG.warn("Error releasing machine "+machine+"; continuing...", e);
+                        exceptions.add(e);
+                    }
+                }
+                machines.clear();
+            }
+        } finally {
+            try {
+                if (managementContext != null) Entities.destroyAll(managementContext);
+            } catch (Exception e) {
+                LOG.warn("Error destroying management context", e);
+                exceptions.add(e);
+            }
+        }
+        
+        // TODO Debate about whether to:
+        //  - use destroyAllCatching (i.e. not propagating exception)
+        //    Benefit is that other tests in class will subsequently be run, rather than bailing out.
+        //  - propagate exceptions from tearDown
+        //    Benefit is that we don't hide errors; release(...) etc should not be throwing exceptions.
+        if (exceptions.size() > 0) {
+            throw new CompoundRuntimeException("Error in tearDown of "+getClass(), exceptions);
+        }
+    }
+
+    protected LocalManagementContext newManagementContext() {
+        // loads properties, by default, but not OSGi or anything else
+        return LocalManagementContextForTests.builder(true).useDefaultProperties().build();
+    }
+    
+    protected void stripBrooklynProperties(BrooklynProperties props) {
+        // remove all location properties except for identity and credential
+        // (so key, scripts, etc settings don't interfere with tests) 
+        for (String key : ImmutableSet.copyOf(props.asMapWithStringKeys().keySet())) {
+            if (key.startsWith(BROOKLYN_PROPERTIES_PREFIX) && !(key.endsWith("identity") || key.endsWith("credential"))) {
+                props.remove(key);
+            }
+            if (key.startsWith(BROOKLYN_PROPERTIES_LEGACY_PREFIX) && !(key.endsWith("identity") || key.endsWith("credential"))) {
+                props.remove(key);
+            }
+            
+            // Also removes scriptHeader (e.g. if doing `. ~/.bashrc` and `. ~/.profile`, then that can cause "stdin: is not a tty")
+            if (key.startsWith("brooklyn.ssh")) {
+                props.remove(key);
+            }
+        }
+    }
+    
+    protected void assertSshable(SshMachineLocation machine) {
+        int result = machine.execScript("simplecommand", ImmutableList.of("true"));
+        assertEquals(result, 0);
+    }
+
+    // Use this utility method to ensure machines are released on tearDown
+    protected JcloudsSshMachineLocation obtainMachine(Map<?, ?> conf) throws Exception {
+        assertNotNull(jcloudsLocation);
+        JcloudsSshMachineLocation result = (JcloudsSshMachineLocation)jcloudsLocation.obtain(conf);
+        machines.add(checkNotNull(result, "result"));
+        return result;
+    }
+
+    protected JcloudsSshMachineLocation obtainMachine() throws Exception {
+        return obtainMachine(ImmutableMap.of());
+    }
+    
+    protected void releaseMachine(JcloudsSshMachineLocation machine) {
+        assertNotNull(jcloudsLocation);
+        machines.remove(machine);
+        jcloudsLocation.release(machine);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsStubbedLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsStubbedLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsStubbedLiveTest.java
new file mode 100644
index 0000000..9c70305
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsStubbedLiveTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.util.List;
+import java.util.Set;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.options.TemplateOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * The VM creation is stubbed out, but it still requires live access (i.e. real account credentials)
+ * to generate the template etc.
+ * 
+ * We supply a ComputeServiceRegistry that delegates to the real instance for everything except
+ * VM creation and deletion. For those operations, it delegates to a NodeCreator that 
+ * returns a dummy NodeMetadata, recording all calls made to it.
+ */
+public abstract class AbstractJcloudsStubbedLiveTest extends AbstractJcloudsLiveTest {
+
+    @SuppressWarnings("unused")
+    private static final Logger LOG = LoggerFactory.getLogger(AbstractJcloudsStubbedLiveTest.class);
+
+    public static final String LOCATION_SPEC = "jclouds:" + SOFTLAYER_PROVIDER + ":" + SOFTLAYER_AMS01_REGION_NAME;
+    
+    public static abstract class NodeCreator {
+        public final List<NodeMetadata> created = Lists.newCopyOnWriteArrayList();
+        public final List<String> destroyed = Lists.newCopyOnWriteArrayList();
+        
+        public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template) throws RunNodesException {
+            Set<NodeMetadata> result = Sets.newLinkedHashSet();
+            for (int i = 0; i < count; i++) {
+                NodeMetadata node = newNode(group, template);
+                created.add(node);
+                result.add(node);
+            }
+            return result;
+        }
+        public void destroyNode(String id) {
+            destroyed.add(id);
+        }
+        protected abstract NodeMetadata newNode(String group, Template template);
+    }
+    
+    public static class StubbedComputeService extends DelegatingComputeService {
+        private final NodeCreator nodeCreator;
+        
+        public StubbedComputeService(ComputeService delegate, NodeCreator nodeCreator) {
+            super(delegate);
+            this.nodeCreator = nodeCreator;
+        }
+        @Override
+        public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template) throws RunNodesException {
+            return nodeCreator.createNodesInGroup(group, count, template);
+        }
+        @Override
+        public void destroyNode(String id) {
+            nodeCreator.destroyNode(id);
+        }
+        @Override
+        public Set<? extends NodeMetadata> createNodesInGroup(String group, int count) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, TemplateOptions templateOptions) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
+            throw new UnsupportedOperationException();
+        }
+    }
+    
+    protected NodeCreator nodeCreator;
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        nodeCreator = newNodeCreator();
+        ComputeServiceRegistry computeServiceRegistry = new ComputeServiceRegistry() {
+            @Override
+            public ComputeService findComputeService(ConfigBag conf, boolean allowReuse) {
+                ComputeService delegate = ComputeServiceRegistryImpl.INSTANCE.findComputeService(conf, allowReuse);
+                return new StubbedComputeService(delegate, nodeCreator);
+            }
+        };
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(
+                LOCATION_SPEC, 
+                ImmutableMap.of(
+                        JcloudsLocationConfig.COMPUTE_SERVICE_REGISTRY, computeServiceRegistry,
+                        JcloudsLocationConfig.WAIT_FOR_SSHABLE, "false"));
+    }
+    
+    protected abstract NodeCreator newNodeCreator();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java
new file mode 100644
index 0000000..acf838e
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java
@@ -0,0 +1,188 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.util.Collections;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.LocationSpec;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Template;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.reflect.TypeToken;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.CompoundRuntimeException;
+import brooklyn.util.exceptions.Exceptions;
+
+public class BailOutJcloudsLocation extends JcloudsLocation {
+
+    // Don't care which image; not actually provisioning
+    private static final String US_EAST_IMAGE_ID = "us-east-1/ami-7d7bfc14";
+    public static final RuntimeException BAIL_OUT_FOR_TESTING = new RuntimeException("early termination for test");
+
+    public static final ConfigKey<Function<ConfigBag, Void>> BUILD_TEMPLATE_INTERCEPTOR = ConfigKeys.newConfigKey(
+            new TypeToken<Function<ConfigBag, Void>>() {},
+            "buildtemplateinterceptor");
+
+    public static final ConfigKey<Boolean> BUILD_TEMPLATE = ConfigKeys.newBooleanConfigKey(
+            "buildtemplate");
+
+    private static final long serialVersionUID = -3373789512935057842L;
+
+    ConfigBag lastConfigBag;
+    Template template;
+
+    public BailOutJcloudsLocation() {
+        super();
+    }
+
+    public BailOutJcloudsLocation(Map<?, ?> conf) {
+        super(conf);
+    }
+
+    @Override
+    public Template buildTemplate(ComputeService computeService, ConfigBag config) {
+        lastConfigBag = config;
+        if (getConfig(BUILD_TEMPLATE_INTERCEPTOR) != null) {
+            getConfig(BUILD_TEMPLATE_INTERCEPTOR).apply(config);
+        }
+        if (Boolean.TRUE.equals(getConfig(BUILD_TEMPLATE))) {
+            template = super.buildTemplate(computeService, config);
+        }
+        throw BAIL_OUT_FOR_TESTING;
+    }
+
+    public Template getTemplate() {
+        return template;
+    }
+
+    public void tryObtain() {
+        tryObtain(Collections.emptyMap());
+    }
+
+    public void tryObtain(Map<?, ?> flags) {
+        tryObtainAndCheck(flags, Predicates.alwaysTrue());
+    }
+
+    public void tryObtainAndCheck(Map<?, ?> flags, Predicate<? super ConfigBag> test) {
+        try {
+            obtain(flags);
+        } catch (Exception e) {
+            if (e == BAIL_OUT_FOR_TESTING || e.getCause() == BAIL_OUT_FOR_TESTING
+                    || (e instanceof CompoundRuntimeException && ((CompoundRuntimeException) e).getAllCauses().contains(BAIL_OUT_FOR_TESTING))) {
+                test.apply(lastConfigBag);
+            } else {
+                throw Exceptions.propagate(e);
+            }
+        }
+    }
+
+    @Override
+    @VisibleForTesting
+    public UserCreation createUserStatements(@Nullable Image image, ConfigBag config) {
+        return super.createUserStatements(image, config);
+    }
+
+
+    public static BailOutJcloudsLocation newBailOutJcloudsLocation(ManagementContext mgmt) {
+        return newBailOutJcloudsLocation(mgmt, Collections.<ConfigKey<?>, Object>emptyMap());
+    }
+
+    public static BailOutJcloudsLocation newBailOutJcloudsLocation(ManagementContext mgmt, Map<ConfigKey<?>, ?> config) {
+        Map<ConfigKey<?>, ?> allConfig = MutableMap.<ConfigKey<?>, Object>builder()
+                .put(IMAGE_ID, "bogus")
+                .put(CLOUD_PROVIDER, "aws-ec2")
+                .put(ACCESS_IDENTITY, "bogus")
+                .put(CLOUD_REGION_ID, "bogus")
+                .put(ACCESS_CREDENTIAL, "bogus")
+                .put(USER, "fred")
+                .put(MIN_RAM, 16)
+                .put(JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 1)
+                .putAll(config)
+                .build();
+        return mgmt.getLocationManager().createLocation(
+                LocationSpec.create(BailOutJcloudsLocation.class).configure(allConfig));
+    }
+
+
+    // todo better name
+
+    /** As {@link BailOutJcloudsLocation}, counting the number of {@link #buildTemplate} calls. */
+    public static class CountingBailOutJcloudsLocation extends BailOutJcloudsLocation {
+        private static final long serialVersionUID = 2433684033045735773L;
+        int buildTemplateCount = 0;
+        @Override
+        public Template buildTemplate(ComputeService computeService, ConfigBag config) {
+            buildTemplateCount++;
+            return super.buildTemplate(computeService, config);
+        }
+    }
+
+    public static CountingBailOutJcloudsLocation newCountingBailOutJcloudsLocation(ManagementContext mgmt, Map flags) {
+        LocationSpec<CountingBailOutJcloudsLocation> spec = LocationSpec.create(CountingBailOutJcloudsLocation.class)
+                .configure(flags);
+        return mgmt.getLocationManager().createLocation(spec);
+    }
+
+    /** @see #newBailOutJcloudsLocationForLiveTest(LocalManagementContext, Map)} */
+    public static BailOutJcloudsLocation newBailOutJcloudsLocationForLiveTest(LocalManagementContext mgmt) {
+        return newBailOutJcloudsLocationForLiveTest(mgmt, Collections.<ConfigKey<?>, Object>emptyMap());
+    }
+
+    /**
+     * Takes identity and access credential from management context's Brooklyn properties and sets
+     * inbound ports to [22, 80, 9999].
+     */
+    public static BailOutJcloudsLocation newBailOutJcloudsLocationForLiveTest(LocalManagementContext mgmt, Map<ConfigKey<?>, ?> config) {
+        BrooklynProperties brooklynProperties = mgmt.getBrooklynProperties();
+        String identity = (String) brooklynProperties.get("brooklyn.location.jclouds.aws-ec2.identity");
+        if (identity == null) identity = (String) brooklynProperties.get("brooklyn.jclouds.aws-ec2.identity");
+        String credential = (String) brooklynProperties.get("brooklyn.location.jclouds.aws-ec2.credential");
+        if (credential == null) credential = (String) brooklynProperties.get("brooklyn.jclouds.aws-ec2.credential");
+
+        Map<ConfigKey<?>, ?> allConfig = MutableMap.<ConfigKey<?>, Object>builder()
+                .put(CLOUD_PROVIDER, AbstractJcloudsLiveTest.AWS_EC2_PROVIDER)
+                .put(CLOUD_REGION_ID, AbstractJcloudsLiveTest.AWS_EC2_USEAST_REGION_NAME)
+                .put(IMAGE_ID, US_EAST_IMAGE_ID) // so Brooklyn does not attempt to load all EC2 images
+                .put(ACCESS_IDENTITY, identity)
+                .put(ACCESS_CREDENTIAL, credential)
+                .put(INBOUND_PORTS, "[22, 80, 9999]")
+                .put(BUILD_TEMPLATE, true)
+                .putAll(config)
+                .build();
+
+        return newBailOutJcloudsLocation(mgmt, allConfig);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePoolLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePoolLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePoolLiveTest.java
new file mode 100644
index 0000000..3fda145
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePoolLiveTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import org.apache.brooklyn.location.jclouds.pool.MachineSet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.pool.MachinePoolPredicates;
+import org.apache.brooklyn.location.jclouds.pool.ReusableMachineTemplate;
+import brooklyn.management.internal.LocalManagementContext;
+
+public class BrooklynMachinePoolLiveTest {
+
+    public static final Logger log = LoggerFactory.getLogger(BrooklynMachinePoolLiveTest.class);
+    
+    public static class SamplePool extends BrooklynMachinePool {
+        public SamplePool(JcloudsLocation l) {
+            super(l);
+        }
+
+        public final static ReusableMachineTemplate 
+            USUAL_VM = 
+                new ReusableMachineTemplate("usual").templateOwnedByMe().
+                tagOptional("tagForUsualVm").
+                metadataOptional("metadataForUsualVm", "12345").
+                minRam(1024).minCores(2);
+
+        public final static ReusableMachineTemplate 
+            ANYONE_NOT_TINY_VM = 
+                new ReusableMachineTemplate("anyone").
+                minRam(512).minCores(1).strict(false);
+
+        public static final ReusableMachineTemplate 
+            VM_LARGE1 = 
+                new ReusableMachineTemplate("vm.large1").templateOwnedByMe().
+                minRam(16384).minCores(4),
+            VM_SMALL1 = 
+                new ReusableMachineTemplate("vm.small1").templateOwnedByMe().smallest();
+        
+        { registerTemplates(USUAL_VM, ANYONE_NOT_TINY_VM, VM_LARGE1, VM_SMALL1); }
+    }
+
+
+    private LocalManagementContext managementContext;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = new LocalManagementContext();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) managementContext.terminate();
+    }
+    
+    @Test(groups="Live")
+    public void buildClaimAndDestroy() {
+        SamplePool p = new SamplePool(resolve("aws-ec2:us-west-1"));
+        log.info("buildClaimAndDestroy: created pool");
+        p.refresh();
+        log.info("buildClaimAndDestroy: refreshed pool");
+        p.ensureExists(2, SamplePool.USUAL_VM);
+        log.info("buildClaimAndDestroy: ensure have 2");
+        SshMachineLocation l = p.obtain(SamplePool.USUAL_VM);
+        Assert.assertNotNull(l);
+        log.info("buildClaimAndDestroy: claimed 1");
+        MachineSet unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM));
+        log.info("buildClaimAndDestroy: unclaimed now "+unclaimedUsual);
+        Assert.assertTrue(!unclaimedUsual.isEmpty(), "should have been unclaimed machines (can fail if there are some we cannot connect to, ie blacklisted)");
+        p.destroy(unclaimedUsual);
+        p.destroy(l);
+        unclaimedUsual = p.unclaimed(MachinePoolPredicates.matching(SamplePool.USUAL_VM));
+        log.info("buildClaimAndDestroy: destroyed, unclaimed now "+unclaimedUsual);
+        log.info("end");
+    }
+    
+
+    private JcloudsLocation resolve(String spec) {
+        return (JcloudsLocation) managementContext.getLocationRegistry().resolve(new JcloudsLocationResolver().getPrefix() + ":" + spec);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DelegatingComputeService.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DelegatingComputeService.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DelegatingComputeService.java
new file mode 100644
index 0000000..8e718e2
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/DelegatingComputeService.java
@@ -0,0 +1,229 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.RunScriptOnNodesException;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.options.RunScriptOptions;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.Location;
+import org.jclouds.scriptbuilder.domain.Statement;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public class DelegatingComputeService implements ComputeService {
+
+    private final ComputeService delegate;
+    
+    public DelegatingComputeService(ComputeService delegate) {
+        this.delegate = delegate;
+    }
+    
+    @Override
+    public ComputeServiceContext getContext() {
+        return delegate.getContext();
+    }
+
+    @Override
+    public TemplateBuilder templateBuilder() {
+        return delegate.templateBuilder();
+    }
+
+    @Override
+    public TemplateOptions templateOptions() {
+        return delegate.templateOptions();
+    }
+
+    @Override
+    public Set<? extends Hardware> listHardwareProfiles() {
+        return delegate.listHardwareProfiles();
+    }
+
+    @Override
+    public Set<? extends Image> listImages() {
+        return delegate.listImages();
+    }
+
+    @Override
+    public Image getImage(String id) {
+        return delegate.getImage(id);
+    }
+
+    @Override
+    public Set<? extends ComputeMetadata> listNodes() {
+        return delegate.listNodes();
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> listNodesByIds(Iterable<String> ids) {
+        return delegate.listNodesByIds(ids);
+    }
+
+    @Override
+    public Set<? extends Location> listAssignableLocations() {
+        return delegate.listAssignableLocations();
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template) throws RunNodesException {
+        return delegate.createNodesInGroup(group, count, template);
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> createNodesInGroup(String group, int count, TemplateOptions templateOptions)
+            throws RunNodesException {
+        return delegate.createNodesInGroup(group, count, templateOptions);
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> createNodesInGroup(String group, int count) throws RunNodesException {
+        return delegate.createNodesInGroup(group, count);
+    }
+
+    @Override
+    public void resumeNode(String id) {
+        delegate.resumeNode(id);
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> resumeNodesMatching(Predicate<NodeMetadata> filter) {
+        return delegate.resumeNodesMatching(filter);
+    }
+
+    @Override
+    public void suspendNode(String id) {
+        delegate.suspendNode(id);
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> suspendNodesMatching(Predicate<NodeMetadata> filter) {
+        return delegate.suspendNodesMatching(filter);
+    }
+
+    @Override
+    public void destroyNode(String id) {
+        delegate.destroyNode(id);
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter) {
+        return delegate.destroyNodesMatching(filter);
+    }
+
+    @Override
+    public void rebootNode(String id) {
+        delegate.rebootNode(id);
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> rebootNodesMatching(Predicate<NodeMetadata> filter) {
+        return delegate.rebootNodesMatching(filter);
+    }
+
+    @Override
+    public NodeMetadata getNodeMetadata(String id) {
+        return delegate.getNodeMetadata(id);
+    }
+
+    @Override
+    public Set<? extends NodeMetadata> listNodesDetailsMatching(Predicate<ComputeMetadata> filter) {
+        return delegate.listNodesDetailsMatching(filter);
+    }
+
+    @Override
+    public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, String runScript)
+            throws RunScriptOnNodesException {
+        return delegate.runScriptOnNodesMatching(filter, runScript);
+    }
+
+    @Override
+    public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Statement runScript)
+            throws RunScriptOnNodesException {
+        return delegate.runScriptOnNodesMatching(filter, runScript);
+    }
+
+    @Override
+    public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
+            String runScript, RunScriptOptions options) throws RunScriptOnNodesException {
+        return delegate.runScriptOnNodesMatching(filter, runScript, options);
+    }
+
+    @Override
+    public Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
+            Statement runScript, RunScriptOptions options) throws RunScriptOnNodesException {
+        return delegate.runScriptOnNodesMatching(filter, runScript, options);
+    }
+
+    @Override
+    public ExecResponse runScriptOnNode(String id, Statement runScript, RunScriptOptions options) {
+        return delegate.runScriptOnNode(id, runScript, options);
+    }
+
+    @Override
+    public ListenableFuture<ExecResponse> submitScriptOnNode(String id, String runScript, RunScriptOptions options) {
+        return delegate.submitScriptOnNode(id, runScript, options);
+    }
+
+    @Override
+    public ListenableFuture<ExecResponse> submitScriptOnNode(String id, Statement runScript, RunScriptOptions options) {
+        return delegate.submitScriptOnNode(id, runScript, options);
+    }
+
+    @Override
+    public ExecResponse runScriptOnNode(String id, Statement runScript) {
+        return delegate.runScriptOnNode(id, runScript);
+    }
+
+    @Override
+    public ExecResponse runScriptOnNode(String id, String runScript, RunScriptOptions options) {
+        return delegate.runScriptOnNode(id, runScript, options);
+    }
+
+    @Override
+    public ExecResponse runScriptOnNode(String id, String runScript) {
+        return delegate.runScriptOnNode(id, runScript);
+    }
+
+    @Override
+    public Optional<ImageExtension> getImageExtension() {
+        return delegate.getImageExtension();
+    }
+
+    @Override
+    public Optional<SecurityGroupExtension> getSecurityGroupExtension() {
+        return delegate.getSecurityGroupExtension();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
new file mode 100644
index 0000000..2694ed5
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
@@ -0,0 +1,228 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.stream.Streams;
+
+/**
+ * Tests that the correct address is advertised for the VM - for its public/private, 
+ * its subnet hostname, etc.
+ */
+public class JcloudsAddressesLiveTest extends AbstractJcloudsLiveTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsAddressesLiveTest.class);
+
+    public static final String AWS_EC2_REGION_NAME = AWS_EC2_USEAST_REGION_NAME;
+    public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + (AWS_EC2_REGION_NAME == null ? "" : ":" + AWS_EC2_REGION_NAME);
+    
+    // Image: {id=us-east-1/ami-7d7bfc14, providerId=ami-7d7bfc14, name=RightImage_CentOS_6.3_x64_v5.8.8.5, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=6.0, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, version=5.8.8.5, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
+    public static final String AWS_EC2_CENTOS_IMAGE_ID = "us-east-1/ami-7d7bfc14";
+
+    // Image: {id=us-east-1/ami-d0f89fb9, providerId=ami-d0f89fb9, name=ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=12.04, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, is64Bit=true}, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, version=20130411.1, status=AVAILABLE[available], loginUser=ubuntu, userMetadata={owner=099720109477, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
+    public static final String AWS_EC2_UBUNTU_IMAGE_ID = "us-east-1/ami-d0f89fb9";
+    
+    // Image: {id=us-east-1/ami-5e008437, providerId=ami-5e008437, name=RightImage_Ubuntu_10.04_x64_v5.8.8.3, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=10.04, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, version=5.8.8.3, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
+    // Uses "root" as loginUser
+    public static final String AWS_EC2_UBUNTU_10_IMAGE_ID = "us-east-1/ami-5e008437";
+
+    public static final String RACKSPACE_LOCATION_SPEC = "jclouds:" + RACKSPACE_PROVIDER;
+    
+    // Image: {id=LON/c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, providerId=c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, name=CentOS 6.0, location={scope=ZONE, id=LON, description=LON, parent=rackspace-cloudservers-uk, iso3166Codes=[GB-SLG]}, os={family=centos, name=CentOS 6.0, version=6.0, description=CentOS 6.0, is64Bit=true}, description=CentOS 6.0, status=AVAILABLE, loginUser=root, userMetadata={os_distro=centos, com.rackspace__1__visible_core=1, com.rackspace__1__build_rackconnect=1, com.rackspace__1__options=0, image_type=base, cache_in_nova=True, com.rackspace__1__source=kickstart, org.openstack__1__os_distro=org.centos, com.rackspace__1__release_build_date=2013-07-25_18-56-29, auto_disk_config=True, com.rackspace__1__release_version=5, os_type=linux, com.rackspace__1__visible_rackconnect=1, com.rackspace__1__release_id=210, com.rackspace__1__visible_managed=0, com.rackspace__1__build_core=1, org.openstack__1__os_version=6.0, org.openstack__1__architecture=x64, com.rackspace__1__build_ma
 naged=0}}
+    public static final String RACKSPACE_CENTOS_IMAGE_NAME_REGEX = "CentOS 6.0";
+    
+    protected JcloudsSshMachineLocation machine;
+    
+    @Test(groups = {"Live"})
+    protected void testAwsEc2Addresses() throws Exception {
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
+        
+        machine = createEc2Machine(ImmutableMap.<String,Object>of());
+        assertSshable(machine);
+
+        String locationAddress = machine.getAddress().getHostName();
+        InetAddress address = machine.getAddress();
+        Set<String> publicAddresses = machine.getPublicAddresses();
+        Set<String> privateAddresses = machine.getPrivateAddresses();
+        String subnetIp = machine.getSubnetIp();
+        String hostname = machine.getHostname();
+        String subnetHostname = machine.getSubnetHostname();
+        String msg = "locationAddress="+locationAddress+"; address="+address+"; publicAddrs="+publicAddresses+"; privateAddrs="+privateAddresses+"; subnetIp="+subnetIp+"; hostname="+hostname+"; subnetHostname="+subnetHostname;
+        LOG.info("node: "+msg);
+
+        // On AWS, machine advertises its FQ hostname that is accessible from inside and outside the region
+        assertReachable(machine, locationAddress, msg);
+        assertReachableFromMachine(machine, locationAddress, msg);
+
+        assertReachable(machine, address, msg);
+        
+        assertTrue(publicAddresses.size() > 0, msg);
+        for (String publicAddress: publicAddresses) {
+            assertReachable(machine, publicAddress, msg);
+        }
+        
+        // On AWS, private address is not reachable from outside.
+        // If you ran this test from the same AWS region, it would fail!
+        assertTrue(privateAddresses.size() > 0, msg);
+        for (String privateAddress: privateAddresses) {
+            assertReachableFromMachine(machine, privateAddress, msg);
+            assertNotReachable(machine, privateAddress, msg);
+        }
+        
+        assertNotNull(subnetIp, msg);
+        assertReachableFromMachine(machine, subnetIp, msg);
+
+        // hostname is reachable from inside; not necessarily reachable from outside
+        assertNotNull(hostname, msg);
+        assertReachableFromMachine(machine, hostname, msg);
+        
+        assertNotNull(subnetHostname, msg);
+        assertReachableFromMachine(machine, subnetHostname, msg);
+    }
+
+    @Test(groups = {"Live"})
+    protected void testRackspaceAddresses() throws Exception {
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
+        
+        machine = createRackspaceMachine(ImmutableMap.<String,Object>of());
+        assertSshable(machine);
+
+        String locationAddress = machine.getAddress().getHostAddress();
+        InetAddress address = machine.getAddress();
+        Set<String> publicAddresses = machine.getPublicAddresses();
+        Set<String> privateAddresses = machine.getPrivateAddresses();
+        String subnetIp = machine.getSubnetIp();
+        String hostname = machine.getHostname();
+        String subnetHostname = machine.getSubnetHostname();
+        String msg = "locationAddress="+locationAddress+"; address="+address+"; publicAddrs="+publicAddresses+"; privateAddrs="+privateAddresses+"; subnetIp="+subnetIp+"; hostname="+hostname+"; subnetHostname="+subnetHostname;
+        LOG.info("node: "+msg);
+
+        // On Rackspace, IP is accessible from inside and outside.
+        assertReachable(machine, locationAddress, msg);
+        assertReachableFromMachine(machine, locationAddress, msg);
+
+        assertReachable(machine, address, msg);
+        
+        assertTrue(publicAddresses.size() > 0, msg);
+        for (String publicAddress: publicAddresses) {
+            assertReachable(machine, publicAddress, msg);
+        }
+        
+        // On Rackspace, don't care if no private addresses
+        for (String privateAddress: privateAddresses) {
+            assertReachableFromMachine(machine, privateAddress, msg);
+            assertNotReachable(machine, privateAddress, msg);
+        }
+        
+        assertNotNull(subnetIp, msg);
+        assertReachableFromMachine(machine, subnetIp, msg);
+
+        // hostname is reachable from inside; not necessarily reachable from outside
+        assertNotNull(hostname, msg);
+        assertReachableFromMachine(machine, hostname, msg);
+        
+        assertNotNull(subnetHostname, msg);
+        assertReachableFromMachine(machine, subnetHostname, msg);
+    }
+
+    private void assertReachable(SshMachineLocation machine, InetAddress addr, String msg) {
+        assertReachable(machine, addr.getHostAddress(), msg);
+    }
+
+    private void assertReachable(SshMachineLocation machine, String addr, String msg) {
+        assertReachability(true, machine, addr, msg);
+    }
+    
+    private void assertNotReachable(SshMachineLocation machine, String addr, String msg) {
+        assertReachability(false, machine, addr, msg);
+    }
+
+    private void assertReachability(boolean expectedReachable, SshMachineLocation machine, String addr, String msg) {
+        SshMachineLocation tmpMachine = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure(machine.config().getBag().getAllConfig())
+                .configure("address", addr));
+        try {
+            boolean sshable = tmpMachine.isSshable();
+            assertEquals(sshable, expectedReachable, addr+" not sshable; "+msg);
+        } finally {
+            Locations.unmanage(tmpMachine);
+        }
+    }
+
+    // TODO Assumes that "ping" will work; i.e. that ICMP is not firewall'ed
+    private void assertReachableFromMachine(SshMachineLocation machine, String addr, String msg) {
+        OutputStream outStream = new ByteArrayOutputStream();
+        OutputStream errStream = new ByteArrayOutputStream();
+        int result = machine.execScript(MutableMap.of("out", outStream, "err", errStream), "reach "+addr, ImmutableList.of("ping -c 1 "+addr));
+        String outString = outStream.toString();
+        String errString = errStream.toString();
+        assertEquals(result, 0, "result="+0+"; err="+errString+"; out="+outString+"; msg="+msg);
+    }
+
+    @Override
+    protected void releaseMachine(JcloudsSshMachineLocation machine) {
+        jcloudsLocation.release(machine);
+    }
+    
+    private JcloudsSshMachineLocation createEc2Machine(Map<String,? extends Object> conf) throws Exception {
+        return obtainMachine(MutableMap.<String,Object>builder()
+                .putAll(conf)
+                .putIfAbsent("imageId", AWS_EC2_CENTOS_IMAGE_ID)
+                .putIfAbsent("hardwareId", AWS_EC2_SMALL_HARDWARE_ID)
+                .putIfAbsent("inboundPorts", ImmutableList.of(22))
+                .build());
+    }
+    
+    private JcloudsSshMachineLocation createRackspaceMachine(Map<String,? extends Object> conf) throws Exception {
+        return obtainMachine(MutableMap.<String,Object>builder()
+                .putAll(conf)
+                .putIfAbsent("inboundPorts", ImmutableList.of(22))
+                .build());
+    }
+    
+    protected void assertSshable(Map<?,?> machineConfig) {
+        SshMachineLocation machineWithThatConfig = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure(machineConfig));
+        try {
+            assertSshable(machineWithThatConfig);
+        } finally {
+            Streams.closeQuietly(machineWithThatConfig);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverAwsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverAwsLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverAwsLiveTest.java
new file mode 100644
index 0000000..2f708f3
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverAwsLiveTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.net.InetAddress;
+import java.util.Map;
+import java.util.Set;
+
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.collections.MutableMap;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class JcloudsByonLocationResolverAwsLiveTest extends AbstractJcloudsLiveTest {
+
+    private static final String AWS_REGION = "eu-west-1";
+    private static final String AWS_LOCATION_SPEC = "jclouds:aws-ec2:"+AWS_REGION;
+    
+    private String awsVmUser;
+    private String awsVmInstanceId;
+    private String awsVmIp;
+    private String awsVmHostname;
+     
+    private LocalManagementContext classManagementContext;
+    private JcloudsLocation classEc2Loc;
+    private JcloudsSshMachineLocation classEc2Vm;
+
+    @BeforeClass(groups="Live")
+    public void setUpClass() throws Exception {
+        classManagementContext = newManagementContext();
+        classEc2Loc = (JcloudsLocation) classManagementContext.getLocationRegistry().resolve(AWS_LOCATION_SPEC);
+        classEc2Vm = (JcloudsSshMachineLocation)classEc2Loc.obtain(MutableMap.<String,Object>builder()
+                .put("hardwareId", AWS_EC2_SMALL_HARDWARE_ID)
+                .put("inboundPorts", ImmutableList.of(22))
+                .build());
+        awsVmUser = classEc2Vm.getUser();
+        awsVmInstanceId = classEc2Vm.getNode().getProviderId(); // id without region (e.g. "i-6ff96d2f" instead of "eu-west-1/i-6ff96d2f")
+        awsVmIp = classEc2Vm.getAddress().getHostAddress();
+        awsVmHostname = classEc2Vm.getAddress().getHostName();
+    }
+    
+    @AfterClass(alwaysRun=true)
+    public void tearDownClass() throws Exception {
+        try {
+            if (classEc2Vm != null) {
+                classEc2Loc.release(classEc2Vm);
+            }
+        } finally {
+            if (classManagementContext != null) classManagementContext.terminate();
+        }
+    }
+
+    // TODO Requires that a VM already exists; could create that VM first to make test more robust
+    @Test(groups={"Live"})
+    public void testResolvesJcloudsByonAws() throws Exception {
+        String spec = "jcloudsByon:(provider=\"aws-ec2\",region=\""+AWS_REGION+"\",user=\""+awsVmUser+"\",hosts=\""+awsVmInstanceId+"\",anotherprop=myval)";
+
+        FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> loc = resolve(spec);
+        
+        Set<JcloudsSshMachineLocation> machines = loc.getAllMachines();
+        JcloudsSshMachineLocation machine = Iterables.getOnlyElement(machines);
+        assertEquals(machine.getParent().getProvider(), "aws-ec2");
+        assertEquals(machine.getAddress().getHostAddress(), awsVmIp);
+        assertEquals(machine.getAddress().getHostName(), awsVmHostname);
+        assertEquals(machine.getUser(), awsVmUser);
+        assertEquals(machine.config().getBag().getStringKey("anotherprop"), "myval");
+        
+        assertTrue(machine.isSshable());
+    }
+
+    @Test(groups={"Live"})
+    public void testResolvesNamedJcloudsByon() throws Exception {
+        String spec = "jcloudsByon:(provider=\"aws-ec2\",region=\""+AWS_REGION+"\",user=\""+awsVmUser+"\",hosts=\""+awsVmInstanceId+"\")";
+        brooklynProperties.put("brooklyn.location.named.mynamed", spec);
+        
+        FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> loc = resolve("named:mynamed");
+        assertEquals(loc.obtain().getAddress(), InetAddress.getByName(awsVmHostname));
+    }
+
+    @Test(groups={"Live"})
+    public void testJcloudsPropertiesPrecedence() throws Exception {
+        String spec = "jcloudsByon:(provider=\"aws-ec2\",region=\""+AWS_REGION+"\",user=\""+awsVmUser+"\",hosts=\""+awsVmInstanceId+"\")";
+        brooklynProperties.put("brooklyn.location.named.mynamed", spec);
+        
+        // prefer those in spec string over everything else
+        brooklynProperties.put("brooklyn.location.named.mynamed.user", "user-inNamed");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.user", "user-inProviderSpecific");
+        brooklynProperties.put("brooklyn.jclouds.aws-ec2.user", "user-inProviderSpecificDeprecated");
+        brooklynProperties.put("brooklyn.location.jclouds.user", "user-inJcloudsGeneric");
+        brooklynProperties.put("brooklyn.jclouds.user", "user-inJcloudsGenericDeprecated");
+        brooklynProperties.put("brooklyn.location.user", "user-inLocationGeneric");
+
+        // prefer those in "named" over everything else (except spec string itself)
+        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyFile", "privateKeyFile-inProviderSpecific");
+        brooklynProperties.put("brooklyn.jclouds.aws-ec2.privateKeyFile", "privateKeyFile-inProviderSpecificDeprecated");
+        brooklynProperties.put("brooklyn.location.jclouds.privateKeyFile", "privateKeyFile-inJcloudsGeneric");
+        brooklynProperties.put("brooklyn.jclouds.privateKeyFile", "privateKeyFile-inJcloudsGenericDeprecated");
+        brooklynProperties.put("brooklyn.location.privateKeyFile", "privateKeyFile-inLocationGeneric");
+
+        // prefer those in provider-specific over generic
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.publicKeyFile", "publicKeyFile-inProviderSpecific");
+        brooklynProperties.put("brooklyn.jclouds.aws-ec2.publicKeyFile", "publicKeyFile-inProviderSpecificDeprecated");
+        brooklynProperties.put("brooklyn.location.jclouds.publicKeyFile", "publicKeyFile-inJcloudsGeneric");
+        brooklynProperties.put("brooklyn.jclouds.publicKeyFile", "publicKeyFile-inJcloudsGenericDeprecated");
+        brooklynProperties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inLocationGeneric");
+        
+        // prefer those in provider-specific (deprecated scope) over generic
+        brooklynProperties.put("brooklyn.jclouds.aws-ec2.securityGroups", "securityGroups-inProviderSpecificDeprecated");
+        brooklynProperties.put("brooklyn.location.jclouds.securityGroups", "securityGroups-inJcloudsGeneric");
+        brooklynProperties.put("brooklyn.jclouds.securityGroups", "securityGroups-inJcloudsGenericDeprecated");
+        brooklynProperties.put("brooklyn.location.securityGroups", "securityGroups-inLocationGeneric");
+
+        // prefer those in jclouds-generic over location-generic
+        brooklynProperties.put("brooklyn.location.jclouds.loginUser", "loginUser-inJcloudsGeneric");
+        brooklynProperties.put("brooklyn.jclouds.loginUser", "loginUser-inJcloudsGenericDeprecated");
+        brooklynProperties.put("brooklyn.location.loginUser", "loginUser-inLocationGeneric");
+
+        // prefer those in jclouds-generic (deprecated) over location-generic
+        brooklynProperties.put("brooklyn.jclouds.imageId", "imageId-inJcloudsGenericDeprecated");
+        brooklynProperties.put("brooklyn.location.imageId", "imageId-inLocationGeneric");
+
+        // prefer location-generic if nothing else
+        brooklynProperties.put("brooklyn.location.keyPair", "keyPair-inLocationGeneric");
+
+        // prefer deprecated properties in "named" over those less specific
+        brooklynProperties.put("brooklyn.location.named.mynamed.private-key-data", "privateKeyData-inNamed");
+        brooklynProperties.put("brooklyn.jclouds.aws-ec2.privateKeyData", "privateKeyData-inProviderSpecific");
+        brooklynProperties.put("brooklyn.jclouds.privateKeyData", "privateKeyData-inJcloudsGeneric");
+
+        // prefer "named" over everything else: confirm deprecated don't get transformed to overwrite it accidentally
+        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyPassphrase", "privateKeyPassphrase-inNamed");
+        brooklynProperties.put("brooklyn.jclouds.aws-ec2.private-key-passphrase", "privateKeyPassphrase-inProviderSpecific");
+        brooklynProperties.put("brooklyn.jclouds.private-key-passphrase", "privateKeyPassphrase-inJcloudsGeneric");
+
+        Map<String, Object> conf = resolve("named:mynamed").obtain().config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("user"), awsVmUser);
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
+        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
+        assertEquals(conf.get("securityGroups"), "securityGroups-inProviderSpecificDeprecated");
+        assertEquals(conf.get("loginUser"), "loginUser-inJcloudsGeneric");
+        assertEquals(conf.get("imageId"), "imageId-inJcloudsGenericDeprecated");
+        assertEquals(conf.get("keyPair"), "keyPair-inLocationGeneric");
+        assertEquals(conf.get("privateKeyData"), "privateKeyData-inNamed");
+        assertEquals(conf.get("privateKeyPassphrase"), "privateKeyPassphrase-inNamed");
+    }
+    
+    @SuppressWarnings("unchecked")
+    private FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> resolve(String spec) {
+        return (FixedListMachineProvisioningLocation<JcloudsSshMachineLocation>) managementContext.getLocationRegistry().resolve(spec);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverSoftlayerLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverSoftlayerLiveTest.java
new file mode 100644
index 0000000..31831a8
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverSoftlayerLiveTest.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.collections.MutableMap;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class JcloudsByonLocationResolverSoftlayerLiveTest extends AbstractJcloudsLiveTest {
+
+    private static final String SOFTLAYER_REGION = "dal05";
+    private static final String SOFTLAYER_LOCATION_SPEC = "jclouds:softlayer:"+SOFTLAYER_REGION;
+    
+    private String slVmUser;
+    private String slVmInstanceId;
+    private String slVmIp;
+    private String slVmHostname;
+    
+    private LocalManagementContext classManagementContext;
+    private JcloudsLocation classEc2Loc;
+    private JcloudsSshMachineLocation classVm;
+
+    @BeforeClass(groups="Live")
+    public void setUpClass() throws Exception {
+        classManagementContext = newManagementContext();
+        classEc2Loc = (JcloudsLocation) classManagementContext.getLocationRegistry().resolve(SOFTLAYER_LOCATION_SPEC);
+        classVm = (JcloudsSshMachineLocation)classEc2Loc.obtain(MutableMap.<String,Object>builder()
+                .put("inboundPorts", ImmutableList.of(22))
+                .build());
+        slVmUser = classVm.getUser();
+        slVmInstanceId = classVm.getJcloudsId();
+        slVmIp = classVm.getAddress().getHostAddress();
+        slVmHostname = classVm.getNode().getHostname();
+    }
+    
+    @AfterClass(alwaysRun=true)
+    public void tearDownClass() throws Exception {
+        try {
+            if (classVm != null) {
+                classEc2Loc.release(classVm);
+            }
+        } finally {
+            if (classManagementContext != null) classManagementContext.terminate();
+        }
+    }
+
+    @Test(groups={"Live"})
+    public void testResolvesJcloudsByonSoftlayer() throws Exception {
+        checkSoftlayer("jcloudsByon:(provider=\"softlayer\",region=\""+SOFTLAYER_REGION+"\",hosts=\""+slVmInstanceId+"\",user=\""+slVmUser+"\")");
+        checkSoftlayer("jcloudsByon:(provider=\"softlayer\",region=\""+SOFTLAYER_REGION+"\",hosts=\""+slVmHostname+"\")");
+        checkSoftlayer("jcloudsByon:(provider=\"softlayer\",region=\""+SOFTLAYER_REGION+"\",hosts=\""+slVmIp+"\")");
+        checkSoftlayer("jcloudsByon:(provider=\"softlayer\",hosts=\""+slVmIp+"\")");
+    }
+    
+    private void checkSoftlayer(String spec) {
+        FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> loc = resolve(spec);
+        
+        Set<JcloudsSshMachineLocation> machines = loc.getAllMachines();
+        JcloudsSshMachineLocation machine = Iterables.getOnlyElement(machines);
+        assertEquals(machine.getParent().getProvider(), "softlayer");
+        assertEquals(machine.getNode().getId(), slVmInstanceId);
+        assertEquals(machine.getAddress().getHostAddress(), slVmIp);
+        assertTrue(slVmHostname.equals(machine.getAddress().getHostName()) || slVmIp.equals(machine.getAddress().getHostName()), 
+            "address hostname is: "+machine.getAddress().getHostName());
+        assertTrue(slVmHostname.equals(machine.getNode().getHostname()) || slVmIp.equals(machine.getNode().getHostname()), 
+            "node hostname is: "+machine.getNode().getHostname());
+        
+        // could also assert this, given a user credential, but not currently set up
+//        assertTrue(machine.isSshable());
+    }
+
+    @SuppressWarnings("unchecked")
+    private FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> resolve(String spec) {
+        return (FixedListMachineProvisioningLocation<JcloudsSshMachineLocation>) managementContext.getLocationRegistry().resolve(spec);
+    }
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverTest.java
new file mode 100644
index 0000000..3f7c837
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolverTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.fail;
+
+import java.util.NoSuchElementException;
+
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+
+public class JcloudsByonLocationResolverTest {
+
+    private LocalManagementContext managementContext;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+
+    @Test
+    public void testThrowsOnInvalid() throws Exception {
+        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
+        assertThrowsIllegalArgument("jcloudsByon"); // no hosts
+        assertThrowsIllegalArgument("jcloudsByon:()"); // no hosts
+        assertThrowsIllegalArgument("jcloudsByon:(hosts=\"\")"); // empty hosts
+        assertThrowsIllegalArgument("jcloudsByon:(hosts=\"i-72b1b132\""); // no closing bracket
+        assertThrowsIllegalArgument("jcloudsByon:(hosts=\"i-72b1b132\", name)"); // no value for name
+        assertThrowsIllegalArgument("jcloudsByon:(hosts=\"i-72b1b132\", name=)"); // no value for name
+    }
+
+    @SuppressWarnings("unchecked")
+    private FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> resolve(String spec) {
+        return (FixedListMachineProvisioningLocation<JcloudsSshMachineLocation>) managementContext.getLocationRegistry().resolve(spec);
+    }
+    
+    private void assertThrowsNoSuchElement(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (NoSuchElementException e) {
+            // success
+        }
+    }
+    
+    private void assertThrowsIllegalArgument(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsHardwareProfilesStubbedLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsHardwareProfilesStubbedLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsHardwareProfilesStubbedLiveTest.java
new file mode 100644
index 0000000..8f9b1ea
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsHardwareProfilesStubbedLiveTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadata.Status;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.domain.LoginCredentials;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import brooklyn.util.collections.MutableMap;
+
+import com.google.common.collect.ImmutableList;
+
+public class JcloudsHardwareProfilesStubbedLiveTest extends AbstractJcloudsStubbedLiveTest {
+
+    @SuppressWarnings("unused")
+    private static final Logger log = LoggerFactory.getLogger(JcloudsHardwareProfilesStubbedLiveTest.class);
+    
+    private Template template;
+    
+    @Override
+    protected NodeCreator newNodeCreator() {
+        return new NodeCreator() {
+            @Override protected NodeMetadata newNode(String group, Template template) {
+                JcloudsHardwareProfilesStubbedLiveTest.this.template = template;
+                
+                NodeMetadata result = new NodeMetadataBuilder()
+                        .id("myid")
+                        .credentials(LoginCredentials.builder().identity("myuser").credential("mypassword").build())
+                        .loginPort(22)
+                        .status(Status.RUNNING)
+                        .publicAddresses(ImmutableList.of("173.194.32.123"))
+                        .privateAddresses(ImmutableList.of("172.168.10.11"))
+                        .build();
+                return result;
+            }
+        };
+    }
+
+    @Test(groups={"Live", "Live-sanity"})
+    public void testJcloudsCreateWithHardwareProfiles() throws Exception {
+        obtainMachine(MutableMap.of(JcloudsLocationConfig.MIN_RAM, "4096"));
+        assertTrue(template.getHardware().getRam() >= 4096, "template="+template);
+        
+        obtainMachine(MutableMap.of(JcloudsLocationConfig.MIN_CORES, "4"));
+        assertTrue(template.getHardware().getProcessors().get(0).getCores() >= 4, "template="+template);
+
+        obtainMachine(MutableMap.of(JcloudsLocationConfig.MIN_DISK, "51"));
+        assertTrue(template.getHardware().getVolumes().get(0).getSize() >= 51, "template="+template);
+        
+        String hardwareId = "cpu=1,memory=6144,disk=25,type=LOCAL";
+        obtainMachine(MutableMap.of(JcloudsLocationConfig.HARDWARE_ID, hardwareId));
+        assertEquals(template.getHardware().getId(), hardwareId, "template="+template);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
new file mode 100644
index 0000000..7bce1ab
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import brooklyn.management.internal.LocalManagementContext;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * @author Shane Witbeck
+ */
+public class JcloudsLocationMetadataTest implements JcloudsLocationConfig {
+
+    protected BrooklynProperties brooklynProperties;
+    protected LocalManagementContext managementContext;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance(BrooklynProperties.Factory.builderEmpty().build());
+        brooklynProperties = managementContext.getBrooklynProperties();
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+
+
+    @Test
+    public void testGetsDefaultAwsEc2Metadata() throws Exception {
+        Location loc = managementContext.getLocationRegistry().resolve("jclouds:aws-ec2:us-west-1");
+        
+        assertEquals(loc.getConfig(LocationConfigKeys.LATITUDE), 40.0d);
+        assertEquals(loc.getConfig(LocationConfigKeys.LONGITUDE), -120.0d);
+        assertEquals(loc.getConfig(LocationConfigKeys.ISO_3166), ImmutableSet.of("US-CA"));
+    }
+
+    @Test
+    public void testCanOverrideDefaultAwsEc2Metadata() throws Exception {
+        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2@us-west-1.latitude", "41.2");
+        Location loc = managementContext.getLocationRegistry().resolve("jclouds:aws-ec2:us-west-1");
+        
+        assertEquals(loc.getConfig(LocationConfigKeys.LATITUDE), 41.2d);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
new file mode 100644
index 0000000..006f62e
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.net.InetAddress;
+import java.util.Collections;
+
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class JcloudsLocationRebindMachineLiveTest extends AbstractJcloudsLiveTest {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(JcloudsLocationRebindMachineLiveTest.class);
+    
+    private static final String EUWEST_IMAGE_ID = AWS_EC2_EUWEST_REGION_NAME+"/"+"ami-89def4fd";
+    private static final String IMAGE_OWNER = "411009282317";
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
+    }
+
+    @Test(groups = { "Live", "Live-sanity" })
+    public void testRebindWithIncorrectId() throws Exception {
+        try {
+            jcloudsLocation.rebindMachine(ImmutableMap.of("id", "incorrectid", "hostname", "myhostname", "user", "myusername"));
+        } catch (IllegalArgumentException e) {
+            if (e.getMessage().contains("node not found")) {
+                // success
+            } else {
+                throw e;
+            }
+        }
+    }
+    
+    @Test(groups = { "Live" })
+    public void testRebindVm() throws Exception {
+        // FIXME How to create a machine - go directly through jclouds instead?
+        //       Going through LocationRegistry.resolve, loc and loc2 might be same instance
+        
+        // Create a VM through jclouds
+        JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID, "imageOwner", IMAGE_OWNER));
+        assertTrue(machine.isSshable());
+        LOG.info("obtained "+machine);
+
+        String id = checkNotNull(machine.getJcloudsId(), "id");
+        InetAddress address = checkNotNull(machine.getAddress(), "address");
+        String hostname = checkNotNull(address.getHostName(), "hostname");
+        String user = checkNotNull(machine.getUser(), "user");
+        
+        // Create a new jclouds location, and re-bind the existing VM to that
+        JcloudsLocation loc2 = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
+        SshMachineLocation machine2 = loc2.rebindMachine(ImmutableMap.of("id", id, "hostname", hostname, "user", user));
+        
+        LOG.info("rebinded to "+machine2);
+        
+        // Confirm the re-bound machine is wired up
+        assertTrue(machine2.isSshable());
+        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), ImmutableSet.of(machine2));
+        
+        // Confirm can release the re-bound machine via the new jclouds location
+        loc2.release(machine2);
+        assertFalse(machine.isSshable());
+        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), Collections.emptySet());
+    }
+    
+    @Test(groups = { "Live" })
+    public void testRebindVmDeprecated() throws Exception {
+        // FIXME See comments in testRebindVm
+
+        // Create a VM through jclouds
+        JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID, "imageOwner", IMAGE_OWNER));
+        assertTrue(machine.isSshable());
+
+        String id = machine.getJcloudsId();
+        InetAddress address = machine.getAddress();
+        String hostname = address.getHostName();
+        String username = machine.getUser();
+        
+        // Create a new jclouds location, and re-bind the existing VM to that
+        JcloudsLocation loc2 = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
+        // pass deprecated userName
+        SshMachineLocation machine2 = loc2.rebindMachine(ImmutableMap.of("id", id, "hostname", hostname, "userName", username));
+        
+        // Confirm the re-bound machine is wired up
+        assertTrue(machine2.isSshable());
+        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), ImmutableSet.of(machine2));
+        
+        // Confirm can release the re-bound machine via the new jclouds location
+        loc2.release(machine2);
+        assertFalse(machine.isSshable());
+        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), Collections.emptySet());
+    }
+
+    // Useful for debugging; accesss a hard-coded existing instance so don't need to wait for provisioning a new one
+    @Test(enabled=false, groups = { "Live" })
+    public void testRebindVmToHardcodedInstance() throws Exception {
+        String id = "eu-west-1/i-5504f21d";
+        InetAddress address = InetAddress.getByName("ec2-176-34-93-58.eu-west-1.compute.amazonaws.com");
+        String hostname = address.getHostName();
+        String username = "root";
+        
+        SshMachineLocation machine = jcloudsLocation.rebindMachine(ImmutableMap.of("id", id, "hostname", hostname, "userName", username));
+        
+        // Confirm the re-bound machine is wired up
+        assertTrue(machine.isSshable());
+        assertEquals(ImmutableSet.copyOf(jcloudsLocation.getChildren()), ImmutableSet.of(machine));
+    }
+}


[29/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/entity/trait/StartableMethodsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/trait/StartableMethodsTest.java b/core/src/test/java/brooklyn/entity/trait/StartableMethodsTest.java
index 640cc2f..1a3537d 100644
--- a/core/src/test/java/brooklyn/entity/trait/StartableMethodsTest.java
+++ b/core/src/test/java/brooklyn/entity/trait/StartableMethodsTest.java
@@ -30,7 +30,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.FailingEntity.RecordingEventListener;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.task.Tasks;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java b/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
index ad4a1f3..6683bdd 100644
--- a/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
+++ b/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
@@ -48,8 +48,8 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.EntityInternal.FeedSupport;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java b/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java
index a5c5420..b2f3ef8 100644
--- a/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java
+++ b/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java
@@ -34,9 +34,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.test.Asserts;
 import brooklyn.test.HttpService;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java b/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
index 671251f..a1d0851 100644
--- a/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
+++ b/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
@@ -44,7 +44,7 @@ import brooklyn.entity.basic.EntityInternal.FeedSupport;
 import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.FeedConfig;
 import brooklyn.event.feed.PollConfig;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/event/feed/shell/ShellFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/shell/ShellFeedIntegrationTest.java b/core/src/test/java/brooklyn/event/feed/shell/ShellFeedIntegrationTest.java
index 600478f..1e39212 100644
--- a/core/src/test/java/brooklyn/event/feed/shell/ShellFeedIntegrationTest.java
+++ b/core/src/test/java/brooklyn/event/feed/shell/ShellFeedIntegrationTest.java
@@ -42,7 +42,7 @@ import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.function.FunctionFeedTest;
 import brooklyn.event.feed.ssh.SshPollValue;
 import brooklyn.event.feed.ssh.SshValueFunctions;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.stream.Streams;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/event/feed/ssh/SshFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/ssh/SshFeedIntegrationTest.java b/core/src/test/java/brooklyn/event/feed/ssh/SshFeedIntegrationTest.java
index 10aefd2..40a7d65 100644
--- a/core/src/test/java/brooklyn/event/feed/ssh/SshFeedIntegrationTest.java
+++ b/core/src/test/java/brooklyn/event/feed/ssh/SshFeedIntegrationTest.java
@@ -40,8 +40,8 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.EntityInternal.FeedSupport;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.stream.Streams;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
index d5d3b63..7ecba77 100644
--- a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
+++ b/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
@@ -30,9 +30,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java b/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java
index a48b662..33b8934 100644
--- a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java
+++ b/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java
@@ -39,8 +39,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.text.Strings;
 import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/access/PortForwardManagerLocationResolverTest.java b/core/src/test/java/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
deleted file mode 100644
index a737cd1..0000000
--- a/core/src/test/java/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.management.internal.LocalManagementContext;
-
-public class PortForwardManagerLocationResolverTest {
-
-    private LocalManagementContext managementContext;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testReturnsSameInstanceBasedOnScope() {
-        Location global1 = resolve("portForwardManager()"); // defaults to global
-        Location global2 = resolve("portForwardManager()");
-        Location global3 = resolve("portForwardManager(scope=global)");
-        assertSame(global1, global2);
-        assertSame(global1, global3);
-        
-        Location a1 = resolve("portForwardManager(scope=a)");
-        Location a2 = resolve("portForwardManager(scope=a)");
-        assertSame(a1, a2);
-        assertNotSame(global1, a1);
-        
-        Location b1 = resolve("portForwardManager(scope=b)");
-        assertNotSame(global1, b1);
-        assertNotSame(a1, b1);
-    }
-
-    private Location resolve(String val) {
-        Location l = managementContext.getLocationRegistry().resolve(val);
-        Assert.assertNotNull(l);
-        return l;
-    }
-    
-    private void assertSame(Location loc1, Location loc2) {
-        Assert.assertNotNull(loc1);
-        Assert.assertTrue(loc1 instanceof PortForwardManager, "loc1="+loc1);
-        Assert.assertSame(loc1, loc2);
-    }
-    
-    private void assertNotSame(Location loc1, Location loc2) {
-        Assert.assertNotNull(loc1);
-        Assert.assertNotNull(loc2);
-        Assert.assertTrue(loc1 instanceof PortForwardManager, "loc1="+loc1);
-        Assert.assertTrue(loc2 instanceof PortForwardManager, "loc2="+loc2);
-        Assert.assertNotSame(loc1, loc2);
-        Assert.assertNotEquals(((PortForwardManager)loc1).getId(), ((PortForwardManager)loc2).getId());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java b/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java
deleted file mode 100644
index 5d8f029..0000000
--- a/core/src/test/java/brooklyn/location/access/PortForwardManagerRebindTest.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotEquals;
-
-import java.io.File;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.event.AttributeSensor;
-import org.apache.brooklyn.api.management.ha.MementoCopyMode;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.apache.brooklyn.test.entity.TestEntityImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.rebind.RebindOptions;
-import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
-import brooklyn.entity.rebind.persister.FileBasedObjectStore;
-import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.net.Networking;
-import brooklyn.util.os.Os;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.time.Time;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-import com.google.common.net.HostAndPort;
-
-public class PortForwardManagerRebindTest extends RebindTestFixtureWithApp {
-
-    private static final Logger log = LoggerFactory.getLogger(PortForwardManagerRebindTest.class);
-
-    private String machineAddress = "1.2.3.4";
-    private SshMachineLocation origSimulatedMachine;
-
-    @Override
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        super.setUp();
-
-        origSimulatedMachine = origManagementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", Networking.getInetAddressWithFixedName(machineAddress))
-                .configure("port", 1234)
-                .configure("user", "myuser"));
-    }
-    
-    @Test
-    public void testAssociationPreservedOnRebind() throws Exception {
-        String publicIpId = "5.6.7.8";
-        String publicAddress = "5.6.7.8";
-
-        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
-        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
-
-        // We first wait for persisted, to ensure that it is the PortForwardManager.onChanged that is causing persistence.
-        RebindTestUtils.waitForPersisted(origApp);
-        origPortForwardManager.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), origSimulatedMachine, 80);
-     
-        newApp = rebind();
-        
-        // After rebind, confirm that lookups still work
-        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
-        Location newSimulatedMachine = newApp.getManagementContext().getLocationManager().getLocation(origSimulatedMachine.getId());
-        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
-        
-        assertEquals(newPortForwardManager.lookup(newSimulatedMachine, 80), HostAndPort.fromParts(publicAddress, 40080));
-        assertEquals(newPortForwardManager.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
-    }
-    
-    @Test
-    public void testAssociationPreservedOnStateExport() throws Exception {
-        String publicIpId = "5.6.7.8";
-        String publicAddress = "5.6.7.8";
-
-        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
-        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
-
-        origPortForwardManager.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), origSimulatedMachine, 80);
-
-        String label = origManagementContext.getManagementNodeId()+"-"+Time.makeDateSimpleStampString();
-        PersistenceObjectStore targetStore = BrooklynPersistenceUtils.newPersistenceObjectStore(origManagementContext, null, 
-            "tmp/web-persistence-"+label+"-"+Identifiers.makeRandomId(4));
-        File dir = ((FileBasedObjectStore)targetStore).getBaseDir();
-        // only register the parent dir because that will prevent leaks for the random ID
-        Os.deleteOnExitEmptyParentsUpTo(dir.getParentFile(), dir.getParentFile());
-        BrooklynPersistenceUtils.writeMemento(origManagementContext, targetStore, MementoCopyMode.LOCAL);            
-
-        RebindTestUtils.waitForPersisted(origApp);
-        log.info("Using manual export dir "+dir+" for rebind instead of "+mementoDir);
-        newApp = rebind(RebindOptions.create().mementoDir(dir));
-        
-        // After rebind, confirm that lookups still work
-        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
-        Location newSimulatedMachine = newApp.getManagementContext().getLocationManager().getLocation(origSimulatedMachine.getId());
-        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
-        
-        assertEquals(newPortForwardManager.lookup(newSimulatedMachine, 80), HostAndPort.fromParts(publicAddress, 40080));
-        assertEquals(newPortForwardManager.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
-        
-        // delete the dir here, to be more likely not to leak it on failure
-        newManagementContext.getRebindManager().stop();
-        Os.deleteRecursively(dir);
-    }
-    
-    @Test
-    public void testAssociationPreservedOnRebindLegacy() throws Exception {
-        String publicIpId = "5.6.7.8";
-        String publicAddress = "5.6.7.8";
-
-        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
-        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
-
-        // We first wait for persisted, to ensure that it is the PortForwardManager.onChanged that is causing persistence.
-        RebindTestUtils.waitForPersisted(origApp);
-        origPortForwardManager.recordPublicIpHostname(publicIpId, publicAddress);
-        origPortForwardManager.acquirePublicPortExplicit(publicIpId, 40080);
-        origPortForwardManager.associate(publicIpId, 40080, origSimulatedMachine, 80);
-     
-        newApp = rebind();
-        
-        // After rebind, confirm that lookups still work
-        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
-        Location newSimulatedMachine = newApp.getManagementContext().getLocationManager().getLocation(origSimulatedMachine.getId());
-        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
-        
-        assertEquals(newPortForwardManager.getPublicIpHostname(publicIpId), publicAddress);
-        assertEquals(newPortForwardManager.lookup(newSimulatedMachine, 80), HostAndPort.fromParts(publicAddress, 40080));
-        assertEquals(newPortForwardManager.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
-    }
-    
-    @Test
-    public void testAcquirePortCounterPreservedOnRebindLegacy() throws Exception {
-        String publicIpId = "5.6.7.8";
-
-        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
-        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
-
-        // We first wait for persisted, to ensure that it is the PortForwardManager.onChanged that is causing persistence.
-        RebindTestUtils.waitForPersisted(origApp);
-        int acquiredPort = origPortForwardManager.acquirePublicPort(publicIpId);
-     
-        newApp = rebind();
-        
-        // After rebind, confirm that lookups still work
-        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
-        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
-        
-        int acquiredPort2 = newPortForwardManager.acquirePublicPort(publicIpId);
-        assertNotEquals(acquiredPort, acquiredPort2);
-    }
-    
-    public static class MyEntity extends TestEntityImpl {
-        public static final ConfigKey<PortForwardManager> PORT_FORWARD_MANAGER = ConfigKeys.newConfigKey(PortForwardManager.class, "myentity.portForwardManager");
-        public static final AttributeSensor<PortForwardManager> PORT_FORWARD_MANAGER_LIVE = Sensors.newSensor(PortForwardManager.class, "myentity.portForwardManager.live");
-
-        @Override
-        public void init() {
-            super.init();
-            
-            if (getConfig(PORT_FORWARD_MANAGER) == null) {
-                PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
-                setAttribute(PORT_FORWARD_MANAGER_LIVE, pfm);
-                setConfig(PORT_FORWARD_MANAGER, pfm);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/access/PortForwardManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/access/PortForwardManagerTest.java b/core/src/test/java/brooklyn/location/access/PortForwardManagerTest.java
deleted file mode 100644
index bf1ce2a..0000000
--- a/core/src/test/java/brooklyn/location/access/PortForwardManagerTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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 brooklyn.location.access;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertNull;
-
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.net.Networking;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.net.HostAndPort;
-
-public class PortForwardManagerTest extends BrooklynAppUnitTestSupport {
-
-    private static final Logger log = LoggerFactory.getLogger(PortForwardManagerTest.class);
-
-    private Map<HostAndPort, HostAndPort> portMapping;
-    private SshMachineLocation machine1;
-    private SshMachineLocation machine2;
-    private PortForwardManager pfm;
-    
-    @Override
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        super.setUp();
-
-        pfm = (PortForwardManager) mgmt.getLocationRegistry().resolve("portForwardManager(scope=global)");
-
-        machine1 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", Networking.getInetAddressWithFixedName("1.2.3.4"))
-                .configure("port", 1234)
-                .configure("user", "myuser"));
-        machine2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", Networking.getInetAddressWithFixedName("1.2.3.5"))
-                .configure("port", 1234)
-                .configure("user", "myuser"));
-    }
-    
-    @Test
-    public void testAssociateWithLocation() throws Exception {
-        String publicIpId = "myipid";
-        String publicAddress = "5.6.7.8";
-
-        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80);
-     
-        assertEquals(pfm.lookup(machine1, 80), HostAndPort.fromParts(publicAddress, 40080));
-        assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
-    }
-    
-    @Test
-    public void testAssociateWithoutLocation() throws Exception {
-        String publicIpId = "myipid";
-        String publicAddress = "5.6.7.8";
-
-        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), 80);
-     
-        assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
-        assertNull(pfm.lookup(machine1, 80));
-    }
-    
-    @Test
-    public void testAcquirePortDoesNotReturnDuplicate() throws Exception {
-        String publicIpId = "myipid";
-
-        int port1 = pfm.acquirePublicPort(publicIpId);
-        int port2 = pfm.acquirePublicPort(publicIpId);
-        assertNotEquals(port1, port2);
-    }
-    
-    @Test
-    public void testAcquirePortRespectsStartingPortNumber() throws Exception {
-        BrooklynProperties props = BrooklynProperties.Factory.newEmpty();
-        props.put(PortForwardManager.PORT_FORWARD_MANAGER_STARTING_PORT, 1234);
-        LocalManagementContextForTests mgmt2 = new LocalManagementContextForTests(props);
-        try {
-            PortForwardManager pfm2 = (PortForwardManager) mgmt2.getLocationRegistry().resolve("portForwardManager(scope=global)");
-            int port = pfm2.acquirePublicPort("myipid");
-            assertEquals(port, 1234);
-        } finally {
-            Entities.destroyAll(mgmt2);
-        }
-    }
-    
-    @Test
-    public void testForgetPortMapping() throws Exception {
-        String publicIpId = "myipid";
-        String publicAddress = "5.6.7.8";
-
-        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80);
-        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40081), machine1, 81);
-        pfm.forgetPortMapping(publicIpId, 40080);
-        
-        assertNull(pfm.lookup(publicIpId, 80));
-        assertNull(pfm.lookup(machine1, 80));
-        assertEquals(pfm.lookup(publicIpId, 81), HostAndPort.fromParts(publicAddress, 40081));
-        assertEquals(pfm.lookup(publicIpId, 81), HostAndPort.fromParts(publicAddress, 40081));
-    }
-    
-    @Test
-    public void testForgetPortMappingsOfMachine() throws Exception {
-        String publicIpId = "myipid";
-        String publicIpId2 = "myipid2";
-        String publicAddress = "5.6.7.8";
-
-        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80);
-        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40081), machine1, 81);
-        pfm.associate(publicIpId2, HostAndPort.fromParts(publicAddress, 40082), machine2, 80);
-        pfm.forgetPortMappings(machine1);
-        
-        assertNull(pfm.lookup(machine1, 80));
-        assertNull(pfm.lookup(machine1, 81));
-        assertNull(pfm.lookup(publicIpId, 80));
-        assertEquals(pfm.lookup(machine2, 80), HostAndPort.fromParts(publicAddress, 40082));
-    }
-    
-    @Test
-    public void testAssociateLegacy() throws Exception {
-        String publicIpId = "myipid";
-        String publicAddress = "5.6.7.8";
-
-        pfm.acquirePublicPortExplicit(publicIpId, 40080);
-        pfm.recordPublicIpHostname(publicIpId, publicAddress);
-        pfm.associate(publicIpId, 40080, machine1, 80);
-        
-        assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
-        assertEquals(pfm.lookup(machine1, 80), HostAndPort.fromParts(publicAddress, 40080));
-    }
-
-    @Test
-    public void testAssociationListeners() throws Exception {
-        final AtomicInteger associationCreatedCount = new AtomicInteger(0);
-        final AtomicInteger associationDeletedCount = new AtomicInteger(0);
-
-        final String publicIpId = "myipid";
-        final String anotherIpId = "anotherIpId";
-
-        pfm.addAssociationListener(new PortForwardManager.AssociationListener() {
-            @Override
-            public void onAssociationCreated(PortForwardManager.AssociationMetadata metadata) {
-                associationCreatedCount.incrementAndGet();
-            }
-
-            @Override
-            public void onAssociationDeleted(PortForwardManager.AssociationMetadata metadata) {
-                associationDeletedCount.incrementAndGet();
-            }
-        }, new Predicate<PortForwardManager.AssociationMetadata>() {
-            @Override
-            public boolean apply(PortForwardManager.AssociationMetadata metadata) {
-                return publicIpId.equals(metadata.getPublicIpId());
-            }
-        });
-
-        pfm.associate(publicIpId, HostAndPort.fromParts(publicIpId, 40080), machine1, 80);
-        pfm.associate(anotherIpId, HostAndPort.fromParts(anotherIpId, 40081), machine1, 80);
-        pfm.forgetPortMapping(publicIpId, 40080);
-        pfm.forgetPortMapping(anotherIpId, 40081);
-
-        assertEquals(associationCreatedCount.get(), 1);
-        assertEquals(associationDeletedCount.get(), 1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java b/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
deleted file mode 100644
index 30991ef..0000000
--- a/core/src/test/java/brooklyn/location/basic/AbstractLocationTest.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class AbstractLocationTest {
-
-    public static class ConcreteLocation extends AbstractLocation {
-        private static final long serialVersionUID = 3954199300889119970L;
-        @SetFromFlag(defaultVal="mydefault")
-        String myfield;
-
-        public ConcreteLocation() {
-            super();
-        }
-
-        public ConcreteLocation(Map<?,?> properties) {
-            super(properties);
-        }
-    }
-
-    private ManagementContext mgmt;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        mgmt = LocalManagementContextForTests.newInstance();
-    }
-    
-    @AfterMethod(alwaysRun = true)
-    public void tearDown(){
-        if (mgmt!=null) Entities.destroyAll(mgmt);
-    }
-
-    private ConcreteLocation createConcrete() {
-        return createConcrete(MutableMap.<String,Object>of());
-    }
-    private ConcreteLocation createConcrete(Map<String,?> flags) {
-        return createConcrete(null, flags);
-    }
-    @SuppressWarnings("deprecation")
-    private ConcreteLocation createConcrete(String id, Map<String,?> flags) {
-        return mgmt.getLocationManager().createLocation( LocationSpec.create(ConcreteLocation.class).id(id).configure(flags) );
-    }
-    
-    @Test
-    public void testEqualsUsesId() {
-        Location l1 = createConcrete("1", MutableMap.of("name", "bob"));
-        Location l1b = new ConcreteLocation(ImmutableMap.of("id", 1));
-        Location l2 = createConcrete("2", MutableMap.of("name", "frank"));
-        assertEquals(l1, l1b);
-        assertNotEquals(l1, l2);
-    }
-
-    @Test
-    public void nullNameAndParentLocationIsAcceptable() {
-        Location location = createConcrete(MutableMap.of("name", null, "parentLocation", null));
-        assertEquals(location.getDisplayName(), null);
-        assertEquals(location.getParent(), null);
-    }
-
-    @Test
-    public void testSettingParentLocation() {
-        Location location = createConcrete();
-        Location locationSub = createConcrete();
-        locationSub.setParent(location);
-        
-        assertEquals(ImmutableList.copyOf(location.getChildren()), ImmutableList.of(locationSub));
-        assertEquals(locationSub.getParent(), location);
-    }
-
-    @Test
-    public void testClearingParentLocation() {
-        Location location = createConcrete();
-        Location locationSub = createConcrete();
-        locationSub.setParent(location);
-        
-        locationSub.setParent(null);
-        assertEquals(ImmutableList.copyOf(location.getChildren()), Collections.emptyList());
-        assertEquals(locationSub.getParent(), null);
-    }
-    
-    @Test
-    public void testContainsLocation() {
-        Location location = createConcrete();
-        Location locationSub = createConcrete();
-        locationSub.setParent(location);
-        
-        assertTrue(location.containsLocation(location));
-        assertTrue(location.containsLocation(locationSub));
-        assertFalse(locationSub.containsLocation(location));
-    }
-
-
-    @Test
-    public void queryingNameReturnsNameGivenInConstructor() {
-        String name = "Outer Mongolia";
-        Location location = createConcrete(MutableMap.of("name", "Outer Mongolia"));
-        assertEquals(location.getDisplayName(), name);;
-    }
-
-    @Test
-    public void constructorParentLocationReturnsExpectedLocation() {
-        Location parent = createConcrete(MutableMap.of("name", "Middle Earth"));
-        Location child = createConcrete(MutableMap.of("name", "The Shire", "parentLocation", parent));
-        assertEquals(child.getParent(), parent);
-        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
-    }
-
-    @Test
-    public void setParentLocationReturnsExpectedLocation() {
-        Location parent = createConcrete(MutableMap.of("name", "Middle Earth"));
-        Location child = createConcrete(MutableMap.of("name", "The Shire"));
-        child.setParent(parent);
-        assertEquals(child.getParent(), parent);
-        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
-    }
-    
-    @Test
-    public void testAddChildToParentLocationReturnsExpectedLocation() {
-        ConcreteLocation parent = createConcrete();
-        Location child = createConcrete();
-        parent.addChild(child);
-        assertEquals(child.getParent(), parent);
-        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
-    }
-
-    @Test
-    public void testFieldSetFromFlag() {
-        ConcreteLocation loc = createConcrete(MutableMap.of("myfield", "myval"));
-        assertEquals(loc.myfield, "myval");
-    }
-    
-    @Test
-    public void testFieldSetFromFlagUsesDefault() {
-        ConcreteLocation loc = createConcrete();
-        assertEquals(loc.myfield, "mydefault");
-    }
-
-    @Test
-    public void testLocationTags() throws Exception {
-        LocationInternal loc = mgmt.getLocationManager().createLocation(LocationSpec.create(ConcreteLocation.class).tag("x"));
-        assertEquals(loc.tags().getTags(), MutableSet.of("x"));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java b/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
deleted file mode 100644
index 457a8b1..0000000
--- a/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-import java.util.Map;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
-import brooklyn.management.internal.LocalManagementContext;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class AggregatingMachineProvisioningLocationTest {
-
-    
-    private LocalManagementContext managementContext;
-    private AggregatingMachineProvisioningLocation<LocalhostMachine> aggregator;
-    private LocalhostMachine machine1a;
-    private LocalhostMachine machine1b;
-    private LocalhostMachine machine2a;
-    private LocalhostMachine machine2b;
-    private MachineProvisioningLocation<LocalhostMachine> provisioner1;
-    private MachineProvisioningLocation<LocalhostMachine> provisioner2;
-    
-    @BeforeMethod(alwaysRun=true)
-    @SuppressWarnings("unchecked")
-    public void setUp() {
-        managementContext = new LocalManagementContextForTests();
-        machine1a = newLocation(LocalhostMachine.class, "1a");
-        machine1b = newLocation(LocalhostMachine.class, "1b");
-        machine2a = newLocation(LocalhostMachine.class, "2a");
-        machine2b = newLocation(LocalhostMachine.class, "2b");
-        provisioner1 = newLocation(FixedListMachineProvisioningLocation.class, ImmutableMap.of("machines", ImmutableList.of(machine1a, machine1b)));
-        provisioner2 = newLocation(FixedListMachineProvisioningLocation.class, ImmutableMap.of("machines", ImmutableList.of(machine2a, machine2b)));
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testObtainAndRelease() throws Exception {
-        aggregator = newLocation(AggregatingMachineProvisioningLocation.class, ImmutableMap.of("provisioners", ImmutableList.of(provisioner1, provisioner2)));
-        assertEquals(aggregator.obtain(), machine1a);
-        assertEquals(aggregator.obtain(), machine2a);
-        assertEquals(aggregator.obtain(), machine1b);
-        assertEquals(aggregator.obtain(), machine2b);
-        
-        try {
-            aggregator.obtain();
-            fail();
-        } catch (NoMachinesAvailableException e) {
-            // success
-        }
-        
-        aggregator.release(machine2b);
-        assertEquals(aggregator.obtain(), machine2b);
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testReleaseWhenNotHeldThrows() throws Exception {
-        aggregator = newLocation(AggregatingMachineProvisioningLocation.class, ImmutableMap.of("provisioners", ImmutableList.of(provisioner1, provisioner2)));
-        try {
-            aggregator.release(machine1a);
-            fail();
-        } catch (IllegalStateException e) {
-            if (!e.toString().contains("machine is not currently allocated")) throw e;
-        }
-    }
-
-    private <T extends Location> T newLocation(Class<T> clazz, String displayName) {
-        return newLocation(clazz, displayName, ImmutableMap.of());
-    }
-
-    private <T extends Location> T newLocation(Class<T> clazz, Map<?,?> config) {
-        return newLocation(clazz, "mydisplayname", config);
-    }
-    
-    private <T extends Location> T newLocation(Class<T> clazz, String displayName, Map<?,?> config) {
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(clazz)
-                .displayName(displayName)
-                .configure(config));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java b/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java
deleted file mode 100644
index 603050d..0000000
--- a/core/src/test/java/brooklyn/location/basic/ByonLocationResolverTest.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.net.InetAddress;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Networking;
-import brooklyn.util.net.UserAndHostAndPort;
-import brooklyn.util.os.Os;
-import brooklyn.util.text.StringPredicates;
-
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-public class ByonLocationResolverTest {
-
-    private static final Logger log = LoggerFactory.getLogger(ByonLocationResolverTest.class);
-    
-    private BrooklynProperties brooklynProperties;
-    private LocalManagementContext managementContext;
-    private Predicate<CharSequence> defaultNamePredicate;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-        brooklynProperties = managementContext.getBrooklynProperties();
-        defaultNamePredicate = StringPredicates.startsWith(FixedListMachineProvisioningLocation.class.getSimpleName());
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testTakesByonScopedProperties() {
-        brooklynProperties.put("brooklyn.location.byon.privateKeyFile", "myprivatekeyfile");
-        brooklynProperties.put("brooklyn.location.byon.publicKeyFile", "mypublickeyfile");
-        brooklynProperties.put("brooklyn.location.byon.privateKeyData", "myprivateKeyData");
-        brooklynProperties.put("brooklyn.location.byon.publicKeyData", "myPublicKeyData");
-        brooklynProperties.put("brooklyn.location.byon.privateKeyPassphrase", "myprivateKeyPassphrase");
-
-        Map<String, Object> conf = resolve("byon(hosts=\"1.1.1.1\")").config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
-        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
-        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
-        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
-        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
-    }
-
-    @Test
-    public void testNamedByonLocation() throws Exception {
-        brooklynProperties.put("brooklyn.location.named.mynamed", "byon(hosts=\"1.1.1.1\")");
-        
-        FixedListMachineProvisioningLocation<MachineLocation> loc = resolve("named:mynamed");
-        assertEquals(loc.obtain().getAddress(), InetAddress.getByName("1.1.1.1"));
-    }
-
-    @Test
-    public void testPropertiesInSpec() throws Exception {
-        FixedListMachineProvisioningLocation<MachineLocation> loc = resolve("byon(privateKeyFile=myprivatekeyfile,hosts=\"1.1.1.1\")");
-        SshMachineLocation machine = (SshMachineLocation)loc.obtain();
-        
-        assertEquals(machine.config().getBag().getStringKey("privateKeyFile"), "myprivatekeyfile");
-        assertEquals(machine.getAddress(), Networking.getInetAddressWithFixedName("1.1.1.1"));
-    }
-
-    @Test
-    public void testPropertyScopePrecedence() throws Exception {
-        brooklynProperties.put("brooklyn.location.named.mynamed", "byon(hosts=\"1.1.1.1\")");
-        
-        // prefer those in "named" over everything else
-        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
-        brooklynProperties.put("brooklyn.location.byon.privateKeyFile", "privateKeyFile-inProviderSpecific");
-        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
-
-        // prefer those in provider-specific over generic
-        brooklynProperties.put("brooklyn.location.byon.publicKeyFile", "publicKeyFile-inProviderSpecific");
-        brooklynProperties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inGeneric");
-
-        // prefer location-generic if nothing else
-        brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
-
-        Map<String, Object> conf = resolve("named:mynamed").config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
-        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
-        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
-    }
-
-    @Test
-    public void testThrowsOnInvalid() throws Exception {
-        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
-        assertThrowsIllegalArgument("byon"); // no hosts
-        assertThrowsIllegalArgument("byon()"); // no hosts
-        assertThrowsIllegalArgument("byon(hosts=\"\")"); // empty hosts
-        assertThrowsIllegalArgument("byon(hosts=\"1.1.1.1\""); // no closing bracket
-        assertThrowsIllegalArgument("byon(hosts=\"1.1.1.1\", name)"); // no value for name
-        assertThrowsIllegalArgument("byon(hosts=\"1.1.1.1\", name=)"); // no value for name
-    }
-    
-    @Test(expectedExceptions={IllegalArgumentException.class})
-    public void testRegistryCommaResolutionInListNotAllowed() throws NoMachinesAvailableException {
-        // disallowed since 0.7.0
-        // fails because it interprets the entire string as a single byon spec, which does not parse
-        managementContext.getLocationRegistry().resolve(ImmutableList.of("byon(hosts=\"192.168.0.1\",user=bob),byon(hosts=\"192.168.0.2\",user=bob2)"));
-    }
-
-    @Test
-    public void testResolvesHosts() throws Exception {
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1\")"), ImmutableSet.of("1.1.1.1"));
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1\")"), ImmutableSet.of("1.1.1.1"));
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1,1.1.1.2\")"), ImmutableSet.of("1.1.1.1","1.1.1.2"));
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1, 1.1.1.2\")"), ImmutableSet.of("1.1.1.1","1.1.1.2"));
-    }
-
-    @Test
-    public void testWithOldStyleColon() throws Exception {
-        assertByonClusterEquals(resolve("byon:(hosts=\"1.1.1.1\")"), ImmutableSet.of("1.1.1.1"));
-        assertByonClusterEquals(resolve("byon:(hosts=\"1.1.1.1\", name=myname)"), ImmutableSet.of("1.1.1.1"), "myname");
-    }
-
-    @Test
-    public void testUsesDisplayName() throws Exception {
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1\", name=myname)"), ImmutableSet.of("1.1.1.1"), "myname");
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1\", name=\"myname\")"), ImmutableSet.of("1.1.1.1"), "myname");
-    }
-
-    @Test
-    public void testResolvesHostsGlobExpansion() throws Exception {
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.{1,2}\")"), ImmutableSet.of("1.1.1.1","1.1.1.2"));
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.{1.1,2.{1,2}}\")"), 
-                ImmutableSet.of("1.1.1.1","1.1.2.1","1.1.2.2"));
-        assertByonClusterEquals(resolve("byon(hosts=\"1.1.{1,2}.{1,2}\")"), 
-                ImmutableSet.of("1.1.1.1","1.1.1.2","1.1.2.1","1.1.2.2"));
-    }
-
-    @Test(groups="Integration")
-    public void testNiceError() throws Exception {
-        Asserts.assertFailsWith(new Runnable() {
-            @Override public void run() {
-                FixedListMachineProvisioningLocation<MachineLocation> x =
-                        resolve("byon(hosts=\"1.1.1.{1,2}}\")");
-                log.error("got "+x+" but should have failed (your DNS is giving an IP for hostname '1.1.1.1}' (with the extra '}')");
-            }
-        }, new Predicate<Throwable>() {
-            @Override
-            public boolean apply(@Nullable Throwable input) {
-                String s = input.toString();
-                // words
-                if (!s.contains("Invalid host")) return false;
-                // problematic entry
-                if (!s.contains("1.1.1.1}")) return false;
-                // original spec
-                if (!s.contains("1.1.1.{1,2}}")) return false;
-                return true;
-            }
-        });
-    }
-
-    @Test
-    public void testResolvesUsernameAtHost() throws Exception {
-        assertByonClusterWithUsersEquals(resolve("byon(hosts=\"myuser@1.1.1.1\")"), 
-                ImmutableSet.of(UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 22)));
-        assertByonClusterWithUsersEquals(resolve("byon(hosts=\"myuser@1.1.1.1,myuser2@1.1.1.1\")"), ImmutableSet.of(
-                UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 22), UserAndHostAndPort.fromParts("myuser2", "1.1.1.1", 22)));
-        assertByonClusterWithUsersEquals(resolve("byon(hosts=\"myuser@1.1.1.1,myuser2@1.1.1.2\")"), ImmutableSet.of(
-                UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 22), UserAndHostAndPort.fromParts("myuser2", "1.1.1.2", 22)));
-    }
-
-    @Test
-    public void testResolvesUserArg() throws Exception {
-        assertByonClusterWithUsersEquals(resolve("byon(hosts=\"1.1.1.1\",user=bob)"), 
-                ImmutableSet.of(UserAndHostAndPort.fromParts("bob", "1.1.1.1", 22)));
-        assertByonClusterWithUsersEquals(resolve("byon(user=\"bob\",hosts=\"myuser@1.1.1.1,1.1.1.1\")"), 
-                ImmutableSet.of(UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 22), UserAndHostAndPort.fromParts("bob", "1.1.1.1", 22)));
-    }
-
-    @Test
-    public void testResolvesUserArg2() throws Exception {
-        String spec = "byon(hosts=\"1.1.1.1\",user=bob)";
-        FixedListMachineProvisioningLocation<MachineLocation> ll = resolve(spec);
-        SshMachineLocation l = (SshMachineLocation)ll.obtain();
-        Assert.assertEquals("bob", l.getUser());
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testResolvesUserArg3() throws Exception {
-        String spec = "byon(hosts=\"1.1.1.1\")";
-        managementContext.getLocationRegistry().getProperties().putAll(MutableMap.of(
-                "brooklyn.location.named.foo", spec,
-                "brooklyn.location.named.foo.user", "bob"));
-        ((BasicLocationRegistry)managementContext.getLocationRegistry()).updateDefinedLocations();
-        
-        MachineProvisioningLocation<SshMachineLocation> ll = (MachineProvisioningLocation<SshMachineLocation>) 
-                new NamedLocationResolver().newLocationFromString(MutableMap.of(), "named:foo", managementContext.getLocationRegistry());
-        SshMachineLocation l = ll.obtain(MutableMap.of());
-        Assert.assertEquals("bob", l.getUser());
-    }
-
-    @Test
-    public void testResolvesPortArg() throws Exception {
-        assertByonClusterWithUsersEquals(resolve("byon(user=bob,port=8022,hosts=\"1.1.1.1\")"), 
-                ImmutableSet.of(UserAndHostAndPort.fromParts("bob", "1.1.1.1", 8022)));
-        assertByonClusterWithUsersEquals(resolve("byon(user=bob,port=8022,hosts=\"myuser@1.1.1.1,1.1.1.2:8901\")"), 
-                ImmutableSet.of(UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 8022), UserAndHostAndPort.fromParts("bob", "1.1.1.2", 8901)));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    /** private key should be inherited, so confirm that happens correctly */
-    public void testResolvesPrivateKeyArgInheritance() throws Exception {
-        String spec = "byon(hosts=\"1.1.1.1\")";
-        managementContext.getLocationRegistry().getProperties().putAll(MutableMap.of(
-                "brooklyn.location.named.foo", spec,
-                "brooklyn.location.named.foo.user", "bob",
-                "brooklyn.location.named.foo.privateKeyFile", "/tmp/x"));
-        ((BasicLocationRegistry)managementContext.getLocationRegistry()).updateDefinedLocations();
-        
-        MachineProvisioningLocation<SshMachineLocation> ll = (MachineProvisioningLocation<SshMachineLocation>) 
-                new NamedLocationResolver().newLocationFromString(MutableMap.of(), "named:foo", managementContext.getLocationRegistry());
-        
-        Assert.assertEquals("/tmp/x", ll.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE));
-        Assert.assertTrue(((LocationInternal)ll).config().getLocalRaw(LocationConfigKeys.PRIVATE_KEY_FILE).isPresent());
-        Assert.assertEquals("/tmp/x", ((LocationInternal)ll).config().getLocalBag().getStringKey(LocationConfigKeys.PRIVATE_KEY_FILE.getName()));
-        Assert.assertEquals("/tmp/x", ((LocationInternal)ll).config().getBag().get(LocationConfigKeys.PRIVATE_KEY_FILE));
-
-        SshMachineLocation l = ll.obtain(MutableMap.of());
-        
-        Assert.assertEquals("/tmp/x", l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE));
-        
-        Assert.assertTrue(l.config().getRaw(LocationConfigKeys.PRIVATE_KEY_FILE).isPresent());
-        Assert.assertTrue(l.config().getLocalRaw(LocationConfigKeys.PRIVATE_KEY_FILE).isAbsent());
-
-        Assert.assertEquals("/tmp/x", l.config().getBag().getStringKey(LocationConfigKeys.PRIVATE_KEY_FILE.getName()));
-        Assert.assertEquals("/tmp/x", l.config().getBag().getStringKey(LocationConfigKeys.PRIVATE_KEY_FILE.getName()));
-
-        Assert.assertEquals("/tmp/x", l.config().getBag().get(LocationConfigKeys.PRIVATE_KEY_FILE));
-    }
-
-    @Test
-    public void testResolvesLocalTempDir() throws Exception {
-        String localTempDir = Os.mergePaths(Os.tmp(), "testResolvesUsernameAtHost");
-        brooklynProperties.put("brooklyn.location.byon.localTempDir", localTempDir);
-
-        FixedListMachineProvisioningLocation<MachineLocation> byon = resolve("byon(hosts=\"1.1.1.1\",osFamily=\"windows\")");
-        MachineLocation machine = byon.obtain();
-        assertEquals(machine.getConfig(SshMachineLocation.LOCAL_TEMP_DIR), localTempDir);
-    }
-
-    @Test
-    public void testMachinesObtainedInOrder() throws Exception {
-        List<String> ips = ImmutableList.of("1.1.1.1", "1.1.1.6", "1.1.1.3", "1.1.1.4", "1.1.1.5");
-        String spec = "byon(hosts=\""+Joiner.on(",").join(ips)+"\")";
-        
-        MachineProvisioningLocation<MachineLocation> ll = resolve(spec);
-
-        for (String expected : ips) {
-            MachineLocation obtained = ll.obtain(ImmutableMap.of());
-            assertEquals(obtained.getAddress().getHostAddress(), expected);
-        }
-    }
-    
-    @Test
-    public void testEmptySpec() throws Exception {
-        String spec = "byon";
-        Map<String, ?> flags = ImmutableMap.of(
-                "hosts", ImmutableList.of("1.1.1.1", "2.2.2.22"),
-                "name", "foo",
-                "user", "myuser"
-        );
-        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
-        SshMachineLocation location1 = (SshMachineLocation)provisioner.obtain(ImmutableMap.of());
-        Assert.assertEquals("myuser", location1.getUser());
-        Assert.assertEquals("1.1.1.1", location1.getAddress().getHostAddress());
-    }
-
-    @Test
-    public void testWindowsMachines() throws Exception {
-        brooklynProperties.put("brooklyn.location.byon.user", "myuser");
-        brooklynProperties.put("brooklyn.location.byon.password", "mypassword");
-        String spec = "byon";
-        Map<String, ?> flags = ImmutableMap.of(
-                "hosts", ImmutableList.of("1.1.1.1", "2.2.2.2"),
-                "osfamily", "windows"
-        );
-        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
-        WinRmMachineLocation location = (WinRmMachineLocation) provisioner.obtain(ImmutableMap.of());
-
-        assertEquals(location.config().get(WinRmMachineLocation.USER), "myuser");
-        assertEquals(location.config().get(WinRmMachineLocation.PASSWORD), "mypassword");
-        assertEquals(location.config().get(WinRmMachineLocation.ADDRESS).getHostAddress(), "1.1.1.1");
-    }
-
-    @Test
-    public void testNoneWindowsMachines() throws Exception {
-        String spec = "byon";
-        Map<String, ?> flags = ImmutableMap.of(
-                "hosts", ImmutableList.of("1.1.1.1", "2.2.2.2"),
-                "osfamily", "linux"
-        );
-        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
-        MachineLocation location = provisioner.obtain(ImmutableMap.of());
-        assertTrue(location instanceof SshMachineLocation, "Expected location to be SshMachineLocation, found " + location);
-    }
-
-    @Test
-    public void testAdditionalConfig() throws Exception {
-        FixedListMachineProvisioningLocation<MachineLocation> loc = resolve("byon(mykey=myval,hosts=\"1.1.1.1\")");
-        MachineLocation machine = loc.obtain(ImmutableMap.of());
-        assertEquals(machine.getConfig(ConfigKeys.newConfigKey(String.class, "mykey")), "myval");
-    }
-
-    private void assertByonClusterEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<String> expectedHosts) {
-        assertByonClusterEquals(cluster, expectedHosts, defaultNamePredicate);
-    }
-    
-    private void assertByonClusterEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<String> expectedHosts, String expectedName) {
-        assertByonClusterEquals(cluster, expectedHosts, Predicates.equalTo(expectedName));
-    }
-    
-    private void assertByonClusterEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<String> expectedHosts, Predicate<? super String> expectedName) {
-        Set<String> actualHosts = ImmutableSet.copyOf(Iterables.transform(cluster.getMachines(), new Function<MachineLocation, String>() {
-            @Override public String apply(MachineLocation input) {
-                return input.getAddress().getHostName();
-            }}));
-        assertEquals(actualHosts, expectedHosts);
-        assertTrue(expectedName.apply(cluster.getDisplayName()), "name="+cluster.getDisplayName());
-    }
-
-    private void assertByonClusterWithUsersEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<UserAndHostAndPort> expectedHosts) {
-        assertByonClusterWithUsersEquals(cluster, expectedHosts, defaultNamePredicate);
-    }
-    
-    private void assertByonClusterWithUsersEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<UserAndHostAndPort> expectedHosts, Predicate<? super String> expectedName) {
-        Set<UserAndHostAndPort> actualHosts = ImmutableSet.copyOf(Iterables.transform(cluster.getMachines(), new Function<MachineLocation, UserAndHostAndPort>() {
-            @Override public UserAndHostAndPort apply(MachineLocation input) {
-                SshMachineLocation machine = (SshMachineLocation) input;
-                return UserAndHostAndPort.fromParts(machine.getUser(), machine.getAddress().getHostName(), machine.getPort());
-            }}));
-        assertEquals(actualHosts, expectedHosts);
-        assertTrue(expectedName.apply(cluster.getDisplayName()), "name="+cluster.getDisplayName());
-    }
-
-    private void assertThrowsNoSuchElement(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (NoSuchElementException e) {
-            // success
-        }
-    }
-    
-    private void assertThrowsIllegalArgument(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-    }
-    
-    @SuppressWarnings("unchecked")
-    private FixedListMachineProvisioningLocation<MachineLocation> resolve(String val) {
-        return (FixedListMachineProvisioningLocation<MachineLocation>) managementContext.getLocationRegistry().resolve(val);
-    }
-    
-    @SuppressWarnings("unchecked")
-    private FixedListMachineProvisioningLocation<MachineLocation> resolve(String val, Map<?, ?> locationFlags) {
-        return (FixedListMachineProvisioningLocation<MachineLocation>) managementContext.getLocationRegistry().resolve(val, locationFlags);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java b/core/src/test/java/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
deleted file mode 100644
index 3dcbe1e..0000000
--- a/core/src/test/java/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import java.io.File;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.location.Location;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.os.Os;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-public class FixedListMachineProvisioningLocationRebindTest {
-
-    private FixedListMachineProvisioningLocation<SshMachineLocation> origLoc;
-    private ClassLoader classLoader = getClass().getClassLoader();
-    private ManagementContext origManagementContext;
-    private TestApplication origApp;
-    private TestApplication newApp;
-    private File mementoDir;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        mementoDir = Os.newTempDir(getClass());
-        origManagementContext = RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
-        
-        origLoc = new FixedListMachineProvisioningLocation.Builder(origManagementContext.getLocationManager())
-                .addAddresses("localhost", "127.0.0.1")
-                .user("myuser")
-                .keyFile("/path/to/myPrivateKeyFile")
-                .keyData("myKeyData")
-                .keyPassphrase("myKeyPassphrase")
-                .build();
-        origApp = ApplicationBuilder.newManagedApp(TestApplication.class, origManagementContext);
-        origApp.start(ImmutableList.of(origLoc));
-    }
-
-    @AfterMethod(alwaysRun = true)
-    public void tearDown() throws Exception {
-        if (origManagementContext != null) Entities.destroyAll(origManagementContext);
-        if (newApp != null) Entities.destroyAll(newApp.getManagementContext());
-        if (mementoDir != null) RebindTestUtils.deleteMementoDir(mementoDir);
-    }
-    
-    @Test
-    public void testRebindPreservesConfig() throws Exception {
-        newApp = rebind();
-        FixedListMachineProvisioningLocation<SshMachineLocation> newLoc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(newApp.getLocations(), 0);
-        
-        assertEquals(newLoc.getId(), origLoc.getId());
-        assertEquals(newLoc.getDisplayName(), origLoc.getDisplayName());
-        assertEquals(newLoc.getHostGeoInfo(), origLoc.getHostGeoInfo());
-        assertEquals(newLoc.getConfig(LocationConfigKeys.USER), origLoc.getConfig(LocationConfigKeys.USER));
-        assertEquals(newLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE), origLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE));
-        assertEquals(newLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), origLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE));
-        assertEquals(newLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_DATA), origLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_DATA));
-    }
-
-    @Test
-    public void testRebindParentRelationship() throws Exception {
-        newApp = rebind();
-        FixedListMachineProvisioningLocation<SshMachineLocation> newLoc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(newApp.getLocations(), 0);
-        
-        assertLocationIdsEqual(newLoc.getChildren(), origLoc.getChildren());
-        assertEquals(Iterables.get(newLoc.getChildren(), 0).getParent(), newLoc);
-        assertEquals(Iterables.get(newLoc.getChildren(), 1).getParent(), newLoc);
-    }
-
-    @Test
-    public void testRebindPreservesInUseMachines() throws Exception {
-        SshMachineLocation inuseMachine = origLoc.obtain();
-        origApp.setAttribute(TestApplication.SERVICE_UP, true); // to force persist, and thus avoid race
-        
-        newApp = rebind();
-        FixedListMachineProvisioningLocation<SshMachineLocation> newLoc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(newApp.getLocations(), 0);
-        
-        assertLocationIdsEqual(newLoc.getInUse(), origLoc.getInUse());
-        assertLocationIdsEqual(newLoc.getAvailable(), origLoc.getAvailable());
-    }
-
-    private TestApplication rebind() throws Exception {
-        RebindTestUtils.waitForPersisted(origApp);
-        return (TestApplication) RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
-    }
-    
-    private void assertLocationIdsEqual(Iterable<? extends Location> actual, Iterable<? extends Location> expected) {
-        Function<Location, String> locationIdFunction = new Function<Location, String>() {
-            @Override public String apply(@Nullable Location input) {
-                return (input != null) ? input.getId() : null;
-            }
-        };
-        Set<String> actualIds = MutableSet.copyOf(Iterables.transform(actual, locationIdFunction));
-        Set<String> expectedIds = MutableSet.copyOf(Iterables.transform(expected, locationIdFunction));
-        
-        assertEquals(actualIds, expectedIds);
-    }
-}


[12/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
deleted file mode 100644
index 2d5d511..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.stream.Streams;
-
-/**
- * Tests that the correct address is advertised for the VM - for its public/private, 
- * its subnet hostname, etc.
- */
-public class JcloudsAddressesLiveTest extends AbstractJcloudsLiveTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsAddressesLiveTest.class);
-
-    public static final String AWS_EC2_REGION_NAME = AWS_EC2_USEAST_REGION_NAME;
-    public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + (AWS_EC2_REGION_NAME == null ? "" : ":" + AWS_EC2_REGION_NAME);
-    
-    // Image: {id=us-east-1/ami-7d7bfc14, providerId=ami-7d7bfc14, name=RightImage_CentOS_6.3_x64_v5.8.8.5, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=6.0, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, version=5.8.8.5, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
-    public static final String AWS_EC2_CENTOS_IMAGE_ID = "us-east-1/ami-7d7bfc14";
-
-    // Image: {id=us-east-1/ami-d0f89fb9, providerId=ami-d0f89fb9, name=ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=12.04, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, is64Bit=true}, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, version=20130411.1, status=AVAILABLE[available], loginUser=ubuntu, userMetadata={owner=099720109477, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
-    public static final String AWS_EC2_UBUNTU_IMAGE_ID = "us-east-1/ami-d0f89fb9";
-    
-    // Image: {id=us-east-1/ami-5e008437, providerId=ami-5e008437, name=RightImage_Ubuntu_10.04_x64_v5.8.8.3, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=10.04, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, version=5.8.8.3, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
-    // Uses "root" as loginUser
-    public static final String AWS_EC2_UBUNTU_10_IMAGE_ID = "us-east-1/ami-5e008437";
-
-    public static final String RACKSPACE_LOCATION_SPEC = "jclouds:" + RACKSPACE_PROVIDER;
-    
-    // Image: {id=LON/c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, providerId=c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, name=CentOS 6.0, location={scope=ZONE, id=LON, description=LON, parent=rackspace-cloudservers-uk, iso3166Codes=[GB-SLG]}, os={family=centos, name=CentOS 6.0, version=6.0, description=CentOS 6.0, is64Bit=true}, description=CentOS 6.0, status=AVAILABLE, loginUser=root, userMetadata={os_distro=centos, com.rackspace__1__visible_core=1, com.rackspace__1__build_rackconnect=1, com.rackspace__1__options=0, image_type=base, cache_in_nova=True, com.rackspace__1__source=kickstart, org.openstack__1__os_distro=org.centos, com.rackspace__1__release_build_date=2013-07-25_18-56-29, auto_disk_config=True, com.rackspace__1__release_version=5, os_type=linux, com.rackspace__1__visible_rackconnect=1, com.rackspace__1__release_id=210, com.rackspace__1__visible_managed=0, com.rackspace__1__build_core=1, org.openstack__1__os_version=6.0, org.openstack__1__architecture=x64, com.rackspace__1__build_ma
 naged=0}}
-    public static final String RACKSPACE_CENTOS_IMAGE_NAME_REGEX = "CentOS 6.0";
-    
-    protected JcloudsSshMachineLocation machine;
-    
-    @Test(groups = {"Live"})
-    protected void testAwsEc2Addresses() throws Exception {
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
-        
-        machine = createEc2Machine(ImmutableMap.<String,Object>of());
-        assertSshable(machine);
-
-        String locationAddress = machine.getAddress().getHostName();
-        InetAddress address = machine.getAddress();
-        Set<String> publicAddresses = machine.getPublicAddresses();
-        Set<String> privateAddresses = machine.getPrivateAddresses();
-        String subnetIp = machine.getSubnetIp();
-        String hostname = machine.getHostname();
-        String subnetHostname = machine.getSubnetHostname();
-        String msg = "locationAddress="+locationAddress+"; address="+address+"; publicAddrs="+publicAddresses+"; privateAddrs="+privateAddresses+"; subnetIp="+subnetIp+"; hostname="+hostname+"; subnetHostname="+subnetHostname;
-        LOG.info("node: "+msg);
-
-        // On AWS, machine advertises its FQ hostname that is accessible from inside and outside the region
-        assertReachable(machine, locationAddress, msg);
-        assertReachableFromMachine(machine, locationAddress, msg);
-
-        assertReachable(machine, address, msg);
-        
-        assertTrue(publicAddresses.size() > 0, msg);
-        for (String publicAddress: publicAddresses) {
-            assertReachable(machine, publicAddress, msg);
-        }
-        
-        // On AWS, private address is not reachable from outside.
-        // If you ran this test from the same AWS region, it would fail!
-        assertTrue(privateAddresses.size() > 0, msg);
-        for (String privateAddress: privateAddresses) {
-            assertReachableFromMachine(machine, privateAddress, msg);
-            assertNotReachable(machine, privateAddress, msg);
-        }
-        
-        assertNotNull(subnetIp, msg);
-        assertReachableFromMachine(machine, subnetIp, msg);
-
-        // hostname is reachable from inside; not necessarily reachable from outside
-        assertNotNull(hostname, msg);
-        assertReachableFromMachine(machine, hostname, msg);
-        
-        assertNotNull(subnetHostname, msg);
-        assertReachableFromMachine(machine, subnetHostname, msg);
-    }
-
-    @Test(groups = {"Live"})
-    protected void testRackspaceAddresses() throws Exception {
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
-        
-        machine = createRackspaceMachine(ImmutableMap.<String,Object>of());
-        assertSshable(machine);
-
-        String locationAddress = machine.getAddress().getHostAddress();
-        InetAddress address = machine.getAddress();
-        Set<String> publicAddresses = machine.getPublicAddresses();
-        Set<String> privateAddresses = machine.getPrivateAddresses();
-        String subnetIp = machine.getSubnetIp();
-        String hostname = machine.getHostname();
-        String subnetHostname = machine.getSubnetHostname();
-        String msg = "locationAddress="+locationAddress+"; address="+address+"; publicAddrs="+publicAddresses+"; privateAddrs="+privateAddresses+"; subnetIp="+subnetIp+"; hostname="+hostname+"; subnetHostname="+subnetHostname;
-        LOG.info("node: "+msg);
-
-        // On Rackspace, IP is accessible from inside and outside.
-        assertReachable(machine, locationAddress, msg);
-        assertReachableFromMachine(machine, locationAddress, msg);
-
-        assertReachable(machine, address, msg);
-        
-        assertTrue(publicAddresses.size() > 0, msg);
-        for (String publicAddress: publicAddresses) {
-            assertReachable(machine, publicAddress, msg);
-        }
-        
-        // On Rackspace, don't care if no private addresses
-        for (String privateAddress: privateAddresses) {
-            assertReachableFromMachine(machine, privateAddress, msg);
-            assertNotReachable(machine, privateAddress, msg);
-        }
-        
-        assertNotNull(subnetIp, msg);
-        assertReachableFromMachine(machine, subnetIp, msg);
-
-        // hostname is reachable from inside; not necessarily reachable from outside
-        assertNotNull(hostname, msg);
-        assertReachableFromMachine(machine, hostname, msg);
-        
-        assertNotNull(subnetHostname, msg);
-        assertReachableFromMachine(machine, subnetHostname, msg);
-    }
-
-    private void assertReachable(SshMachineLocation machine, InetAddress addr, String msg) {
-        assertReachable(machine, addr.getHostAddress(), msg);
-    }
-
-    private void assertReachable(SshMachineLocation machine, String addr, String msg) {
-        assertReachability(true, machine, addr, msg);
-    }
-    
-    private void assertNotReachable(SshMachineLocation machine, String addr, String msg) {
-        assertReachability(false, machine, addr, msg);
-    }
-
-    private void assertReachability(boolean expectedReachable, SshMachineLocation machine, String addr, String msg) {
-        SshMachineLocation tmpMachine = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure(machine.config().getBag().getAllConfig())
-                .configure("address", addr));
-        try {
-            boolean sshable = tmpMachine.isSshable();
-            assertEquals(sshable, expectedReachable, addr+" not sshable; "+msg);
-        } finally {
-            Locations.unmanage(tmpMachine);
-        }
-    }
-
-    // TODO Assumes that "ping" will work; i.e. that ICMP is not firewall'ed
-    private void assertReachableFromMachine(SshMachineLocation machine, String addr, String msg) {
-        OutputStream outStream = new ByteArrayOutputStream();
-        OutputStream errStream = new ByteArrayOutputStream();
-        int result = machine.execScript(MutableMap.of("out", outStream, "err", errStream), "reach "+addr, ImmutableList.of("ping -c 1 "+addr));
-        String outString = outStream.toString();
-        String errString = errStream.toString();
-        assertEquals(result, 0, "result="+0+"; err="+errString+"; out="+outString+"; msg="+msg);
-    }
-
-    @Override
-    protected void releaseMachine(JcloudsSshMachineLocation machine) {
-        jcloudsLocation.release(machine);
-    }
-    
-    private JcloudsSshMachineLocation createEc2Machine(Map<String,? extends Object> conf) throws Exception {
-        return obtainMachine(MutableMap.<String,Object>builder()
-                .putAll(conf)
-                .putIfAbsent("imageId", AWS_EC2_CENTOS_IMAGE_ID)
-                .putIfAbsent("hardwareId", AWS_EC2_SMALL_HARDWARE_ID)
-                .putIfAbsent("inboundPorts", ImmutableList.of(22))
-                .build());
-    }
-    
-    private JcloudsSshMachineLocation createRackspaceMachine(Map<String,? extends Object> conf) throws Exception {
-        return obtainMachine(MutableMap.<String,Object>builder()
-                .putAll(conf)
-                .putIfAbsent("inboundPorts", ImmutableList.of(22))
-                .build());
-    }
-    
-    protected void assertSshable(Map<?,?> machineConfig) {
-        SshMachineLocation machineWithThatConfig = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure(machineConfig));
-        try {
-            assertSshable(machineWithThatConfig);
-        } finally {
-            Streams.closeQuietly(machineWithThatConfig);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverAwsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverAwsLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverAwsLiveTest.java
deleted file mode 100644
index 822bae0..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverAwsLiveTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.net.InetAddress;
-import java.util.Map;
-import java.util.Set;
-
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-public class JcloudsByonLocationResolverAwsLiveTest extends AbstractJcloudsLiveTest {
-
-    private static final String AWS_REGION = "eu-west-1";
-    private static final String AWS_LOCATION_SPEC = "jclouds:aws-ec2:"+AWS_REGION;
-    
-    private String awsVmUser;
-    private String awsVmInstanceId;
-    private String awsVmIp;
-    private String awsVmHostname;
-     
-    private LocalManagementContext classManagementContext;
-    private JcloudsLocation classEc2Loc;
-    private JcloudsSshMachineLocation classEc2Vm;
-
-    @BeforeClass(groups="Live")
-    public void setUpClass() throws Exception {
-        classManagementContext = newManagementContext();
-        classEc2Loc = (JcloudsLocation) classManagementContext.getLocationRegistry().resolve(AWS_LOCATION_SPEC);
-        classEc2Vm = (JcloudsSshMachineLocation)classEc2Loc.obtain(MutableMap.<String,Object>builder()
-                .put("hardwareId", AWS_EC2_SMALL_HARDWARE_ID)
-                .put("inboundPorts", ImmutableList.of(22))
-                .build());
-        awsVmUser = classEc2Vm.getUser();
-        awsVmInstanceId = classEc2Vm.getNode().getProviderId(); // id without region (e.g. "i-6ff96d2f" instead of "eu-west-1/i-6ff96d2f")
-        awsVmIp = classEc2Vm.getAddress().getHostAddress();
-        awsVmHostname = classEc2Vm.getAddress().getHostName();
-    }
-    
-    @AfterClass(alwaysRun=true)
-    public void tearDownClass() throws Exception {
-        try {
-            if (classEc2Vm != null) {
-                classEc2Loc.release(classEc2Vm);
-            }
-        } finally {
-            if (classManagementContext != null) classManagementContext.terminate();
-        }
-    }
-
-    // TODO Requires that a VM already exists; could create that VM first to make test more robust
-    @Test(groups={"Live"})
-    public void testResolvesJcloudsByonAws() throws Exception {
-        String spec = "jcloudsByon:(provider=\"aws-ec2\",region=\""+AWS_REGION+"\",user=\""+awsVmUser+"\",hosts=\""+awsVmInstanceId+"\",anotherprop=myval)";
-
-        FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> loc = resolve(spec);
-        
-        Set<JcloudsSshMachineLocation> machines = loc.getAllMachines();
-        JcloudsSshMachineLocation machine = Iterables.getOnlyElement(machines);
-        assertEquals(machine.getParent().getProvider(), "aws-ec2");
-        assertEquals(machine.getAddress().getHostAddress(), awsVmIp);
-        assertEquals(machine.getAddress().getHostName(), awsVmHostname);
-        assertEquals(machine.getUser(), awsVmUser);
-        assertEquals(machine.config().getBag().getStringKey("anotherprop"), "myval");
-        
-        assertTrue(machine.isSshable());
-    }
-
-    @Test(groups={"Live"})
-    public void testResolvesNamedJcloudsByon() throws Exception {
-        String spec = "jcloudsByon:(provider=\"aws-ec2\",region=\""+AWS_REGION+"\",user=\""+awsVmUser+"\",hosts=\""+awsVmInstanceId+"\")";
-        brooklynProperties.put("brooklyn.location.named.mynamed", spec);
-        
-        FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> loc = resolve("named:mynamed");
-        assertEquals(loc.obtain().getAddress(), InetAddress.getByName(awsVmHostname));
-    }
-
-    @Test(groups={"Live"})
-    public void testJcloudsPropertiesPrecedence() throws Exception {
-        String spec = "jcloudsByon:(provider=\"aws-ec2\",region=\""+AWS_REGION+"\",user=\""+awsVmUser+"\",hosts=\""+awsVmInstanceId+"\")";
-        brooklynProperties.put("brooklyn.location.named.mynamed", spec);
-        
-        // prefer those in spec string over everything else
-        brooklynProperties.put("brooklyn.location.named.mynamed.user", "user-inNamed");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.user", "user-inProviderSpecific");
-        brooklynProperties.put("brooklyn.jclouds.aws-ec2.user", "user-inProviderSpecificDeprecated");
-        brooklynProperties.put("brooklyn.location.jclouds.user", "user-inJcloudsGeneric");
-        brooklynProperties.put("brooklyn.jclouds.user", "user-inJcloudsGenericDeprecated");
-        brooklynProperties.put("brooklyn.location.user", "user-inLocationGeneric");
-
-        // prefer those in "named" over everything else (except spec string itself)
-        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyFile", "privateKeyFile-inProviderSpecific");
-        brooklynProperties.put("brooklyn.jclouds.aws-ec2.privateKeyFile", "privateKeyFile-inProviderSpecificDeprecated");
-        brooklynProperties.put("brooklyn.location.jclouds.privateKeyFile", "privateKeyFile-inJcloudsGeneric");
-        brooklynProperties.put("brooklyn.jclouds.privateKeyFile", "privateKeyFile-inJcloudsGenericDeprecated");
-        brooklynProperties.put("brooklyn.location.privateKeyFile", "privateKeyFile-inLocationGeneric");
-
-        // prefer those in provider-specific over generic
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.publicKeyFile", "publicKeyFile-inProviderSpecific");
-        brooklynProperties.put("brooklyn.jclouds.aws-ec2.publicKeyFile", "publicKeyFile-inProviderSpecificDeprecated");
-        brooklynProperties.put("brooklyn.location.jclouds.publicKeyFile", "publicKeyFile-inJcloudsGeneric");
-        brooklynProperties.put("brooklyn.jclouds.publicKeyFile", "publicKeyFile-inJcloudsGenericDeprecated");
-        brooklynProperties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inLocationGeneric");
-        
-        // prefer those in provider-specific (deprecated scope) over generic
-        brooklynProperties.put("brooklyn.jclouds.aws-ec2.securityGroups", "securityGroups-inProviderSpecificDeprecated");
-        brooklynProperties.put("brooklyn.location.jclouds.securityGroups", "securityGroups-inJcloudsGeneric");
-        brooklynProperties.put("brooklyn.jclouds.securityGroups", "securityGroups-inJcloudsGenericDeprecated");
-        brooklynProperties.put("brooklyn.location.securityGroups", "securityGroups-inLocationGeneric");
-
-        // prefer those in jclouds-generic over location-generic
-        brooklynProperties.put("brooklyn.location.jclouds.loginUser", "loginUser-inJcloudsGeneric");
-        brooklynProperties.put("brooklyn.jclouds.loginUser", "loginUser-inJcloudsGenericDeprecated");
-        brooklynProperties.put("brooklyn.location.loginUser", "loginUser-inLocationGeneric");
-
-        // prefer those in jclouds-generic (deprecated) over location-generic
-        brooklynProperties.put("brooklyn.jclouds.imageId", "imageId-inJcloudsGenericDeprecated");
-        brooklynProperties.put("brooklyn.location.imageId", "imageId-inLocationGeneric");
-
-        // prefer location-generic if nothing else
-        brooklynProperties.put("brooklyn.location.keyPair", "keyPair-inLocationGeneric");
-
-        // prefer deprecated properties in "named" over those less specific
-        brooklynProperties.put("brooklyn.location.named.mynamed.private-key-data", "privateKeyData-inNamed");
-        brooklynProperties.put("brooklyn.jclouds.aws-ec2.privateKeyData", "privateKeyData-inProviderSpecific");
-        brooklynProperties.put("brooklyn.jclouds.privateKeyData", "privateKeyData-inJcloudsGeneric");
-
-        // prefer "named" over everything else: confirm deprecated don't get transformed to overwrite it accidentally
-        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyPassphrase", "privateKeyPassphrase-inNamed");
-        brooklynProperties.put("brooklyn.jclouds.aws-ec2.private-key-passphrase", "privateKeyPassphrase-inProviderSpecific");
-        brooklynProperties.put("brooklyn.jclouds.private-key-passphrase", "privateKeyPassphrase-inJcloudsGeneric");
-
-        Map<String, Object> conf = resolve("named:mynamed").obtain().config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("user"), awsVmUser);
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
-        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
-        assertEquals(conf.get("securityGroups"), "securityGroups-inProviderSpecificDeprecated");
-        assertEquals(conf.get("loginUser"), "loginUser-inJcloudsGeneric");
-        assertEquals(conf.get("imageId"), "imageId-inJcloudsGenericDeprecated");
-        assertEquals(conf.get("keyPair"), "keyPair-inLocationGeneric");
-        assertEquals(conf.get("privateKeyData"), "privateKeyData-inNamed");
-        assertEquals(conf.get("privateKeyPassphrase"), "privateKeyPassphrase-inNamed");
-    }
-    
-    @SuppressWarnings("unchecked")
-    private FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> resolve(String spec) {
-        return (FixedListMachineProvisioningLocation<JcloudsSshMachineLocation>) managementContext.getLocationRegistry().resolve(spec);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverSoftlayerLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverSoftlayerLiveTest.java
deleted file mode 100644
index b60d4e8..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverSoftlayerLiveTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Set;
-
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-public class JcloudsByonLocationResolverSoftlayerLiveTest extends AbstractJcloudsLiveTest {
-
-    private static final String SOFTLAYER_REGION = "dal05";
-    private static final String SOFTLAYER_LOCATION_SPEC = "jclouds:softlayer:"+SOFTLAYER_REGION;
-    
-    private String slVmUser;
-    private String slVmInstanceId;
-    private String slVmIp;
-    private String slVmHostname;
-    
-    private LocalManagementContext classManagementContext;
-    private JcloudsLocation classEc2Loc;
-    private JcloudsSshMachineLocation classVm;
-
-    @BeforeClass(groups="Live")
-    public void setUpClass() throws Exception {
-        classManagementContext = newManagementContext();
-        classEc2Loc = (JcloudsLocation) classManagementContext.getLocationRegistry().resolve(SOFTLAYER_LOCATION_SPEC);
-        classVm = (JcloudsSshMachineLocation)classEc2Loc.obtain(MutableMap.<String,Object>builder()
-                .put("inboundPorts", ImmutableList.of(22))
-                .build());
-        slVmUser = classVm.getUser();
-        slVmInstanceId = classVm.getJcloudsId();
-        slVmIp = classVm.getAddress().getHostAddress();
-        slVmHostname = classVm.getNode().getHostname();
-    }
-    
-    @AfterClass(alwaysRun=true)
-    public void tearDownClass() throws Exception {
-        try {
-            if (classVm != null) {
-                classEc2Loc.release(classVm);
-            }
-        } finally {
-            if (classManagementContext != null) classManagementContext.terminate();
-        }
-    }
-
-    @Test(groups={"Live"})
-    public void testResolvesJcloudsByonSoftlayer() throws Exception {
-        checkSoftlayer("jcloudsByon:(provider=\"softlayer\",region=\""+SOFTLAYER_REGION+"\",hosts=\""+slVmInstanceId+"\",user=\""+slVmUser+"\")");
-        checkSoftlayer("jcloudsByon:(provider=\"softlayer\",region=\""+SOFTLAYER_REGION+"\",hosts=\""+slVmHostname+"\")");
-        checkSoftlayer("jcloudsByon:(provider=\"softlayer\",region=\""+SOFTLAYER_REGION+"\",hosts=\""+slVmIp+"\")");
-        checkSoftlayer("jcloudsByon:(provider=\"softlayer\",hosts=\""+slVmIp+"\")");
-    }
-    
-    private void checkSoftlayer(String spec) {
-        FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> loc = resolve(spec);
-        
-        Set<JcloudsSshMachineLocation> machines = loc.getAllMachines();
-        JcloudsSshMachineLocation machine = Iterables.getOnlyElement(machines);
-        assertEquals(machine.getParent().getProvider(), "softlayer");
-        assertEquals(machine.getNode().getId(), slVmInstanceId);
-        assertEquals(machine.getAddress().getHostAddress(), slVmIp);
-        assertTrue(slVmHostname.equals(machine.getAddress().getHostName()) || slVmIp.equals(machine.getAddress().getHostName()), 
-            "address hostname is: "+machine.getAddress().getHostName());
-        assertTrue(slVmHostname.equals(machine.getNode().getHostname()) || slVmIp.equals(machine.getNode().getHostname()), 
-            "node hostname is: "+machine.getNode().getHostname());
-        
-        // could also assert this, given a user credential, but not currently set up
-//        assertTrue(machine.isSshable());
-    }
-
-    @SuppressWarnings("unchecked")
-    private FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> resolve(String spec) {
-        return (FixedListMachineProvisioningLocation<JcloudsSshMachineLocation>) managementContext.getLocationRegistry().resolve(spec);
-    }
-    
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverTest.java
deleted file mode 100644
index 44af0c7..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsByonLocationResolverTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.fail;
-
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.FixedListMachineProvisioningLocation;
-import brooklyn.management.internal.LocalManagementContext;
-
-public class JcloudsByonLocationResolverTest {
-
-    private LocalManagementContext managementContext;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-
-    @Test
-    public void testThrowsOnInvalid() throws Exception {
-        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
-        assertThrowsIllegalArgument("jcloudsByon"); // no hosts
-        assertThrowsIllegalArgument("jcloudsByon:()"); // no hosts
-        assertThrowsIllegalArgument("jcloudsByon:(hosts=\"\")"); // empty hosts
-        assertThrowsIllegalArgument("jcloudsByon:(hosts=\"i-72b1b132\""); // no closing bracket
-        assertThrowsIllegalArgument("jcloudsByon:(hosts=\"i-72b1b132\", name)"); // no value for name
-        assertThrowsIllegalArgument("jcloudsByon:(hosts=\"i-72b1b132\", name=)"); // no value for name
-    }
-
-    @SuppressWarnings("unchecked")
-    private FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> resolve(String spec) {
-        return (FixedListMachineProvisioningLocation<JcloudsSshMachineLocation>) managementContext.getLocationRegistry().resolve(spec);
-    }
-    
-    private void assertThrowsNoSuchElement(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (NoSuchElementException e) {
-            // success
-        }
-    }
-    
-    private void assertThrowsIllegalArgument(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsHardwareProfilesStubbedLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsHardwareProfilesStubbedLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsHardwareProfilesStubbedLiveTest.java
deleted file mode 100644
index 8d7f55e..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsHardwareProfilesStubbedLiveTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.NodeMetadata.Status;
-import org.jclouds.compute.domain.NodeMetadataBuilder;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.domain.LoginCredentials;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.collect.ImmutableList;
-
-public class JcloudsHardwareProfilesStubbedLiveTest extends AbstractJcloudsStubbedLiveTest {
-
-    @SuppressWarnings("unused")
-    private static final Logger log = LoggerFactory.getLogger(JcloudsHardwareProfilesStubbedLiveTest.class);
-    
-    private Template template;
-    
-    @Override
-    protected NodeCreator newNodeCreator() {
-        return new NodeCreator() {
-            @Override protected NodeMetadata newNode(String group, Template template) {
-                JcloudsHardwareProfilesStubbedLiveTest.this.template = template;
-                
-                NodeMetadata result = new NodeMetadataBuilder()
-                        .id("myid")
-                        .credentials(LoginCredentials.builder().identity("myuser").credential("mypassword").build())
-                        .loginPort(22)
-                        .status(Status.RUNNING)
-                        .publicAddresses(ImmutableList.of("173.194.32.123"))
-                        .privateAddresses(ImmutableList.of("172.168.10.11"))
-                        .build();
-                return result;
-            }
-        };
-    }
-
-    @Test(groups={"Live", "Live-sanity"})
-    public void testJcloudsCreateWithHardwareProfiles() throws Exception {
-        obtainMachine(MutableMap.of(JcloudsLocationConfig.MIN_RAM, "4096"));
-        assertTrue(template.getHardware().getRam() >= 4096, "template="+template);
-        
-        obtainMachine(MutableMap.of(JcloudsLocationConfig.MIN_CORES, "4"));
-        assertTrue(template.getHardware().getProcessors().get(0).getCores() >= 4, "template="+template);
-
-        obtainMachine(MutableMap.of(JcloudsLocationConfig.MIN_DISK, "51"));
-        assertTrue(template.getHardware().getVolumes().get(0).getSize() >= 51, "template="+template);
-        
-        String hardwareId = "cpu=1,memory=6144,disk=25,type=LOCAL";
-        obtainMachine(MutableMap.of(JcloudsLocationConfig.HARDWARE_ID, hardwareId));
-        assertEquals(template.getHardware().getId(), hardwareId, "template="+template);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
deleted file mode 100644
index 4454045..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.management.internal.LocalManagementContext;
-
-import com.google.common.collect.ImmutableSet;
-
-/**
- * @author Shane Witbeck
- */
-public class JcloudsLocationMetadataTest implements JcloudsLocationConfig {
-
-    protected BrooklynProperties brooklynProperties;
-    protected LocalManagementContext managementContext;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance(BrooklynProperties.Factory.builderEmpty().build());
-        brooklynProperties = managementContext.getBrooklynProperties();
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-
-
-    @Test
-    public void testGetsDefaultAwsEc2Metadata() throws Exception {
-        Location loc = managementContext.getLocationRegistry().resolve("jclouds:aws-ec2:us-west-1");
-        
-        assertEquals(loc.getConfig(LocationConfigKeys.LATITUDE), 40.0d);
-        assertEquals(loc.getConfig(LocationConfigKeys.LONGITUDE), -120.0d);
-        assertEquals(loc.getConfig(LocationConfigKeys.ISO_3166), ImmutableSet.of("US-CA"));
-    }
-
-    @Test
-    public void testCanOverrideDefaultAwsEc2Metadata() throws Exception {
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2@us-west-1.latitude", "41.2");
-        Location loc = managementContext.getLocationRegistry().resolve("jclouds:aws-ec2:us-west-1");
-        
-        assertEquals(loc.getConfig(LocationConfigKeys.LATITUDE), 41.2d);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
deleted file mode 100644
index d2f1b84..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationRebindMachineLiveTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.net.InetAddress;
-import java.util.Collections;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.location.basic.SshMachineLocation;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public class JcloudsLocationRebindMachineLiveTest extends AbstractJcloudsLiveTest {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsLocationRebindMachineLiveTest.class);
-    
-    private static final String EUWEST_IMAGE_ID = AWS_EC2_EUWEST_REGION_NAME+"/"+"ami-89def4fd";
-    private static final String IMAGE_OWNER = "411009282317";
-
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
-    }
-
-    @Test(groups = { "Live", "Live-sanity" })
-    public void testRebindWithIncorrectId() throws Exception {
-        try {
-            jcloudsLocation.rebindMachine(ImmutableMap.of("id", "incorrectid", "hostname", "myhostname", "user", "myusername"));
-        } catch (IllegalArgumentException e) {
-            if (e.getMessage().contains("node not found")) {
-                // success
-            } else {
-                throw e;
-            }
-        }
-    }
-    
-    @Test(groups = { "Live" })
-    public void testRebindVm() throws Exception {
-        // FIXME How to create a machine - go directly through jclouds instead?
-        //       Going through LocationRegistry.resolve, loc and loc2 might be same instance
-        
-        // Create a VM through jclouds
-        JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID, "imageOwner", IMAGE_OWNER));
-        assertTrue(machine.isSshable());
-        LOG.info("obtained "+machine);
-
-        String id = checkNotNull(machine.getJcloudsId(), "id");
-        InetAddress address = checkNotNull(machine.getAddress(), "address");
-        String hostname = checkNotNull(address.getHostName(), "hostname");
-        String user = checkNotNull(machine.getUser(), "user");
-        
-        // Create a new jclouds location, and re-bind the existing VM to that
-        JcloudsLocation loc2 = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
-        SshMachineLocation machine2 = loc2.rebindMachine(ImmutableMap.of("id", id, "hostname", hostname, "user", user));
-        
-        LOG.info("rebinded to "+machine2);
-        
-        // Confirm the re-bound machine is wired up
-        assertTrue(machine2.isSshable());
-        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), ImmutableSet.of(machine2));
-        
-        // Confirm can release the re-bound machine via the new jclouds location
-        loc2.release(machine2);
-        assertFalse(machine.isSshable());
-        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), Collections.emptySet());
-    }
-    
-    @Test(groups = { "Live" })
-    public void testRebindVmDeprecated() throws Exception {
-        // FIXME See comments in testRebindVm
-
-        // Create a VM through jclouds
-        JcloudsSshMachineLocation machine = obtainMachine(ImmutableMap.of("imageId", EUWEST_IMAGE_ID, "imageOwner", IMAGE_OWNER));
-        assertTrue(machine.isSshable());
-
-        String id = machine.getJcloudsId();
-        InetAddress address = machine.getAddress();
-        String hostname = address.getHostName();
-        String username = machine.getUser();
-        
-        // Create a new jclouds location, and re-bind the existing VM to that
-        JcloudsLocation loc2 = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_PROVIDER+":"+AWS_EC2_EUWEST_REGION_NAME);
-        // pass deprecated userName
-        SshMachineLocation machine2 = loc2.rebindMachine(ImmutableMap.of("id", id, "hostname", hostname, "userName", username));
-        
-        // Confirm the re-bound machine is wired up
-        assertTrue(machine2.isSshable());
-        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), ImmutableSet.of(machine2));
-        
-        // Confirm can release the re-bound machine via the new jclouds location
-        loc2.release(machine2);
-        assertFalse(machine.isSshable());
-        assertEquals(ImmutableSet.copyOf(loc2.getChildren()), Collections.emptySet());
-    }
-
-    // Useful for debugging; accesss a hard-coded existing instance so don't need to wait for provisioning a new one
-    @Test(enabled=false, groups = { "Live" })
-    public void testRebindVmToHardcodedInstance() throws Exception {
-        String id = "eu-west-1/i-5504f21d";
-        InetAddress address = InetAddress.getByName("ec2-176-34-93-58.eu-west-1.compute.amazonaws.com");
-        String hostname = address.getHostName();
-        String username = "root";
-        
-        SshMachineLocation machine = jcloudsLocation.rebindMachine(ImmutableMap.of("id", id, "hostname", hostname, "userName", username));
-        
-        // Confirm the re-bound machine is wired up
-        assertTrue(machine.isSshable());
-        assertEquals(ImmutableSet.copyOf(jcloudsLocation.getChildren()), ImmutableSet.of(machine));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationResolverTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
deleted file mode 100644
index 0dc2658..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationResolverTest.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.event.basic.MapConfigKey;
-import brooklyn.event.basic.SetConfigKey;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.collections.MutableSet;
-
-public class JcloudsLocationResolverTest {
-
-    private static final Logger log = LoggerFactory.getLogger(JcloudsLocationResolverTest.class);
-    
-    private LocalManagementContext managementContext;
-    private BrooklynProperties brooklynProperties;
-
-    @BeforeMethod(alwaysRun = true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-        brooklynProperties = managementContext.getBrooklynProperties();
-
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.identity", "aws-ec2-id");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.credential", "aws-ec2-cred");
-        brooklynProperties.put("brooklyn.location.jclouds.rackspace-cloudservers-uk.identity", "cloudservers-uk-id");
-        brooklynProperties.put("brooklyn.location.jclouds.rackspace-cloudservers-uk.credential", "cloudservers-uk-cred");
-    }
-
-    @AfterMethod(alwaysRun = true)
-    public void tearDown() throws Exception {
-        if (managementContext != null)
-            managementContext.terminate();
-    }
-
-    @Test
-    public void testJcloudsTakesDotSeparateProperty() {
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.loginUser.privateKeyFile", "myfile");
-        String file = resolve("jclouds:aws-ec2").getConfig(JcloudsLocation.LOGIN_USER_PRIVATE_KEY_FILE);
-        assertEquals(file, "myfile");
-    }
-
-    @Test
-    public void testJcloudsTakesProviderScopedProperties() {
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyFile", "myprivatekeyfile");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.publicKeyFile", "mypublickeyfile");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyData", "myprivateKeyData");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.publicKeyData", "myPublicKeyData");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyPassphrase", "myprivateKeyPassphrase");
-        Map<String, Object> conf = resolve("jclouds:aws-ec2").config().getBag().getAllConfig();
-
-        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
-        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
-        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
-        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
-        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
-    }
-
-    @Test
-    public void testJcloudsTakesGenericScopedProperties() {
-        brooklynProperties.put("brooklyn.location.jclouds.privateKeyFile", "myprivatekeyfile");
-        brooklynProperties.put("brooklyn.location.jclouds.publicKeyFile", "mypublickeyfile");
-        brooklynProperties.put("brooklyn.location.jclouds.privateKeyData", "myprivateKeyData");
-        brooklynProperties.put("brooklyn.location.jclouds.publicKeyData", "myPublicKeyData");
-        brooklynProperties.put("brooklyn.location.jclouds.privateKeyPassphrase", "myprivateKeyPassphrase");
-        Map<String, Object> conf = resolve("jclouds:aws-ec2").config().getBag().getAllConfig();
-
-        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
-        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
-        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
-        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
-        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
-    }
-
-    @Test
-    public void testJcloudsTakesDeprecatedProperties() {
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.private-key-file", "myprivatekeyfile");
-        brooklynProperties.put("brooklyn.location.jclouds.public-key-file", "mypublickeyfile");
-        brooklynProperties.put("brooklyn.location.jclouds.private-key-data", "myprivateKeyData");
-        brooklynProperties.put("brooklyn.location.jclouds.public-key-data", "myPublicKeyData");
-        brooklynProperties.put("brooklyn.location.jclouds.private-key-passphrase", "myprivateKeyPassphrase");
-        brooklynProperties.put("brooklyn.location.jclouds.image-id", "myimageid");
-        Map<String, Object> conf = resolve("jclouds:aws-ec2").config().getBag().getAllConfig();
-
-        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
-        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
-        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
-        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
-        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
-        assertEquals(conf.get("imageId"), "myimageid");
-    }
-
-    @Test
-    public void testJcloudsPropertiesPrecedence() {
-        brooklynProperties.put("brooklyn.location.named.myaws-ec2", "jclouds:aws-ec2");
-
-        // prefer those in "named" over everything else
-        brooklynProperties.put("brooklyn.location.named.myaws-ec2.privateKeyFile", "privateKeyFile-inNamed");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyFile", "privateKeyFile-inProviderSpecific");
-        brooklynProperties.put("brooklyn.location.jclouds.privateKeyFile", "privateKeyFile-inJcloudsGeneric");
-
-        // prefer those in provider-specific over generic
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.publicKeyFile", "publicKeyFile-inProviderSpecific");
-        brooklynProperties.put("brooklyn.location.jclouds.publicKeyFile", "publicKeyFile-inJcloudsGeneric");
-
-        // prefer deprecated properties in "named" over those less specific
-        brooklynProperties.put("brooklyn.location.named.myaws-ec2.private-key-data", "privateKeyData-inNamed");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.privateKeyData", "privateKeyData-inProviderSpecific");
-        brooklynProperties.put("brooklyn.location.jclouds.privateKeyData", "privateKeyData-inJcloudsGeneric");
-
-        // prefer generic if nothing else
-        brooklynProperties.put("brooklyn.location.jclouds.publicKeyData", "publicKeyData-inJcloudsGeneric");
-
-        // prefer "named" over everything else: confirm deprecated don't get
-        // transformed to overwrite it accidentally
-        brooklynProperties
-                .put("brooklyn.location.named.myaws-ec2.privateKeyPassphrase", "privateKeyPassphrase-inNamed");
-        brooklynProperties.put("brooklyn.location.jclouds.aws-ec2.private-key-passphrase",
-                "privateKeyPassphrase-inProviderSpecific");
-        brooklynProperties.put("brooklyn.location.jclouds.private-key-passphrase", "privateKeyPassphrase-inJcloudsGeneric");
-
-        Map<String, Object> conf = resolve("named:myaws-ec2").config().getBag().getAllConfig();
-
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
-        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
-        assertEquals(conf.get("privateKeyData"), "privateKeyData-inNamed");
-        assertEquals(conf.get("publicKeyData"), "publicKeyData-inJcloudsGeneric");
-        assertEquals(conf.get("privateKeyPassphrase"), "privateKeyPassphrase-inNamed");
-    }
-
-    @Test
-    public void testJcloudsLoads() {
-        Assert.assertTrue(resolve("jclouds:aws-ec2") instanceof JcloudsLocation);
-    }
-
-    @Test
-    public void testJcloudsImplicitLoads() {
-        Assert.assertTrue(resolve("aws-ec2") instanceof JcloudsLocation);
-    }
-
-    @Test
-    public void testJcloudsLocationLoads() {
-        Assert.assertTrue(resolve("aws-ec2:eu-west-1") instanceof JcloudsLocation);
-    }
-
-    @Test
-    public void testJcloudsRegionOnlyLoads() {
-        Assert.assertTrue(resolve("eu-west-1") instanceof JcloudsLocation);
-    }
-
-    @Test
-    public void testJcloudsEndpointLoads() {
-        JcloudsLocation loc = resolve("jclouds:openstack-nova:http://foo/api");
-        assertEquals(loc.getProvider(), "openstack-nova");
-        assertEquals(loc.getEndpoint(), "http://foo/api");
-    }
-
-    @Test
-    public void testJcloudsEndpointLoadsAsProperty() {
-        brooklynProperties.put("brooklyn.location.jclouds.openstack-nova.endpoint", "myendpoint");
-        JcloudsLocation loc = resolve("jclouds:openstack-nova");
-        // just checking
-        assertEquals(loc.config().getLocalBag().getStringKey("endpoint"), "myendpoint");
-        assertEquals(loc.getConfig(CloudLocationConfig.CLOUD_ENDPOINT), "myendpoint");
-        // this is the one we really care about!:
-        assertEquals(loc.getEndpoint(), "myendpoint");
-    }
-
-    @Test
-    public void testJcloudsLegacyRandomProperty() {
-        brooklynProperties.put("brooklyn.location.jclouds.openstack-nova.foo", "bar");
-        JcloudsLocation loc = resolve("jclouds:openstack-nova");
-        assertEquals(loc.config().getLocalBag().getStringKey("foo"), "bar");
-    }
-
-    @Test
-    public void testJcloudsRandomProperty() {
-        brooklynProperties.put("brooklyn.location.jclouds.openstack-nova.foo", "bar");
-        JcloudsLocation loc = resolve("jclouds:openstack-nova");
-        assertEquals(loc.config().getLocalBag().getStringKey("foo"), "bar");
-    }
-
-    @Test
-    public void testThrowsOnInvalid() throws Exception {
-        // Tries to treat "wrongprefix" as a cloud provider
-        assertThrows("wrongprefix:aws-ec2:us-east-1", NoSuchElementException.class);
-
-        // no provider
-        assertThrows("jclouds", IllegalArgumentException.class);
-
-        // empty provider
-        assertThrows("jclouds:", IllegalArgumentException.class);
-
-        // invalid provider
-        assertThrows("jclouds:doesnotexist", NoSuchElementException.class);
-    }
-
-    @Test
-    public void testResolvesJclouds() throws Exception {
-        // test with provider + region
-        assertJcloudsEquals(resolve("jclouds:aws-ec2:us-east-1"), "aws-ec2", "us-east-1");
-
-        // test with provider that has no region
-        assertJcloudsEquals(resolve("jclouds:rackspace-cloudservers-uk"), "rackspace-cloudservers-uk", null);
-    }
-
-    @Test
-    public void testJcloudsRegionOverridesParent() {
-        Map<String, Object> conf;
-        
-        brooklynProperties.put("brooklyn.location.named.softlayer-was", "jclouds:softlayer:was01");
-        brooklynProperties.put("brooklyn.location.named.softlayer-was2", "jclouds:softlayer:was01");
-        brooklynProperties.put("brooklyn.location.named.softlayer-was2.region", "was02");
-        conf = resolve("named:softlayer-was").config().getBag().getAllConfig();
-        assertEquals(conf.get("region"), "was01");
-        
-        conf = resolve("named:softlayer-was2").config().getBag().getAllConfig();
-        assertEquals(conf.get("region"), "was02");
-        
-        conf = ((LocationInternal) managementContext.getLocationRegistry().resolve("named:softlayer-was2", MutableMap.of("region", "was03")))
-            .config().getBag().getAllConfig();;
-        assertEquals(conf.get("region"), "was03");
-    }
-    
-    // TODO Visual inspection test that it logs warnings
-    @Test
-    public void testLogsWarnings() throws Exception {
-        assertJcloudsEquals(resolve("jclouds:jclouds:aws-ec2:us-east-1"), "aws-ec2", "us-east-1");
-        assertJcloudsEquals(resolve("us-east-1"), "aws-ec2", "us-east-1");
-
-        // TODO Should we enforce a jclouds prefix? Currently we don't
-        // assertJcloudsEquals(resolve("aws-ec2:us-east-1"), "aws-ec2",
-        // "us-east-1");
-
-    }
-
-    @Test
-    public void testResolvesJcloudsFromNamedOfNamedWithPropertiesOverriddenCorrectly() throws Exception {
-        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop1", "1");
-        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop2", "1");
-        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop3", "1");
-        brooklynProperties.put("brooklyn.location.named.foo", "jclouds:softlayer:138124");
-        brooklynProperties.put("brooklyn.location.named.foo.prop2", "2");
-        brooklynProperties.put("brooklyn.location.named.foo.prop3", "2");
-        brooklynProperties.put("brooklyn.location.named.bar", "named:foo");
-        brooklynProperties.put("brooklyn.location.named.bar.prop3", "3");
-        
-        JcloudsLocation l = resolve("named:bar");
-        assertJcloudsEquals(l, "softlayer", "138124");
-        assertEquals(l.config().getLocalBag().getStringKey("prop3"), "3");
-        assertEquals(l.config().getLocalBag().getStringKey("prop2"), "2");
-        assertEquals(l.config().getLocalBag().getStringKey("prop1"), "1");
-    }
-
-    @Test
-    public void testResolvesListAndMapProperties() throws Exception {
-        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop1", "[ a, b ]");
-        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop2", "{ a: 1, b: 2 }");
-        brooklynProperties.put("brooklyn.location.named.foo", "jclouds:softlayer:ams01");
-        
-        JcloudsLocation l = resolve("named:foo");
-        assertJcloudsEquals(l, "softlayer", "ams01");
-        assertEquals(l.config().get(new SetConfigKey<String>(String.class, "prop1")), MutableSet.of("a", "b"));
-        assertEquals(l.config().get(new MapConfigKey<String>(String.class, "prop2")), MutableMap.of("a", 1, "b", 2));
-    }
-    
-    @Test
-    public void testResolvesListAndMapPropertiesWithoutMergeOnInheritance() throws Exception {
-        // when we have a yaml way to specify config we may wish to have different semantics;
-        // it could depend on the collection config key whether to merge on inheritance
-        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop1", "[ a, b ]");
-        brooklynProperties.put("brooklyn.location.jclouds.softlayer.prop2", "{ a: 1, b: 2 }");
-        brooklynProperties.put("brooklyn.location.named.foo", "jclouds:softlayer:ams01");
-        
-        brooklynProperties.put("brooklyn.location.named.foo.prop1", "[ a: 1, c: 3 ]");
-        brooklynProperties.put("brooklyn.location.named.foo.prop2", "{ b: 3, c: 3 }");
-        brooklynProperties.put("brooklyn.location.named.bar", "named:foo");
-        brooklynProperties.put("brooklyn.location.named.bar.prop2", "{ c: 4, d: 4 }");
-        
-        // these do NOT affect the maps
-        brooklynProperties.put("brooklyn.location.named.foo.prop2.z", "9");
-        brooklynProperties.put("brooklyn.location.named.foo.prop3.z", "9");
-        
-        JcloudsLocation l = resolve("named:bar");
-        assertJcloudsEquals(l, "softlayer", "ams01");
-        
-        Set<? extends String> prop1 = l.config().get(new SetConfigKey<String>(String.class, "prop1"));
-        log.info("prop1: "+prop1);
-        assertEquals(prop1, MutableSet.of("a: 1", "c: 3"));
-        
-        Map<String, String> prop2 = l.config().get(new MapConfigKey<String>(String.class, "prop2"));
-        log.info("prop2: "+prop2);
-        assertEquals(prop2, MutableMap.of("c", 4, "d", 4));
-        
-        Map<String, String> prop3 = l.config().get(new MapConfigKey<String>(String.class, "prop3"));
-        log.info("prop3: "+prop3);
-        assertEquals(prop3, null);
-    }
-
-    private void assertJcloudsEquals(JcloudsLocation loc, String expectedProvider, String expectedRegion) {
-        assertEquals(loc.getProvider(), expectedProvider);
-        assertEquals(loc.getRegion(), expectedRegion);
-    }
-
-    private void assertThrows(String val, Class<?> expectedExceptionType) throws Exception {
-        try {
-            resolve(val);
-            fail();
-        } catch (Exception e) {
-            if (!expectedExceptionType.isInstance(e))
-                throw e; // otherwise success
-
-        }
-    }
-
-    @Test(expectedExceptions = { NoSuchElementException.class, IllegalArgumentException.class }, expectedExceptionsMessageRegExp = ".*insufficient.*")
-    public void testJcloudsOnlyFails() {
-        resolve("jclouds");
-    }
-
-    private JcloudsLocation resolve(String spec) {
-        return (JcloudsLocation) managementContext.getLocationRegistry().resolve(spec);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationTemplateOptionsCustomisersLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationTemplateOptionsCustomisersLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationTemplateOptionsCustomisersLiveTest.java
deleted file mode 100644
index d22e134..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationTemplateOptionsCustomisersLiveTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.text.Identifiers;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.ec2.domain.BlockDeviceMapping;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import java.io.ByteArrayOutputStream;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-public class JcloudsLocationTemplateOptionsCustomisersLiveTest extends AbstractJcloudsLiveTest {
-
-    private static final String LOCATION_SPEC = AWS_EC2_PROVIDER + ":" + AWS_EC2_USEAST_REGION_NAME;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        jcloudsLocation = resolve(LOCATION_SPEC);
-    }
-
-    // Doesn't actually do much with the cloud, but jclouds requires identity and credential before it will work
-    @Test(groups = "Live")
-    public void testGeneralPurposeTemplateOptionCustomisation() throws Exception {
-        ConfigKey<Map<String, Object>> key = JcloudsLocationConfig.TEMPLATE_OPTIONS;
-
-        ConfigBag config = ConfigBag.newInstance()
-                .configure(key, ImmutableMap.of("iamInstanceProfileName", (Object)"helloworld"));
-        AWSEC2TemplateOptions templateOptions = jcloudsLocation.getComputeService().templateOptions().as(AWSEC2TemplateOptions.class);
-
-        invokeCustomizeTemplateOptions(templateOptions, JcloudsLocationConfig.TEMPLATE_OPTIONS, config);
-
-        assertEquals(templateOptions.getIAMInstanceProfileName(), "helloworld");
-    }
-
-    // Doesn't actually do much with the cloud, but jclouds requires identity and credential before it will work
-    @Test(groups = "Live")
-    public void testGeneralPurposeTemplateOptionCustomisationWithList() throws Exception {
-        ConfigKey<Map<String, Object>> key = JcloudsLocationConfig.TEMPLATE_OPTIONS;
-
-        ConfigBag config = ConfigBag.newInstance()
-                        .configure(key, ImmutableMap.of(
-                                "iamInstanceProfileName", (Object) "helloworld",
-                                "mapNewVolumeToDeviceName", (Object) ImmutableList.of("/dev/sda1/", 123, true)));
-        AWSEC2TemplateOptions templateOptions = jcloudsLocation.getComputeService().templateOptions().as(AWSEC2TemplateOptions.class);
-
-        invokeCustomizeTemplateOptions(templateOptions, JcloudsLocationConfig.TEMPLATE_OPTIONS, config);
-
-        assertEquals(templateOptions.getIAMInstanceProfileName(), "helloworld");
-        assertEquals(templateOptions.getBlockDeviceMappings().size(), 1);
-        BlockDeviceMapping blockDeviceMapping = templateOptions.getBlockDeviceMappings().iterator().next();
-        assertEquals(blockDeviceMapping.getDeviceName(), "/dev/sda1/");
-        assertEquals(blockDeviceMapping.getEbsVolumeSize(), (Integer)123);
-        assertTrue(blockDeviceMapping.getEbsDeleteOnTermination());
-    }
-
-    /**
-     * Invoke a specific template options customizer on a TemplateOptions instance.
-     *
-     * @param templateOptions the TemplateOptions instance that you expect the customizer to modify.
-     * @param keyToTest the config key that identifies the customizer. This must be present in both @{code locationConfig} and @{link JcloudsLocation.SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES}.
-     * @param locationConfig simulated configuration for the location. This must contain at least an entry for @{code keyToTest}.
-     */
-    private void invokeCustomizeTemplateOptions(TemplateOptions templateOptions, ConfigKey<?> keyToTest, ConfigBag locationConfig) {
-        checkNotNull(templateOptions, "templateOptions");
-        checkNotNull(keyToTest, "keyToTest");
-        checkNotNull(locationConfig, "locationConfig");
-        checkState(JcloudsLocation.SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.containsKey(keyToTest),
-                "SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES does not contain a customiser for the key " + keyToTest.getName());
-        checkState(locationConfig.containsKey(keyToTest),
-                "location config does not contain the key " + keyToTest.getName());
-
-        JcloudsLocation.CustomizeTemplateOptions code = JcloudsLocation.SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.get(keyToTest);
-        code.apply(templateOptions, locationConfig, locationConfig.get(keyToTest));
-    }
-
-    private JcloudsLocation resolve(String spec) {
-        return (JcloudsLocation) managementContext.getLocationRegistry().resolve("jclouds:"+spec);
-    }
-}


[25/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java
new file mode 100644
index 0000000..6645217
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.apache.brooklyn.location.access;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+
+import java.io.File;
+
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.management.ha.MementoCopyMode;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.test.entity.TestEntity;
+import org.apache.brooklyn.test.entity.TestEntityImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.rebind.RebindOptions;
+import brooklyn.entity.rebind.RebindTestFixtureWithApp;
+import brooklyn.entity.rebind.RebindTestUtils;
+import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
+import brooklyn.entity.rebind.persister.FileBasedObjectStore;
+import brooklyn.entity.rebind.persister.PersistenceObjectStore;
+import brooklyn.event.basic.Sensors;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.net.Networking;
+import brooklyn.util.os.Os;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.time.Time;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.common.net.HostAndPort;
+
+public class PortForwardManagerRebindTest extends RebindTestFixtureWithApp {
+
+    private static final Logger log = LoggerFactory.getLogger(PortForwardManagerRebindTest.class);
+
+    private String machineAddress = "1.2.3.4";
+    private SshMachineLocation origSimulatedMachine;
+
+    @Override
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        super.setUp();
+
+        origSimulatedMachine = origManagementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getInetAddressWithFixedName(machineAddress))
+                .configure("port", 1234)
+                .configure("user", "myuser"));
+    }
+    
+    @Test
+    public void testAssociationPreservedOnRebind() throws Exception {
+        String publicIpId = "5.6.7.8";
+        String publicAddress = "5.6.7.8";
+
+        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
+        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+
+        // We first wait for persisted, to ensure that it is the PortForwardManager.onChanged that is causing persistence.
+        RebindTestUtils.waitForPersisted(origApp);
+        origPortForwardManager.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), origSimulatedMachine, 80);
+     
+        newApp = rebind();
+        
+        // After rebind, confirm that lookups still work
+        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
+        Location newSimulatedMachine = newApp.getManagementContext().getLocationManager().getLocation(origSimulatedMachine.getId());
+        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+        
+        assertEquals(newPortForwardManager.lookup(newSimulatedMachine, 80), HostAndPort.fromParts(publicAddress, 40080));
+        assertEquals(newPortForwardManager.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
+    }
+    
+    @Test
+    public void testAssociationPreservedOnStateExport() throws Exception {
+        String publicIpId = "5.6.7.8";
+        String publicAddress = "5.6.7.8";
+
+        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
+        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+
+        origPortForwardManager.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), origSimulatedMachine, 80);
+
+        String label = origManagementContext.getManagementNodeId()+"-"+Time.makeDateSimpleStampString();
+        PersistenceObjectStore targetStore = BrooklynPersistenceUtils.newPersistenceObjectStore(origManagementContext, null, 
+            "tmp/web-persistence-"+label+"-"+Identifiers.makeRandomId(4));
+        File dir = ((FileBasedObjectStore)targetStore).getBaseDir();
+        // only register the parent dir because that will prevent leaks for the random ID
+        Os.deleteOnExitEmptyParentsUpTo(dir.getParentFile(), dir.getParentFile());
+        BrooklynPersistenceUtils.writeMemento(origManagementContext, targetStore, MementoCopyMode.LOCAL);            
+
+        RebindTestUtils.waitForPersisted(origApp);
+        log.info("Using manual export dir "+dir+" for rebind instead of "+mementoDir);
+        newApp = rebind(RebindOptions.create().mementoDir(dir));
+        
+        // After rebind, confirm that lookups still work
+        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
+        Location newSimulatedMachine = newApp.getManagementContext().getLocationManager().getLocation(origSimulatedMachine.getId());
+        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+        
+        assertEquals(newPortForwardManager.lookup(newSimulatedMachine, 80), HostAndPort.fromParts(publicAddress, 40080));
+        assertEquals(newPortForwardManager.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
+        
+        // delete the dir here, to be more likely not to leak it on failure
+        newManagementContext.getRebindManager().stop();
+        Os.deleteRecursively(dir);
+    }
+    
+    @Test
+    public void testAssociationPreservedOnRebindLegacy() throws Exception {
+        String publicIpId = "5.6.7.8";
+        String publicAddress = "5.6.7.8";
+
+        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
+        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+
+        // We first wait for persisted, to ensure that it is the PortForwardManager.onChanged that is causing persistence.
+        RebindTestUtils.waitForPersisted(origApp);
+        origPortForwardManager.recordPublicIpHostname(publicIpId, publicAddress);
+        origPortForwardManager.acquirePublicPortExplicit(publicIpId, 40080);
+        origPortForwardManager.associate(publicIpId, 40080, origSimulatedMachine, 80);
+     
+        newApp = rebind();
+        
+        // After rebind, confirm that lookups still work
+        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
+        Location newSimulatedMachine = newApp.getManagementContext().getLocationManager().getLocation(origSimulatedMachine.getId());
+        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+        
+        assertEquals(newPortForwardManager.getPublicIpHostname(publicIpId), publicAddress);
+        assertEquals(newPortForwardManager.lookup(newSimulatedMachine, 80), HostAndPort.fromParts(publicAddress, 40080));
+        assertEquals(newPortForwardManager.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
+    }
+    
+    @Test
+    public void testAcquirePortCounterPreservedOnRebindLegacy() throws Exception {
+        String publicIpId = "5.6.7.8";
+
+        TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntity.class));
+        PortForwardManager origPortForwardManager = origEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+
+        // We first wait for persisted, to ensure that it is the PortForwardManager.onChanged that is causing persistence.
+        RebindTestUtils.waitForPersisted(origApp);
+        int acquiredPort = origPortForwardManager.acquirePublicPort(publicIpId);
+     
+        newApp = rebind();
+        
+        // After rebind, confirm that lookups still work
+        TestEntity newEntity = (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));
+        PortForwardManager newPortForwardManager = newEntity.getConfig(MyEntity.PORT_FORWARD_MANAGER);
+        
+        int acquiredPort2 = newPortForwardManager.acquirePublicPort(publicIpId);
+        assertNotEquals(acquiredPort, acquiredPort2);
+    }
+    
+    public static class MyEntity extends TestEntityImpl {
+        public static final ConfigKey<PortForwardManager> PORT_FORWARD_MANAGER = ConfigKeys.newConfigKey(PortForwardManager.class, "myentity.portForwardManager");
+        public static final AttributeSensor<PortForwardManager> PORT_FORWARD_MANAGER_LIVE = Sensors.newSensor(PortForwardManager.class, "myentity.portForwardManager.live");
+
+        @Override
+        public void init() {
+            super.init();
+            
+            if (getConfig(PORT_FORWARD_MANAGER) == null) {
+                PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
+                setAttribute(PORT_FORWARD_MANAGER_LIVE, pfm);
+                setConfig(PORT_FORWARD_MANAGER, pfm);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java
new file mode 100644
index 0000000..904e9dc
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java
@@ -0,0 +1,193 @@
+/*
+ * 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.apache.brooklyn.location.access;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNull;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.BrooklynAppUnitTestSupport;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.net.Networking;
+
+import com.google.common.base.Predicate;
+import com.google.common.net.HostAndPort;
+
+public class PortForwardManagerTest extends BrooklynAppUnitTestSupport {
+
+    private static final Logger log = LoggerFactory.getLogger(PortForwardManagerTest.class);
+
+    private Map<HostAndPort, HostAndPort> portMapping;
+    private SshMachineLocation machine1;
+    private SshMachineLocation machine2;
+    private PortForwardManager pfm;
+    
+    @Override
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        super.setUp();
+
+        pfm = (PortForwardManager) mgmt.getLocationRegistry().resolve("portForwardManager(scope=global)");
+
+        machine1 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getInetAddressWithFixedName("1.2.3.4"))
+                .configure("port", 1234)
+                .configure("user", "myuser"));
+        machine2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getInetAddressWithFixedName("1.2.3.5"))
+                .configure("port", 1234)
+                .configure("user", "myuser"));
+    }
+    
+    @Test
+    public void testAssociateWithLocation() throws Exception {
+        String publicIpId = "myipid";
+        String publicAddress = "5.6.7.8";
+
+        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80);
+     
+        assertEquals(pfm.lookup(machine1, 80), HostAndPort.fromParts(publicAddress, 40080));
+        assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
+    }
+    
+    @Test
+    public void testAssociateWithoutLocation() throws Exception {
+        String publicIpId = "myipid";
+        String publicAddress = "5.6.7.8";
+
+        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), 80);
+     
+        assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
+        assertNull(pfm.lookup(machine1, 80));
+    }
+    
+    @Test
+    public void testAcquirePortDoesNotReturnDuplicate() throws Exception {
+        String publicIpId = "myipid";
+
+        int port1 = pfm.acquirePublicPort(publicIpId);
+        int port2 = pfm.acquirePublicPort(publicIpId);
+        assertNotEquals(port1, port2);
+    }
+    
+    @Test
+    public void testAcquirePortRespectsStartingPortNumber() throws Exception {
+        BrooklynProperties props = BrooklynProperties.Factory.newEmpty();
+        props.put(PortForwardManager.PORT_FORWARD_MANAGER_STARTING_PORT, 1234);
+        LocalManagementContextForTests mgmt2 = new LocalManagementContextForTests(props);
+        try {
+            PortForwardManager pfm2 = (PortForwardManager) mgmt2.getLocationRegistry().resolve("portForwardManager(scope=global)");
+            int port = pfm2.acquirePublicPort("myipid");
+            assertEquals(port, 1234);
+        } finally {
+            Entities.destroyAll(mgmt2);
+        }
+    }
+    
+    @Test
+    public void testForgetPortMapping() throws Exception {
+        String publicIpId = "myipid";
+        String publicAddress = "5.6.7.8";
+
+        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80);
+        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40081), machine1, 81);
+        pfm.forgetPortMapping(publicIpId, 40080);
+        
+        assertNull(pfm.lookup(publicIpId, 80));
+        assertNull(pfm.lookup(machine1, 80));
+        assertEquals(pfm.lookup(publicIpId, 81), HostAndPort.fromParts(publicAddress, 40081));
+        assertEquals(pfm.lookup(publicIpId, 81), HostAndPort.fromParts(publicAddress, 40081));
+    }
+    
+    @Test
+    public void testForgetPortMappingsOfMachine() throws Exception {
+        String publicIpId = "myipid";
+        String publicIpId2 = "myipid2";
+        String publicAddress = "5.6.7.8";
+
+        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40080), machine1, 80);
+        pfm.associate(publicIpId, HostAndPort.fromParts(publicAddress, 40081), machine1, 81);
+        pfm.associate(publicIpId2, HostAndPort.fromParts(publicAddress, 40082), machine2, 80);
+        pfm.forgetPortMappings(machine1);
+        
+        assertNull(pfm.lookup(machine1, 80));
+        assertNull(pfm.lookup(machine1, 81));
+        assertNull(pfm.lookup(publicIpId, 80));
+        assertEquals(pfm.lookup(machine2, 80), HostAndPort.fromParts(publicAddress, 40082));
+    }
+    
+    @Test
+    public void testAssociateLegacy() throws Exception {
+        String publicIpId = "myipid";
+        String publicAddress = "5.6.7.8";
+
+        pfm.acquirePublicPortExplicit(publicIpId, 40080);
+        pfm.recordPublicIpHostname(publicIpId, publicAddress);
+        pfm.associate(publicIpId, 40080, machine1, 80);
+        
+        assertEquals(pfm.lookup(publicIpId, 80), HostAndPort.fromParts(publicAddress, 40080));
+        assertEquals(pfm.lookup(machine1, 80), HostAndPort.fromParts(publicAddress, 40080));
+    }
+
+    @Test
+    public void testAssociationListeners() throws Exception {
+        final AtomicInteger associationCreatedCount = new AtomicInteger(0);
+        final AtomicInteger associationDeletedCount = new AtomicInteger(0);
+
+        final String publicIpId = "myipid";
+        final String anotherIpId = "anotherIpId";
+
+        pfm.addAssociationListener(new PortForwardManager.AssociationListener() {
+            @Override
+            public void onAssociationCreated(PortForwardManager.AssociationMetadata metadata) {
+                associationCreatedCount.incrementAndGet();
+            }
+
+            @Override
+            public void onAssociationDeleted(PortForwardManager.AssociationMetadata metadata) {
+                associationDeletedCount.incrementAndGet();
+            }
+        }, new Predicate<PortForwardManager.AssociationMetadata>() {
+            @Override
+            public boolean apply(PortForwardManager.AssociationMetadata metadata) {
+                return publicIpId.equals(metadata.getPublicIpId());
+            }
+        });
+
+        pfm.associate(publicIpId, HostAndPort.fromParts(publicIpId, 40080), machine1, 80);
+        pfm.associate(anotherIpId, HostAndPort.fromParts(anotherIpId, 40081), machine1, 80);
+        pfm.forgetPortMapping(publicIpId, 40080);
+        pfm.forgetPortMapping(anotherIpId, 40081);
+
+        assertEquals(associationCreatedCount.get(), 1);
+        assertEquals(associationDeletedCount.get(), 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java
new file mode 100644
index 0000000..4977195
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.flags.SetFromFlag;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class AbstractLocationTest {
+
+    public static class ConcreteLocation extends AbstractLocation {
+        private static final long serialVersionUID = 3954199300889119970L;
+        @SetFromFlag(defaultVal="mydefault")
+        String myfield;
+
+        public ConcreteLocation() {
+            super();
+        }
+
+        public ConcreteLocation(Map<?,?> properties) {
+            super(properties);
+        }
+    }
+
+    private ManagementContext mgmt;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        mgmt = LocalManagementContextForTests.newInstance();
+    }
+    
+    @AfterMethod(alwaysRun = true)
+    public void tearDown(){
+        if (mgmt!=null) Entities.destroyAll(mgmt);
+    }
+
+    private ConcreteLocation createConcrete() {
+        return createConcrete(MutableMap.<String,Object>of());
+    }
+    private ConcreteLocation createConcrete(Map<String,?> flags) {
+        return createConcrete(null, flags);
+    }
+    @SuppressWarnings("deprecation")
+    private ConcreteLocation createConcrete(String id, Map<String,?> flags) {
+        return mgmt.getLocationManager().createLocation( LocationSpec.create(ConcreteLocation.class).id(id).configure(flags) );
+    }
+    
+    @Test
+    public void testEqualsUsesId() {
+        Location l1 = createConcrete("1", MutableMap.of("name", "bob"));
+        Location l1b = new ConcreteLocation(ImmutableMap.of("id", 1));
+        Location l2 = createConcrete("2", MutableMap.of("name", "frank"));
+        assertEquals(l1, l1b);
+        assertNotEquals(l1, l2);
+    }
+
+    @Test
+    public void nullNameAndParentLocationIsAcceptable() {
+        Location location = createConcrete(MutableMap.of("name", null, "parentLocation", null));
+        assertEquals(location.getDisplayName(), null);
+        assertEquals(location.getParent(), null);
+    }
+
+    @Test
+    public void testSettingParentLocation() {
+        Location location = createConcrete();
+        Location locationSub = createConcrete();
+        locationSub.setParent(location);
+        
+        assertEquals(ImmutableList.copyOf(location.getChildren()), ImmutableList.of(locationSub));
+        assertEquals(locationSub.getParent(), location);
+    }
+
+    @Test
+    public void testClearingParentLocation() {
+        Location location = createConcrete();
+        Location locationSub = createConcrete();
+        locationSub.setParent(location);
+        
+        locationSub.setParent(null);
+        assertEquals(ImmutableList.copyOf(location.getChildren()), Collections.emptyList());
+        assertEquals(locationSub.getParent(), null);
+    }
+    
+    @Test
+    public void testContainsLocation() {
+        Location location = createConcrete();
+        Location locationSub = createConcrete();
+        locationSub.setParent(location);
+        
+        assertTrue(location.containsLocation(location));
+        assertTrue(location.containsLocation(locationSub));
+        assertFalse(locationSub.containsLocation(location));
+    }
+
+
+    @Test
+    public void queryingNameReturnsNameGivenInConstructor() {
+        String name = "Outer Mongolia";
+        Location location = createConcrete(MutableMap.of("name", "Outer Mongolia"));
+        assertEquals(location.getDisplayName(), name);;
+    }
+
+    @Test
+    public void constructorParentLocationReturnsExpectedLocation() {
+        Location parent = createConcrete(MutableMap.of("name", "Middle Earth"));
+        Location child = createConcrete(MutableMap.of("name", "The Shire", "parentLocation", parent));
+        assertEquals(child.getParent(), parent);
+        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
+    }
+
+    @Test
+    public void setParentLocationReturnsExpectedLocation() {
+        Location parent = createConcrete(MutableMap.of("name", "Middle Earth"));
+        Location child = createConcrete(MutableMap.of("name", "The Shire"));
+        child.setParent(parent);
+        assertEquals(child.getParent(), parent);
+        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
+    }
+    
+    @Test
+    public void testAddChildToParentLocationReturnsExpectedLocation() {
+        ConcreteLocation parent = createConcrete();
+        Location child = createConcrete();
+        parent.addChild(child);
+        assertEquals(child.getParent(), parent);
+        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
+    }
+
+    @Test
+    public void testFieldSetFromFlag() {
+        ConcreteLocation loc = createConcrete(MutableMap.of("myfield", "myval"));
+        assertEquals(loc.myfield, "myval");
+    }
+    
+    @Test
+    public void testFieldSetFromFlagUsesDefault() {
+        ConcreteLocation loc = createConcrete();
+        assertEquals(loc.myfield, "mydefault");
+    }
+
+    @Test
+    public void testLocationTags() throws Exception {
+        LocationInternal loc = mgmt.getLocationManager().createLocation(LocationSpec.create(ConcreteLocation.class).tag("x"));
+        assertEquals(loc.tags().getTags(), MutableSet.of("x"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
new file mode 100644
index 0000000..05b53b2
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import brooklyn.management.internal.LocalManagementContext;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class AggregatingMachineProvisioningLocationTest {
+
+    
+    private LocalManagementContext managementContext;
+    private AggregatingMachineProvisioningLocation<LocalhostMachine> aggregator;
+    private LocalhostMachine machine1a;
+    private LocalhostMachine machine1b;
+    private LocalhostMachine machine2a;
+    private LocalhostMachine machine2b;
+    private MachineProvisioningLocation<LocalhostMachine> provisioner1;
+    private MachineProvisioningLocation<LocalhostMachine> provisioner2;
+    
+    @BeforeMethod(alwaysRun=true)
+    @SuppressWarnings("unchecked")
+    public void setUp() {
+        managementContext = new LocalManagementContextForTests();
+        machine1a = newLocation(LocalhostMachine.class, "1a");
+        machine1b = newLocation(LocalhostMachine.class, "1b");
+        machine2a = newLocation(LocalhostMachine.class, "2a");
+        machine2b = newLocation(LocalhostMachine.class, "2b");
+        provisioner1 = newLocation(FixedListMachineProvisioningLocation.class, ImmutableMap.of("machines", ImmutableList.of(machine1a, machine1b)));
+        provisioner2 = newLocation(FixedListMachineProvisioningLocation.class, ImmutableMap.of("machines", ImmutableList.of(machine2a, machine2b)));
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testObtainAndRelease() throws Exception {
+        aggregator = newLocation(AggregatingMachineProvisioningLocation.class, ImmutableMap.of("provisioners", ImmutableList.of(provisioner1, provisioner2)));
+        assertEquals(aggregator.obtain(), machine1a);
+        assertEquals(aggregator.obtain(), machine2a);
+        assertEquals(aggregator.obtain(), machine1b);
+        assertEquals(aggregator.obtain(), machine2b);
+        
+        try {
+            aggregator.obtain();
+            fail();
+        } catch (NoMachinesAvailableException e) {
+            // success
+        }
+        
+        aggregator.release(machine2b);
+        assertEquals(aggregator.obtain(), machine2b);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void testReleaseWhenNotHeldThrows() throws Exception {
+        aggregator = newLocation(AggregatingMachineProvisioningLocation.class, ImmutableMap.of("provisioners", ImmutableList.of(provisioner1, provisioner2)));
+        try {
+            aggregator.release(machine1a);
+            fail();
+        } catch (IllegalStateException e) {
+            if (!e.toString().contains("machine is not currently allocated")) throw e;
+        }
+    }
+
+    private <T extends Location> T newLocation(Class<T> clazz, String displayName) {
+        return newLocation(clazz, displayName, ImmutableMap.of());
+    }
+
+    private <T extends Location> T newLocation(Class<T> clazz, Map<?,?> config) {
+        return newLocation(clazz, "mydisplayname", config);
+    }
+    
+    private <T extends Location> T newLocation(Class<T> clazz, String displayName, Map<?,?> config) {
+        return managementContext.getLocationManager().createLocation(LocationSpec.create(clazz)
+                .displayName(displayName)
+                .configure(config));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java
new file mode 100644
index 0000000..141ab5d
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java
@@ -0,0 +1,423 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Networking;
+import brooklyn.util.net.UserAndHostAndPort;
+import brooklyn.util.os.Os;
+import brooklyn.util.text.StringPredicates;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class ByonLocationResolverTest {
+
+    private static final Logger log = LoggerFactory.getLogger(ByonLocationResolverTest.class);
+    
+    private BrooklynProperties brooklynProperties;
+    private LocalManagementContext managementContext;
+    private Predicate<CharSequence> defaultNamePredicate;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+        brooklynProperties = managementContext.getBrooklynProperties();
+        defaultNamePredicate = StringPredicates.startsWith(FixedListMachineProvisioningLocation.class.getSimpleName());
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testTakesByonScopedProperties() {
+        brooklynProperties.put("brooklyn.location.byon.privateKeyFile", "myprivatekeyfile");
+        brooklynProperties.put("brooklyn.location.byon.publicKeyFile", "mypublickeyfile");
+        brooklynProperties.put("brooklyn.location.byon.privateKeyData", "myprivateKeyData");
+        brooklynProperties.put("brooklyn.location.byon.publicKeyData", "myPublicKeyData");
+        brooklynProperties.put("brooklyn.location.byon.privateKeyPassphrase", "myprivateKeyPassphrase");
+
+        Map<String, Object> conf = resolve("byon(hosts=\"1.1.1.1\")").config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
+        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
+        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
+        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
+        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
+    }
+
+    @Test
+    public void testNamedByonLocation() throws Exception {
+        brooklynProperties.put("brooklyn.location.named.mynamed", "byon(hosts=\"1.1.1.1\")");
+        
+        FixedListMachineProvisioningLocation<MachineLocation> loc = resolve("named:mynamed");
+        assertEquals(loc.obtain().getAddress(), InetAddress.getByName("1.1.1.1"));
+    }
+
+    @Test
+    public void testPropertiesInSpec() throws Exception {
+        FixedListMachineProvisioningLocation<MachineLocation> loc = resolve("byon(privateKeyFile=myprivatekeyfile,hosts=\"1.1.1.1\")");
+        SshMachineLocation machine = (SshMachineLocation)loc.obtain();
+        
+        assertEquals(machine.config().getBag().getStringKey("privateKeyFile"), "myprivatekeyfile");
+        assertEquals(machine.getAddress(), Networking.getInetAddressWithFixedName("1.1.1.1"));
+    }
+
+    @Test
+    public void testPropertyScopePrecedence() throws Exception {
+        brooklynProperties.put("brooklyn.location.named.mynamed", "byon(hosts=\"1.1.1.1\")");
+        
+        // prefer those in "named" over everything else
+        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
+        brooklynProperties.put("brooklyn.location.byon.privateKeyFile", "privateKeyFile-inProviderSpecific");
+        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
+
+        // prefer those in provider-specific over generic
+        brooklynProperties.put("brooklyn.location.byon.publicKeyFile", "publicKeyFile-inProviderSpecific");
+        brooklynProperties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inGeneric");
+
+        // prefer location-generic if nothing else
+        brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
+
+        Map<String, Object> conf = resolve("named:mynamed").config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
+        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
+        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
+    }
+
+    @Test
+    public void testThrowsOnInvalid() throws Exception {
+        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
+        assertThrowsIllegalArgument("byon"); // no hosts
+        assertThrowsIllegalArgument("byon()"); // no hosts
+        assertThrowsIllegalArgument("byon(hosts=\"\")"); // empty hosts
+        assertThrowsIllegalArgument("byon(hosts=\"1.1.1.1\""); // no closing bracket
+        assertThrowsIllegalArgument("byon(hosts=\"1.1.1.1\", name)"); // no value for name
+        assertThrowsIllegalArgument("byon(hosts=\"1.1.1.1\", name=)"); // no value for name
+    }
+    
+    @Test(expectedExceptions={IllegalArgumentException.class})
+    public void testRegistryCommaResolutionInListNotAllowed() throws NoMachinesAvailableException {
+        // disallowed since 0.7.0
+        // fails because it interprets the entire string as a single byon spec, which does not parse
+        managementContext.getLocationRegistry().resolve(ImmutableList.of("byon(hosts=\"192.168.0.1\",user=bob),byon(hosts=\"192.168.0.2\",user=bob2)"));
+    }
+
+    @Test
+    public void testResolvesHosts() throws Exception {
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1\")"), ImmutableSet.of("1.1.1.1"));
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1\")"), ImmutableSet.of("1.1.1.1"));
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1,1.1.1.2\")"), ImmutableSet.of("1.1.1.1","1.1.1.2"));
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1, 1.1.1.2\")"), ImmutableSet.of("1.1.1.1","1.1.1.2"));
+    }
+
+    @Test
+    public void testWithOldStyleColon() throws Exception {
+        assertByonClusterEquals(resolve("byon:(hosts=\"1.1.1.1\")"), ImmutableSet.of("1.1.1.1"));
+        assertByonClusterEquals(resolve("byon:(hosts=\"1.1.1.1\", name=myname)"), ImmutableSet.of("1.1.1.1"), "myname");
+    }
+
+    @Test
+    public void testUsesDisplayName() throws Exception {
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1\", name=myname)"), ImmutableSet.of("1.1.1.1"), "myname");
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.1\", name=\"myname\")"), ImmutableSet.of("1.1.1.1"), "myname");
+    }
+
+    @Test
+    public void testResolvesHostsGlobExpansion() throws Exception {
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.1.{1,2}\")"), ImmutableSet.of("1.1.1.1","1.1.1.2"));
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.{1.1,2.{1,2}}\")"), 
+                ImmutableSet.of("1.1.1.1","1.1.2.1","1.1.2.2"));
+        assertByonClusterEquals(resolve("byon(hosts=\"1.1.{1,2}.{1,2}\")"), 
+                ImmutableSet.of("1.1.1.1","1.1.1.2","1.1.2.1","1.1.2.2"));
+    }
+
+    @Test(groups="Integration")
+    public void testNiceError() throws Exception {
+        Asserts.assertFailsWith(new Runnable() {
+            @Override public void run() {
+                FixedListMachineProvisioningLocation<MachineLocation> x =
+                        resolve("byon(hosts=\"1.1.1.{1,2}}\")");
+                log.error("got "+x+" but should have failed (your DNS is giving an IP for hostname '1.1.1.1}' (with the extra '}')");
+            }
+        }, new Predicate<Throwable>() {
+            @Override
+            public boolean apply(@Nullable Throwable input) {
+                String s = input.toString();
+                // words
+                if (!s.contains("Invalid host")) return false;
+                // problematic entry
+                if (!s.contains("1.1.1.1}")) return false;
+                // original spec
+                if (!s.contains("1.1.1.{1,2}}")) return false;
+                return true;
+            }
+        });
+    }
+
+    @Test
+    public void testResolvesUsernameAtHost() throws Exception {
+        assertByonClusterWithUsersEquals(resolve("byon(hosts=\"myuser@1.1.1.1\")"), 
+                ImmutableSet.of(UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 22)));
+        assertByonClusterWithUsersEquals(resolve("byon(hosts=\"myuser@1.1.1.1,myuser2@1.1.1.1\")"), ImmutableSet.of(
+                UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 22), UserAndHostAndPort.fromParts("myuser2", "1.1.1.1", 22)));
+        assertByonClusterWithUsersEquals(resolve("byon(hosts=\"myuser@1.1.1.1,myuser2@1.1.1.2\")"), ImmutableSet.of(
+                UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 22), UserAndHostAndPort.fromParts("myuser2", "1.1.1.2", 22)));
+    }
+
+    @Test
+    public void testResolvesUserArg() throws Exception {
+        assertByonClusterWithUsersEquals(resolve("byon(hosts=\"1.1.1.1\",user=bob)"), 
+                ImmutableSet.of(UserAndHostAndPort.fromParts("bob", "1.1.1.1", 22)));
+        assertByonClusterWithUsersEquals(resolve("byon(user=\"bob\",hosts=\"myuser@1.1.1.1,1.1.1.1\")"), 
+                ImmutableSet.of(UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 22), UserAndHostAndPort.fromParts("bob", "1.1.1.1", 22)));
+    }
+
+    @Test
+    public void testResolvesUserArg2() throws Exception {
+        String spec = "byon(hosts=\"1.1.1.1\",user=bob)";
+        FixedListMachineProvisioningLocation<MachineLocation> ll = resolve(spec);
+        SshMachineLocation l = (SshMachineLocation)ll.obtain();
+        Assert.assertEquals("bob", l.getUser());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testResolvesUserArg3() throws Exception {
+        String spec = "byon(hosts=\"1.1.1.1\")";
+        managementContext.getLocationRegistry().getProperties().putAll(MutableMap.of(
+                "brooklyn.location.named.foo", spec,
+                "brooklyn.location.named.foo.user", "bob"));
+        ((BasicLocationRegistry)managementContext.getLocationRegistry()).updateDefinedLocations();
+        
+        MachineProvisioningLocation<SshMachineLocation> ll = (MachineProvisioningLocation<SshMachineLocation>)
+                new NamedLocationResolver().newLocationFromString(MutableMap.of(), "named:foo", managementContext.getLocationRegistry());
+        SshMachineLocation l = ll.obtain(MutableMap.of());
+        Assert.assertEquals("bob", l.getUser());
+    }
+
+    @Test
+    public void testResolvesPortArg() throws Exception {
+        assertByonClusterWithUsersEquals(resolve("byon(user=bob,port=8022,hosts=\"1.1.1.1\")"), 
+                ImmutableSet.of(UserAndHostAndPort.fromParts("bob", "1.1.1.1", 8022)));
+        assertByonClusterWithUsersEquals(resolve("byon(user=bob,port=8022,hosts=\"myuser@1.1.1.1,1.1.1.2:8901\")"), 
+                ImmutableSet.of(UserAndHostAndPort.fromParts("myuser", "1.1.1.1", 8022), UserAndHostAndPort.fromParts("bob", "1.1.1.2", 8901)));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    /** private key should be inherited, so confirm that happens correctly */
+    public void testResolvesPrivateKeyArgInheritance() throws Exception {
+        String spec = "byon(hosts=\"1.1.1.1\")";
+        managementContext.getLocationRegistry().getProperties().putAll(MutableMap.of(
+                "brooklyn.location.named.foo", spec,
+                "brooklyn.location.named.foo.user", "bob",
+                "brooklyn.location.named.foo.privateKeyFile", "/tmp/x"));
+        ((BasicLocationRegistry)managementContext.getLocationRegistry()).updateDefinedLocations();
+        
+        MachineProvisioningLocation<SshMachineLocation> ll = (MachineProvisioningLocation<SshMachineLocation>) 
+                new NamedLocationResolver().newLocationFromString(MutableMap.of(), "named:foo", managementContext.getLocationRegistry());
+        
+        Assert.assertEquals("/tmp/x", ll.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE));
+        Assert.assertTrue(((LocationInternal)ll).config().getLocalRaw(LocationConfigKeys.PRIVATE_KEY_FILE).isPresent());
+        Assert.assertEquals("/tmp/x", ((LocationInternal)ll).config().getLocalBag().getStringKey(LocationConfigKeys.PRIVATE_KEY_FILE.getName()));
+        Assert.assertEquals("/tmp/x", ((LocationInternal)ll).config().getBag().get(LocationConfigKeys.PRIVATE_KEY_FILE));
+
+        SshMachineLocation l = ll.obtain(MutableMap.of());
+        
+        Assert.assertEquals("/tmp/x", l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE));
+        
+        Assert.assertTrue(l.config().getRaw(LocationConfigKeys.PRIVATE_KEY_FILE).isPresent());
+        Assert.assertTrue(l.config().getLocalRaw(LocationConfigKeys.PRIVATE_KEY_FILE).isAbsent());
+
+        Assert.assertEquals("/tmp/x", l.config().getBag().getStringKey(LocationConfigKeys.PRIVATE_KEY_FILE.getName()));
+        Assert.assertEquals("/tmp/x", l.config().getBag().getStringKey(LocationConfigKeys.PRIVATE_KEY_FILE.getName()));
+
+        Assert.assertEquals("/tmp/x", l.config().getBag().get(LocationConfigKeys.PRIVATE_KEY_FILE));
+    }
+
+    @Test
+    public void testResolvesLocalTempDir() throws Exception {
+        String localTempDir = Os.mergePaths(Os.tmp(), "testResolvesUsernameAtHost");
+        brooklynProperties.put("brooklyn.location.byon.localTempDir", localTempDir);
+
+        FixedListMachineProvisioningLocation<MachineLocation> byon = resolve("byon(hosts=\"1.1.1.1\",osFamily=\"windows\")");
+        MachineLocation machine = byon.obtain();
+        assertEquals(machine.getConfig(SshMachineLocation.LOCAL_TEMP_DIR), localTempDir);
+    }
+
+    @Test
+    public void testMachinesObtainedInOrder() throws Exception {
+        List<String> ips = ImmutableList.of("1.1.1.1", "1.1.1.6", "1.1.1.3", "1.1.1.4", "1.1.1.5");
+        String spec = "byon(hosts=\""+Joiner.on(",").join(ips)+"\")";
+        
+        MachineProvisioningLocation<MachineLocation> ll = resolve(spec);
+
+        for (String expected : ips) {
+            MachineLocation obtained = ll.obtain(ImmutableMap.of());
+            assertEquals(obtained.getAddress().getHostAddress(), expected);
+        }
+    }
+    
+    @Test
+    public void testEmptySpec() throws Exception {
+        String spec = "byon";
+        Map<String, ?> flags = ImmutableMap.of(
+                "hosts", ImmutableList.of("1.1.1.1", "2.2.2.22"),
+                "name", "foo",
+                "user", "myuser"
+        );
+        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
+        SshMachineLocation location1 = (SshMachineLocation)provisioner.obtain(ImmutableMap.of());
+        Assert.assertEquals("myuser", location1.getUser());
+        Assert.assertEquals("1.1.1.1", location1.getAddress().getHostAddress());
+    }
+
+    @Test
+    public void testWindowsMachines() throws Exception {
+        brooklynProperties.put("brooklyn.location.byon.user", "myuser");
+        brooklynProperties.put("brooklyn.location.byon.password", "mypassword");
+        String spec = "byon";
+        Map<String, ?> flags = ImmutableMap.of(
+                "hosts", ImmutableList.of("1.1.1.1", "2.2.2.2"),
+                "osfamily", "windows"
+        );
+        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
+        WinRmMachineLocation location = (WinRmMachineLocation) provisioner.obtain(ImmutableMap.of());
+
+        assertEquals(location.config().get(WinRmMachineLocation.USER), "myuser");
+        assertEquals(location.config().get(WinRmMachineLocation.PASSWORD), "mypassword");
+        assertEquals(location.config().get(WinRmMachineLocation.ADDRESS).getHostAddress(), "1.1.1.1");
+    }
+
+    @Test
+    public void testNoneWindowsMachines() throws Exception {
+        String spec = "byon";
+        Map<String, ?> flags = ImmutableMap.of(
+                "hosts", ImmutableList.of("1.1.1.1", "2.2.2.2"),
+                "osfamily", "linux"
+        );
+        MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
+        MachineLocation location = provisioner.obtain(ImmutableMap.of());
+        assertTrue(location instanceof SshMachineLocation, "Expected location to be SshMachineLocation, found " + location);
+    }
+
+    @Test
+    public void testAdditionalConfig() throws Exception {
+        FixedListMachineProvisioningLocation<MachineLocation> loc = resolve("byon(mykey=myval,hosts=\"1.1.1.1\")");
+        MachineLocation machine = loc.obtain(ImmutableMap.of());
+        assertEquals(machine.getConfig(ConfigKeys.newConfigKey(String.class, "mykey")), "myval");
+    }
+
+    private void assertByonClusterEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<String> expectedHosts) {
+        assertByonClusterEquals(cluster, expectedHosts, defaultNamePredicate);
+    }
+    
+    private void assertByonClusterEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<String> expectedHosts, String expectedName) {
+        assertByonClusterEquals(cluster, expectedHosts, Predicates.equalTo(expectedName));
+    }
+    
+    private void assertByonClusterEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<String> expectedHosts, Predicate<? super String> expectedName) {
+        Set<String> actualHosts = ImmutableSet.copyOf(Iterables.transform(cluster.getMachines(), new Function<MachineLocation, String>() {
+            @Override public String apply(MachineLocation input) {
+                return input.getAddress().getHostName();
+            }}));
+        assertEquals(actualHosts, expectedHosts);
+        assertTrue(expectedName.apply(cluster.getDisplayName()), "name="+cluster.getDisplayName());
+    }
+
+    private void assertByonClusterWithUsersEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<UserAndHostAndPort> expectedHosts) {
+        assertByonClusterWithUsersEquals(cluster, expectedHosts, defaultNamePredicate);
+    }
+    
+    private void assertByonClusterWithUsersEquals(FixedListMachineProvisioningLocation<? extends MachineLocation> cluster, Set<UserAndHostAndPort> expectedHosts, Predicate<? super String> expectedName) {
+        Set<UserAndHostAndPort> actualHosts = ImmutableSet.copyOf(Iterables.transform(cluster.getMachines(), new Function<MachineLocation, UserAndHostAndPort>() {
+            @Override public UserAndHostAndPort apply(MachineLocation input) {
+                SshMachineLocation machine = (SshMachineLocation) input;
+                return UserAndHostAndPort.fromParts(machine.getUser(), machine.getAddress().getHostName(), machine.getPort());
+            }}));
+        assertEquals(actualHosts, expectedHosts);
+        assertTrue(expectedName.apply(cluster.getDisplayName()), "name="+cluster.getDisplayName());
+    }
+
+    private void assertThrowsNoSuchElement(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (NoSuchElementException e) {
+            // success
+        }
+    }
+    
+    private void assertThrowsIllegalArgument(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private FixedListMachineProvisioningLocation<MachineLocation> resolve(String val) {
+        return (FixedListMachineProvisioningLocation<MachineLocation>) managementContext.getLocationRegistry().resolve(val);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private FixedListMachineProvisioningLocation<MachineLocation> resolve(String val, Map<?, ?> locationFlags) {
+        return (FixedListMachineProvisioningLocation<MachineLocation>) managementContext.getLocationRegistry().resolve(val, locationFlags);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
new file mode 100644
index 0000000..c4df75f
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.File;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.rebind.RebindTestUtils;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.os.Os;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class FixedListMachineProvisioningLocationRebindTest {
+
+    private FixedListMachineProvisioningLocation<SshMachineLocation> origLoc;
+    private ClassLoader classLoader = getClass().getClassLoader();
+    private ManagementContext origManagementContext;
+    private TestApplication origApp;
+    private TestApplication newApp;
+    private File mementoDir;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        mementoDir = Os.newTempDir(getClass());
+        origManagementContext = RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
+        
+        origLoc = new FixedListMachineProvisioningLocation.Builder(origManagementContext.getLocationManager())
+                .addAddresses("localhost", "127.0.0.1")
+                .user("myuser")
+                .keyFile("/path/to/myPrivateKeyFile")
+                .keyData("myKeyData")
+                .keyPassphrase("myKeyPassphrase")
+                .build();
+        origApp = ApplicationBuilder.newManagedApp(TestApplication.class, origManagementContext);
+        origApp.start(ImmutableList.of(origLoc));
+    }
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() throws Exception {
+        if (origManagementContext != null) Entities.destroyAll(origManagementContext);
+        if (newApp != null) Entities.destroyAll(newApp.getManagementContext());
+        if (mementoDir != null) RebindTestUtils.deleteMementoDir(mementoDir);
+    }
+    
+    @Test
+    public void testRebindPreservesConfig() throws Exception {
+        newApp = rebind();
+        FixedListMachineProvisioningLocation<SshMachineLocation> newLoc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(newApp.getLocations(), 0);
+        
+        assertEquals(newLoc.getId(), origLoc.getId());
+        assertEquals(newLoc.getDisplayName(), origLoc.getDisplayName());
+        assertEquals(newLoc.getHostGeoInfo(), origLoc.getHostGeoInfo());
+        assertEquals(newLoc.getConfig(LocationConfigKeys.USER), origLoc.getConfig(LocationConfigKeys.USER));
+        assertEquals(newLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE), origLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE));
+        assertEquals(newLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), origLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE));
+        assertEquals(newLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_DATA), origLoc.getConfig(LocationConfigKeys.PRIVATE_KEY_DATA));
+    }
+
+    @Test
+    public void testRebindParentRelationship() throws Exception {
+        newApp = rebind();
+        FixedListMachineProvisioningLocation<SshMachineLocation> newLoc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(newApp.getLocations(), 0);
+        
+        assertLocationIdsEqual(newLoc.getChildren(), origLoc.getChildren());
+        assertEquals(Iterables.get(newLoc.getChildren(), 0).getParent(), newLoc);
+        assertEquals(Iterables.get(newLoc.getChildren(), 1).getParent(), newLoc);
+    }
+
+    @Test
+    public void testRebindPreservesInUseMachines() throws Exception {
+        SshMachineLocation inuseMachine = origLoc.obtain();
+        origApp.setAttribute(TestApplication.SERVICE_UP, true); // to force persist, and thus avoid race
+        
+        newApp = rebind();
+        FixedListMachineProvisioningLocation<SshMachineLocation> newLoc = (FixedListMachineProvisioningLocation<SshMachineLocation>) Iterables.get(newApp.getLocations(), 0);
+        
+        assertLocationIdsEqual(newLoc.getInUse(), origLoc.getInUse());
+        assertLocationIdsEqual(newLoc.getAvailable(), origLoc.getAvailable());
+    }
+
+    private TestApplication rebind() throws Exception {
+        RebindTestUtils.waitForPersisted(origApp);
+        return (TestApplication) RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
+    }
+    
+    private void assertLocationIdsEqual(Iterable<? extends Location> actual, Iterable<? extends Location> expected) {
+        Function<Location, String> locationIdFunction = new Function<Location, String>() {
+            @Override public String apply(@Nullable Location input) {
+                return (input != null) ? input.getId() : null;
+            }
+        };
+        Set<String> actualIds = MutableSet.copyOf(Iterables.transform(actual, locationIdFunction));
+        Set<String> expectedIds = MutableSet.copyOf(Iterables.transform(expected, locationIdFunction));
+        
+        assertEquals(actualIds, expectedIds);
+    }
+}


[19/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationConfig.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationConfig.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationConfig.java
deleted file mode 100644
index 2d570ae..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationConfig.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Semaphore;
-
-import org.jclouds.Constants;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.OsFamily;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.domain.LoginCredentials;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.access.PortForwardManager;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension;
-import brooklyn.util.internal.ssh.SshTool;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.reflect.TypeToken;
-
-public interface JcloudsLocationConfig extends CloudLocationConfig {
-
-    public static final ConfigKey<String> CLOUD_PROVIDER = LocationConfigKeys.CLOUD_PROVIDER;
-
-    public static final ConfigKey<Boolean> RUN_AS_ROOT = ConfigKeys.newBooleanConfigKey("runAsRoot", 
-            "Whether to run initial setup as root (default true)", null);
-    public static final ConfigKey<String> LOGIN_USER = ConfigKeys.newStringConfigKey("loginUser",
-            "Override the user who logs in initially to perform setup " +
-            "(otherwise it is detected from the cloud or known defaults in cloud or VM OS)", null);
-    public static final ConfigKey<String> LOGIN_USER_PASSWORD = ConfigKeys.newStringConfigKey("loginUser.password",
-            "Custom password for the user who logs in initially", null);
-    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_DATA = ConfigKeys.newStringConfigKey("loginUser.privateKeyData",
-            "Custom private key for the user who logs in initially", null);   
-    public static final ConfigKey<String> KEY_PAIR = ConfigKeys.newStringConfigKey("keyPair",
-            "Custom keypair name to be re-used", null);
-    public static final ConfigKey<Boolean> AUTO_GENERATE_KEYPAIRS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-generate-keypairs",
-            "Whether to generate keypairs for Nova");
-    /**
-     * @deprecated since 0.7.0 Use {@link #AUTO_ASSIGN_FLOATING_IP} instead
-     */
-    public static final ConfigKey<Boolean> AUTO_CREATE_FLOATING_IPS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-create-floating-ips",
-            "Whether to generate floating ips for Nova");
-    public static final ConfigKey<Boolean> AUTO_ASSIGN_FLOATING_IP = ConfigKeys.newBooleanConfigKey("autoAssignFloatingIp",
-            "Whether to generate floating ips (in Nova paralance), or elastic IPs (in CloudStack parlance)");
-    // not supported in jclouds
-//    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_PASSPHRASE = ConfigKeys.newStringKey("loginUser.privateKeyPassphrase", 
-//            "Passphrase for the custom private key for the user who logs in initially", null);
-    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_FILE = ConfigKeys.newStringConfigKey("loginUser.privateKeyFile",
-            "Custom private key for the user who logs in initially", null); 
-    public static final ConfigKey<String> EXTRA_PUBLIC_KEY_DATA_TO_AUTH = ConfigKeys.newStringConfigKey("extraSshPublicKeyData",
-        "Additional public key data to add to authorized_keys", null);
-    @SuppressWarnings("serial")
-    public static final ConfigKey<List<String>> EXTRA_PUBLIC_KEY_URLS_TO_AUTH = ConfigKeys.newConfigKey(new TypeToken<List<String>>() {}, 
-        "extraSshPublicKeyUrls", "Additional public keys (files or URLs, in SSH2/RFC4716/id_rsa.pub format) to add to authorized_keys", null);
-
-    public static final ConfigKey<Boolean> DONT_CREATE_USER = ConfigKeys.newBooleanConfigKey("dontCreateUser", 
-            "Whether to skip creation of 'user' when provisioning machines (default false)", false);
-    public static final ConfigKey<Boolean> GRANT_USER_SUDO = ConfigKeys.newBooleanConfigKey("grantUserSudo",
-            "Whether to grant the created user sudo privileges. Irrelevant if dontCreateUser is true. Default: true.", true);
-    public static final ConfigKey<Boolean> DISABLE_ROOT_AND_PASSWORD_SSH = ConfigKeys.newBooleanConfigKey("disableRootAndPasswordSsh",
-        "Whether to disable direct SSH access for root and disable password-based SSH, "
-        + "if creating a user with a key-based login; "
-        + "defaults to true (set false to leave root users alone)", true);
-    public static final ConfigKey<String> CUSTOM_TEMPLATE_OPTIONS_SCRIPT_CONTENTS = ConfigKeys.newStringConfigKey("customTemplateOptionsScriptContents",
-        "A custom script to pass to jclouds as part of template options, run after AdminAccess, "
-        + "for use primarily where a command which must run as root on first login before switching to the admin user, "
-        + "e.g. to customize sudoers; may start in an odd location (e.g. /tmp/bootstrap); "
-        + "NB: most commands should be run by entities, or if VM-specific but sudo is okay, then via setup.script, not via this");
-    
-    public static final ConfigKey<LoginCredentials> CUSTOM_CREDENTIALS = new BasicConfigKey<LoginCredentials>(LoginCredentials.class,
-            "customCredentials", "Custom jclouds LoginCredentials object to be used to connect to the VM", null);
-    
-    public static final ConfigKey<String> GROUP_ID = ConfigKeys.newStringConfigKey("groupId",
-            "The Jclouds group provisioned machines should be members of. " +
-            "Users of this config key are also responsible for configuring security groups.");
-    
-    // jclouds compatibility
-    public static final ConfigKey<String> JCLOUDS_KEY_USERNAME = ConfigKeys.newStringConfigKey(
-            "userName", "Equivalent to 'user'; provided for jclouds compatibility", null);
-    public static final ConfigKey<String> JCLOUDS_KEY_ENDPOINT = ConfigKeys.newStringConfigKey(
-            Constants.PROPERTY_ENDPOINT, "Equivalent to 'endpoint'; provided for jclouds compatibility", null);
-    
-    // note causing problems on centos due to use of `sudo -n`; but required for default RHEL VM
-    /**
-     * @deprecated since 0.8.0; instead configure this on the entity. See SoftwareProcess.OPEN_IPTABLES.
-     */
-    @Deprecated
-    public static final ConfigKey<Boolean> OPEN_IPTABLES = ConfigKeys.newBooleanConfigKey("openIptables", 
-            "[DEPRECATED - use openIptables on SoftwareProcess entity] Whether to open the INBOUND_PORTS via iptables rules; " +
-            "if true then ssh in to run iptables commands, as part of machine provisioning", false);
-
-    /**
-     * @deprecated since 0.8.0; instead configure this on the entity. See SoftwareProcess.STOP_IPTABLES.
-     */
-    @Deprecated
-    public static final ConfigKey<Boolean> STOP_IPTABLES = ConfigKeys.newBooleanConfigKey("stopIptables", 
-            "[DEPRECATED - use stopIptables on SoftwareProcess entity] Whether to stop iptables entirely; " +
-            "if true then ssh in to stop the iptables service, as part of machine provisioning", false);
-
-    public static final ConfigKey<String> HARDWARE_ID = ConfigKeys.newStringConfigKey("hardwareId",
-            "A system-specific identifier for the hardware profile or machine type to be used when creating a VM", null);
-    
-    public static final ConfigKey<String> IMAGE_ID = ConfigKeys.newStringConfigKey("imageId", 
-            "A system-specific identifier for the VM image to be used when creating a VM", null);
-    public static final ConfigKey<String> IMAGE_NAME_REGEX = ConfigKeys.newStringConfigKey("imageNameRegex", 
-            "A regular expression to be compared against the 'name' when selecting the VM image to be used when creating a VM", null);
-    public static final ConfigKey<String> IMAGE_DESCRIPTION_REGEX = ConfigKeys.newStringConfigKey("imageDescriptionRegex", 
-            "A regular expression to be compared against the 'description' when selecting the VM image to be used when creating a VM", null);
-
-    public static final ConfigKey<String> TEMPLATE_SPEC = ConfigKeys.newStringConfigKey("templateSpec", 
-            "A jclouds 'spec' string consisting of properties and values to be used when creating a VM " +
-            "(in most cases the properties can, and should, be specified individually using other Brooklyn location config keys)", null);
-
-    public static final ConfigKey<String> DEFAULT_IMAGE_ID = ConfigKeys.newStringConfigKey("defaultImageId", 
-            "A system-specific identifier for the VM image to be used by default when creating a VM " +
-            "(if no other VM image selection criteria are supplied)", null);
-
-    public static final ConfigKey<TemplateBuilder> TEMPLATE_BUILDER = ConfigKeys.newConfigKey(TemplateBuilder.class,
-            "templateBuilder", "A TemplateBuilder instance provided programmatically, to be used when creating a VM");
-
-    public static final ConfigKey<Object> SECURITY_GROUPS = new BasicConfigKey<Object>(Object.class, "securityGroups",
-            "Security groups to be applied when creating a VM, on supported clouds " +
-            "(either a single group identifier as a String, or an Iterable<String> or String[])", null);
-
-    public static final ConfigKey<String> USER_METADATA_STRING = ConfigKeys.newStringConfigKey("userMetadataString", 
-        "Arbitrary user data, as a single string, on supported clouds (AWS)", null);
-
-    @Deprecated /** @deprecated since 0.7.0 even AWS (the only one where this was supported) does not seem to want this uuencoded;
-      use #USER_METADATA_STRING */
-    public static final ConfigKey<String> USER_DATA_UUENCODED = ConfigKeys.newStringConfigKey("userData", 
-        "Arbitrary user data, as a single string in uuencoded format, on supported clouds (AWS)", null);
-
-    public static final ConfigKey<Object> STRING_TAGS = new BasicConfigKey<Object>(Object.class, "tags", 
-            "Tags to be applied when creating a VM, on supported clouds " +
-            "(either a single tag as a String, or an Iterable<String> or String[];" +
-            "note this is not key-value pairs (e.g. what AWS calls 'tags'), for that see userMetadata)", null);
-
-    @Deprecated /** @deprecated since 0.7.0 use #STRING_TAGS */
-    public static final ConfigKey<Object> TAGS = STRING_TAGS;
-
-    public static final ConfigKey<Object> USER_METADATA_MAP = new BasicConfigKey<Object>(Object.class, "userMetadata", 
-            "Arbitrary user metadata, as a map (or String of comma-separated key=value pairs), on supported clouds; " +
-            "note often values cannot be null", null);
-    @Deprecated /** @deprecated since 0.7.0 use #USER_METADATA_MAP */
-    public static final ConfigKey<Object> USER_METADATA = USER_METADATA_MAP;
-
-    public static final ConfigKey<Boolean> INCLUDE_BROOKLYN_USER_METADATA = ConfigKeys.newBooleanConfigKey("includeBrooklynUserMetadata", 
-        "Whether to set metadata about the context of a machine, e.g. brooklyn-entity-id, brooklyn-app-name (default true)", true);
-
-    public static final ConfigKey<Boolean> MAP_DEV_RANDOM_TO_DEV_URANDOM = ConfigKeys.newBooleanConfigKey(
-            "installDevUrandom", "Map /dev/random to /dev/urandom to prevent halting on insufficient entropy", true);
-
-    /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */
-    @Deprecated
-    public static final ConfigKey<JcloudsLocationCustomizer> JCLOUDS_LOCATION_CUSTOMIZER = ConfigKeys.newConfigKey(JcloudsLocationCustomizer.class,
-            "customizer", "Optional location customizer");
-
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Collection<JcloudsLocationCustomizer>> JCLOUDS_LOCATION_CUSTOMIZERS = ConfigKeys.newConfigKey(
-            new TypeToken<Collection<JcloudsLocationCustomizer>>() {},
-            "customizers", "Optional location customizers");
-
-    /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */
-    @Deprecated
-    public static final ConfigKey<String> JCLOUDS_LOCATION_CUSTOMIZER_TYPE = ConfigKeys.newStringConfigKey(
-            "customizerType", "Optional location customizer type (to be class-loaded and constructed with no-arg constructor)");
-
-    /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */
-    @Deprecated
-    public static final ConfigKey<String> JCLOUDS_LOCATION_CUSTOMIZERS_SUPPLIER_TYPE = ConfigKeys.newStringConfigKey(
-            "customizersSupplierType", "Optional type of a Supplier<Collection<JcloudsLocationCustomizer>> " +
-            "(to be class-loaded and constructed with ConfigBag or no-arg constructor)");
-
-    public static final ConfigKey<String> LOCAL_TEMP_DIR = SshTool.PROP_LOCAL_TEMP_DIR;
-    
-    public static final ConfigKey<Integer> OVERRIDE_RAM = ConfigKeys.newIntegerConfigKey("overrideRam", "Custom ram value");    
-    
-    public static final ConfigKey<String> NETWORK_NAME = ConfigKeys.newStringConfigKey(
-        "networkName", "Network name or ID where the instance should be created (e.g. the subnet ID in AWS");
-
-    /**
-     * CUSTOM_MACHINE_SETUP_SCRIPT_URL accepts a URL location that points to a shell script. 
-     * Please have a look at locations/jclouds/src/main/resources/sample/script/setup-server.sh as an example
-     */
-    public static final ConfigKey<String> CUSTOM_MACHINE_SETUP_SCRIPT_URL = ConfigKeys.newStringConfigKey(
-            "setup.script", "Custom script to customize a node");
-    
-    @SuppressWarnings("serial")
-    public static final ConfigKey<List<String>> CUSTOM_MACHINE_SETUP_SCRIPT_URL_LIST = ConfigKeys.newConfigKey(new TypeToken<List<String>>() {},
-            "setup.scripts", "A list of scripts to customize a node");
-    
-    public static final ConfigKey<String> CUSTOM_MACHINE_SETUP_SCRIPT_VARS = ConfigKeys.newStringConfigKey(
-            "setup.script.vars", "vars to customize a setup.script i.e.: key1:value1,key2:value2");
-    
-    public static final ConfigKey<Boolean> GENERATE_HOSTNAME = ConfigKeys.newBooleanConfigKey(
-            "generate.hostname", "Use the nodename generated by jclouds", false);
-
-    public static final ConfigKey<Boolean> USE_PORT_FORWARDING = ConfigKeys.newBooleanConfigKey(
-            "portforwarding.enabled", 
-            "Whether to setup port-forwarding to subsequently access the VM (over the ssh port)",
-            false);
-    
-    @Beta
-    public static final ConfigKey<Boolean> USE_JCLOUDS_SSH_INIT = ConfigKeys.newBooleanConfigKey(
-            "useJcloudsSshInit", 
-            "Whether to use jclouds for initial ssh-based setup (i.e. as part of the 'TemplateOptions'); "
-                    + "if false will use core brooklyn ssh utilities. "
-                    + "This config is beta; its default could be changed and/or the option removed in an upcoming release.", 
-            true);
-    
-    public static final ConfigKey<JcloudsPortForwarderExtension> PORT_FORWARDER = ConfigKeys.newConfigKey(
-            JcloudsPortForwarderExtension.class, "portforwarding.forwarder", "The port-forwarder to use");
-    
-    public static final ConfigKey<PortForwardManager> PORT_FORWARDING_MANAGER = BrooklynAccessUtils
-            .PORT_FORWARDING_MANAGER;
-
-    public static final ConfigKey<Integer> MACHINE_CREATE_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
-            "machineCreateAttempts", "Number of times to retry if jclouds fails to create a VM", 1);
-
-    public static final ConfigKey<Integer> MAX_CONCURRENT_MACHINE_CREATIONS = ConfigKeys.newIntegerConfigKey(
-            "maxConcurrentMachineCreations", "Maximum number of concurrent machine-creations", Integer.MAX_VALUE);
-
-    public static final ConfigKey<Semaphore> MACHINE_CREATION_SEMAPHORE = ConfigKeys.newConfigKey(
-            Semaphore.class, "machineCreationSemaphore", "Semaphore for controlling concurrent machine creation", null);
-
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Function<Iterable<? extends Image>,Image>> IMAGE_CHOOSER = ConfigKeys.newConfigKey(
-        new TypeToken<Function<Iterable<? extends Image>,Image>>() {},
-        "imageChooser", "An image chooser function to control which images are preferred", 
-        new BrooklynImageChooser().chooser());
-
-    public static final ConfigKey<OsFamily> OS_FAMILY = ConfigKeys.newConfigKey(OsFamily.class, "osFamily", 
-        "OS family, e.g. CentOS, Debian, RHEL, Ubuntu");
-    public static final ConfigKey<String> OS_VERSION_REGEX = ConfigKeys.newStringConfigKey("osVersionRegex", 
-        "Regular expression for the OS version to load");
-
-    public static final ConfigKey<OsFamily> OS_FAMILY_OVERRIDE = ConfigKeys.newConfigKey(OsFamily.class, "osFamilyOverride", 
-            "OS family of VMs (ignores VM metadata from jclouds, and assumes this value)");
-
-    public static final ConfigKey<ComputeServiceRegistry> COMPUTE_SERVICE_REGISTRY = ConfigKeys.newConfigKey(
-            ComputeServiceRegistry.class,
-            "jclouds.computeServiceRegistry",
-            "Registry/Factory for creating jclouds ComputeService; default is almost always fine, except where tests want to customize behaviour",
-            ComputeServiceRegistryImpl.INSTANCE);
-    
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Map<String,Object>> TEMPLATE_OPTIONS = ConfigKeys.newConfigKey(
-            new TypeToken<Map<String, Object>>() {}, "templateOptions", "Additional jclouds template options");
-
-    // TODO
-    
-//  "noDefaultSshKeys" - hints that local ssh keys should not be read as defaults
-    // this would be useful when we need to indicate a password
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationCustomizer.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationCustomizer.java
deleted file mode 100644
index a21891c..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationCustomizer.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.options.TemplateOptions;
-
-import com.google.common.annotations.Beta;
-
-import brooklyn.util.config.ConfigBag;
-
-/**
- * Customization hooks to allow apps to perform specific customisation at each stage of jclouds machine provisioning.
- * For example, an app could attach an EBS volume to an EC2 node, or configure a desired availability zone.
- * <p/>
- * Instances will be invoked with the {@link ConfigBag} being used to obtain a machine by the
- * {@link JcloudsLocation }if such a constructor exists. If not, the default no argument constructor
- * will be invoked.
- */
-@Beta
-public interface JcloudsLocationCustomizer {
-
-    /**
-     * Override to configure {@link org.jclouds.compute.domain.TemplateBuilder templateBuilder}
-     * before it is built and immutable.
-     */
-    void customize(JcloudsLocation location, ComputeService computeService, TemplateBuilder templateBuilder);
-
-    /**
-     * Override to configure a subclass of this with the built template, or to configure the built
-     * template's {@link org.jclouds.compute.options.TemplateOptions}.
-     * <p/>
-     * This method will be called before {@link #customize(JcloudsLocation, ComputeService, TemplateOptions)}.
-     */
-    void customize(JcloudsLocation location, ComputeService computeService, Template template);
-
-    /**
-     * Override to configure the {@link org.jclouds.compute.options.TemplateOptions} that will
-     * be used by {@link brooklyn.location.jclouds.JcloudsLocation} to obtain machines.
-     */
-    void customize(JcloudsLocation location, ComputeService computeService, TemplateOptions templateOptions);
-
-    /**
-     * Override to configure the given machine once it has been created and started by Jclouds.
-     * <p/>
-     * If {@link brooklyn.location.jclouds.JcloudsLocationConfig#WAIT_FOR_SSHABLE} is true the
-     * machine is guaranteed to be SSHable when this method is called.
-     * 
-     * @since 0.7.0; use {@link #customize(JcloudsLocation, ComputeService, JcloudsMachineLocation)}
-     */
-    @Deprecated
-    void customize(JcloudsLocation location, ComputeService computeService, JcloudsSshMachineLocation machine);
-    
-    /**
-     * Override to handle machine-related cleanup before Jclouds is called to release (destroy) the machine.
-     * 
-     * @since 0.7.0; use {@link #preRelease(JcloudsMachineLocation)}
-     */
-    @Deprecated
-    void preRelease(JcloudsSshMachineLocation machine);
-
-    /**
-     * Override to handle machine-related cleanup after Jclouds is called to release (destroy) the machine.
-     * 
-     * @since 0.7.0; use {@link #postRelesae(JcloudsMachineLocation)}
-     */
-    @Deprecated
-    void postRelease(JcloudsSshMachineLocation machine);
-
-    /**
-     * Override to configure the given machine once it has been created and started by Jclouds.
-     * <p/>
-     * If {@link brooklyn.location.jclouds.JcloudsLocationConfig#WAIT_FOR_SSHABLE} is true the
-     * machine is guaranteed to be SSHable when this method is called.
-     */
-    void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine);
-    
-    /**
-     * Override to handle machine-related cleanup before Jclouds is called to release (destroy) the machine.
-     */
-    void preRelease(JcloudsMachineLocation machine);
-
-    /**
-     * Override to handle machine-related cleanup after Jclouds is called to release (destroy) the machine.
-     */
-    void postRelease(JcloudsMachineLocation machine);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationResolver.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationResolver.java
deleted file mode 100644
index 0a07898..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationResolver.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.jclouds.apis.ApiMetadata;
-import org.jclouds.apis.Apis;
-import org.jclouds.providers.ProviderMetadata;
-import org.jclouds.providers.Providers;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.BasicLocationRegistry;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.LocationConfigUtils;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.util.text.Strings;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-@SuppressWarnings("rawtypes")
-public class JcloudsLocationResolver implements LocationResolver {
-
-    public static final Logger log = LoggerFactory.getLogger(JcloudsLocationResolver.class);
-    
-    private static final String JCLOUDS = "jclouds";
-    
-    public static final Map<String,ProviderMetadata> PROVIDERS = getProvidersMap();
-    public static final Map<String,ApiMetadata> APIS = getApisMap();
-    
-    private static Map<String,ProviderMetadata> getProvidersMap() {
-        Map<String,ProviderMetadata> result = Maps.newLinkedHashMap();
-        for (ProviderMetadata p: Providers.all()) {
-            result.put(p.getId(), p);
-        }
-        return ImmutableMap.copyOf(result);
-    }
-
-    private static Map<String,ApiMetadata> getApisMap() {
-        Map<String,ApiMetadata> result = Maps.newLinkedHashMap();
-        for (ApiMetadata api: Apis.all()) {
-            result.put(api.getId(), api);
-        }
-        return ImmutableMap.copyOf(result);
-    }
-
-    public static final Collection<String> AWS_REGIONS = Arrays.asList(
-            // from http://docs.amazonwebservices.com/general/latest/gr/rande.html as of Apr 2012.
-            // it is suggested not to maintain this list here, instead to require aws-ec2 explicitly named.
-            "eu-west-1","us-east-1","us-west-1","us-west-2","ap-southeast-1","ap-northeast-1","sa-east-1");
-         
-    private ManagementContext managementContext;
-
-    @Override
-    public void init(ManagementContext managementContext) {
-        this.managementContext = checkNotNull(managementContext, "managementContext");
-    }
-    
-    protected class JcloudsSpecParser {
-        String providerOrApi;
-        String parameter;
-        
-        public JcloudsSpecParser parse(String spec, boolean dryrun) {
-            JcloudsSpecParser result = new JcloudsSpecParser();
-            int split = spec.indexOf(':');
-            if (split<0) {
-                if (spec.equalsIgnoreCase(getPrefix())) {
-                    if (dryrun) return null;
-                    throw new IllegalArgumentException("Cannot use '"+spec+"' as a location ID; it is insufficient. "+
-                           "Try jclouds:aws-ec2 (for example).");
-                }
-                result.providerOrApi = spec;
-                result.parameter = null;
-            } else {
-                result.providerOrApi = spec.substring(0, split);
-                result.parameter = spec.substring(split+1);
-                int numJcloudsPrefixes = 0;
-                while (result.providerOrApi.equalsIgnoreCase(getPrefix())) {
-                    //strip any number of jclouds: prefixes, for use by static "resolve" method
-                    numJcloudsPrefixes++;
-                    result.providerOrApi = result.parameter;
-                    result.parameter = null;
-                    split = result.providerOrApi.indexOf(':');
-                    if (split>=0) {
-                        result.parameter = result.providerOrApi.substring(split+1);
-                        result.providerOrApi = result.providerOrApi.substring(0, split);
-                    }
-                }
-                if (!dryrun && numJcloudsPrefixes > 1) {
-                    log.warn("Use of deprecated location spec '"+spec+"'; in future use a single \"jclouds\" prefix");
-                }
-            }
-            
-            if (result.parameter==null && AWS_REGIONS.contains(result.providerOrApi)) {
-                // treat amazon as a default
-                result.parameter = result.providerOrApi;
-                result.providerOrApi = "aws-ec2";
-                if (!dryrun)
-                    log.warn("Use of deprecated location '"+result.parameter+"'; in future refer to with explicit " +
-                            "provider '"+result.providerOrApi+":"+result.parameter+"'");
-            }
-            
-            return result;
-        }
-
-        public boolean isProvider() {
-            return PROVIDERS.containsKey(providerOrApi);
-        }
-
-        public boolean isApi() {
-            return APIS.containsKey(providerOrApi);
-        }
-        
-        public String getProviderOrApi() {
-            return providerOrApi;
-        }
-        
-        public String getParameter() {
-            return parameter;
-        }
-    }
-    
-    @Override
-    @SuppressWarnings("unchecked")
-    public JcloudsLocation newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        Map globalProperties = registry.getProperties();
-
-        JcloudsSpecParser details = new JcloudsSpecParser().parse(spec, false);
-        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
-
-        boolean isProvider = details.isProvider();
-        String providerOrApi = details.providerOrApi;
-        // gce claims to be an api ... perhaps just a bug? email sent to jclouds dev list, 28 mar 2014
-        isProvider = isProvider || "google-compute-engine".equals(providerOrApi);
-        
-        if (Strings.isEmpty(providerOrApi)) {
-            throw new IllegalArgumentException("Cloud provider/API type not specified in spec \""+spec+"\"");
-        }
-        if (!isProvider && !details.isApi()) {
-            throw new NoSuchElementException("Cloud provider/API type "+providerOrApi+" is not supported by jclouds");
-        }
-        
-        // For everything in brooklyn.properties, only use things with correct prefix (and remove that prefix).
-        // But for everything passed in via locationFlags, pass those as-is.
-        // TODO Should revisit the locationFlags: where are these actually used? Reason accepting properties without
-        //      full prefix is that the map's context is explicitly this location, rather than being generic properties.
-        Map allProperties = getAllProperties(registry, globalProperties);
-        String regionOrEndpoint = details.parameter;
-        if (regionOrEndpoint==null && isProvider) regionOrEndpoint = (String)locationFlags.get(LocationConfigKeys.CLOUD_REGION_ID.getName());
-        Map jcloudsProperties = new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties(providerOrApi, regionOrEndpoint, namedLocation, allProperties);
-        jcloudsProperties.putAll(locationFlags);
-        
-        if (regionOrEndpoint!=null) {
-            // apply the regionOrEndpoint (e.g. from the parameter) as appropriate -- but only if it has not been overridden
-            if (isProvider) {
-                // providers from ServiceLoader take a location (endpoint already configured), and optionally a region name
-                // NB blank might be supplied if spec string is "mycloud:" -- that should be respected, 
-                // whereas no parameter/regionName ie null value -- "mycloud" -- means don't set
-                if (Strings.isBlank(Strings.toString(jcloudsProperties.get(JcloudsLocationConfig.CLOUD_REGION_ID.getName()))))
-                    jcloudsProperties.put(JcloudsLocationConfig.CLOUD_REGION_ID.getName(), regionOrEndpoint);
-            } else {
-                // other "providers" are APIs so take an _endpoint_ (but not a location);
-                // see note above re null here
-                if (Strings.isBlank(Strings.toString(jcloudsProperties.get(JcloudsLocationConfig.CLOUD_ENDPOINT.getName()))))
-                    jcloudsProperties.put(JcloudsLocationConfig.CLOUD_ENDPOINT.getName(), regionOrEndpoint);
-            }
-        }
-        
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationClass())
-                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, jcloudsProperties, globalProperties, namedLocation))
-                .configure(jcloudsProperties) );
-    }
-
-    @SuppressWarnings("unchecked")
-    private Map getAllProperties(brooklyn.location.LocationRegistry registry, Map<?,?> properties) {
-        Map<Object,Object> allProperties = Maps.newHashMap();
-        if (registry!=null) allProperties.putAll(registry.getProperties());
-        allProperties.putAll(properties);
-        return allProperties;
-    }
-    
-    @Override
-    public String getPrefix() {
-        return JCLOUDS;
-    }
-
-    protected Class<? extends JcloudsLocation> getLocationClass() {
-        return JcloudsLocation.class;
-    }
-    
-    @Override
-    public boolean accepts(String spec, LocationRegistry registry) {
-        if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true)) return true;
-        JcloudsSpecParser details = new JcloudsSpecParser().parse(spec, true);
-        if (details==null) return false;
-        if (details.isProvider() || details.isApi()) return true;
-        return false;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineLocation.java
deleted file mode 100644
index accda93..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineLocation.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.HasSubnetHostname;
-
-public interface JcloudsMachineLocation extends MachineLocation, HasSubnetHostname {
-    
-    @Override
-    public JcloudsLocation getParent();
-    
-    public NodeMetadata getNode();
-    
-    public Template getTemplate();
-
-    public String getJcloudsId();
-
-    /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */
-    @Override
-    public String getSubnetHostname();
-
-    String getUser();
-
-    int getPort();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineNamer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineNamer.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineNamer.java
deleted file mode 100644
index 301ed43..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineNamer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import brooklyn.location.cloud.names.BasicCloudMachineNamer;
-import brooklyn.util.config.ConfigBag;
-
-public class JcloudsMachineNamer extends BasicCloudMachineNamer {
-
-    @Override
-    /** returns the max length of a VM name for the cloud specified in setup;
-     * this value is typically decremented by 9 to make room for jclouds labels */
-    public Integer getCustomMaxNameLength(ConfigBag setup) {
-        // otherwise, for some known clouds which only allow a short name, use that length
-        if ("vcloud".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) ))
-            return 24;
-        if ("abiquo".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) ))
-            return 39;
-        if ("google-compute-engine".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) ))
-            return 39;
-        if ("softlayer".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) ))
-            return 55;
-        // TODO other cloud max length rules
-
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPredicates.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPredicates.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPredicates.java
deleted file mode 100644
index 9220a28..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPredicates.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import org.jclouds.compute.domain.ComputeMetadata;
-import org.jclouds.domain.Location;
-
-import com.google.common.base.Predicate;
-
-public class JcloudsPredicates {
-
-    public static class NodeInLocation implements Predicate<ComputeMetadata> {
-        private String regionId;
-        private boolean matchNullLocations;
-        public NodeInLocation(String regionId, boolean matchNullLocations) {
-            this.regionId = regionId;
-            this.matchNullLocations = matchNullLocations;
-        }
-        @Override
-        public boolean apply(ComputeMetadata input) {
-            boolean exclude;
-            Location nodeLocation = input.getLocation();
-            if (nodeLocation==null) return matchNullLocations;
-            
-            exclude = true;
-            while (nodeLocation!=null && exclude) {
-                if (nodeLocation.getId().equals(regionId)) {
-                    // matching location info found
-                    exclude = false;
-                }
-                nodeLocation = nodeLocation.getParent();
-            }
-            return !exclude;
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java
deleted file mode 100644
index 19b6c7a..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigUtils;
-import brooklyn.location.basic.DeprecatedKeysMappingBuilder;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.LocationPropertiesFromBrooklynProperties;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.javalang.JavaClassNames;
-
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-
-/**
- * <p>
- * The properties to use for a jclouds location, loaded from brooklyn.properties file
- * </p>
- * 
- * Preferred format is:
- * 
- * <ul>
- * <li>
- * brooklyn.location.named.NAME.key 
- * </li>
- * <li>
- * brooklyn.location.jclouds.PROVIDER.key
- * </li>
- * </ul>
- * 
- * <p>
- * A number of properties are also supported, listed in the {@code JcloudsLocationConfig}
- * </p>
- * 
- * @author andrea
- **/
-public class JcloudsPropertiesFromBrooklynProperties extends LocationPropertiesFromBrooklynProperties {
-
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsPropertiesFromBrooklynProperties.class);
-
-    @SuppressWarnings("deprecation")
-    private static final Map<String, String> DEPRECATED_JCLOUDS_KEYS_MAPPING = new DeprecatedKeysMappingBuilder(LOG)
-            .putAll(LocationPropertiesFromBrooklynProperties.DEPRECATED_KEYS_MAPPING)
-            .camelToHyphen(JcloudsLocation.IMAGE_ID)
-            .camelToHyphen(JcloudsLocation.IMAGE_NAME_REGEX)
-            .camelToHyphen(JcloudsLocation.IMAGE_DESCRIPTION_REGEX)
-            .camelToHyphen(JcloudsLocation.HARDWARE_ID)
-            .build();
-
-    @Override
-    public Map<String, Object> getLocationProperties(String provider, String namedLocation, Map<String, ?> properties) {
-        throw new UnsupportedOperationException("Instead use getJcloudsProperties(String,String,String,Map)");
-    }
-    
-    /**
-     * @see LocationPropertiesFromBrooklynProperties#getLocationProperties(String, String, Map)
-     */
-    public Map<String, Object> getJcloudsProperties(String providerOrApi, String regionOrEndpoint, String namedLocation, Map<String, ?> properties) {
-        if(Strings.isNullOrEmpty(namedLocation) && Strings.isNullOrEmpty(providerOrApi)) {
-            throw new IllegalArgumentException("Neither cloud provider/API nor location name have been specified correctly");
-        }
-
-        ConfigBag jcloudsProperties = ConfigBag.newInstance();
-        String provider = getProviderName(providerOrApi, namedLocation, properties);
-        
-        // named properties are preferred over providerOrApi properties
-        jcloudsProperties.put(LocationConfigKeys.CLOUD_PROVIDER, provider);
-        jcloudsProperties.putAll(transformDeprecated(getGenericLocationSingleWordProperties(properties)));
-        jcloudsProperties.putAll(transformDeprecated(getGenericJcloudsSingleWordProperties(providerOrApi, properties)));
-        jcloudsProperties.putAll(transformDeprecated(getProviderOrApiJcloudsProperties(providerOrApi, properties)));
-        jcloudsProperties.putAll(transformDeprecated(getRegionJcloudsProperties(providerOrApi, regionOrEndpoint, properties)));
-        if (!Strings.isNullOrEmpty(namedLocation)) jcloudsProperties.putAll(transformDeprecated(getNamedJcloudsProperties(namedLocation, properties)));
-        setLocalTempDir(properties, jcloudsProperties);
-
-        return jcloudsProperties.getAllConfigRaw();
-    }
-
-    protected String getProviderName(String providerOrApi, String namedLocationName, Map<String, ?> properties) {
-        String provider = providerOrApi;
-        if (!Strings.isNullOrEmpty(namedLocationName)) {
-            String providerDefinition = (String) properties.get(String.format("brooklyn.location.named.%s", namedLocationName));
-            if (providerDefinition!=null) {
-                String provider2 = getProviderFromDefinition(providerDefinition);
-                if (provider==null) {
-                    // 0.7.0 25 Feb -- is this even needed?
-                    LOG.warn(JavaClassNames.niceClassAndMethod()+" NOT set with provider, inferring from locationName "+namedLocationName+" as "+provider2);
-                    provider = provider2;
-                } else if (!provider.equals(provider2)) {
-                    // 0.7.0 25 Feb -- previously we switched to provider2 in this case, but that was wrong when
-                    // working with chains of names; not sure why this case would ever occur (apart from tests which have been changed)
-                    // 28 Mar seen this warning many times but only in cases when NOT changing is the right behaviour 
-                    LOG.debug(JavaClassNames.niceClassAndMethod()+" NOT changing provider from "+provider+" to candidate "+provider2);
-                }
-            }
-        }
-        return provider;
-    }
-    
-    protected String getProviderFromDefinition(String definition) {
-        return Iterables.get(Splitter.on(":").split(definition), 1);
-    }
-
-    protected Map<String, Object> getGenericJcloudsSingleWordProperties(String providerOrApi, Map<String, ?> properties) {
-        if (Strings.isNullOrEmpty(providerOrApi)) return Maps.newHashMap();
-        String deprecatedPrefix = "brooklyn.jclouds.";
-        String preferredPrefix = "brooklyn.location.jclouds.";
-        return getMatchingSingleWordProperties(preferredPrefix, deprecatedPrefix, properties);
-    }
-
-    protected Map<String, Object> getProviderOrApiJcloudsProperties(String providerOrApi, Map<String, ?> properties) {
-        if (Strings.isNullOrEmpty(providerOrApi)) return Maps.newHashMap();
-        String preferredPrefix = String.format("brooklyn.location.jclouds.%s.", providerOrApi);
-        String deprecatedPrefix = String.format("brooklyn.jclouds.%s.", providerOrApi);
-        
-        return getMatchingProperties(preferredPrefix, deprecatedPrefix, properties);
-    }
-
-    protected Map<String, Object> getRegionJcloudsProperties(String providerOrApi, String regionName, Map<String, ?> properties) {
-        if (Strings.isNullOrEmpty(providerOrApi) || Strings.isNullOrEmpty(regionName)) return Maps.newHashMap();
-        String preferredPrefix = String.format("brooklyn.location.jclouds.%s@%s.", providerOrApi, regionName);
-        String deprecatedPrefix = String.format("brooklyn.jclouds.%s@%s.", providerOrApi, regionName);
-        
-        return getMatchingProperties(preferredPrefix, deprecatedPrefix, properties);
-    }
-
-    protected Map<String, Object> getNamedJcloudsProperties(String locationName, Map<String, ?> properties) {
-        if(locationName == null) return Maps.newHashMap();
-        String prefix = String.format("brooklyn.location.named.%s.", locationName);
-        return ConfigUtils.filterForPrefixAndStrip(properties, prefix).asMapWithStringKeys();
-    }
-
-    @Override
-    protected Map<String, String> getDeprecatedKeysMapping() {
-        return DEPRECATED_JCLOUDS_KEYS_MAPPING;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
deleted file mode 100644
index 205771a..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.annotation.Nullable;
-
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.callables.RunScriptOnNode;
-import org.jclouds.compute.domain.ExecResponse;
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.OperatingSystem;
-import org.jclouds.compute.domain.OsFamily;
-import org.jclouds.compute.domain.Processor;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.options.RunScriptOptions;
-import org.jclouds.domain.LoginCredentials;
-import org.jclouds.scriptbuilder.domain.InterpretableStatement;
-import org.jclouds.scriptbuilder.domain.Statement;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.HardwareDetails;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.BasicHardwareDetails;
-import brooklyn.location.basic.BasicMachineDetails;
-import brooklyn.location.basic.BasicOsDetails;
-import brooklyn.location.basic.HasSubnetHostname;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.net.Networking;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.net.HostAndPort;
-import com.google.common.util.concurrent.ListenableFuture;
-
-public class JcloudsSshMachineLocation extends SshMachineLocation implements JcloudsMachineLocation {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsSshMachineLocation.class);
-    private static final long serialVersionUID = -443866395634771659L;
-
-    @SetFromFlag
-    JcloudsLocation jcloudsParent;
-    
-    @SetFromFlag
-    NodeMetadata node;
-    
-    @SetFromFlag
-    Template template;
-    
-    private RunScriptOnNode.Factory runScriptFactory;
-    
-    public JcloudsSshMachineLocation() {
-    }
-    
-    /**
-     * @deprecated since 0.6; use LocationSpec (which calls no-arg constructor)
-     */
-    @Deprecated
-    public JcloudsSshMachineLocation(Map<?,?> flags, JcloudsLocation jcloudsParent, NodeMetadata node) {
-        super(flags);
-        this.jcloudsParent = jcloudsParent;
-        this.node = node;
-        
-        init();
-    }
-
-    @Override
-    public void init() {
-        if (jcloudsParent != null) {
-            super.init();
-            ComputeServiceContext context = jcloudsParent.getComputeService().getContext();
-            runScriptFactory = context.utils().injector().getInstance(RunScriptOnNode.Factory.class);
-        } else {
-            // TODO Need to fix the rebind-detection, and not call init() on rebind.
-            // This will all change when locations become entities.
-            if (LOG.isDebugEnabled()) LOG.debug("Not doing init() of {} because parent not set; presuming rebinding", this);
-        }
-    }
-    
-    @Override
-    public void rebind() {
-        super.rebind();
-        ComputeServiceContext context = jcloudsParent.getComputeService().getContext();
-        runScriptFactory = context.utils().injector().getInstance(RunScriptOnNode.Factory.class);
-    }
-    
-    @Override
-    public String toVerboseString() {
-        return Objects.toStringHelper(this).omitNullValues()
-                .add("id", getId()).add("name", getDisplayName())
-                .add("user", getUser()).add("address", getAddress()).add("port", getConfig(SSH_PORT))
-                .add("node", getNode())
-                .add("jcloudsId", getJcloudsId())
-                .add("privateAddresses", node.getPrivateAddresses())
-                .add("publicAddresses", node.getPublicAddresses())
-                .add("parentLocation", getParent())
-                .add("osDetails", getOsDetails())
-                .toString();
-    }
-
-    @Override
-    public NodeMetadata getNode() {
-        return node;
-    }
-    
-    @Override
-    public Template getTemplate() {
-        return template;
-    }
-    
-    @Override
-    public JcloudsLocation getParent() {
-        return jcloudsParent;
-    }
-    
-    @Override
-    public String getHostname() {
-        return node.getHostname();
-    }
-    
-    /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */
-    @Override
-    public Set<String> getPublicAddresses() {
-        return node.getPublicAddresses();
-    }
-    
-    @Override
-    public Set<String> getPrivateAddresses() {
-        return node.getPrivateAddresses();
-    }
-
-    @Override
-    public String getSubnetHostname() {
-        String privateHostname = jcloudsParent.getPrivateHostname(node, Optional.<HostAndPort>absent(), config().getBag());
-        return privateHostname;
-    }
-
-    @Override
-    public String getSubnetIp() {
-        Optional<String> privateAddress = getPrivateAddress();
-        if (privateAddress.isPresent()) {
-            return privateAddress.get();
-        }
-
-        String hostname = jcloudsParent.getPublicHostname(node, Optional.<HostAndPort>absent(), config().getBag());
-        if (hostname != null && !Networking.isValidIp4(hostname)) {
-            try {
-                return InetAddress.getByName(hostname).getHostAddress();
-            } catch (UnknownHostException e) {
-                LOG.debug("Cannot resolve IP for hostname {} of machine {} (so returning hostname): {}", new Object[] {hostname, this, e});
-            }
-        }
-        return hostname;
-    }
-
-    protected Optional<String> getPrivateAddress() {
-        if (groovyTruth(node.getPrivateAddresses())) {
-            for (String p : node.getPrivateAddresses()) {
-                // disallow local only addresses
-                if (Networking.isLocalOnly(p)) continue;
-                // other things may be public or private, but either way, return it
-                return Optional.of(p);
-            }
-        }
-        return Optional.absent();
-    }
-    
-    @Override
-    public String getJcloudsId() {
-        return node.getId();
-    }
-    
-    /** executes the given statements on the server using jclouds ScriptBuilder,
-     * wrapping in a script which is polled periodically.
-     * the output is returned once the script completes (disadvantage compared to other methods)
-     * but the process is nohupped and the SSH session is not kept, 
-     * so very useful for long-running processes
-     */
-    public ListenableFuture<ExecResponse> submitRunScript(String ...statements) {
-        return submitRunScript(new InterpretableStatement(statements));
-    }
-    public ListenableFuture<ExecResponse> submitRunScript(Statement script) {
-        return submitRunScript(script, new RunScriptOptions());            
-    }
-    public ListenableFuture<ExecResponse> submitRunScript(Statement script, RunScriptOptions options) {
-        return runScriptFactory.submit(node, script, options);
-    }
-    /** uses submitRunScript to execute the commands, and throws error if it fails or returns non-zero */
-    public void execRemoteScript(String ...commands) {
-        try {
-            ExecResponse result = submitRunScript(commands).get();
-            if (result.getExitStatus()!=0)
-                throw new IllegalStateException("Error running remote commands (code "+result.getExitStatus()+"): "+commands);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-            throw Throwables.propagate(e);
-        } catch (ExecutionException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-
-    /**
-     * Retrieves the password for this VM, if one exists. The behaviour/implementation is different for different clouds.
-     * e.g. on Rackspace, the password for a windows VM is available immediately; on AWS-EC2, for a Windows VM you need 
-     * to poll repeatedly until the password is available which can take up to 15 minutes.
-     */
-    public String waitForPassword() {
-        // TODO Hacky; don't want aws specific stuff here but what to do?!
-        if (jcloudsParent.getProvider().equals("aws-ec2")) {
-            try {
-                return JcloudsUtil.waitForPasswordOnAws(jcloudsParent.getComputeService(), node, 15, TimeUnit.MINUTES);
-            } catch (TimeoutException e) {
-                throw Throwables.propagate(e);
-            }
-        } else {
-            LoginCredentials credentials = node.getCredentials();
-            return (credentials != null) ? credentials.getPassword() : null;
-        }
-    }
-
-    @Override
-    protected MachineDetails inferMachineDetails() {
-        Optional<String> name = Optional.absent();
-        Optional<String> version = Optional.absent();
-        Optional<String> architecture = Optional.absent();
-
-        OperatingSystem os = node.getOperatingSystem();
-        if (os == null && getTemplate() != null && getTemplate().getImage() != null)
-            // some nodes (eg cloudstack, gce) might not get OS available on the node,
-            // so also try taking it from the template if available
-            os = getTemplate().getImage().getOperatingSystem();
-
-        if (os != null) {
-            // Note using family rather than name. Name is often unset.
-            name = Optional.fromNullable(os.getFamily() != null && !OsFamily.UNRECOGNIZED.equals(os.getFamily()) ? os.getFamily().toString() : null);
-            version = Optional.fromNullable(!Strings.isBlank(os.getVersion()) ? os.getVersion() : null);
-            // Using is64Bit rather then getArch because getArch often returns "paravirtual"
-            architecture = Optional.fromNullable(os.is64Bit() ? BasicOsDetails.OsArchs.X_86_64 : BasicOsDetails.OsArchs.I386);
-        }
-
-        Hardware hardware = node.getHardware();
-        Optional<Integer> ram = hardware==null ? Optional.<Integer>absent() : Optional.fromNullable(hardware.getRam());
-        Optional<Integer> cpus = hardware==null ? Optional.<Integer>absent() : Optional.fromNullable(hardware.getProcessors() != null ? hardware.getProcessors().size() : null);
-
-        // Skip superclass' SSH to machine if all data is present, otherwise defer to super
-        if (name.isPresent() && version.isPresent() && architecture.isPresent() && ram.isPresent() && cpus.isPresent()) {
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Gathered machine details from Jclouds, skipping SSH test on {}", this);
-            }
-            OsDetails osD = new BasicOsDetails(name.get(), architecture.get(), version.get());
-            HardwareDetails hwD = new BasicHardwareDetails(cpus.get(), ram.get());
-            return new BasicMachineDetails(hwD, osD);
-        } else if ("false".equalsIgnoreCase(getConfig(JcloudsLocation.WAIT_FOR_SSHABLE))) {
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Machine details for {} missing from Jclouds, but skipping SSH test because waitForSshable=false. name={}, version={}, " +
-                        "arch={}, ram={}, #cpus={}",
-                        new Object[]{this, name, version, architecture, ram, cpus});
-            }
-            OsDetails osD = new BasicOsDetails(name.orNull(), architecture.orNull(), version.orNull());
-            HardwareDetails hwD = new BasicHardwareDetails(cpus.orNull(), ram.orNull());
-            return new BasicMachineDetails(hwD, osD);
-        } else {
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Machine details for {} missing from Jclouds, using SSH test instead. name={}, version={}, " +
-                                "arch={}, ram={}, #cpus={}",
-                        new Object[]{this, name, version, architecture, ram, cpus});
-            }
-            return super.inferMachineDetails();
-        }
-    }
-
-    @Override
-    public Map<String, String> toMetadataRecord() {
-        Hardware hardware = node.getHardware();
-        List<? extends Processor> processors = (hardware != null) ? hardware.getProcessors() : null;
-        
-        ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
-        builder.putAll(super.toMetadataRecord());
-        putIfNotNull(builder, "provider", getParent().getProvider());
-        putIfNotNull(builder, "account", getParent().getIdentity());
-        putIfNotNull(builder, "serverId", node.getProviderId());
-        putIfNotNull(builder, "imageId", node.getImageId());
-        putIfNotNull(builder, "instanceTypeName", (hardware != null ? hardware.getName() : null));
-        putIfNotNull(builder, "instanceTypeId", (hardware != null ? hardware.getProviderId() : null));
-        putIfNotNull(builder, "ram", "" + (hardware != null ? hardware.getRam() : null));
-        putIfNotNull(builder, "cpus", "" + (processors != null ? processors.size() : null));
-        
-        try {
-            OsDetails osDetails = getOsDetails();
-            putIfNotNull(builder, "osName", osDetails.getName());
-            putIfNotNull(builder, "osArch", osDetails.getArch());
-            putIfNotNull(builder, "is64bit", osDetails.is64bit() ? "true" : "false");
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            LOG.warn("Unable to get OS Details for "+node+"; continuing", e);
-        }
-        
-        return builder.build();
-    }
-    
-    private void putIfNotNull(ImmutableMap.Builder<String, String> builder, String key, @Nullable String value) {
-        if (value != null) builder.put(key, value);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsUtil.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsUtil.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsUtil.java
deleted file mode 100644
index 90c6035..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsUtil.java
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideLoginCredentials;
-import static org.jclouds.compute.util.ComputeServiceUtils.execHttpResponse;
-import static org.jclouds.scriptbuilder.domain.Statements.appendFile;
-import static org.jclouds.scriptbuilder.domain.Statements.exec;
-import static org.jclouds.scriptbuilder.domain.Statements.interpret;
-import static org.jclouds.scriptbuilder.domain.Statements.newStatementList;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.annotation.Nullable;
-
-import org.jclouds.Constants;
-import org.jclouds.ContextBuilder;
-import org.jclouds.aws.ec2.AWSEC2Api;
-import org.jclouds.blobstore.BlobStoreContext;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.RunScriptOnNodesException;
-import org.jclouds.compute.domain.ExecResponse;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.OperatingSystem;
-import org.jclouds.compute.options.RunScriptOptions;
-import org.jclouds.compute.predicates.OperatingSystemPredicates;
-import org.jclouds.docker.DockerApi;
-import org.jclouds.docker.domain.Container;
-import org.jclouds.domain.LoginCredentials;
-import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey;
-import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData;
-import org.jclouds.ec2.domain.PasswordData;
-import org.jclouds.ec2.features.WindowsApi;
-import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
-import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
-import org.jclouds.scriptbuilder.domain.Statement;
-import org.jclouds.scriptbuilder.domain.Statements;
-import org.jclouds.ssh.SshClient;
-import org.jclouds.sshj.config.SshjSshClientModule;
-import org.jclouds.util.Predicates2;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Charsets;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.io.Files;
-import com.google.inject.Module;
-
-import brooklyn.entity.basic.Sanitizer;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.net.Protocol;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.ssh.IptablesCommands;
-import brooklyn.util.ssh.IptablesCommands.Chain;
-import brooklyn.util.ssh.IptablesCommands.Policy;
-
-public class JcloudsUtil implements JcloudsLocationConfig {
-
-    // TODO Review what utility methods are needed, and what is now supported in jclouds 1.1
-
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsUtil.class);
-
-    /**
-     * @deprecated since 0.7; see {@link BashCommands}
-     */
-    @Deprecated
-    public static String APT_INSTALL = "apt-get install -f -y -qq --force-yes";
-
-    /**
-     * @deprecated since 0.7; see {@link BashCommands}
-     */
-    @Deprecated
-    public static String installAfterUpdatingIfNotPresent(String cmd) {
-       String aptInstallCmd = APT_INSTALL + " " + cmd;
-       return String.format("which %s || (%s || (apt-get update && %s))", cmd, aptInstallCmd, aptInstallCmd);
-    }
-
-    /**
-     * @deprecated since 0.7
-     */
-    @Deprecated
-    public static Predicate<NodeMetadata> predicateMatchingById(final NodeMetadata node) {
-        return predicateMatchingById(node.getId());
-    }
-
-    /**
-     * @deprecated since 0.7
-     */
-    @Deprecated
-    public static Predicate<NodeMetadata> predicateMatchingById(final String id) {
-        Predicate<NodeMetadata> nodePredicate = new Predicate<NodeMetadata>() {
-            @Override public boolean apply(NodeMetadata arg0) {
-                return id.equals(arg0.getId());
-            }
-            @Override public String toString() {
-                return "node.id=="+id;
-            }
-        };
-        return nodePredicate;
-    }
-
-    /**
-     * @deprecated since 0.7; see {@link IptablesCommands}
-     */
-    @Deprecated
-    public static Statement authorizePortInIpTables(int port) {
-        // TODO gogrid rules only allow ports 22, 3389, 80 and 443.
-        // the first rule will be ignored, so we have to apply this
-        // directly
-        return Statements.newStatementList(// just in case iptables are being used, try to open 8080
-                exec("iptables -I INPUT 1 -p tcp --dport " + port + " -j ACCEPT"),//
-                exec("iptables -I RH-Firewall-1-INPUT 1 -p tcp --dport " + port + " -j ACCEPT"),//
-                exec("iptables-save"));
-    }
-
-    /**
-     * @throws RunScriptOnNodesException
-     * @throws IllegalStateException     If do not find exactly one matching node
-     *
-     * @deprecated since 0.7
-     */
-    @Deprecated
-    public static ExecResponse runScriptOnNode(ComputeService computeService, NodeMetadata node, Statement statement, String scriptName) throws RunScriptOnNodesException {
-        // TODO Includes workaround for NodeMetadata's equals/hashcode method being wrong.
-
-        Map<? extends NodeMetadata, ExecResponse> scriptResults = computeService.runScriptOnNodesMatching(
-                JcloudsUtil.predicateMatchingById(node),
-                statement,
-                new RunScriptOptions().nameTask(scriptName));
-        if (scriptResults.isEmpty()) {
-            throw new IllegalStateException("No matching node found when executing script "+scriptName+": expected="+node);
-        } else if (scriptResults.size() > 1) {
-            throw new IllegalStateException("Multiple nodes matched predicate: id="+node.getId()+"; expected="+node+"; actual="+scriptResults.keySet());
-        } else {
-            return Iterables.getOnlyElement(scriptResults.values());
-        }
-    }
-
-    /**
-     * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)}
-     */
-    @Deprecated
-    public static final Statement APT_RUN_SCRIPT = newStatementList(//
-          exec(installAfterUpdatingIfNotPresent("curl")),//
-          exec("(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||"),//
-          execHttpResponse(URI.create("http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install")),//
-          exec(new StringBuilder()//
-                .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
-                // jeos hasn't enough room!
-                .append("rm -rf /var/cache/apt /usr/lib/vmware-tools\n")//
-                .append("echo \"export PATH=\\\"$JAVA_HOME/bin/:$PATH\\\"\" >> /root/.bashrc")//
-                .toString()));
-
-    /**
-     * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)}
-     */
-    @Deprecated
-    public static final Statement YUM_RUN_SCRIPT = newStatementList(
-          exec("which curl ||yum --nogpgcheck -y install curl"),//
-          exec("(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||"),//
-          execHttpResponse(URI.create("http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install")),//
-          exec(new StringBuilder()//
-                .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n") //
-                .append("echo \"export PATH=\\\"$JAVA_HOME/bin/:$PATH\\\"\" >> /root/.bashrc")//
-                .toString()));
-
-    /**
-     * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)}
-     */
-    @Deprecated
-    public static final Statement ZYPPER_RUN_SCRIPT = exec(new StringBuilder()//
-          .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")//
-          .append("which curl || zypper install curl\n")//
-          .append("(which java && java -fullversion 2>&1|egrep -q 1.6 ) || zypper install java-1.6.0-openjdk\n")//
-          .toString());
-
-    // Code taken from RunScriptData
-    /**
-     * @deprecated since 0.7; see {@link BashCommands#installJava7()} and {@link BashCommands#INSTALL_CURL}
-     */
-    @Deprecated
-    public static Statement installJavaAndCurl(OperatingSystem os) {
-       if (os == null || OperatingSystemPredicates.supportsApt().apply(os))
-          return APT_RUN_SCRIPT;
-       else if (OperatingSystemPredicates.supportsYum().apply(os))
-          return YUM_RUN_SCRIPT;
-       else if (OperatingSystemPredicates.supportsZypper().apply(os))
-          return ZYPPER_RUN_SCRIPT;
-       else
-          throw new IllegalArgumentException("don't know how to handle" + os.toString());
-    }
-
-    /**
-     * @deprecated since 0.7; see {@link ComputeServiceRegistry#findComputeService(ConfigBag, boolean)}
-     */
-    @Deprecated
-    public static ComputeService findComputeService(ConfigBag conf) {
-        return ComputeServiceRegistryImpl.INSTANCE.findComputeService(conf, true);
-    }
-
-    /**
-     * @deprecated since 0.7; see {@link ComputeServiceRegistry#findComputeService(ConfigBag, boolean)}
-     */
-    @Deprecated
-    public static ComputeService findComputeService(ConfigBag conf, boolean allowReuse) {
-        return ComputeServiceRegistryImpl.INSTANCE.findComputeService(conf, allowReuse);
-    }
-
-    /**
-     * Returns the jclouds modules we typically install
-     *
-     * @deprecated since 0.7; see {@link ComputeServiceRegistry}
-     */
-    @Deprecated
-    public static ImmutableSet<Module> getCommonModules() {
-        return ImmutableSet.<Module> of(
-                new SshjSshClientModule(),
-                new SLF4JLoggingModule(),
-                new BouncyCastleCryptoModule());
-    }
-
-    /**
-     *  Temporary constructor to address https://issues.apache.org/jira/browse/JCLOUDS-615.
-     *  <p>
-     *  See https://issues.apache.org/jira/browse/BROOKLYN-6 .
-     *  When https://issues.apache.org/jira/browse/JCLOUDS-615 is fixed in the jclouds we use,
-     *  we can remove the useSoftlayerFix argument.
-     *  <p>
-     *  (Marked Beta as that argument will likely be removed.)
-     *
-     *  @since 0.7.0 */
-    @Beta
-    public static BlobStoreContext newBlobstoreContext(String provider, @Nullable String endpoint, String identity, String credential) {
-        Properties overrides = new Properties();
-        // * Java 7,8 bug workaround - sockets closed by GC break the internal bookkeeping
-        //   of HttpUrlConnection, leading to invalid handling of the "HTTP/1.1 100 Continue"
-        //   response. Coupled with a bug when using SSL sockets reads will block
-        //   indefinitely even though a read timeout is explicitly set.
-        // * Java 6 ignores the header anyways as it is included in its restricted headers black list.
-        // * Also there's a bug in SL object store which still expects Content-Length bytes
-        //   even when it responds with a 408 timeout response, leading to incorrectly
-        //   interpreting the next request (triggered by above problem).
-        overrides.setProperty(Constants.PROPERTY_STRIP_EXPECT_HEADER, "true");
-
-        ContextBuilder contextBuilder = ContextBuilder.newBuilder(provider).credentials(identity, credential);
-        contextBuilder.modules(MutableList.copyOf(JcloudsUtil.getCommonModules()));
-        if (!brooklyn.util.text.Strings.isBlank(endpoint)) {
-            contextBuilder.endpoint(endpoint);
-        }
-        contextBuilder.overrides(overrides);
-        BlobStoreContext context = contextBuilder.buildView(BlobStoreContext.class);
-        return context;
-    }
-
-    /**
-     * @deprecated since 0.7
-     */
-    @Deprecated
-    protected static String getDeprecatedProperty(ConfigBag conf, String key) {
-        if (conf.containsKey(key)) {
-            LOG.warn("Jclouds using deprecated brooklyn-jclouds property "+key+": "+Sanitizer.sanitize(conf.getAllConfig()));
-            return (String) conf.getStringKey(key);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * @deprecated since 0.7
-     */
-    @Deprecated
-    // Do this so that if there's a problem with our USERNAME's ssh key, we can still get in to check
-    // TODO Once we're really confident there are not going to be regular problems, then delete this
-    public static Statement addAuthorizedKeysToRoot(File publicKeyFile) throws IOException {
-        String publicKey = Files.toString(publicKeyFile, Charsets.UTF_8);
-        return addAuthorizedKeysToRoot(publicKey);
-    }
-
-    /**
-     * @deprecated since 0.7
-     */
-    @Deprecated
-    public static Statement addAuthorizedKeysToRoot(String publicKey) {
-        return newStatementList(
-                appendFile("/root/.ssh/authorized_keys", Splitter.on('\n').split(publicKey)),
-                interpret("chmod 600 /root/.ssh/authorized_keys"));
-    }
-
-    public static String getFirstReachableAddress(ComputeServiceContext context, NodeMetadata node) {
-        // To pick the address, it relies on jclouds `sshForNode().apply(Node)` to check all IPs of node (private+public),
-        // to find one that is reachable. It does `openSocketFinder.findOpenSocketOnNode(node, node.getLoginPort(), ...)`.
-        // This keeps trying for time org.jclouds.compute.reference.ComputeServiceConstants.Timeouts.portOpen.
-        // TODO Want to configure this timeout here.
-        //
-        // TODO We could perhaps instead just set `templateOptions.blockOnPort(loginPort, 120)`, but need
-        // to be careful to only set that if config WAIT_FOR_SSHABLE is true. For some advanced networking examples
-        // (e.g. using DNAT on CloudStack), the brooklyn machine won't be able to reach the VM until some additional
-        // setup steps have been done. See links from Andrea:
-        //     https://github.com/jclouds/jclouds/pull/895
-        //     https://issues.apache.org/jira/browse/WHIRR-420
-        //     jclouds.ssh.max-retries
-        //     jclouds.ssh.retry-auth
-
-        SshClient client;
-        try {
-            client = context.utils().sshForNode().apply(node);
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            /* i've seen: java.lang.IllegalStateException: Optional.get() cannot be called on an absent value
-             * from org.jclouds.crypto.ASN1Codec.createASN1Sequence(ASN1Codec.java:86), if the ssh key has a passphrase, against AWS.
-             *
-             * others have reported: java.lang.IllegalArgumentException: DER length more than 4 bytes
-             * when using a key with a passphrase (perhaps from other clouds?); not sure if that's this callpath or a different one.
-             */
-            throw new IllegalStateException("Unable to connect SshClient to "+node+"; check that the node is accessible and that the SSH key exists and is correctly configured, including any passphrase defined", e);
-        }
-        return client.getHostAddress();
-    }
-
-    // Suggest at least 15 minutes for timeout
-    public static String waitForPasswordOnAws(ComputeService computeService, final NodeMetadata node, long timeout, TimeUnit timeUnit) throws TimeoutException {
-        ComputeServiceContext computeServiceContext = computeService.getContext();
-        AWSEC2Api ec2Client = computeServiceContext.unwrapApi(AWSEC2Api.class);
-        final WindowsApi client = ec2Client.getWindowsApi().get();
-        final String region = node.getLocation().getParent().getId();
-
-        // The Administrator password will take some time before it is ready - Amazon says sometimes 15 minutes.
-        // So we create a predicate that tests if the password is ready, and wrap it in a retryable predicate.
-        Predicate<String> passwordReady = new Predicate<String>() {
-            @Override public boolean apply(String s) {
-                if (Strings.isNullOrEmpty(s)) return false;
-                PasswordData data = client.getPasswordDataInRegion(region, s);
-                if (data == null) return false;
-                return !Strings.isNullOrEmpty(data.getPasswordData());
-            }
-        };
-
-        LOG.info("Waiting for password, for "+node.getProviderId()+":"+node.getId());
-        Predicate<String> passwordReadyRetryable = Predicates2.retry(passwordReady, timeUnit.toMillis(timeout), 10*1000, TimeUnit.MILLISECONDS);
-        boolean ready = passwordReadyRetryable.apply(node.getProviderId());
-        if (!ready) throw new TimeoutException("Password not available for "+node+" in region "+region+" after "+timeout+" "+timeUnit.name());
-
-        // Now pull together Amazon's encrypted password blob, and the private key that jclouds generated
-        PasswordDataAndPrivateKey dataAndKey = new PasswordDataAndPrivateKey(
-                client.getPasswordDataInRegion(region, node.getProviderId()),
-                node.getCredentials().getPrivateKey());
-
-        // And apply it to the decryption function
-        WindowsLoginCredentialsFromEncryptedData f = computeServiceContext.utils().injector().getInstance(WindowsLoginCredentialsFromEncryptedData.class);
-        LoginCredentials credentials = f.apply(dataAndKey);
-
-        return credentials.getPassword();
-    }
-
-    public static Map<Integer, Integer> dockerPortMappingsFor(JcloudsLocation docker, String containerId) {
-        ComputeServiceContext context = null;
-        try {
-            Properties properties = new Properties();
-            properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
-            properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
-            context = ContextBuilder.newBuilder("docker")
-                    .endpoint(docker.getEndpoint())
-                    .credentials(docker.getIdentity(), docker.getCredential())
-                    .overrides(properties)
-                    .modules(ImmutableSet.<Module>of(new SLF4JLoggingModule(), new SshjSshClientModule()))
-                    .build(ComputeServiceContext.class);
-            DockerApi api = context.unwrapApi(DockerApi.class);
-            Container container = api.getContainerApi().inspectContainer(containerId);
-            Map<Integer, Integer> portMappings = Maps.newLinkedHashMap();
-            Map<String, List<Map<String, String>>> ports = container.networkSettings().ports();
-            if (ports == null) ports = ImmutableMap.<String, List<Map<String,String>>>of();
-
-            LOG.debug("Docker will forward these ports {}", ports);
-            for (Map.Entry<String, List<Map<String, String>>> entrySet : ports.entrySet()) {
-                String containerPort = Iterables.get(Splitter.on("/").split(entrySet.getKey()), 0);
-                String hostPort = Iterables.getOnlyElement(Iterables.transform(entrySet.getValue(),
-                        new Function<Map<String, String>, String>() {
-                            @Override
-                            public String apply(Map<String, String> hostIpAndPort) {
-                                return hostIpAndPort.get("HostPort");
-                            }
-                        }));
-                portMappings.put(Integer.parseInt(containerPort), Integer.parseInt(hostPort));
-            }
-            return portMappings;
-        } finally {
-            if (context != null) {
-                context.close();
-            }
-        }
-    }
-
-    /**
-     * @deprecated since 0.7
-     */
-    @Deprecated
-    public static void mapSecurityGroupRuleToIpTables(ComputeService computeService, NodeMetadata node,
-            LoginCredentials credentials, String networkInterface, Iterable<Integer> ports) {
-        for (Integer port : ports) {
-            String insertIptableRule = IptablesCommands.insertIptablesRule(Chain.INPUT, networkInterface,
-                    Protocol.TCP, port, Policy.ACCEPT);
-            Statement statement = Statements.newStatementList(exec(insertIptableRule));
-            ExecResponse response = computeService.runScriptOnNode(node.getId(), statement,
-                    overrideLoginCredentials(credentials).runAsRoot(false));
-            if (response.getExitStatus() != 0) {
-                String msg = String.format("Cannot insert the iptables rule for port %d. Error: %s", port,
-                        response.getError());
-                LOG.error(msg);
-                throw new RuntimeException(msg);
-            }
-        }
-    }
-
-}



[35/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
new file mode 100644
index 0000000..eee375b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
@@ -0,0 +1,708 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static brooklyn.util.GroovyJavaMethods.elvis;
+import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.Closeable;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.brooklyn.api.entity.rebind.RebindSupport;
+import org.apache.brooklyn.api.entity.trait.Configurable;
+import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.mementos.LocationMemento;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.basic.AbstractBrooklynObject;
+import brooklyn.config.ConfigInheritance;
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.rebind.BasicLocationRebindSupport;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.internal.BrooklynFeatureEnablement;
+import brooklyn.internal.storage.BrooklynStorage;
+import brooklyn.internal.storage.Reference;
+import brooklyn.internal.storage.impl.BasicReference;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.geo.HasHostGeoInfo;
+import org.apache.brooklyn.location.geo.HostGeoInfo;
+import brooklyn.management.internal.LocalLocationManager;
+import brooklyn.management.internal.ManagementContextInternal;
+import brooklyn.util.collections.SetFromLiveMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.flags.FlagUtils;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.stream.Streams;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * A basic implementation of the {@link Location} interface.
+ *
+ * This provides an implementation which works according to the requirements of
+ * the interface documentation, and is ready to be extended to make more specialized locations.
+ * 
+ * Override {@link #configure(Map)} to add special initialization logic.
+ */
+public abstract class AbstractLocation extends AbstractBrooklynObject implements LocationInternal, HasHostGeoInfo, Configurable {
+    
+    private static final long serialVersionUID = -7495805474138619830L;
+
+    /** @deprecated since 0.7.0 shouldn't be public */
+    @Deprecated
+    public static final Logger LOG = LoggerFactory.getLogger(AbstractLocation.class);
+
+    public static final ConfigKey<Location> PARENT_LOCATION = new BasicConfigKey<Location>(Location.class, "parentLocation");
+
+    public static final ConfigKey<Boolean> TEMPORARY_LOCATION = ConfigKeys.newBooleanConfigKey("temporaryLocation",
+            "Indicates that the location is a temporary location that has been created to test connectivity, and that" +
+            "the location's events should not be recorded by usage listeners", false);
+
+    private final AtomicBoolean configured = new AtomicBoolean();
+    
+    private Reference<Long> creationTimeUtc = new BasicReference<Long>(System.currentTimeMillis());
+    
+    // _not_ set from flag; configured explicitly in configure, because we also need to update the parent's list of children
+    private Reference<Location> parent = new BasicReference<Location>();
+    
+    // NB: all accesses should be synchronized
+    private Set<Location> children = Sets.newLinkedHashSet();
+
+    private Reference<String> name = new BasicReference<String>();
+    private boolean displayNameAutoGenerated = true;
+
+    private Reference<HostGeoInfo> hostGeoInfo = new BasicReference<HostGeoInfo>();
+
+    private BasicConfigurationSupport config = new BasicConfigurationSupport();
+    
+    private ConfigBag configBag = new ConfigBag();
+
+    private volatile boolean managed;
+
+    private boolean inConstruction;
+
+    private Reference<Map<Class<?>, Object>> extensions = new BasicReference<Map<Class<?>, Object>>(Maps.<Class<?>, Object>newConcurrentMap());
+
+    private final LocationDynamicType locationType;
+
+    /**
+     * Construct a new instance of an AbstractLocation.
+     */
+    public AbstractLocation() {
+        this(Maps.newLinkedHashMap());
+    }
+    
+    /**
+     * Construct a new instance of an AbstractLocation.
+     *
+     * The properties map recognizes the following keys:
+     * <ul>
+     * <li>name - a name for the location
+     * <li>parentLocation - the parent {@link Location}
+     * </ul>
+     * 
+     * Other common properties (retrieved via get/findLocationProperty) include:
+     * <ul>
+     * <li>latitude
+     * <li>longitude
+     * <li>displayName
+     * <li>iso3166 - list of iso3166-2 code strings
+     * <li>timeZone
+     * <li>abbreviatedName
+     * </ul>
+     */
+    public AbstractLocation(Map<?,?> properties) {
+        super(properties);
+        inConstruction = true;
+        
+        // When one calls getConfig(key), we want to use the default value specified on *this* location
+        // if it overrides the default config, by using the type object 
+        locationType = new LocationDynamicType(this);
+        
+        if (isLegacyConstruction()) {
+            AbstractBrooklynObject checkWeGetThis = configure(properties);
+            assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this;
+
+            boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
+            if (!deferConstructionChecks) {
+                FlagUtils.checkRequiredFields(this);
+            }
+        }
+        
+        inConstruction = false;
+    }
+
+    protected void assertNotYetManaged() {
+        if (!inConstruction && Locations.isManaged(this)) {
+            LOG.warn("Configuration being made to {} after deployment; may not be supported in future versions", this);
+        }
+        //throw new IllegalStateException("Cannot set configuration "+key+" on active location "+this)
+    }
+
+    public void setManagementContext(ManagementContextInternal managementContext) {
+        super.setManagementContext(managementContext);
+        if (displayNameAutoGenerated && getId() != null) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4)));
+
+        if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_USE_BROOKLYN_LIVE_OBJECTS_DATAGRID_STORAGE)) {
+            Location oldParent = parent.get();
+            Set<Location> oldChildren = children;
+            Map<String, Object> oldConfig = configBag.getAllConfig();
+            Long oldCreationTimeUtc = creationTimeUtc.get();
+            String oldDisplayName = name.get();
+            HostGeoInfo oldHostGeoInfo = hostGeoInfo.get();
+
+            parent = managementContext.getStorage().getReference(getId()+"-parent");
+            children = SetFromLiveMap.create(managementContext.getStorage().<Location,Boolean>getMap(getId()+"-children"));
+            creationTimeUtc = managementContext.getStorage().getReference(getId()+"-creationTime");
+            hostGeoInfo = managementContext.getStorage().getReference(getId()+"-hostGeoInfo");
+            name = managementContext.getStorage().getReference(getId()+"-displayName");
+
+            // Only override stored defaults if we have actual values. We might be in setManagementContext
+            // because we are reconstituting an existing entity in a new brooklyn management-node (in which
+            // case believe what is already in the storage), or we might be in the middle of creating a new 
+            // entity. Normally for a new entity (using EntitySpec creation approach), this will get called
+            // before setting the parent etc. However, for backwards compatibility we still support some
+            // things calling the entity's constructor directly.
+            if (oldParent != null) parent.set(oldParent);
+            if (oldChildren.size() > 0) children.addAll(oldChildren);
+            if (creationTimeUtc.isNull()) creationTimeUtc.set(oldCreationTimeUtc);
+            if (hostGeoInfo.isNull()) hostGeoInfo.set(oldHostGeoInfo);
+            if (name.isNull()) {
+                name.set(oldDisplayName);
+            } else {
+                displayNameAutoGenerated = false;
+            }
+
+            configBag = ConfigBag.newLiveInstance(managementContext.getStorage().<String,Object>getMap(getId()+"-config"));
+            if (oldConfig.size() > 0) {
+                configBag.putAll(oldConfig);
+            }
+        }
+    }
+
+    /**
+     * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly;
+     * see overridden method for more info
+     */
+    @SuppressWarnings("serial")
+    @Override
+    @Deprecated
+    public AbstractLocation configure(Map<?,?> properties) {
+        assertNotYetManaged();
+        
+        boolean firstTime = !configured.getAndSet(true);
+            
+        configBag.putAll(properties);
+        
+        if (properties.containsKey(PARENT_LOCATION.getName())) {
+            // need to ensure parent's list of children is also updated
+            setParent(configBag.get(PARENT_LOCATION));
+            
+            // don't include parentLocation in configBag, as breaks rebind
+            configBag.remove(PARENT_LOCATION);
+        }
+
+        // NB: flag-setting done here must also be done in BasicLocationRebindSupport 
+        FlagUtils.setFieldsFromFlagsWithBag(this, properties, configBag, firstTime);
+        FlagUtils.setAllConfigKeys(this, configBag, false);
+
+        if (properties.containsKey("displayName")) {
+            name.set((String) removeIfPossible(properties, "displayName"));
+            displayNameAutoGenerated = false;
+        } else if (properties.containsKey("name")) {
+            name.set((String) removeIfPossible(properties, "name"));
+            displayNameAutoGenerated = false;
+        } else if (isLegacyConstruction()) {
+            name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4)));
+            displayNameAutoGenerated = true;
+        }
+
+        // TODO Explicitly dealing with iso3166 here because want custom splitter rule comma-separated string.
+        // Is there a better way to do it (e.g. more similar to latitude, where configKey+TypeCoercion is enough)?
+        if (groovyTruth(properties.get("iso3166"))) {
+            Object rawCodes = removeIfPossible(properties, "iso3166");
+            Set<String> codes;
+            if (rawCodes instanceof CharSequence) {
+                codes = ImmutableSet.copyOf(Splitter.on(",").trimResults().split((CharSequence)rawCodes));
+            } else {
+                codes = TypeCoercions.coerce(rawCodes, new TypeToken<Set<String>>() {});
+            }
+            configBag.put(LocationConfigKeys.ISO_3166, codes);
+        }
+        
+        return this;
+    }
+
+    // TODO ensure no callers rely on 'remove' semantics, and don't remove;
+    // or perhaps better use a config bag so we know what is used v unused
+    private static Object removeIfPossible(Map<?,?> map, Object key) {
+        try {
+            return map.remove(key);
+        } catch (Exception e) {
+            return map.get(key);
+        }
+    }
+    
+    public boolean isManaged() {
+        return getManagementContext() != null && managed;
+    }
+
+    public void onManagementStarted() {
+        if (displayNameAutoGenerated) name.set(getClass().getSimpleName()+":"+getId().substring(0, Math.min(getId().length(),4)));
+        this.managed = true;
+    }
+    
+    public void onManagementStopped() {
+        this.managed = false;
+        if (getManagementContext().isRunning()) {
+            BrooklynStorage storage = ((ManagementContextInternal)getManagementContext()).getStorage();
+            storage.remove(getId()+"-parent");
+            storage.remove(getId()+"-children");
+            storage.remove(getId()+"-creationTime");
+            storage.remove(getId()+"-hostGeoInfo");
+            storage.remove(getId()+"-displayName");
+            storage.remove(getId()+"-config");
+        }
+    }
+    
+    @Override
+    public String getDisplayName() {
+        return name.get();
+    }
+    
+    protected boolean isDisplayNameAutoGenerated() {
+        return displayNameAutoGenerated;
+    }
+    
+    @Override
+    public Location getParent() {
+        return parent.get();
+    }
+    
+    @Override
+    public Collection<Location> getChildren() {
+        synchronized (children) {
+            return ImmutableList.copyOf(children);
+        }
+    }
+
+    @Override
+    public void setParent(Location newParent) {
+        setParent(newParent, true);
+    }
+    
+    public void setParent(Location newParent, boolean updateChildListParents) {
+        if (newParent == this) {
+            throw new IllegalArgumentException("Location cannot be its own parent: "+this);
+        }
+        if (newParent == parent.get()) {
+            return; // no-op; already have desired parent
+        }
+        
+        if (parent.get() != null) {
+            Location oldParent = parent.get();
+            parent.set(null);
+            if (updateChildListParents)
+                ((AbstractLocation)oldParent).removeChild(this);
+        }
+        // TODO Should we support a location changing parent? The resulting unmanage/manage might cause problems.
+        // The code above suggests we do, but maybe we should warn or throw error, or at least test it!
+        
+        parent.set(newParent);
+        if (newParent != null) {
+            if (updateChildListParents)
+                ((AbstractLocation)newParent).addChild(this);
+        }
+        
+        onChanged();
+    }
+
+    @Override
+    public ConfigurationSupportInternal config() {
+        return config ;
+    }
+
+    private class BasicConfigurationSupport implements ConfigurationSupportInternal {
+
+        @Override
+        public <T> T get(ConfigKey<T> key) {
+            if (hasConfig(key, false)) return getLocalBag().get(key);
+            if (getParent() != null && isInherited(key)) {
+                return getParent().getConfig(key);
+            }
+            
+            // In case this entity class has overridden the given key (e.g. to set default), then retrieve this entity's key
+            // TODO when locations become entities, the duplication of this compared to EntityConfigMap.getConfig will disappear.
+            @SuppressWarnings("unchecked")
+            ConfigKey<T> ownKey = (ConfigKey<T>) elvis(locationType.getConfigKey(key.getName()), key);
+
+            return ownKey.getDefaultValue();
+        }
+
+        @Override
+        public <T> T get(HasConfigKey<T> key) {
+            return get(key.getConfigKey());
+        }
+
+        @Override
+        public <T> T set(ConfigKey<T> key, T val) {
+            T result = configBag.put(key, val);
+            onChanged();
+            return result;
+        }
+
+        @Override
+        public <T> T set(HasConfigKey<T> key, T val) {
+            return set(key.getConfigKey(), val);
+        }
+
+        @Override
+        public <T> T set(ConfigKey<T> key, Task<T> val) {
+            // TODO Support for locations
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public <T> T set(HasConfigKey<T> key, Task<T> val) {
+            // TODO Support for locations
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ConfigBag getBag() {
+            ConfigBag result = ConfigBag.newInstanceExtending(configBag, ImmutableMap.of());
+            Location p = getParent();
+            if (p!=null) result.putIfAbsent(((LocationInternal)p).config().getBag());
+            return result;
+        }
+
+        @Override
+        public ConfigBag getLocalBag() {
+            return configBag;
+        }
+
+        @Override
+        public Maybe<Object> getRaw(ConfigKey<?> key) {
+            if (hasConfig(key, false)) return Maybe.of(getLocalBag().getStringKey(key.getName()));
+            if (getParent() != null && isInherited(key)) return ((LocationInternal)getParent()).config().getRaw(key);
+            return Maybe.absent();
+        }
+
+        @Override
+        public Maybe<Object> getRaw(HasConfigKey<?> key) {
+            return getRaw(key.getConfigKey());
+        }
+
+        @Override
+        public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
+            if (hasConfig(key, false)) return Maybe.of(getLocalBag().getStringKey(key.getName()));
+            return Maybe.absent();
+        }
+
+        @Override
+        public Maybe<Object> getLocalRaw(HasConfigKey<?> key) {
+            return getLocalRaw(key.getConfigKey());
+        }
+
+        @Override
+        public void addToLocalBag(Map<String, ?> vals) {
+            configBag.putAll(vals);
+        }
+
+        @Override
+        public void removeFromLocalBag(String key) {
+            configBag.remove(key);
+        }
+
+        @Override
+        public void refreshInheritedConfig() {
+            // no-op for location
+        }
+        
+        @Override
+        public void refreshInheritedConfigOfChildren() {
+            // no-op for location
+        }
+        
+        private boolean hasConfig(ConfigKey<?> key, boolean includeInherited) {
+            if (includeInherited && isInherited(key)) {
+                return getBag().containsKey(key);
+            } else {
+                return getLocalBag().containsKey(key);
+            }
+        }
+        
+        private boolean isInherited(ConfigKey<?> key) {
+            ConfigInheritance inheritance = key.getInheritance();
+            if (inheritance==null) inheritance = getDefaultInheritance();
+            return inheritance.isInherited(key, getParent(), AbstractLocation.this);
+        }
+
+        private ConfigInheritance getDefaultInheritance() {
+            return ConfigInheritance.ALWAYS;
+        }
+    }
+    
+    @Override
+    public <T> T getConfig(HasConfigKey<T> key) {
+        return config().get(key);
+    }
+
+    @Override
+    public <T> T getConfig(ConfigKey<T> key) {
+        return config().get(key);
+    }
+
+    @Override
+    @Deprecated
+    public boolean hasConfig(ConfigKey<?> key, boolean includeInherited) {
+        return config.hasConfig(key, includeInherited);
+    }
+
+    @Override
+    @Deprecated
+    public Map<String,Object> getAllConfig(boolean includeInherited) {
+        // TODO Have no information about what to include/exclude inheritance wise.
+        // however few things use getAllConfigBag()
+        ConfigBag bag = (includeInherited ? config().getBag() : config().getLocalBag());
+        return bag.getAllConfig();
+    }
+    
+    @Override
+    @Deprecated
+    public ConfigBag getAllConfigBag() {
+        // TODO see comments in EntityConfigMap and on interface methods. 
+        // here ConfigBag is used exclusively so
+        // we have no information about what to include/exclude inheritance wise.
+        // however few things use getAllConfigBag()
+        return config().getBag();
+    }
+    
+    @Override
+    public ConfigBag getLocalConfigBag() {
+        return config().getLocalBag();
+    }
+
+    /** 
+     * @deprecated since 0.7; use {@link #getLocalConfigBag()}
+     * @since 0.6
+     */
+    @Deprecated
+    public ConfigBag getRawLocalConfigBag() {
+        return config().getLocalBag();
+    }
+    
+    @Override
+    @Deprecated
+    public <T> T setConfig(ConfigKey<T> key, T value) {
+        return config().set(key, value);
+    }
+
+    /**
+     * @since 0.6.0 (?) - use getDisplayName
+     * @deprecated since 0.7.0; use {@link #getDisplayName()}
+     */
+    @Deprecated
+    public void setName(String newName) {
+        setDisplayName(newName);
+    }
+
+    public void setDisplayName(String newName) {
+        name.set(newName);
+        displayNameAutoGenerated = false;
+        onChanged();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (! (o instanceof Location)) {
+            return false;
+        }
+
+        Location l = (Location) o;
+        return getId().equals(l.getId());
+    }
+
+    @Override
+    public int hashCode() {
+        return getId().hashCode();
+    }
+
+    @Override
+    public boolean containsLocation(Location potentialDescendent) {
+        Location loc = potentialDescendent;
+        while (loc != null) {
+            if (this == loc) return true;
+            loc = loc.getParent();
+        }
+        return false;
+    }
+
+    protected <T extends Location> T addChild(LocationSpec<T> spec) {
+        T child = getManagementContext().getLocationManager().createLocation(spec);
+        addChild(child);
+        return child;
+    }
+    
+    @SuppressWarnings("deprecation")
+    public void addChild(Location child) {
+        // Previously, setParent delegated to addChildLocation and we sometimes ended up with
+        // duplicate entries here. Instead this now uses a similar scheme to 
+        // AbstractLocation.setParent/addChild (with any weaknesses for distribution that such a 
+        // scheme might have...).
+        // 
+        // We continue to use a list to allow identical-looking locations, but they must be different 
+        // instances.
+        
+        synchronized (children) {
+            for (Location contender : children) {
+                if (contender == child) {
+                    // don't re-add; no-op
+                    return;
+                }
+            }
+
+            children.add(child);
+        }
+        
+        if (isManaged()) {
+            if (!getManagementContext().getLocationManager().isManaged(child)) {
+                Locations.manage(child, getManagementContext());
+            }
+        } else if (getManagementContext() != null) {
+            if (((LocalLocationManager)getManagementContext().getLocationManager()).getLocationEvenIfPreManaged(child.getId()) == null) {
+                ((ManagementContextInternal)getManagementContext()).prePreManage(child);
+            }
+        }
+
+        children.add(child);
+        child.setParent(this);
+        
+        onChanged();
+    }
+    
+    public boolean removeChild(Location child) {
+        boolean removed;
+        synchronized (children) {
+            removed = children.remove(child);
+        }
+        if (removed) {
+            if (child instanceof Closeable) {
+                Streams.closeQuietly((Closeable)child);
+            }
+            child.setParent(null);
+            
+            if (isManaged()) {
+                getManagementContext().getLocationManager().unmanage(child);
+            }
+        }
+        onChanged();
+        return removed;
+    }
+
+    protected void onChanged() {
+        // currently changes simply trigger re-persistence; there is no intermediate listener as we do for EntityChangeListener
+        if (isManaged()) {
+            getManagementContext().getRebindManager().getChangeListener().onChanged(this);
+        }
+    }
+
+    /** Default String representation is simplified name of class, together with selected fields. */
+    @Override
+    public String toString() {
+        return string().toString();
+    }
+    
+    @Override
+    public String toVerboseString() {
+        return toString();
+    }
+
+    /** override this, adding to the returned value, to supply additional fields to include in the toString */
+    protected ToStringHelper string() {
+        return Objects.toStringHelper(getClass()).add("id", getId()).add("name", name);
+    }
+    
+    @Override
+    public HostGeoInfo getHostGeoInfo() { return hostGeoInfo.get(); }
+    
+    public void setHostGeoInfo(HostGeoInfo hostGeoInfo) {
+        if (hostGeoInfo!=null) { 
+            this.hostGeoInfo.set(hostGeoInfo);
+            setConfig(LocationConfigKeys.LATITUDE, hostGeoInfo.latitude); 
+            setConfig(LocationConfigKeys.LONGITUDE, hostGeoInfo.longitude); 
+        } 
+    }
+
+    @Override
+    public RebindSupport<LocationMemento> getRebindSupport() {
+        return new BasicLocationRebindSupport(this);
+    }
+    
+    @Override
+    public boolean hasExtension(Class<?> extensionType) {
+        return extensions.get().containsKey(checkNotNull(extensionType, "extensionType"));
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T> T getExtension(Class<T> extensionType) {
+        Object extension = extensions.get().get(checkNotNull(extensionType, "extensionType"));
+        if (extension == null) {
+            throw new IllegalArgumentException("No extension of type "+extensionType+" registered for location "+this);
+        }
+        return (T) extension;
+    }
+    
+    @Override
+    public <T> void addExtension(Class<T> extensionType, T extension) {
+        checkNotNull(extensionType, "extensionType");
+        checkNotNull(extension, "extension");
+        checkArgument(extensionType.isInstance(extension), "extension %s does not implement %s", extension, extensionType);
+        extensions.get().put(extensionType, extension);
+    }
+
+    @Override
+    public Map<String, String> toMetadataRecord() {
+        ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+        if (getDisplayName() != null) builder.put("displayName", getDisplayName());
+        if (getParent() != null && getParent().getDisplayName() != null) {
+            builder.put("parentDisplayName", getParent().getDisplayName());
+        }
+        return builder.build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java
new file mode 100644
index 0000000..59a0771
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocationResolver.java
@@ -0,0 +1,189 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationSpec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.location.basic.AbstractLocationResolver.SpecParser.ParsedSpec;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.text.KeyValueParser;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Examples of valid specs:
+ *   <ul>
+ *     <li>byon(hosts=myhost)
+ *     <li>byon(hosts=myhost,myhost2)
+ *     <li>byon(hosts="myhost, myhost2")
+ *     <li>byon(hosts=myhost,myhost2, name=abc)
+ *     <li>byon(hosts="myhost, myhost2", name="my location name")
+ *   </ul>
+ * 
+ * @author aled
+ */
+@SuppressWarnings({"unchecked","rawtypes"})
+public abstract class AbstractLocationResolver implements LocationResolver {
+
+    public static final Logger log = LoggerFactory.getLogger(AbstractLocationResolver.class);
+    
+    protected volatile ManagementContext managementContext;
+
+    protected volatile SpecParser specParser;
+
+    protected abstract Class<? extends Location> getLocationType();
+    
+    protected abstract SpecParser getSpecParser();
+    
+    @Override
+    public void init(ManagementContext managementContext) {
+        this.managementContext = checkNotNull(managementContext, "managementContext");
+        this.specParser = getSpecParser();
+    }
+    
+    @Override
+    public boolean accepts(String spec, LocationRegistry registry) {
+        return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true);
+    }
+
+    @Override
+    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        ConfigBag config = extractConfig(locationFlags, spec, registry);
+        Map globalProperties = registry.getProperties();
+        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
+        
+        if (registry != null) {
+            LocationPropertiesFromBrooklynProperties.setLocalTempDir(globalProperties, config);
+        }
+
+        return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationType())
+            .configure(config.getAllConfig())
+            .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+    }
+
+    protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, LocationRegistry registry) {
+        Map globalProperties = registry.getProperties();
+        ParsedSpec parsedSpec = specParser.parse(spec);
+        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
+        
+        // prefer args map over location flags
+        Map<String, Object> filteredProperties = getFilteredLocationProperties(getPrefix(), namedLocation, globalProperties);
+        ConfigBag flags = ConfigBag.newInstance(parsedSpec.argsMap).putIfAbsent(locationFlags).putIfAbsent(filteredProperties);
+
+        return flags;
+    }
+    
+    protected Map<String, Object> getFilteredLocationProperties(String provider, String namedLocation, Map<String, ?> globalProperties) {
+        return new LocationPropertiesFromBrooklynProperties().getLocationProperties(getPrefix(), namedLocation, globalProperties);
+    }
+    
+    /**
+     * Parses a spec, by default of the general form "prefix:parts1:part2(arg1=val1,arg2=val2)"
+     */
+    protected static class SpecParser {
+        
+        protected static class ParsedSpec {
+            public final String spec;
+            public final List<String> partsList;
+            public final Map<String,String> argsMap;
+            
+            ParsedSpec(String spec, List<String> partsList, Map<String,String> argsMap) {
+                this.spec = spec;
+                this.partsList = ImmutableList.copyOf(partsList);
+                this.argsMap = Collections.unmodifiableMap(MutableMap.copyOf(argsMap));
+            }
+        }
+        
+        protected final String prefix;
+        protected final Pattern pattern;
+        private String exampleUsage;
+        
+        public SpecParser(String prefix) {
+            this.prefix = prefix;
+            pattern = Pattern.compile("("+prefix+"|"+prefix.toLowerCase()+"|"+prefix.toUpperCase()+")" + "(:)?" + "(\\((.*)\\))?$");
+        }
+        
+        public SpecParser(String prefix, Pattern pattern) {
+            this.prefix = prefix;
+            this.pattern = pattern;
+        }
+        
+        public SpecParser setExampleUsage(String exampleUsage) {
+            this.exampleUsage = exampleUsage;
+            return this;
+        }
+
+        protected String getUsage(String spec) {
+            if (exampleUsage == null) {
+                return "Spec should be in the form "+pattern;
+            } else {
+                return "for example, "+exampleUsage;
+            }
+        }
+        
+        protected void checkParsedSpec(ParsedSpec parsedSpec) {
+            // If someone tries "byon:(),byon:()" as a single spec, we get weird key-values!
+            for (String key : parsedSpec.argsMap.keySet()) {
+                if (key.contains(":") || key.contains("{") || key.contains("}") || key.contains("(") || key.contains(")")) {
+                    throw new IllegalArgumentException("Invalid byon spec: "+parsedSpec.spec+" (key="+key+")");
+                }
+            }
+            String name = parsedSpec.argsMap.get("name");
+            if (parsedSpec.argsMap.containsKey("name") && (name == null || name.isEmpty())) {
+                throw new IllegalArgumentException("Invalid location '"+parsedSpec.spec+"'; if name supplied then value must be non-empty");
+            }
+            String displayName = parsedSpec.argsMap.get("displayName");
+            if (parsedSpec.argsMap.containsKey("displayName") && (displayName == null || displayName.isEmpty())) {
+                throw new IllegalArgumentException("Invalid location '"+parsedSpec.spec+"'; if displayName supplied then value must be non-empty");
+            }
+        }
+        
+        public ParsedSpec parse(String spec) {
+            Matcher matcher = pattern.matcher(spec);
+            if (!matcher.matches()) {
+                throw new IllegalArgumentException("Invalid location '"+spec+"'; "+getUsage(spec));
+            }
+            
+            String argsPart = matcher.group(3);
+            if (argsPart != null && argsPart.startsWith("(") && argsPart.endsWith(")")) {
+                // TODO Hacky; hosts("1.1.1.1") returns argsPart=("1.1.1.1")
+                argsPart = argsPart.substring(1, argsPart.length()-1);
+            }
+            Map<String, String> argsMap = KeyValueParser.parseMap(argsPart);
+            ParsedSpec result = new ParsedSpec(spec, ImmutableList.<String>of(), argsMap);
+            checkParsedSpec(result);
+            return result;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
new file mode 100644
index 0000000..33e8efa
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
@@ -0,0 +1,139 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.io.Closeable;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.stream.Streams;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Takes a list of other provisioners, and round-robins across them when obtaining a machine.
+ */
+public class AggregatingMachineProvisioningLocation<T extends MachineLocation> extends AbstractLocation 
+        implements MachineProvisioningLocation<T>, Closeable {
+
+    private Object lock;
+    
+    @SetFromFlag
+    protected List<MachineProvisioningLocation<T>> provisioners;
+    
+    @SetFromFlag
+    protected Map<T, MachineProvisioningLocation<T>> inUse;
+
+    protected final AtomicInteger obtainCounter = new AtomicInteger();
+    
+    public AggregatingMachineProvisioningLocation() {
+        this(Maps.newLinkedHashMap());
+    }
+    
+    public AggregatingMachineProvisioningLocation(Map properties) {
+        super(properties);
+
+        if (isLegacyConstruction()) {
+            init();
+        }
+    }
+
+    @Override
+    public void init() {
+        super.init();
+    }
+    
+    @Override
+    public String toVerboseString() {
+        return Objects.toStringHelper(this).omitNullValues()
+                .add("id", getId()).add("name", getDisplayName())
+                .add("provisioners", provisioners)
+                .toString();
+    }
+
+    @Override
+    public AbstractLocation configure(Map<?,?> properties) {
+        if (lock == null) {
+            lock = new Object();
+            provisioners = Lists.<MachineProvisioningLocation<T>>newArrayList();
+            inUse = Maps.<T, MachineProvisioningLocation<T>>newLinkedHashMap();
+        }
+        return super.configure(properties);
+    }
+    
+    @Override
+    public AggregatingMachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void close() {
+        for (MachineProvisioningLocation<?> provisioner : provisioners) {
+            if (provisioner instanceof Closeable) {
+                Streams.closeQuietly((Closeable)provisioner);
+            }
+        }
+    }
+    
+    public T obtain() throws NoMachinesAvailableException {
+        return obtain(Maps.<String,Object>newLinkedHashMap());
+    }
+    
+    @Override
+    public T obtain(Map<?,?> flags) throws NoMachinesAvailableException {
+        checkState(provisioners.size() > 0, "no provisioners!");
+        int index = obtainCounter.getAndIncrement();
+        for (int i = 0; i < provisioners.size(); i++) {
+            MachineProvisioningLocation<T> provisioner = provisioners.get(index++ % provisioners.size());
+            try {
+                T machine = provisioner.obtain(flags);
+                inUse.put(machine, provisioner);
+                return machine;
+            } catch (NoMachinesAvailableException e) {
+                // move on; try next
+            }
+        }
+        throw new NoMachinesAvailableException("No machines available in "+toString());
+    }
+
+    @Override
+    public void release(T machine) {
+        MachineProvisioningLocation<T> provisioner = inUse.remove(machine);
+        if (provisioner != null) {
+            provisioner.release(machine);
+        } else {
+            throw new IllegalStateException("Request to release machine "+machine+", but this machine is not currently allocated");
+        }
+    }
+
+    @Override
+    public Map<String,Object> getProvisioningFlags(Collection<String> tags) {
+        return Maps.<String,Object>newLinkedHashMap();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java
new file mode 100644
index 0000000..fc90a68
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicHardwareDetails.java
@@ -0,0 +1,56 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import javax.annotation.concurrent.Immutable;
+
+import com.google.common.base.Objects;
+
+import org.apache.brooklyn.location.HardwareDetails;
+
+@Immutable
+public class BasicHardwareDetails implements HardwareDetails {
+
+    private final Integer cpuCount;
+    private final Integer ram;
+
+    public BasicHardwareDetails(Integer cpuCount, Integer ram) {
+        this.cpuCount = cpuCount;
+        this.ram = ram;
+    }
+
+    @Override
+    public Integer getCpuCount() {
+        return cpuCount;
+    }
+
+    @Override
+    public Integer getRam() {
+        return ram;
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(HardwareDetails.class)
+                .omitNullValues()
+                .add("cpuCount", cpuCount)
+                .add("ram", ram)
+                .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java
new file mode 100644
index 0000000..550ca12
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationDefinition.java
@@ -0,0 +1,85 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.LocationDefinition;
+import brooklyn.util.text.Identifiers;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
+public class BasicLocationDefinition implements LocationDefinition {
+
+    private final String id;
+    private final String name;
+    private final String spec;
+    private final Map<String,Object> config;
+
+    public BasicLocationDefinition(String name, String spec, Map<String,? extends Object> config) {
+        this(Identifiers.makeRandomId(8), name, spec, config);
+    }
+    
+    public BasicLocationDefinition(String id, String name, String spec, Map<String,? extends Object> config) {      
+        this.id = Preconditions.checkNotNull(id);
+        this.name = name;
+        this.spec = Preconditions.checkNotNull(spec);
+        this.config = config==null ? ImmutableMap.<String, Object>of() : ImmutableMap.<String, Object>copyOf(config);
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+    
+    public String getSpec() {
+        return spec;
+    }
+    
+    @Override
+    public Map<String, Object> getConfig() {
+        return config;
+    }
+    
+    @Override
+    public boolean equals(Object o) {
+        if (this==o) return true;
+        if ((o instanceof LocationDefinition) && id.equals(((LocationDefinition)o).getId())) return true;
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "LocationDefinition{" +
+                "id='" + getId() + '\'' +
+                ", name='" + getName() + '\'' +
+                ", spec='" + getSpec() + '\'' +
+                ", config=" + getConfig() +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
new file mode 100644
index 0000000..1c21e32
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicLocationRegistry.java
@@ -0,0 +1,480 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationSpec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.api.catalog.BrooklynCatalog;
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.management.ManagementContext;
+
+import brooklyn.catalog.CatalogPredicates;
+import brooklyn.config.ConfigMap;
+import brooklyn.config.ConfigPredicates;
+import brooklyn.config.ConfigUtils;
+import brooklyn.management.internal.LocalLocationManager;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.guava.Maybe.Absent;
+import brooklyn.util.javalang.JavaClassNames;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+import brooklyn.util.text.WildcardGlobs;
+import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+
+/**
+ * See {@link LocationRegistry} for general description.
+ * <p>
+ * TODO The relationship between the catalog and the location registry is a bit messy.
+ * For all existing code, the location registry is the definitive way to resolve
+ * locations. 
+ * <p>
+ * Any location item added to the catalog must therefore be registered here.
+ * Whenever an item is added to the catalog, it will automatically call 
+ * {@link #updateDefinedLocation(CatalogItem)}. Similarly, when a location
+ * is deleted from the catalog it will call {@link #removeDefinedLocation(CatalogItem)}.
+ * <p>
+ * However, the location item in the catalog has an unparsed blob of YAML, which contains
+ * important things like the type and the config of the location. This is only parsed when 
+ * {@link BrooklynCatalog#createSpec(CatalogItem)} is called. We therefore jump through 
+ * some hoops to wire together the catalog and the registry.
+ * <p>
+ * To add a location to the catalog, and then to resolve a location that is in the catalog, 
+ * it goes through the following steps:
+ * 
+ * <ol>
+ *   <li>Call {@link BrooklynCatalog#addItems(String)}
+ *     <ol>
+ *       <li>This automatically calls {@link #updateDefinedLocation(CatalogItem)}
+ *       <li>A LocationDefinition is creating, using as its id the {@link CatalogItem#getSymbolicName()}.
+ *           The definition's spec is {@code brooklyn.catalog:<symbolicName>:<version>},
+ *     </ol>
+ *   <li>A blueprint can reference the catalog item using its symbolic name, 
+ *       such as the YAML {@code location: my-new-location}.
+ *       (this feels similar to the "named locations").
+ *     <ol>
+ *       <li>This automatically calls {@link #resolve(String)}.
+ *       <li>The LocationDefinition is found by lookig up this name.
+ *       <li>The {@link LocationDefiniton.getSpec()} is retrieved; the right {@link LocationResolver} is
+ *           found for it.
+ *       <li>This uses the {@link CatalogLocationResolver}, because the spec starts with {@code brooklyn.catalog:}.
+ *       <li>This resolver extracts from the spec the <symobolicName>:<version>, and looks up the 
+ *           catalog item using {@link BrooklynCatalog#getCatalogItem(String, String)}.
+ *       <li>It then creates a {@link LocationSpec} by calling {@link BrooklynCatalog#createSpec(CatalogItem)}.
+ *         <ol>
+ *           <li>This first tries to use the type (that is in the YAML) as a simple Java class.
+ *           <li>If that fails, it will resolve the type using {@link #resolve(String, Boolean, Map)}, which
+ *               returns an actual location object.
+ *           <li>It extracts from that location object the appropriate metadata to create a {@link LocationSpec},
+ *               returns the spec and discards the location object.
+ *         </ol>
+ *       <li>The resolver creates the {@link Location} from the {@link LocationSpec}
+ *     </ol>
+ * </ol>
+ * 
+ * There is no concept of a location version in this registry. The version
+ * in the catalog is generally ignored.
+ */
+@SuppressWarnings({"rawtypes","unchecked"})
+public class BasicLocationRegistry implements LocationRegistry {
+
+    // TODO save / serialize
+    // (we persist live locations, ie those in the LocationManager, but not "catalog" locations, ie those in this Registry)
+    
+    public static final Logger log = LoggerFactory.getLogger(BasicLocationRegistry.class);
+
+    /**
+     * Splits a comma-separated list of locations (names or specs) into an explicit list.
+     * The splitting is very careful to handle commas embedded within specs, to split correctly.
+     */
+    public static List<String> expandCommaSeparateLocations(String locations) {
+        return WildcardGlobs.getGlobsAfterBraceExpansion("{"+locations+"}", false, PhraseTreatment.INTERIOR_NOT_EXPANDABLE, PhraseTreatment.INTERIOR_NOT_EXPANDABLE);
+        // don't do this, it tries to expand commas inside parentheses which is not good!
+//        QuotedStringTokenizer.builder().addDelimiterChars(",").buildList((String)id);
+    }
+
+    private final ManagementContext mgmt;
+    /** map of defined locations by their ID */
+    private final Map<String,LocationDefinition> definedLocations = new LinkedHashMap<String, LocationDefinition>();
+
+    protected final Map<String,LocationResolver> resolvers = new LinkedHashMap<String, LocationResolver>();
+
+    private final Set<String> specsWarnedOnException = Sets.newConcurrentHashSet();
+
+    public BasicLocationRegistry(ManagementContext mgmt) {
+        this.mgmt = checkNotNull(mgmt, "mgmt");
+        findServices();
+        updateDefinedLocations();
+    }
+
+    protected void findServices() {
+        ServiceLoader<LocationResolver> loader = ServiceLoader.load(LocationResolver.class, mgmt.getCatalogClassLoader());
+        for (LocationResolver r: loader) {
+            registerResolver(r);
+        }
+        if (log.isDebugEnabled()) log.debug("Location resolvers are: "+resolvers);
+        if (resolvers.isEmpty()) log.warn("No location resolvers detected: is src/main/resources correctly included?");
+    }
+
+    /** Registers the given resolver, invoking {@link LocationResolver#init(ManagementContext)} on the argument
+     * and returning true, unless the argument indicates false for {@link LocationResolver.EnableableLocationResolver#isEnabled()} */
+    public boolean registerResolver(LocationResolver r) {
+        r.init(mgmt);
+        if (r instanceof LocationResolver.EnableableLocationResolver) {
+            if (!((LocationResolver.EnableableLocationResolver)r).isEnabled()) {
+                return false;
+            }
+        }
+        resolvers.put(r.getPrefix(), r);
+        return true;
+    }
+    
+    @Override
+    public Map<String,LocationDefinition> getDefinedLocations() {
+        synchronized (definedLocations) {
+            return ImmutableMap.<String,LocationDefinition>copyOf(definedLocations);
+        }
+    }
+    
+    @Override
+    public LocationDefinition getDefinedLocationById(String id) {
+        return definedLocations.get(id);
+    }
+
+    @Override
+    public LocationDefinition getDefinedLocationByName(String name) {
+        synchronized (definedLocations) {
+            for (LocationDefinition l: definedLocations.values()) {
+                if (l.getName().equals(name)) return l;
+            }
+            return null;
+        }
+    }
+
+    @Override
+    public void updateDefinedLocation(LocationDefinition l) {
+        synchronized (definedLocations) { 
+            definedLocations.put(l.getId(), l); 
+        }
+    }
+
+    /**
+     * Converts the given item from the catalog into a LocationDefinition, and adds it
+     * to the registry (overwriting anything already registered with the id
+     * {@link CatalogItem#getCatalogItemId()}.
+     */
+    public void updateDefinedLocation(CatalogItem<Location, LocationSpec<?>> item) {
+        String id = item.getCatalogItemId();
+        String symbolicName = item.getSymbolicName();
+        String spec = CatalogLocationResolver.NAME + ":" + id;
+        Map<String, Object> config = ImmutableMap.<String, Object>of();
+        BasicLocationDefinition locDefinition = new BasicLocationDefinition(symbolicName, symbolicName, spec, config);
+        
+        updateDefinedLocation(locDefinition);
+    }
+
+    public void removeDefinedLocation(CatalogItem<Location, LocationSpec<?>> item) {
+        removeDefinedLocation(item.getSymbolicName());
+    }
+    
+    @Override
+    public void removeDefinedLocation(String id) {
+        LocationDefinition removed;
+        synchronized (definedLocations) { 
+            removed = definedLocations.remove(id);
+        }
+        if (removed == null && log.isDebugEnabled()) {
+            log.debug("{} was asked to remove location with id {} but no such location was registered", this, id);
+        }
+    }
+    
+    public void updateDefinedLocations() {
+        synchronized (definedLocations) {
+            // first read all properties starting  brooklyn.location.named.xxx
+            // (would be nice to move to a better way, e.g. yaml, then deprecate this approach, but first
+            // we need ability/format for persisting named locations, and better support for adding+saving via REST/GUI)
+            int count = 0; 
+            String NAMED_LOCATION_PREFIX = "brooklyn.location.named.";
+            ConfigMap namedLocationProps = mgmt.getConfig().submap(ConfigPredicates.startingWith(NAMED_LOCATION_PREFIX));
+            for (String k: namedLocationProps.asMapWithStringKeys().keySet()) {
+                String name = k.substring(NAMED_LOCATION_PREFIX.length());
+                // If has a dot, then is a sub-property of a named location (e.g. brooklyn.location.named.prod1.user=bob)
+                if (!name.contains(".")) {
+                    // this is a new named location
+                    String spec = (String) namedLocationProps.asMapWithStringKeys().get(k);
+                    // make up an ID
+                    String id = Identifiers.makeRandomId(8);
+                    Map<String, Object> config = ConfigUtils.filterForPrefixAndStrip(namedLocationProps.asMapWithStringKeys(), k+".");
+                    definedLocations.put(id, new BasicLocationDefinition(id, name, spec, config));
+                    count++;
+                }
+            }
+            if (log.isDebugEnabled())
+                log.debug("Found "+count+" defined locations from properties (*.named.* syntax): "+definedLocations.values());
+            if (getDefinedLocationByName("localhost")==null && !BasicOsDetails.Factory.newLocalhostInstance().isWindows()
+                    && LocationConfigUtils.isEnabled(mgmt, "brooklyn.location.localhost")) {
+                log.debug("Adding a defined location for localhost");
+                // add 'localhost' *first*
+                ImmutableMap<String, LocationDefinition> oldDefined = ImmutableMap.copyOf(definedLocations);
+                definedLocations.clear();
+                String id = Identifiers.makeRandomId(8);
+                definedLocations.put(id, localhost(id));
+                definedLocations.putAll(oldDefined);
+            }
+            
+            for (CatalogItem<Location, LocationSpec<?>> item : mgmt.getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION)) {
+                updateDefinedLocation(item);
+                count++;
+            }
+        }
+    }
+    
+    @VisibleForTesting
+    void disablePersistence() {
+        // persistence isn't enabled yet anyway (have to manually save things,
+        // defining the format and file etc)
+    }
+
+    protected static BasicLocationDefinition localhost(String id) {
+        return new BasicLocationDefinition(id, "localhost", "localhost", null);
+    }
+    
+    /** to catch circular references */
+    protected ThreadLocal<Set<String>> specsSeen = new ThreadLocal<Set<String>>();
+    
+    @Override @Deprecated
+    public boolean canMaybeResolve(String spec) {
+        return getSpecResolver(spec) != null;
+    }
+
+    @Override
+    public final Location resolve(String spec) {
+        return resolve(spec, true, null).get();
+    }
+    
+    @Override @Deprecated
+    public final Location resolveIfPossible(String spec) {
+        if (!canMaybeResolve(spec)) return null;
+        return resolve(spec, null, null).orNull();
+    }
+    
+    @Deprecated /** since 0.7.0 not used */
+    public final Maybe<Location> resolve(String spec, boolean manage) {
+        return resolve(spec, manage, null);
+    }
+    
+    public Maybe<Location> resolve(String spec, Boolean manage, Map locationFlags) {
+        try {
+            locationFlags = MutableMap.copyOf(locationFlags);
+            if (manage!=null) {
+                locationFlags.put(LocalLocationManager.CREATE_UNMANAGED, !manage);
+            }
+            
+            Set<String> seenSoFar = specsSeen.get();
+            if (seenSoFar==null) {
+                seenSoFar = new LinkedHashSet<String>();
+                specsSeen.set(seenSoFar);
+            }
+            if (seenSoFar.contains(spec))
+                return Maybe.absent(Suppliers.ofInstance(new IllegalStateException("Circular reference in definition of location '"+spec+"' ("+seenSoFar+")")));
+            seenSoFar.add(spec);
+            
+            LocationResolver resolver = getSpecResolver(spec);
+
+            if (resolver != null) {
+                try {
+                    return Maybe.of(resolver.newLocationFromString(locationFlags, spec, this));
+                } catch (RuntimeException e) {
+                    return Maybe.absent(Suppliers.ofInstance(e));
+                }
+            }
+
+            // problem: but let's ensure that classpath is sane to give better errors in common IDE bogus case;
+            // and avoid repeated logging
+            String errmsg;
+            if (spec == null || specsWarnedOnException.add(spec)) {
+                if (resolvers.get("id")==null || resolvers.get("named")==null) {
+                    log.error("Standard location resolvers not installed, location resolution will fail shortly. "
+                            + "This usually indicates a classpath problem, such as when running from an IDE which "
+                            + "has not properly copied META-INF/services from src/main/resources. "
+                            + "Known resolvers are: "+resolvers.keySet());
+                    errmsg = "Unresolvable location '"+spec+"': "
+                            + "Problem detected with location resolver configuration; "
+                            + resolvers.keySet()+" are the only available location resolvers. "
+                            + "More information can be found in the logs.";
+                } else {
+                    log.debug("Location resolution failed for '"+spec+"' (if this is being loaded it will fail shortly): known resolvers are: "+resolvers.keySet());
+                    errmsg = "Unknown location '"+spec+"': "
+                            + "either this location is not recognised or there is a problem with location resolver configuration.";
+                }
+            } else {
+                // For helpful log message construction: assumes classpath will not suddenly become wrong; might happen with OSGi though!
+                if (log.isDebugEnabled()) log.debug("Location resolution failed again for '"+spec+"' (throwing)");
+                errmsg = "Unknown location '"+spec+"': "
+                        + "either this location is not recognised or there is a problem with location resolver configuration.";
+            }
+
+            return Maybe.absent(Suppliers.ofInstance(new NoSuchElementException(errmsg)));
+
+        } finally {
+            specsSeen.remove();
+        }
+    }
+
+    @Override
+    public final Location resolve(String spec, Map locationFlags) {
+        return resolve(spec, null, locationFlags).get();
+    }
+
+    protected LocationResolver getSpecResolver(String spec) {
+        int colonIndex = spec.indexOf(':');
+        int bracketIndex = spec.indexOf("(");
+        int dividerIndex = (colonIndex < 0) ? bracketIndex : (bracketIndex < 0 ? colonIndex : Math.min(bracketIndex, colonIndex));
+        String prefix = dividerIndex >= 0 ? spec.substring(0, dividerIndex) : spec;
+        LocationResolver resolver = resolvers.get(prefix);
+       
+        if (resolver == null)
+            resolver = getSpecDefaultResolver(spec);
+        
+        return resolver;
+    }
+    
+    protected LocationResolver getSpecDefaultResolver(String spec) {
+        return getSpecFirstResolver(spec, "id", "named", "jclouds");
+    }
+    protected LocationResolver getSpecFirstResolver(String spec, String ...resolversToCheck) {
+        for (String resolverId: resolversToCheck) {
+            LocationResolver resolver = resolvers.get(resolverId);
+            if (resolver!=null && resolver.accepts(spec, this))
+                return resolver;
+        }
+        return null;
+    }
+
+    /** providers default impl for RegistryLocationResolver.accepts */
+    public static boolean isResolverPrefixForSpec(LocationResolver resolver, String spec, boolean argumentRequired) {
+        if (spec==null) return false;
+        if (spec.startsWith(resolver.getPrefix()+":")) return true;
+        if (!argumentRequired && spec.equals(resolver.getPrefix())) return true;
+        return false;
+    }
+
+    @Override
+    public List<Location> resolve(Iterable<?> spec) {
+        List<Location> result = new ArrayList<Location>();
+        for (Object id : spec) {
+            if (id instanceof String) {
+                result.add(resolve((String) id));
+            } else if (id instanceof Location) {
+                result.add((Location) id);
+            } else {
+                if (id instanceof Iterable)
+                    throw new IllegalArgumentException("Cannot resolve '"+id+"' to a location; collections of collections not allowed"); 
+                throw new IllegalArgumentException("Cannot resolve '"+id+"' to a location; unsupported type "+
+                        (id == null ? "null" : id.getClass().getName())); 
+            }
+        }
+        return result;
+    }
+    
+    public List<Location> resolveList(Object l) {
+        if (l==null) l = Collections.emptyList();
+        if (l instanceof String) l = JavaStringEscapes.unwrapJsonishListIfPossible((String)l);
+        if (l instanceof Iterable) return resolve((Iterable<?>)l);
+        throw new IllegalArgumentException("Location list must be supplied as a collection or a string, not "+
+            JavaClassNames.simpleClassName(l)+"/"+l);
+    }
+    
+    @Override
+    public Location resolve(LocationDefinition ld) {
+        return resolve(ld, null, null).get();
+    }
+
+    @Override @Deprecated
+    public Location resolveForPeeking(LocationDefinition ld) {
+        // TODO should clean up how locations are stored, figuring out whether they are shared or not;
+        // or maybe better, the API calls to this might just want to get the LocationSpec objects back
+        
+        // for now we use a 'CREATE_UNMANGED' flag to prevent management (leaks and logging)
+        return resolve(ld, ConfigBag.newInstance().configure(LocalLocationManager.CREATE_UNMANAGED, true).getAllConfig());
+    }
+
+    @Override @Deprecated
+    public Location resolve(LocationDefinition ld, Map<?,?> flags) {
+        return resolveLocationDefinition(ld, flags, null);
+    }
+    
+    /** @deprecated since 0.7.0 not used (and optionalName was ignored anyway) */
+    @Deprecated
+    public Location resolveLocationDefinition(LocationDefinition ld, Map locationFlags, String optionalName) {
+        return resolve(ld, null, locationFlags).get();
+    }
+    
+    public Maybe<Location> resolve(LocationDefinition ld, Boolean manage, Map locationFlags) {
+        ConfigBag newLocationFlags = ConfigBag.newInstance(ld.getConfig())
+            .putAll(locationFlags)
+            .putIfAbsentAndNotNull(LocationInternal.NAMED_SPEC_NAME, ld.getName())
+            .putIfAbsentAndNotNull(LocationInternal.ORIGINAL_SPEC, ld.getName());
+        Maybe<Location> result = resolve(ld.getSpec(), manage, newLocationFlags.getAllConfigRaw());
+        if (result.isPresent()) 
+            return result;
+        throw new IllegalStateException("Cannot instantiate location '"+ld+"' pointing at "+ld.getSpec()+": "+
+            Exceptions.collapseText( ((Absent<?>)result).getException() ));
+    }
+
+    @Override
+    public Map getProperties() {
+        return mgmt.getConfig().asMapWithStringKeys();
+    }
+
+    @VisibleForTesting
+    public static void setupLocationRegistryForTesting(ManagementContext mgmt) {
+        // ensure localhost is added (even on windows)
+        LocationDefinition l = mgmt.getLocationRegistry().getDefinedLocationByName("localhost");
+        if (l==null) mgmt.getLocationRegistry().updateDefinedLocation(
+                BasicLocationRegistry.localhost(Identifiers.makeRandomId(8)) );
+        
+        ((BasicLocationRegistry)mgmt.getLocationRegistry()).disablePersistence();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java
new file mode 100644
index 0000000..e4b4575
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineDetails.java
@@ -0,0 +1,181 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.Immutable;
+
+import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.location.MachineDetails;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.location.HardwareDetails;
+import org.apache.brooklyn.location.OsDetails;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.task.DynamicTasks;
+import brooklyn.util.task.TaskTags;
+import brooklyn.util.task.ssh.internal.PlainSshExecTaskFactory;
+import brooklyn.util.task.system.ProcessTaskWrapper;
+
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.base.Splitter;
+import com.google.common.base.Throwables;
+import com.google.common.collect.Maps;
+import com.google.common.io.CharStreams;
+
+@Immutable
+public class BasicMachineDetails implements MachineDetails {
+
+    public static final Logger LOG = LoggerFactory.getLogger(BasicMachineDetails.class);
+
+    private final HardwareDetails hardwareDetails;
+    private final OsDetails osDetails;
+
+    public BasicMachineDetails(HardwareDetails hardwareDetails, OsDetails osDetails) {
+        this.hardwareDetails = checkNotNull(hardwareDetails, "hardwareDetails");
+        this.osDetails = checkNotNull(osDetails, "osDetails");
+    }
+
+    @Nonnull
+    @Override
+    public HardwareDetails getHardwareDetails() {
+        return hardwareDetails;
+    }
+
+    @Nonnull
+    @Override
+    public OsDetails getOsDetails() {
+        return osDetails;
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(MachineDetails.class)
+                .add("os", osDetails)
+                .add("hardware", hardwareDetails)
+                .toString();
+    }
+
+    /**
+     * Creates a MachineDetails for the given location by SSHing to the machine and
+     * running a Bash script to gather data. Should only be called from within a
+     * task context. If this might not be the case then use {@link
+     * #taskForSshMachineLocation(SshMachineLocation)} instead.
+     */
+    static BasicMachineDetails forSshMachineLocation(SshMachineLocation location) {
+        return TaskTags.markInessential(DynamicTasks.queueIfPossible(taskForSshMachineLocation(location))
+                .orSubmitAsync()
+                .asTask())
+                .getUnchecked();
+    }
+
+    /**
+     * @return A task that gathers machine details by SSHing to the machine and running
+     *         a Bash script to gather data.
+     */
+    static Task<BasicMachineDetails> taskForSshMachineLocation(SshMachineLocation location) {
+        BufferedReader reader = new BufferedReader(Streams.reader(
+                new ResourceUtils(BasicMachineDetails.class).getResourceFromUrl(
+                        "classpath://org/apache/brooklyn/location/basic/os-details.sh")));
+        List<String> script;
+        try {
+            script = CharStreams.readLines(reader);
+        } catch (IOException e) {
+            LOG.error("Error reading os-details script", e);
+            throw Throwables.propagate(e);
+        } finally {
+            try {
+                reader.close();
+            } catch (IOException e) {
+                // Not rethrowing e because it might obscure an exception caught by the first catch
+                LOG.error("Error closing os-details script reader", e);
+            }
+        }
+        Task<BasicMachineDetails> task = new PlainSshExecTaskFactory<String>(location, script)
+                .summary("Getting machine details for: " + location)
+                .requiringZeroAndReturningStdout()
+                .returning(taskToMachineDetailsFunction(location))
+                .newTask()
+                .asTask();
+
+        return task;
+    }
+
+    private static Function<ProcessTaskWrapper<?>, BasicMachineDetails> taskToMachineDetailsFunction(final SshMachineLocation location) {
+        return new Function<ProcessTaskWrapper<?>, BasicMachineDetails>() {
+            @Override
+            public BasicMachineDetails apply(ProcessTaskWrapper<?> input) {
+                if (input.getExitCode() != 0) {
+                    LOG.warn("Non-zero exit code when fetching machine details for {}; guessing anonymous linux", location);
+                    return new BasicMachineDetails(new BasicHardwareDetails(null, null),
+                            BasicOsDetails.Factory.ANONYMOUS_LINUX);
+                }
+
+                String stdout = input.getStdout();
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Found following details at {}: {}", location, stdout);
+                }
+
+                Map<String,String> details = Maps.newHashMap(Splitter.on(CharMatcher.anyOf("\r\n"))
+                        .omitEmptyStrings()
+                        .withKeyValueSeparator(":")
+                        .split(stdout));
+
+                String name = details.remove("name");
+                String version = details.remove("version");
+                String architecture = details.remove("architecture");
+                Integer ram = intOrNull(details, "ram");
+                Integer cpuCount = intOrNull(details, "cpus");
+                if (!details.isEmpty()) {
+                    LOG.debug("Unused keys from os-details script: " + Joiner.on(", ").join(details.keySet()));
+                }
+
+                OsDetails osDetails = new BasicOsDetails(name, architecture, version);
+                HardwareDetails hardwareDetails = new BasicHardwareDetails(cpuCount, ram);
+                BasicMachineDetails machineDetails = new BasicMachineDetails(hardwareDetails, osDetails);
+
+                if (LOG.isDebugEnabled())
+                    LOG.debug("Machine details for {}: {}", location, machineDetails);
+
+                return machineDetails;
+            }
+
+            private Integer intOrNull(Map<String, String> details, String key) {
+                try {
+                    return Integer.valueOf(details.remove(key));
+                } catch (NumberFormatException e) {
+                    return null;
+                }
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java
new file mode 100644
index 0000000..ff1c0af
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicMachineMetadata.java
@@ -0,0 +1,83 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import com.google.common.base.Objects;
+import org.apache.brooklyn.location.MachineManagementMixins;
+
+public class BasicMachineMetadata implements MachineManagementMixins.MachineMetadata {
+
+    final String id, name, primaryIp;
+    final Boolean isRunning;
+    final Object originalMetadata;
+    
+    public BasicMachineMetadata(String id, String name, String primaryIp, Boolean isRunning, Object originalMetadata) {
+        super();
+        this.id = id;
+        this.name = name;
+        this.primaryIp = primaryIp;
+        this.isRunning = isRunning;
+        this.originalMetadata = originalMetadata;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getPrimaryIp() {
+        return primaryIp;
+    }
+
+    public Boolean isRunning() {
+        return isRunning;
+    }
+
+    public Object getOriginalMetadata() {
+        return originalMetadata;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(id, isRunning, name, originalMetadata, primaryIp);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (getClass() != obj.getClass()) return false;
+        BasicMachineMetadata other = (BasicMachineMetadata) obj;
+        if (!Objects.equal(id, other.id)) return false;
+        if (!Objects.equal(name, other.name)) return false;
+        if (!Objects.equal(primaryIp, other.primaryIp)) return false;
+        if (!Objects.equal(isRunning, other.isRunning)) return false;
+        if (!Objects.equal(originalMetadata, other.originalMetadata)) return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(this).add("id", id).add("name", name).add("originalMetadata", originalMetadata).toString();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java b/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java
new file mode 100644
index 0000000..364e5f3
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/BasicOsDetails.java
@@ -0,0 +1,122 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.regex.Pattern;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+import com.google.common.base.Objects;
+
+import org.apache.brooklyn.location.OsDetails;
+
+@Immutable
+public class BasicOsDetails implements OsDetails {
+
+    final String name, arch, version;
+    final boolean is64bit;
+    // (?i) forces matches to be case insensitive
+    public static final String UNIX_OS_NAME_PATTERNS = "(?i).*linux.*|centos|debian|fedora|gentoo|rhel|slackware|solaris|suse|ubuntu|coreos";
+
+    /** Sets is64Bit according to value of arch parameter. */
+    public BasicOsDetails(String name, String arch, String version) {
+       this(name, arch, version, arch != null && arch.contains("64"));
+    }
+
+    public BasicOsDetails(String name, String arch, String version, boolean is64Bit) {
+        this.name = name; this.arch = arch; this.version = version; this.is64bit = is64Bit;
+    }
+    
+    // TODO: Should be replaced with an enum like Jclouds' OsFamily and isX methods should
+    // switch against known cases
+    @Nullable
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Nullable
+    @Override
+    public String getArch() {
+        return arch;
+    }
+
+    @Nullable
+    @Override
+    public String getVersion() {
+        return version;
+    }
+
+    @Override
+    public boolean isWindows() {
+        //TODO confirm
+        return getName()!=null && getName().toLowerCase().contains("microsoft");
+    }
+
+    @Override
+    public boolean isLinux() {
+        return getName() != null && Pattern.matches(UNIX_OS_NAME_PATTERNS, getName());
+    }
+
+    @Override
+    public boolean isMac() {
+        return getName()!=null && getName().equals(OsNames.MAC_OS_X);
+    }
+
+    @Override
+    public boolean is64bit() {
+        return is64bit;
+    }
+
+    @Override
+    public String toString() {
+        return Objects.toStringHelper(OsDetails.class)
+                .omitNullValues()
+                .add("name", name)
+                .add("version", version)
+                .add("arch", arch)
+                .toString();
+    }
+
+    public static class OsNames {
+        public static final String MAC_OS_X = "Mac OS X";
+    }
+    
+    public static class OsArchs {
+        public static final String X_86_64 = "x86_64";
+//        public static final String X_86 = "x86";
+//        // is this standard?  or do we ever need the above?
+        public static final String I386 = "i386";
+    }
+
+    public static class OsVersions {
+        public static final String MAC_10_8 = "10.8";
+        public static final String MAC_10_9 = "10.9";
+    }
+    
+    public static class Factory {
+        public static OsDetails newLocalhostInstance() {
+            return new BasicOsDetails(System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version"));
+        }
+        
+        public static final OsDetails ANONYMOUS_LINUX = new BasicOsDetails("linux", OsArchs.I386, "unknown");
+        public static final OsDetails ANONYMOUS_LINUX_64 = new BasicOsDetails("linux", OsArchs.X_86_64, "unknown");
+    }
+    
+}


[44/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/LocationSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationSpec.java b/api/src/main/java/brooklyn/location/LocationSpec.java
deleted file mode 100644
index d91ca93..0000000
--- a/api/src/main/java/brooklyn/location/LocationSpec.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.brooklyn.api.basic.AbstractBrooklynObjectSpec;
-import org.apache.brooklyn.api.management.Task;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-
-import com.google.common.collect.Maps;
-
-/**
- * Gives details of a location to be created. It describes the location's configuration, and is
- * reusable to create multiple locations with the same configuration.
- * 
- * To create a LocationSpec, it is strongly encouraged to use {@code create(...)} methods.
- * 
- * @param <T> The type of location to be created
- * 
- * @author aled
- */
-public class LocationSpec<T extends Location> extends AbstractBrooklynObjectSpec<T,LocationSpec<T>> {
-
-    // TODO Would like to add `configure(ConfigBag)`, but `ConfigBag` is in core rather than api
-    
-    private static final Logger log = LoggerFactory.getLogger(LocationSpec.class);
-
-    private final static long serialVersionUID = 1L;
-
-    /**
-     * Creates a new {@link LocationSpec} instance for a location of the given type. The returned 
-     * {@link LocationSpec} can then be customized.
-     * 
-     * @param type A {@link Location} class
-     */
-    public static <T extends Location> LocationSpec<T> create(Class<T> type) {
-        return new LocationSpec<T>(type);
-    }
-    
-    /**
-     * Creates a new {@link LocationSpec} instance with the given config, for a location of the given type.
-     * 
-     * This is primarily for groovy code; equivalent to {@code LocationSpec.create(type).configure(config)}.
-     * 
-     * @param config The spec's configuration (see {@link LocationSpec#configure(Map)}).
-     * @param type   A {@link Location} class
-     */
-    public static <T extends Location> LocationSpec<T> create(Map<?,?> config, Class<T> type) {
-        return LocationSpec.create(type).configure(config);
-    }
-    
-    /**
-     * Copies entity spec so its configuration can be overridden without modifying the 
-     * original entity spec.
-     */
-    public static <T extends Location> LocationSpec<T> create(LocationSpec<T> spec) {
-        // need this to get LocationSpec<T> rather than LocationSpec<? extends T>
-        @SuppressWarnings("unchecked")
-        Class<T> exactType = (Class<T>)spec.getType();
-        
-        LocationSpec<T> result = create(exactType)
-                .displayName(spec.getDisplayName())
-                .tags(spec.getTags())
-                .configure(spec.getConfig())
-                .configure(spec.getFlags())
-                .catalogItemId(spec.getCatalogItemId())
-                .extensions(spec.getExtensions());
-        
-        if (spec.getParent() != null) result.parent(spec.getParent());
-        
-        return (LocationSpec<T>) result;
-    }
-
-    private String id;
-    private Location parent;
-    private final Map<String, Object> flags = Maps.newLinkedHashMap();
-    private final Map<ConfigKey<?>, Object> config = Maps.newLinkedHashMap();
-    private final Map<Class<?>, Object> extensions = Maps.newLinkedHashMap();
-
-    protected LocationSpec(Class<T> type) {
-        super(type);
-    }
-     
-    protected void checkValidType(Class<? extends T> type) {
-        checkIsImplementation(type, Location.class);
-        checkIsNewStyleImplementation(type);
-    }
-
-    /**
-     * @deprecated since 0.7.0; instead let the management context pick a random+unique id
-     */
-    @Deprecated
-    public LocationSpec<T> id(String val) {
-        id = val;
-        return this;
-    }
-
-    public LocationSpec<T> parent(Location val) {
-        parent = checkNotNull(val, "parent");
-        return this;
-    }
-
-    public LocationSpec<T> configure(Map<?,?> val) {
-        for (Map.Entry<?, ?> entry: val.entrySet()) {
-            if (entry.getKey()==null) throw new NullPointerException("Null key not permitted");
-            if (entry.getKey() instanceof CharSequence)
-                flags.put(entry.getKey().toString(), entry.getValue());
-            else if (entry.getKey() instanceof ConfigKey<?>)
-                config.put((ConfigKey<?>)entry.getKey(), entry.getValue());
-            else if (entry.getKey() instanceof HasConfigKey<?>)
-                config.put(((HasConfigKey<?>)entry.getKey()).getConfigKey(), entry.getValue());
-            else {
-                log.warn("Spec "+this+" ignoring unknown config key "+entry.getKey());
-            }
-        }
-        return this;
-    }
-    
-    public LocationSpec<T> configure(CharSequence key, Object val) {
-        flags.put(checkNotNull(key, "key").toString(), val);
-        return this;
-    }
-    
-    public <V> LocationSpec<T> configure(ConfigKey<V> key, V val) {
-        config.put(checkNotNull(key, "key"), val);
-        return this;
-    }
-
-    public <V> LocationSpec<T> configureIfNotNull(ConfigKey<V> key, V val) {
-        return (val != null) ? configure(key, val) : this;
-    }
-
-    public <V> LocationSpec<T> configure(ConfigKey<V> key, Task<? extends V> val) {
-        config.put(checkNotNull(key, "key"), val);
-        return this;
-    }
-
-    public <V> LocationSpec<T> configure(HasConfigKey<V> key, V val) {
-        config.put(checkNotNull(key, "key").getConfigKey(), val);
-        return this;
-    }
-
-    public <V> LocationSpec<T> configure(HasConfigKey<V> key, Task<? extends V> val) {
-        config.put(checkNotNull(key, "key").getConfigKey(), val);
-        return this;
-    }
-
-    public <V> LocationSpec<T> removeConfig(ConfigKey<V> key) {
-        config.remove( checkNotNull(key, "key") );
-        return this;
-    }
-
-    public <E> LocationSpec<T> extension(Class<E> extensionType, E extension) {
-        extensions.put(checkNotNull(extensionType, "extensionType"), checkNotNull(extension, "extension"));
-        return this;
-    }
-    
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public <E> LocationSpec<T> extensions(Map<Class<?>, ?> extensions) {
-        for (Map.Entry<Class<?>, ?> entry : extensions.entrySet()) {
-            extension((Class)entry.getKey(), entry.getValue());
-        }
-        return this;
-    }
-    
-    /**
-     * @return The id of the location to be created, or null if brooklyn can auto-generate an id
-     * 
-     * @deprecated since 0.7.0; instead let the management context pick a random+unique id
-     */
-    @Deprecated
-    public String getId() {
-        return id;
-    }
-    
-    /**
-     * @return The location's parent
-     */
-    public Location getParent() {
-        return parent;
-    }
-    
-    /**
-     * @return Read-only construction flags
-     * @see SetFromFlag declarations on the location type
-     */
-    public Map<String, ?> getFlags() {
-        return Collections.unmodifiableMap(flags);
-    }
-    
-    /**
-     * @return Read-only configuration values
-     */
-    public Map<ConfigKey<?>, Object> getConfig() {
-        return Collections.unmodifiableMap(config);
-    }
-        
-    /**
-     * @return Read-only extension values
-     */
-    public Map<Class<?>, Object> getExtensions() {
-        return Collections.unmodifiableMap(extensions);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/LocationType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationType.java b/api/src/main/java/brooklyn/location/LocationType.java
deleted file mode 100644
index dceabe3..0000000
--- a/api/src/main/java/brooklyn/location/LocationType.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import org.apache.brooklyn.api.basic.BrooklynType;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Gives type information for a {@link Location}. It is immutable.
- 
- * @since 0.7.0
- */
-@Beta
-public interface LocationType extends BrooklynType {
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/MachineDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/MachineDetails.java b/api/src/main/java/brooklyn/location/MachineDetails.java
deleted file mode 100644
index 4c3ed13..0000000
--- a/api/src/main/java/brooklyn/location/MachineDetails.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import javax.annotation.Nonnull;
-
-/**
- * @since 0.7.0
- */
-public interface MachineDetails {
-
-    @Nonnull
-    HardwareDetails getHardwareDetails();
-
-    @Nonnull
-    OsDetails getOsDetails();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/MachineLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/MachineLocation.java b/api/src/main/java/brooklyn/location/MachineLocation.java
deleted file mode 100644
index 0fde48a..0000000
--- a/api/src/main/java/brooklyn/location/MachineLocation.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.net.InetAddress;
-
-import brooklyn.util.net.HasNetworkAddresses;
-
-/**
- * A location that is a machine.
- *
- * This interface marks a {@link Location} being a network node with an IP address, 
- * and supports appropriate operations on the node.
- */
-public interface MachineLocation extends AddressableLocation, HasNetworkAddresses {
-    /**
-     * @return the machine's network address.
-     */
-    InetAddress getAddress();
-
-    /** @deprecated since 0.7.0. Use getMachineDetails().getOsDetails() instead. */
-    @Deprecated
-    OsDetails getOsDetails();
-
-    /*
-     * @return hardware and operating system-specific details for the machine.
-     */
-    MachineDetails getMachineDetails();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/MachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/MachineLocationCustomizer.java b/api/src/main/java/brooklyn/location/MachineLocationCustomizer.java
deleted file mode 100644
index 83e1009..0000000
--- a/api/src/main/java/brooklyn/location/MachineLocationCustomizer.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Customization hooks to allow apps to perform specific customisation of obtained machines.
- * <p>
- * Users are strongly encouraged to sub-class {@link BasicMachineLocationCustomizer}, to give
- * some protection against this {@link Beta} API changing in future releases.
- */
-@Beta
-public interface MachineLocationCustomizer {
-
-    /**
-     * Override to configure the given machine once it has been created (prior to any use).
-     */
-    void customize(MachineLocation machine);
-    
-    /**
-     * Override to handle machine-related cleanup prior to {@link MachineProvisioningLocation} 
-     * releasing the machine.
-     */
-    void preRelease(MachineLocation machine);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/MachineManagementMixins.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/MachineManagementMixins.java b/api/src/main/java/brooklyn/location/MachineManagementMixins.java
deleted file mode 100644
index 99038ba..0000000
--- a/api/src/main/java/brooklyn/location/MachineManagementMixins.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.util.Map;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Defines mixins for interesting locations.
- */
-public class MachineManagementMixins {
-    
-    public interface RichMachineProvisioningLocation<T extends MachineLocation> extends
-            MachineProvisioningLocation<T>, ListsMachines, GivesMachineMetadata, KillsMachines {}
-
-    public interface ListsMachines {
-        /**
-         * @return A map of machine ID to metadata record for all machines known in a given cloud location.
-         */
-        Map<String,MachineMetadata> listMachines();
-    }
-    
-    public interface GivesMachineMetadata {
-        /**
-         * @return the {@link MachineMetadata} for a given (brooklyn) machine location instance,
-         * or null if not matched.
-         */
-        MachineMetadata getMachineMetadata(MachineLocation location);
-    }
-    
-    public interface KillsMachines {
-        /** Kills the indicated machine; throws if not recognised or possible */
-        void killMachine(MachineLocation machine);
-        
-        /** Kills the machine indicated by the given (server-side) machine id;
-         *  note, the ID is the _cloud-service_ ID,
-         *  that is, pass in getMetadata(machineLocation).getId() not the machineLocation.getId() */
-        void killMachine(String cloudServiceId);
-    }
-    
-    /** very lightweight machine record */
-    public interface MachineMetadata {
-        /** The cloud service ID -- distinct from any Brooklyn {@link Location#getId()} */
-        String getId();
-        String getName();
-        String getPrimaryIp();
-        Boolean isRunning();
-        /** original metadata object, if available; e.g. ComputeMetadata when using jclouds */ 
-        Object getOriginalMetadata();
-    }
-
-    /**
-     * Implement to indicate that a location can suspend and resume machines.
-     */
-    @Beta
-    public interface SuspendResumeLocation extends SuspendsMachines, ResumesMachines {};
-
-
-    @Beta
-    public interface SuspendsMachines {
-        /**
-         * Suspend the indicated machine.
-         */
-        void suspendMachine(MachineLocation location);
-    }
-
-    @Beta
-    public interface ResumesMachines {
-        /**
-         * Resume the indicated machine.
-         */
-        void resumeMachine(MachineLocation location);
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/MachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/MachineProvisioningLocation.java b/api/src/main/java/brooklyn/location/MachineProvisioningLocation.java
deleted file mode 100644
index 8553480..0000000
--- a/api/src/main/java/brooklyn/location/MachineProvisioningLocation.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * A location that is able to provision new machines within its location.
- *
- * This interface extends {@link Location} to add the ability to provision {@link MachineLocation}s in this location.
- */
-public interface MachineProvisioningLocation<T extends MachineLocation> extends ProvisioningLocation<T> {
-    /**
-     * Obtain a machine in this location.
-     * 
-     * @param flags Details of the desired machine (e.g. image, size, open ports, etc; some flag support is limited to selected providers).
-     * "callerContext" can be specified to have custom logging and error messages (useful if starting machines in parallel)
-     * @return a machine that is a child of this location.
-     * @throws NoMachinesAvailableException if there are no machines available in this location (or impls may return null, but that is discouraged)
-     */
-    @Override
-    T obtain(Map<?,?> flags) throws NoMachinesAvailableException;
-
-    /**
-     * Creates a new location of the same type, but with additional creation instructions in the form of flags,
-     * e.g. for specifying subnets, security groups, etc
-     * <p>
-     * Implementers who wish to subclass this provisioning location for additional functionality
-     * in a specific cloud can use the relevant implementation of this method as a guide. 
-     */
-    MachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags);
-    
-    /**
-     * Release a previously-obtained machine.
-     *
-     * @param machine a {@link MachineLocation} previously obtained from a call to {@link #obtain()}
-     * @throws IllegalStateException if the machine did not come from a call to {@link #obtain()} or it has already been released.
-     */
-    @Override
-    void release(T machine);
-    
-    /**
-     * Gets flags, suitable as an argument to {@link #obtain(Map)}. The tags provided give
-     * hints about the machine required. The provisioning-location could be configured to 
-     * understand those tags. 
-     * 
-     * For example, an AWS-location could be configured to understand that a particular entity
-     * type (e.g. "TomcatServer") requires a particular AMI in that region, so would return the 
-     * required image id.
-     *  
-     * @param tags
-     * @return
-     */
-    Map<String,Object> getProvisioningFlags(Collection<String> tags);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/NoMachinesAvailableException.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/NoMachinesAvailableException.java b/api/src/main/java/brooklyn/location/NoMachinesAvailableException.java
deleted file mode 100644
index 0c0201e..0000000
--- a/api/src/main/java/brooklyn/location/NoMachinesAvailableException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-
-/**
- * Indicates no machines are available in a given location.
- */
-public class NoMachinesAvailableException extends LocationNotAvailableException {
-    private static final long serialVersionUID = 1079817235289265761L;
-    
-    public NoMachinesAvailableException(String s) {
-        super(s);
-    }
-
-    public NoMachinesAvailableException(String s, Throwable throwable) {
-        super(s, throwable);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/OsDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/OsDetails.java b/api/src/main/java/brooklyn/location/OsDetails.java
deleted file mode 100644
index 8eb69a2..0000000
--- a/api/src/main/java/brooklyn/location/OsDetails.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import javax.annotation.Nullable;
-
-public interface OsDetails {
-
-    /** The name of the operating system, e.g. "Debian" or "Red Hat Enterprise Linux Server" */
-    @Nullable
-    String getName();
-
-    /**
-     * The version of the operating system. Generally numeric (e.g. "6.3") but occasionally
-     * alphabetic (e.g. Debian's "Squeeze").
-     */
-    @Nullable
-    String getVersion();
-
-    /** The operating system's architecture, e.g. "x86" or "x86_64" */
-    @Nullable
-    String getArch();
-
-    boolean is64bit();
-
-    boolean isWindows();
-    boolean isLinux();
-    boolean isMac();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/PortRange.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/PortRange.java b/api/src/main/java/brooklyn/location/PortRange.java
deleted file mode 100644
index c523b9a..0000000
--- a/api/src/main/java/brooklyn/location/PortRange.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-/**
- * A range of ports (indicator for Location and other APIs).
- * Using methods {@code PortRanges.fromXxx(...)} this is adaptable from a number, a string, or a collection of numbers or a strings.
- * String may be of the form:
- *   <li> "80": just 80
- *   <li> "8080-8090": limited range sequentially; ie try 8080, then 8081, ..., then 8090, then give up
- *   <li> "8080-8000": as above, but descending; ie try 8080, then 8079, ..., then 8000, then give up
- *   <li> "8000+": unlimited range sequentially; ie try 8000, then 8001, then 8002, etc
- *   <li> "80,8080,8000,8080-8099": different ranges, in order; ie try 80, then 8080, then 8000, then 8080 (again), then 8081, ..., then 8099, then give up
- * Ranges (but not lists) may be preceeded by "!" to indicate a randomly selected port:
- * 
- * @see brooklyn.location.basic.PortRanges
- */
-//MAYDO could have:   <li> "~32168-65535" (or "~32168-"): try randomly selected numbers in range 32168-65535 (MAX_PORT) until all have been tried
-public interface PortRange extends Iterable<Integer> {
-    /**
-     * Whether there are any ports in the range.
-     */
-    boolean isEmpty();
-    
-    /**
-     * Note: this method is only here for use with "groovy truth". Users are strongly discouraged  
-     * from calling it directly.
-     *  
-     * @return {@code !isEmpty()}; i.e. true if there is at least one port in the range; false otherwise
-     */
-    boolean asBoolean();
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/PortSupplier.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/PortSupplier.java b/api/src/main/java/brooklyn/location/PortSupplier.java
deleted file mode 100644
index df74fcc..0000000
--- a/api/src/main/java/brooklyn/location/PortSupplier.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-/** Mixin interface for location which allows it to supply ports from a given range */
-public interface PortSupplier {
-
-    /**
-     * Reserve a specific port for an application. If your application requires a specific port - for example, port 80 for a web
-     * server - you should reserve this port before starting your application. Using this method, you will be able to detect if
-     * another application has already claimed this port number.
-     *
-     * @param portNumber the required port number.
-     * @return {@code true} if the port was successfully reserved; {@code false} if it has been previously reserved.
-     */
-    boolean obtainSpecificPort(int portNumber);
-
-    /**
-     * Reserve a port for your application, with a port number in a specific range. If your application requires a port, but it does
-     * not mind exactly which port number - for example, a port for internal JMX monitoring - call this method.
-     *
-     * @param range the range of acceptable port numbers.
-     * @return the port number that has been reserved, or -1 if there was no available port in the acceptable range.
-     */
-    int obtainPort(PortRange range);
-
-    /**
-     * Release a previously reserved port.
-     *
-     * @param portNumber the port number from a call to {@link #obtainPort(PortRange)} or {@link #obtainSpecificPort(int)}
-     */
-    void releasePort(int portNumber);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/brooklyn/location/ProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/ProvisioningLocation.java b/api/src/main/java/brooklyn/location/ProvisioningLocation.java
deleted file mode 100644
index 88d68f5..0000000
--- a/api/src/main/java/brooklyn/location/ProvisioningLocation.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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 brooklyn.location;
-
-import java.util.Map;
-
-/**
- * A location that is able to provision new locations within it.
- */
-public interface ProvisioningLocation<T extends Location> extends Location {
-    /**
-     * Obtain a new (sub)-location in the location represented by this class.
-     * 
-     * @param flags Constraints and details of the location to be provisioned
-     * @return the location provisioned
-     * @throws LocationNotAvailableException if could not provision such a location
-     */
-    T obtain(Map<?,?> flags) throws LocationNotAvailableException;
-
-    /**
-     * Release a previously-obtained location.
-     *
-     * @param location a location previously obtained
-     * @throws IllegalStateException if the machine did not come from a call to {@link #obtain()} or it has already been released.
-     */
-    void release(T machine);
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java b/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java
index 5f1b1aa..844996a 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java
@@ -34,7 +34,7 @@ import org.apache.brooklyn.policy.PolicySpec;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.guava.Maybe;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java
index 16b4a83..7ba0966 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.api.entity.drivers;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.annotations.Beta;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java
index 45bc7a4..fe7134b 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.api.entity.drivers;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * Responsible for creating a driver for a given entity/location. Also used for customizing which 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java b/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java
index b55a2d1..5af103a 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java
@@ -40,7 +40,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 
 import com.google.common.base.Supplier;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java b/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java
index 53cf6bf..5b55a54 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java
@@ -22,7 +22,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * A registry of the entity implementations to be used when creating an entity of a given type.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java b/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java
index 56883fd..74f10ff 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.CaseFormat;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java b/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java
index 39d3613..4b613c3 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.annotations.Beta;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java b/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java
index 1342d3b..a8b6939 100644
--- a/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java
+++ b/api/src/main/java/org/apache/brooklyn/api/management/AccessController.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.api.management;
 
 import org.apache.brooklyn.api.entity.Entity;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.annotations.Beta;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java b/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java
index a6fed43..9e4377c 100644
--- a/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java
+++ b/api/src/main/java/org/apache/brooklyn/api/management/LocationManager.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.api.management;
 import java.util.Collection;
 import java.util.Map;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
 
 /**
  * For managing and querying entities.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java b/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java
index 404aa56..615982b 100644
--- a/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java
+++ b/api/src/main/java/org/apache/brooklyn/api/management/ManagementContext.java
@@ -34,7 +34,7 @@ import org.apache.brooklyn.api.management.entitlement.EntitlementManager;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityManager;
 
 import brooklyn.config.StringConfigMap;
-import brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationRegistry;
 import brooklyn.util.guava.Maybe;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/AddressableLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/AddressableLocation.java b/api/src/main/java/org/apache/brooklyn/location/AddressableLocation.java
new file mode 100644
index 0000000..ba44467
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/AddressableLocation.java
@@ -0,0 +1,43 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import java.net.InetAddress;
+
+/** A location that has an IP address.
+ * <p>
+ * This IP address may be a machine (usually the MachineLocation sub-interface), 
+ * or often an entry point for a service.
+ */
+public interface AddressableLocation extends Location {
+
+    /**
+     * Return the single most appropriate address for this location.
+     * (An implementation or sub-interface definition may supply more information
+     * on the precise semantics of the address.)
+     * 
+     * Should not return null, but in some "special cases" (e.g. CloudFoundryLocation it
+     * may return null if the location is not configured correctly). Users should expect
+     * a non-null result and treat null as a programming error or misconfiguration. 
+     * Implementors of this interface should strive to not return null (and then we'll
+     * remove this caveat from the javadoc!).
+     */
+    InetAddress getAddress();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/BasicMachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/BasicMachineLocationCustomizer.java b/api/src/main/java/org/apache/brooklyn/location/BasicMachineLocationCustomizer.java
new file mode 100644
index 0000000..bbf53d3
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/BasicMachineLocationCustomizer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * A default no-op implementation, which can be extended to override the appropriate methods.
+ * 
+ * Sub-classing will give the user some protection against future API changes - note that 
+ * {@link MachineLocationCustomizer} is marked {@link Beta}.
+ */
+@Beta
+public class BasicMachineLocationCustomizer implements MachineLocationCustomizer {
+
+    @Override
+    public void customize(MachineLocation machine) {
+        // no-op
+    }
+    
+    @Override
+    public void preRelease(MachineLocation machine) {
+        // no-op
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/HardwareDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/HardwareDetails.java b/api/src/main/java/org/apache/brooklyn/location/HardwareDetails.java
new file mode 100644
index 0000000..58acb0b
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/HardwareDetails.java
@@ -0,0 +1,40 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import javax.annotation.Nullable;
+
+/**
+ * @since 0.7.0
+ */
+public interface HardwareDetails {
+
+    /**
+     * The number of CPUs on the machine
+     */
+    @Nullable
+    Integer getCpuCount();
+
+    /**
+     * Amount of RAM in megabytes
+     */
+    @Nullable
+    Integer getRam();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/Location.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/Location.java b/api/src/main/java/org/apache/brooklyn/location/Location.java
new file mode 100644
index 0000000..88a5bfb
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/Location.java
@@ -0,0 +1,146 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.brooklyn.api.basic.BrooklynObject;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+
+/**
+ * A location that an entity can be in. Examples of locations include a single machine
+ * or a pool of machines, or a region within a given cloud. 
+ * 
+ * See {@link brooklyn.entity.trait.Startable#start(Collection)}.
+ * 
+ * Locations may not be {@link Serializable} in subsequent releases!
+ */
+public interface Location extends Serializable, BrooklynObject {
+
+    /**
+     * A unique id for this location.
+     */
+    @Override
+    String getId();
+
+    /**
+     * Get the name assigned to this location.
+     *
+     * @return the name assigned to the location.
+     * @since 0.6 (previously getName())
+     */
+    @Override
+    String getDisplayName();
+
+    /**
+     * Get the 'parent' of this location. Locations are organized into a tree hierarchy, and this method will return a reference
+     * to the parent of this location, or {@code null} if this location is the tree root.
+     *
+     * @return a reference to the parent of this location, or {@code null} if this location is the tree root.
+     * @since 0.6 (previously getParentLocation())
+     */
+    Location getParent();
+
+    /**
+     * Get the 'children' of this location. Locations are organized into a tree hierarchy, and this method will return a
+     * collection containing the children of this location. This collection is an unmodifiable view of the data.
+     *
+     * @return a collection containing the children of this location.
+     * @since 0.6 (previously getChildLocations())
+     */
+    Collection<Location> getChildren();
+
+    /**
+     * Set the 'parent' of this location. If this location was previously a child of a different location, it is removed from
+     * the other location first. It is valid to pass in {@code null} to indicate that the location should be disconnected
+     * from its parent.
+     * 
+     * Adds this location as a child of the new parent (see {@code getChildLocations()}).
+     *
+     * @param newParent the new parent location object, or {@code null} to clear the parent reference.
+     * @since 0.6 (previously setParentLocation(Location))
+     */
+    void setParent(Location newParent);
+
+    /**
+     * @return meta-data about the location (usually a long line, or a small number of lines).
+     * 
+     * @since 0.6
+     */
+    String toVerboseString();
+    
+    /**
+     * Answers true if this location equals or is an ancestor of the given location.
+     */
+    boolean containsLocation(Location potentialDescendent);
+
+    /** 
+     * Returns configuration set at this location or inherited or default.
+     * 
+     * Convenience method for {@code config().get(key)}
+     */
+    <T> T getConfig(ConfigKey<T> key);
+
+    /**
+     * Convenience method for {@code config().get(key)}
+     * 
+     * @see {@link #getConfig(ConfigKey)}
+     */
+    <T> T getConfig(HasConfigKey<T> key);
+
+    /** 
+     * True iff the indication config key is set, either inherited (second argument true) or locally-only (second argument false).
+     * 
+     * @deprecated since 0.7.0; use {@link #config()}, such as {@code ((LocationInternal)location).config().getRaw(key).isPresent()}
+     */
+    @Deprecated
+    boolean hasConfig(ConfigKey<?> key, boolean includeInherited);
+
+    /** 
+     * Returns all config set, either inherited (argument true) or locally-only (argument false).
+     * 
+     * @deprecated since 0.7.0; use {@link #config()}, such as {@code policy.config().getBag()}
+     */
+    @Deprecated
+    public Map<String,Object> getAllConfig(boolean includeInherited);
+    
+    /**
+     * Whether this location has support for the given extension type.
+     * See additional comments in {@link #getExtension(Class)}.
+     * 
+     * @throws NullPointerException if extensionType is null
+     */
+    boolean hasExtension(Class<?> extensionType);
+
+    /**
+     * Returns an extension of the given type. Note that the type must be an exact match for
+     * how the extension was registered (e.g. {@code getExtension(Object.class)} will not match
+     * anything, even though registered extension extend {@link Object}.
+     * <p>
+     * This will not look at extensions of {@link #getParent()}.
+     * 
+     * @throws IllegalArgumentException if this location does not support the given extension type
+     * @throws NullPointerException if extensionType is null
+     */
+    <T> T getExtension(Class<T> extensionType);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/LocationDefinition.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationDefinition.java b/api/src/main/java/org/apache/brooklyn/location/LocationDefinition.java
new file mode 100644
index 0000000..3dd58f6
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/LocationDefinition.java
@@ -0,0 +1,42 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+
+/**
+ * Defines a location, where the {@link #getSpec()} is like a serialized representation
+ * of the location so that Brooklyn can create a corresponding location.
+ * 
+ * Examples include a complete description (e.g. giving a list of machines in a pool), or
+ * a name that matches a named location defined in the brooklyn poperties.
+ * 
+ * Users are not expected to implement this, or to use the interface directly. See
+ * {@link LocationRegistry#resolve(String)} and {@link ManagementContext#getLocationRegistry()}.
+ */
+public interface LocationDefinition {
+
+    public String getId();
+    public String getName();
+    public String getSpec();
+    public Map<String,Object> getConfig();
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/LocationNotAvailableException.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationNotAvailableException.java b/api/src/main/java/org/apache/brooklyn/location/LocationNotAvailableException.java
new file mode 100644
index 0000000..543fb36
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/LocationNotAvailableException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.apache.brooklyn.location;
+
+
+/**
+ * Indicates that a {@link ProvisioningLocation} is not able to provision a requested location
+ */
+public class LocationNotAvailableException extends Exception {
+    private static final long serialVersionUID = 1079817235289265761L;
+    
+    public LocationNotAvailableException(String s) {
+        super(s);
+    }
+
+    public LocationNotAvailableException(String s, Throwable throwable) {
+        super(s, throwable);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/LocationRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationRegistry.java b/api/src/main/java/org/apache/brooklyn/location/LocationRegistry.java
new file mode 100644
index 0000000..83096d1
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/LocationRegistry.java
@@ -0,0 +1,128 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.annotation.Nullable;
+
+import brooklyn.util.guava.Maybe;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * The registry of the sorts of locations that brooklyn knows about. Given a
+ * {@LocationDefinition} or a {@link String} representation of a spec, this can
+ * be used to create a {@link Location} instance.
+ */
+@SuppressWarnings("rawtypes")
+public interface LocationRegistry {
+
+    /** map of ID (possibly randomly generated) to the definition (spec, name, id, and props; 
+     * where spec is the spec as defined, for instance possibly another named:xxx location) */
+    public Map<String,LocationDefinition> getDefinedLocations();
+    
+    /** returns a LocationDefinition given its ID (usually a random string), or null if none */
+    public LocationDefinition getDefinedLocationById(String id);
+    
+    /** returns a LocationDefinition given its name (e.g. for named locations, supply the bit after the "named:" prefix), 
+     * or null if none */
+    public LocationDefinition getDefinedLocationByName(String name);
+
+    /** adds or updates the given defined location */
+    public void updateDefinedLocation(LocationDefinition l);
+
+    /** removes the defined location from the registry (applications running there are unaffected) */
+    public void removeDefinedLocation(String id);
+
+    /** Returns a fully populated (config etc) location from the given definition, with optional add'l flags.
+     * the location will be managed by default, unless the manage parameter is false, 
+     * or the manage parameter is null and the CREATE_UNMANAGED flag is set.
+     * <p>
+     * The manage parameter is {@link Boolean} so that null can be used to say rely on anything in the flags.
+     * 
+     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
+    @Beta
+    public Maybe<Location> resolve(LocationDefinition ld, Boolean manage, Map locationFlags);
+    
+    /** As {@link #resolve(LocationDefinition, Boolean, Map), with the location managed, and no additional flags,
+     * unwrapping the result (throwing if not resolvable) */
+    public Location resolve(LocationDefinition l);
+
+    /** Returns a location created from the given spec, which might correspond to a definition, or created on-the-fly.
+     * Optional flags can be passed through to underlying the location. 
+     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
+    @Beta
+    public Maybe<Location> resolve(String spec, Boolean manage, Map locationFlags);
+    
+    /** efficiently returns for inspection only a fully populated (config etc) location from the given definition; 
+     * the value might be unmanaged so it is not meant for any use other than inspection,
+     * but callers should prefer this when they don't wish to create a new location which will be managed in perpetuity!
+     * 
+     * @deprecated since 0.7.0, use {@link #resolve(LocationDefinition, Boolean, Map)} */
+    @Deprecated
+    public Location resolveForPeeking(LocationDefinition l);
+
+    /** returns fully populated (config etc) location from the given definition, with overrides;
+     * @deprecated since 0.7.0, use {@link #resolve(LocationDefinition, Boolean, Map)} */
+    @Deprecated
+    public Location resolve(LocationDefinition l, Map<?,?> locationFlags);
+    
+    /** See {@link #resolve(String, Boolean, Map)}; asks for the location to be managed, and supplies no additional flags,
+     * and unwraps the result (throwing if the spec cannot be resolve) */
+    public Location resolve(String spec);
+    
+    /** Returns true/false depending whether spec seems like a valid location,
+     * that is it has a chance of being resolved (depending on the spec) but NOT guaranteed,
+     * as it is not passed to the spec;
+     * see {@link #resolve(String, Boolean, Map)} which has stronger guarantees 
+     * @deprecated since 0.7.0, not really needed, and semantics are weak; use {@link #resolve(String, Boolean, Map)} */
+    @Deprecated
+    public boolean canMaybeResolve(String spec);
+    
+    /** As {@link #resolve(String, Boolean, Map)}, but unwrapped
+     * @throws NoSuchElementException if the spec cannot be resolved */
+    public Location resolve(String spec, @Nullable Map locationFlags);
+    
+    /** as {@link #resolve(String)} but returning null (never throwing)
+     * @deprecated since 0.7.0 use {@link #resolve(String, Boolean, Map)} */
+    @Deprecated
+    public Location resolveIfPossible(String spec);
+
+    /**
+     * As {@link #resolve(String)} but takes collections (of strings or locations)
+     * <p>
+     * Expects a collection of elements being individual location spec strings or locations, 
+     * and returns a list of resolved (newly created and managed) locations.
+     * <p>
+     * From 0.7.0 this no longer flattens lists (nested lists are disallowed) 
+     * or parses comma-separated elements (they are resolved as-is)
+     */
+    public List<Location> resolve(Iterable<?> spec);
+    
+    /** Takes a string, interpreted as a comma-separated (or JSON style, when you need internal double quotes or commas) list;
+     * or a list, passed to {@link #resolve(Iterable)}; or null/empty (empty list),
+     * and returns a list of resolved (created and managed) locations */
+    public List<Location> resolveList(Object specList);
+    
+    public Map getProperties();
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/LocationResolver.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationResolver.java b/api/src/main/java/org/apache/brooklyn/location/LocationResolver.java
new file mode 100644
index 0000000..1b9bd18
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/LocationResolver.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Provides a way of creating location instances of a particular type.
+ */
+public interface LocationResolver {
+
+    void init(ManagementContext managementContext);
+    
+    /** the prefix that this resolver will attend to */
+    String getPrefix();
+    
+    /** whether the spec is something which should be passed to this resolver */
+    boolean accepts(String spec, LocationRegistry registry);
+
+    /**
+     * Similar to {@link #newLocationFromString(Map, String)} 
+     * but passing in a reference to the registry itself (from which the base properties are discovered)
+     * and including flags (e.g. user, key, cloud credential) which are known to be for this location.
+     * <p>
+     * introduced to support locations which refer to other locations, e.g. NamedLocationResolver  
+     **/ 
+    @SuppressWarnings("rawtypes")
+    Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry);
+
+    /** @since 0.7.0 exploring this as a mechanism to disable locations */
+    @Beta
+    public interface EnableableLocationResolver extends LocationResolver {
+        /** whether the location is enabled */
+        boolean isEnabled();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/LocationSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationSpec.java b/api/src/main/java/org/apache/brooklyn/location/LocationSpec.java
new file mode 100644
index 0000000..6713cb7
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/LocationSpec.java
@@ -0,0 +1,229 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.brooklyn.api.basic.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.management.Task;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+
+import com.google.common.collect.Maps;
+
+/**
+ * Gives details of a location to be created. It describes the location's configuration, and is
+ * reusable to create multiple locations with the same configuration.
+ * 
+ * To create a LocationSpec, it is strongly encouraged to use {@code create(...)} methods.
+ * 
+ * @param <T> The type of location to be created
+ * 
+ * @author aled
+ */
+public class LocationSpec<T extends Location> extends AbstractBrooklynObjectSpec<T,LocationSpec<T>> {
+
+    // TODO Would like to add `configure(ConfigBag)`, but `ConfigBag` is in core rather than api
+    
+    private static final Logger log = LoggerFactory.getLogger(LocationSpec.class);
+
+    private final static long serialVersionUID = 1L;
+
+    /**
+     * Creates a new {@link LocationSpec} instance for a location of the given type. The returned 
+     * {@link LocationSpec} can then be customized.
+     * 
+     * @param type A {@link Location} class
+     */
+    public static <T extends Location> LocationSpec<T> create(Class<T> type) {
+        return new LocationSpec<T>(type);
+    }
+    
+    /**
+     * Creates a new {@link LocationSpec} instance with the given config, for a location of the given type.
+     * 
+     * This is primarily for groovy code; equivalent to {@code LocationSpec.create(type).configure(config)}.
+     * 
+     * @param config The spec's configuration (see {@link LocationSpec#configure(Map)}).
+     * @param type   A {@link Location} class
+     */
+    public static <T extends Location> LocationSpec<T> create(Map<?,?> config, Class<T> type) {
+        return LocationSpec.create(type).configure(config);
+    }
+    
+    /**
+     * Copies entity spec so its configuration can be overridden without modifying the 
+     * original entity spec.
+     */
+    public static <T extends Location> LocationSpec<T> create(LocationSpec<T> spec) {
+        // need this to get LocationSpec<T> rather than LocationSpec<? extends T>
+        @SuppressWarnings("unchecked")
+        Class<T> exactType = (Class<T>)spec.getType();
+        
+        LocationSpec<T> result = create(exactType)
+                .displayName(spec.getDisplayName())
+                .tags(spec.getTags())
+                .configure(spec.getConfig())
+                .configure(spec.getFlags())
+                .catalogItemId(spec.getCatalogItemId())
+                .extensions(spec.getExtensions());
+        
+        if (spec.getParent() != null) result.parent(spec.getParent());
+        
+        return (LocationSpec<T>) result;
+    }
+
+    private String id;
+    private Location parent;
+    private final Map<String, Object> flags = Maps.newLinkedHashMap();
+    private final Map<ConfigKey<?>, Object> config = Maps.newLinkedHashMap();
+    private final Map<Class<?>, Object> extensions = Maps.newLinkedHashMap();
+
+    protected LocationSpec(Class<T> type) {
+        super(type);
+    }
+     
+    protected void checkValidType(Class<? extends T> type) {
+        checkIsImplementation(type, Location.class);
+        checkIsNewStyleImplementation(type);
+    }
+
+    /**
+     * @deprecated since 0.7.0; instead let the management context pick a random+unique id
+     */
+    @Deprecated
+    public LocationSpec<T> id(String val) {
+        id = val;
+        return this;
+    }
+
+    public LocationSpec<T> parent(Location val) {
+        parent = checkNotNull(val, "parent");
+        return this;
+    }
+
+    public LocationSpec<T> configure(Map<?,?> val) {
+        for (Map.Entry<?, ?> entry: val.entrySet()) {
+            if (entry.getKey()==null) throw new NullPointerException("Null key not permitted");
+            if (entry.getKey() instanceof CharSequence)
+                flags.put(entry.getKey().toString(), entry.getValue());
+            else if (entry.getKey() instanceof ConfigKey<?>)
+                config.put((ConfigKey<?>)entry.getKey(), entry.getValue());
+            else if (entry.getKey() instanceof HasConfigKey<?>)
+                config.put(((HasConfigKey<?>)entry.getKey()).getConfigKey(), entry.getValue());
+            else {
+                log.warn("Spec "+this+" ignoring unknown config key "+entry.getKey());
+            }
+        }
+        return this;
+    }
+    
+    public LocationSpec<T> configure(CharSequence key, Object val) {
+        flags.put(checkNotNull(key, "key").toString(), val);
+        return this;
+    }
+    
+    public <V> LocationSpec<T> configure(ConfigKey<V> key, V val) {
+        config.put(checkNotNull(key, "key"), val);
+        return this;
+    }
+
+    public <V> LocationSpec<T> configureIfNotNull(ConfigKey<V> key, V val) {
+        return (val != null) ? configure(key, val) : this;
+    }
+
+    public <V> LocationSpec<T> configure(ConfigKey<V> key, Task<? extends V> val) {
+        config.put(checkNotNull(key, "key"), val);
+        return this;
+    }
+
+    public <V> LocationSpec<T> configure(HasConfigKey<V> key, V val) {
+        config.put(checkNotNull(key, "key").getConfigKey(), val);
+        return this;
+    }
+
+    public <V> LocationSpec<T> configure(HasConfigKey<V> key, Task<? extends V> val) {
+        config.put(checkNotNull(key, "key").getConfigKey(), val);
+        return this;
+    }
+
+    public <V> LocationSpec<T> removeConfig(ConfigKey<V> key) {
+        config.remove( checkNotNull(key, "key") );
+        return this;
+    }
+
+    public <E> LocationSpec<T> extension(Class<E> extensionType, E extension) {
+        extensions.put(checkNotNull(extensionType, "extensionType"), checkNotNull(extension, "extension"));
+        return this;
+    }
+    
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public <E> LocationSpec<T> extensions(Map<Class<?>, ?> extensions) {
+        for (Map.Entry<Class<?>, ?> entry : extensions.entrySet()) {
+            extension((Class)entry.getKey(), entry.getValue());
+        }
+        return this;
+    }
+    
+    /**
+     * @return The id of the location to be created, or null if brooklyn can auto-generate an id
+     * 
+     * @deprecated since 0.7.0; instead let the management context pick a random+unique id
+     */
+    @Deprecated
+    public String getId() {
+        return id;
+    }
+    
+    /**
+     * @return The location's parent
+     */
+    public Location getParent() {
+        return parent;
+    }
+    
+    /**
+     * @return Read-only construction flags
+     * @see SetFromFlag declarations on the location type
+     */
+    public Map<String, ?> getFlags() {
+        return Collections.unmodifiableMap(flags);
+    }
+    
+    /**
+     * @return Read-only configuration values
+     */
+    public Map<ConfigKey<?>, Object> getConfig() {
+        return Collections.unmodifiableMap(config);
+    }
+        
+    /**
+     * @return Read-only extension values
+     */
+    public Map<Class<?>, Object> getExtensions() {
+        return Collections.unmodifiableMap(extensions);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/LocationType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/LocationType.java b/api/src/main/java/org/apache/brooklyn/location/LocationType.java
new file mode 100644
index 0000000..d7b52ed
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/LocationType.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location;
+
+import org.apache.brooklyn.api.basic.BrooklynType;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Gives type information for a {@link Location}. It is immutable.
+ 
+ * @since 0.7.0
+ */
+@Beta
+public interface LocationType extends BrooklynType {
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/MachineDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineDetails.java b/api/src/main/java/org/apache/brooklyn/location/MachineDetails.java
new file mode 100644
index 0000000..c72d6d9
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/MachineDetails.java
@@ -0,0 +1,34 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import javax.annotation.Nonnull;
+
+/**
+ * @since 0.7.0
+ */
+public interface MachineDetails {
+
+    @Nonnull
+    HardwareDetails getHardwareDetails();
+
+    @Nonnull
+    OsDetails getOsDetails();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/MachineLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineLocation.java b/api/src/main/java/org/apache/brooklyn/location/MachineLocation.java
new file mode 100644
index 0000000..aef8d04
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/MachineLocation.java
@@ -0,0 +1,46 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import java.net.InetAddress;
+
+import brooklyn.util.net.HasNetworkAddresses;
+
+/**
+ * A location that is a machine.
+ *
+ * This interface marks a {@link Location} being a network node with an IP address, 
+ * and supports appropriate operations on the node.
+ */
+public interface MachineLocation extends AddressableLocation, HasNetworkAddresses {
+    /**
+     * @return the machine's network address.
+     */
+    InetAddress getAddress();
+
+    /** @deprecated since 0.7.0. Use getMachineDetails().getOsDetails() instead. */
+    @Deprecated
+    OsDetails getOsDetails();
+
+    /*
+     * @return hardware and operating system-specific details for the machine.
+     */
+    MachineDetails getMachineDetails();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/MachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineLocationCustomizer.java b/api/src/main/java/org/apache/brooklyn/location/MachineLocationCustomizer.java
new file mode 100644
index 0000000..1c81896
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/MachineLocationCustomizer.java
@@ -0,0 +1,42 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Customization hooks to allow apps to perform specific customisation of obtained machines.
+ * <p>
+ * Users are strongly encouraged to sub-class {@link BasicMachineLocationCustomizer}, to give
+ * some protection against this {@link Beta} API changing in future releases.
+ */
+@Beta
+public interface MachineLocationCustomizer {
+
+    /**
+     * Override to configure the given machine once it has been created (prior to any use).
+     */
+    void customize(MachineLocation machine);
+    
+    /**
+     * Override to handle machine-related cleanup prior to {@link MachineProvisioningLocation} 
+     * releasing the machine.
+     */
+    void preRelease(MachineLocation machine);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/api/src/main/java/org/apache/brooklyn/location/MachineManagementMixins.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/location/MachineManagementMixins.java b/api/src/main/java/org/apache/brooklyn/location/MachineManagementMixins.java
new file mode 100644
index 0000000..7e0de8a
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/location/MachineManagementMixins.java
@@ -0,0 +1,92 @@
+/*
+ * 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.apache.brooklyn.location;
+
+import java.util.Map;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Defines mixins for interesting locations.
+ */
+public class MachineManagementMixins {
+    
+    public interface RichMachineProvisioningLocation<T extends MachineLocation> extends
+            MachineProvisioningLocation<T>, ListsMachines, GivesMachineMetadata, KillsMachines {}
+
+    public interface ListsMachines {
+        /**
+         * @return A map of machine ID to metadata record for all machines known in a given cloud location.
+         */
+        Map<String,MachineMetadata> listMachines();
+    }
+    
+    public interface GivesMachineMetadata {
+        /**
+         * @return the {@link MachineMetadata} for a given (brooklyn) machine location instance,
+         * or null if not matched.
+         */
+        MachineMetadata getMachineMetadata(MachineLocation location);
+    }
+    
+    public interface KillsMachines {
+        /** Kills the indicated machine; throws if not recognised or possible */
+        void killMachine(MachineLocation machine);
+        
+        /** Kills the machine indicated by the given (server-side) machine id;
+         *  note, the ID is the _cloud-service_ ID,
+         *  that is, pass in getMetadata(machineLocation).getId() not the machineLocation.getId() */
+        void killMachine(String cloudServiceId);
+    }
+    
+    /** very lightweight machine record */
+    public interface MachineMetadata {
+        /** The cloud service ID -- distinct from any Brooklyn {@link Location#getId()} */
+        String getId();
+        String getName();
+        String getPrimaryIp();
+        Boolean isRunning();
+        /** original metadata object, if available; e.g. ComputeMetadata when using jclouds */ 
+        Object getOriginalMetadata();
+    }
+
+    /**
+     * Implement to indicate that a location can suspend and resume machines.
+     */
+    @Beta
+    public interface SuspendResumeLocation extends SuspendsMachines, ResumesMachines {};
+
+
+    @Beta
+    public interface SuspendsMachines {
+        /**
+         * Suspend the indicated machine.
+         */
+        void suspendMachine(MachineLocation location);
+    }
+
+    @Beta
+    public interface ResumesMachines {
+        /**
+         * Resume the indicated machine.
+         */
+        void resumeMachine(MachineLocation location);
+    }
+
+}
\ No newline at end of file



[31/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java
new file mode 100644
index 0000000..3860eb5
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java
@@ -0,0 +1,360 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.net.HostAndPort;
+import com.google.common.reflect.TypeToken;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.access.PortForwardManager;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.time.Duration;
+import brooklyn.util.time.Time;
+import io.cloudsoft.winrm4j.winrm.WinRmTool;
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+public class WinRmMachineLocation extends AbstractLocation implements MachineLocation {
+
+    private static final Logger LOG = LoggerFactory.getLogger(WinRmMachineLocation.class);
+
+    // FIXME Respect `port` config when using {@link WinRmTool}
+    public static final ConfigKey<Integer> WINRM_PORT = ConfigKeys.newIntegerConfigKey(
+            "port",
+            "WinRM port to use when connecting to the remote machine",
+            5985);
+    
+    // TODO merge with {link SshTool#PROP_USER} and {@link SshMachineLocation#user}
+    public static final ConfigKey<String> USER = ConfigKeys.newStringConfigKey("user",
+            "Username to use when connecting to the remote machine");
+
+    // TODO merge with {link SshTool#PROP_PASSWORD}
+    public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password",
+            "Password to use when connecting to the remote machine");
+
+    public static final ConfigKey<Integer> COPY_FILE_CHUNK_SIZE_BYTES = ConfigKeys.newIntegerConfigKey("windows.copy.file.size.bytes",
+            "Size of file chunks (in bytes) to be used when copying a file to the remote server", 1024);
+
+     public static final ConfigKey<InetAddress> ADDRESS = ConfigKeys.newConfigKey(
+            InetAddress.class,
+            "address",
+            "Address of the remote machine");
+
+    public static final ConfigKey<Integer> EXECUTION_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
+            "windows.exec.attempts",
+            "Number of attempts to execute a remote command",
+            1);
+    
+    // TODO See SshTool#PROP_SSH_TRIES, where it was called "sshTries"; remove duplication? Merge into one well-named thing?
+    public static final ConfigKey<Integer> EXEC_TRIES = ConfigKeys.newIntegerConfigKey(
+            "execTries", 
+            "Max number of times to attempt WinRM operations", 
+            10);
+
+    public static final ConfigKey<Iterable<String>> PRIVATE_ADDRESSES = ConfigKeys.newConfigKey(
+            new TypeToken<Iterable<String>>() {},
+            "privateAddresses",
+            "Private addresses of this machine, e.g. those within the private network", 
+            null);
+
+    public static final ConfigKey<Map<Integer, String>> TCP_PORT_MAPPINGS = ConfigKeys.newConfigKey(
+            new TypeToken<Map<Integer, String>>() {},
+            "tcpPortMappings",
+            "NAT'ed ports, giving the mapping from private TCP port to a public host:port", 
+            null);
+
+    @Override
+    public InetAddress getAddress() {
+        return getConfig(ADDRESS);
+    }
+
+    @Override
+    public OsDetails getOsDetails() {
+        return null;
+    }
+
+    @Override
+    public MachineDetails getMachineDetails() {
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public String getHostname() {
+        InetAddress address = getAddress();
+        return (address != null) ? address.getHostAddress() : null;
+    }
+
+    @Nullable
+    protected String getHostAndPort() {
+        String host = getHostname();
+        return (host == null) ? null : host + ":" + config().get(WINRM_PORT);
+    }
+
+    @Override
+    public Set<String> getPublicAddresses() {
+        InetAddress address = getAddress();
+        return (address == null) ? ImmutableSet.<String>of() : ImmutableSet.of(address.getHostAddress());
+    }
+    
+    @Override
+    public Set<String> getPrivateAddresses() {
+        Iterable<String> result = getConfig(PRIVATE_ADDRESSES);
+        return (result == null) ? ImmutableSet.<String>of() : ImmutableSet.copyOf(result);
+    }
+
+    public WinRmToolResponse executeScript(String script) {
+        return executeScript(ImmutableList.of(script));
+    }
+
+    public WinRmToolResponse executeScript(List<String> script) {
+        int execTries = getRequiredConfig(EXEC_TRIES);
+        Collection<Throwable> exceptions = Lists.newArrayList();
+        for (int i = 0; i < execTries; i++) {
+            try {
+                return executeScriptNoRetry(script);
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                if (i == (execTries+1)) {
+                    LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
+                } else if (i == 0) {
+                    LOG.warn("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
+                } else {
+                    LOG.debug("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
+                }
+                exceptions.add(e);
+            }
+        }
+        throw Exceptions.propagate("failed to execute shell script", exceptions);
+    }
+
+    protected WinRmToolResponse executeScriptNoRetry(List<String> script) {
+        WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
+        WinRmToolResponse response = winRmTool.executeScript(script);
+        return response;
+    }
+
+    public WinRmToolResponse executePsScript(String psScript) {
+        return executePsScript(ImmutableList.of(psScript));
+    }
+
+    public WinRmToolResponse executePsScript(List<String> psScript) {
+        int execTries = getRequiredConfig(EXEC_TRIES);
+        Collection<Throwable> exceptions = Lists.newArrayList();
+        for (int i = 0; i < execTries; i++) {
+            try {
+                return executePsScriptNoRetry(psScript);
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                if (i == (execTries+1)) {
+                    LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
+                } else if (i == 0) {
+                    LOG.warn("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
+                    Time.sleep(Duration.FIVE_SECONDS);
+                } else {
+                    LOG.debug("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
+                    Time.sleep(Duration.FIVE_SECONDS);
+                }
+                exceptions.add(e);
+            }
+        }
+        throw Exceptions.propagate("failed to execute powershell script", exceptions);
+    }
+
+    public WinRmToolResponse executePsScriptNoRetry(List<String> psScript) {
+        WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
+        WinRmToolResponse response = winRmTool.executePs(psScript);
+        return response;
+    }
+
+    public int copyTo(File source, String destination) {
+        FileInputStream sourceStream = null;
+        try {
+            sourceStream = new FileInputStream(source);
+            return copyTo(sourceStream, destination);
+        } catch (FileNotFoundException e) {
+            throw Exceptions.propagate(e);
+        } finally {
+            if (sourceStream != null) {
+                Streams.closeQuietly(sourceStream);
+            }
+        }
+    }
+
+    public int copyTo(InputStream source, String destination) {
+        executePsScript(ImmutableList.of("rm -ErrorAction SilentlyContinue " + destination));
+        try {
+            int chunkSize = getConfig(COPY_FILE_CHUNK_SIZE_BYTES);
+            byte[] inputData = new byte[chunkSize];
+            int bytesRead;
+            int expectedFileSize = 0;
+            while ((bytesRead = source.read(inputData)) > 0) {
+                byte[] chunk;
+                if (bytesRead == chunkSize) {
+                    chunk = inputData;
+                } else {
+                    chunk = Arrays.copyOf(inputData, bytesRead);
+                }
+                executePsScript(ImmutableList.of("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
+                        expectedFileSize + ")) {Add-Content -Encoding Byte -path " + destination +
+                        " -value ([System.Convert]::FromBase64String(\"" + new String(Base64.encodeBase64(chunk)) + "\"))}"));
+                expectedFileSize += bytesRead;
+            }
+
+            return 0;
+        } catch (java.io.IOException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    @Override
+    public void init() {
+        super.init();
+
+        // Register any pre-existing port-mappings with the PortForwardManager
+        Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
+        if (tcpPortMappings != null) {
+            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
+            for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
+                int targetPort = entry.getKey();
+                HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
+                if (!publicEndpoint.hasPort()) {
+                    throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
+                }
+                pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
+            }
+        }
+    }
+    public String getUser() {
+        return config().get(USER);
+    }
+
+    private String getPassword() {
+        return config().get(PASSWORD);
+    }
+
+    private <T> T getRequiredConfig(ConfigKey<T> key) {
+        return checkNotNull(getConfig(key), "key %s must be set", key);
+    }
+    
+    public static String getDefaultUserMetadataString() {
+        // Using an encoded command obviates the need to escape
+        String unencodePowershell = Joiner.on("\r\n").join(ImmutableList.of(
+                // Allow TS connections
+                "$RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\\CIMV2\\TerminalServices -Authentication PacketPrivacy",
+                "$RDP.SetAllowTSConnections(1,1)",
+                "Set-ExecutionPolicy Unrestricted -Force",
+                // Set unlimited values for remote execution limits
+                "Set-Item WSMan:\\localhost\\Shell\\MaxConcurrentUsers 100",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxMemoryPerShellMB 0",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxProcessesPerShell 0",
+                "Set-Item WSMan:\\localhost\\Shell\\MaxShellsPerUser 0",
+                "New-ItemProperty \"HKLM:\\System\\CurrentControlSet\\Control\\LSA\" -Name \"SuppressExtendedProtection\" -Value 1 -PropertyType \"DWord\"",
+                // The following allows scripts to re-authenticate with local credential - this is required
+                // as certain operations cannot be performed with remote credentials
+                "$allowed = @('WSMAN/*')",
+                "$key = 'hklm:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CredentialsDelegation'",
+                "if (!(Test-Path $key)) {",
+                "    md $key",
+                "}",
+                "New-ItemProperty -Path $key -Name AllowFreshCredentials -Value 1 -PropertyType Dword -Force",
+                "New-ItemProperty -Path $key -Name AllowFreshCredentialsWhenNTLMOnly -Value 1 -PropertyType Dword -Force",
+                "$credKey = Join-Path $key 'AllowFreshCredentials'",
+                "if (!(Test-Path $credKey)) {",
+                "    md $credkey",
+                "}",
+                "$ntlmKey = Join-Path $key 'AllowFreshCredentialsWhenNTLMOnly'",
+                "if (!(Test-Path $ntlmKey)) {",
+                "    md $ntlmKey",
+                "}",
+                "$i = 1",
+                "$allowed |% {",
+                "    # Script does not take into account existing entries in this key",
+                "    New-ItemProperty -Path $credKey -Name $i -Value $_ -PropertyType String -Force",
+                "    New-ItemProperty -Path $ntlmKey -Name $i -Value $_ -PropertyType String -Force",
+                "    $i++",
+                "}"
+        ));
+
+        String encoded = new String(Base64.encodeBase64(unencodePowershell.getBytes(Charsets.UTF_16LE)));
+        return "winrm quickconfig -q & " +
+                "winrm set winrm/config/service/auth @{Basic=\"true\"} & " +
+                "winrm set winrm/config/service/auth @{CredSSP=\"true\"} & " +
+                "winrm set winrm/config/client/auth @{CredSSP=\"true\"} & " +
+                "winrm set winrm/config/client @{AllowUnencrypted=\"true\"} & " +
+                "winrm set winrm/config/service @{AllowUnencrypted=\"true\"} & " +
+                "winrm set winrm/config/winrs @{MaxConcurrentUsers=\"100\"} & " +
+                "winrm set winrm/config/winrs @{MaxMemoryPerShellMB=\"0\"} & " +
+                "winrm set winrm/config/winrs @{MaxProcessesPerShell=\"0\"} & " +
+                "winrm set winrm/config/winrs @{MaxShellsPerUser=\"0\"} & " +
+                "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any & " +
+                "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any & " +
+                "powershell -EncodedCommand " + encoded;
+        /* TODO: Find out why scripts with new line characters aren't working on AWS. The following appears as if it *should*
+           work but doesn't - the script simply isn't run. By connecting to the machine via RDP, you can get the script
+           from 'http://169.254.169.254/latest/user-data', and running it at the command prompt works, but for some
+           reason the script isn't run when the VM is provisioned
+        */
+//        return Joiner.on("\r\n").join(ImmutableList.of(
+//                "winrm quickconfig -q",
+//                "winrm set winrm/config/service/auth @{Basic=\"true\"}",
+//                "winrm set winrm/config/client @{AllowUnencrypted=\"true\"}",
+//                "winrm set winrm/config/service @{AllowUnencrypted=\"true\"}",
+//                "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any",
+//                "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any",
+//                // Using an encoded command necessitates the need to escape. The unencoded command is as follows:
+//                // $RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\CIMV2\TerminalServices -Authentication PacketPrivacy
+//                // $Result = $RDP.SetAllowTSConnections(1,1)
+//                "powershell -EncodedCommand JABSAEQAUAAgAD0AIABHAGUAdAAtAFcAbQBpAE8AYgBqAGUAYwB0ACAALQBDAGwAYQBzAHMAI" +
+//                        "ABXAGkAbgAzADIAXwBUAGUAcgBtAGkAbgBhAGwAUwBlAHIAdgBpAGMAZQBTAGUAdAB0AGkAbgBnACAALQBDAG8AbQBwA" +
+//                        "HUAdABlAHIATgBhAG0AZQAgACQAZQBuAHYAOgBjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQAgAC0ATgBhAG0AZQBzAHAAY" +
+//                        "QBjAGUAIAByAG8AbwB0AFwAQwBJAE0AVgAyAFwAVABlAHIAbQBpAG4AYQBsAFMAZQByAHYAaQBjAGUAcwAgAC0AQQB1A" +
+//                        "HQAaABlAG4AdABpAGMAYQB0AGkAbwBuACAAUABhAGMAawBlAHQAUAByAGkAdgBhAGMAeQANAAoAJABSAGUAcwB1AGwAd" +
+//                        "AAgAD0AIAAkAFIARABQAC4AUwBlAHQAQQBsAGwAbwB3AFQAUwBDAG8AbgBuAGUAYwB0AGkAbwBuAHMAKAAxACwAMQApAA=="
+//        ));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java b/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
new file mode 100644
index 0000000..d399b92
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
@@ -0,0 +1,83 @@
+/*
+ * 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.apache.brooklyn.location.cloud;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+
+import org.apache.brooklyn.location.Location;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+@Beta
+public abstract class AbstractAvailabilityZoneExtension implements AvailabilityZoneExtension {
+
+    protected final ManagementContext managementContext;
+    protected final AtomicReference<List<Location>> subLocations = new AtomicReference<List<Location>>();
+    private final Object mutex = new Object();
+    
+    public AbstractAvailabilityZoneExtension(ManagementContext managementContext) {
+        this.managementContext = checkNotNull(managementContext, "managementContext");
+    }
+
+    @Override
+    public List<Location> getSubLocations(int max) {
+        List<Location> all = getAllSubLocations();
+        return all.subList(0, Math.min(max, all.size()));
+    }
+
+    @Override
+    public List<Location> getSubLocationsByName(Predicate<? super String> namePredicate, int max) {
+        List<Location> result = Lists.newArrayList();
+        List<Location> all = getAllSubLocations();
+        for (Location loc : all) {
+            if (isNameMatch(loc, namePredicate)) {
+                result.add(loc);
+            }
+        }
+        return Collections.<Location>unmodifiableList(result);
+    }
+
+    @Override
+    public List<Location> getAllSubLocations() {
+        synchronized (mutex) {
+            if (subLocations.get() == null) {
+                List<Location> result = doGetAllSubLocations();
+                subLocations.set(ImmutableList.copyOf(result));
+            }
+        }
+        return subLocations.get();
+    }
+
+    /**
+     * <strong>Note</strong> this method can be called while synchronized on {@link #mutex}.
+     */
+    // TODO bad pattern, as this will likely call alien code (such as asking cloud provider?!)
+    protected abstract List<Location> doGetAllSubLocations();
+
+    protected abstract boolean isNameMatch(Location loc, Predicate<? super String> namePredicate);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
new file mode 100644
index 0000000..13707b5
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
@@ -0,0 +1,97 @@
+/*
+ * 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.apache.brooklyn.location.cloud;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.internal.ssh.SshTool;
+
+public abstract class AbstractCloudMachineProvisioningLocation extends AbstractLocation
+implements MachineProvisioningLocation<MachineLocation>, CloudLocationConfig
+{
+   public AbstractCloudMachineProvisioningLocation() {
+      super();
+   }
+
+    /** typically wants at least ACCESS_IDENTITY and ACCESS_CREDENTIAL */
+    public AbstractCloudMachineProvisioningLocation(Map<?,?> conf) {
+        super(conf);
+    }
+
+    /** uses reflection to create an object of the same type, assuming a Map constructor;
+     * subclasses can extend and downcast the result */
+    @Override
+    public AbstractCloudMachineProvisioningLocation newSubLocation(Map<?,?> newFlags) {
+        return newSubLocation(getClass(), newFlags);
+    }
+
+    public AbstractCloudMachineProvisioningLocation newSubLocation(Class<? extends AbstractCloudMachineProvisioningLocation> type, Map<?,?> newFlags) {
+        // TODO should be able to use ConfigBag.newInstanceExtending; would require moving stuff around to api etc
+        // TODO was previously `return LocationCreationUtils.newSubLocation(newFlags, this)`; need to retest on CloudStack etc
+        return getManagementContext().getLocationManager().createLocation(LocationSpec.create(type)
+                .parent(this)
+                .configure(config().getLocalBag().getAllConfig()) // FIXME Should this just be inherited?
+                .configure(newFlags));
+    }
+    
+    @Override
+    public Map<String, Object> getProvisioningFlags(Collection<String> tags) {
+        if (tags.size() > 0) {
+            LOG.warn("Location {}, ignoring provisioning tags {}", this, tags);
+        }
+        return MutableMap.<String, Object>of();
+    }
+
+    // ---------------- utilities --------------------
+    
+    protected ConfigBag extractSshConfig(ConfigBag setup, ConfigBag alt) {
+        ConfigBag sshConfig = new ConfigBag();
+        
+        if (setup.containsKey(PASSWORD)) {
+            sshConfig.put(SshTool.PROP_PASSWORD, setup.get(PASSWORD));
+        } else if (alt.containsKey(PASSWORD)) {
+            sshConfig.put(SshTool.PROP_PASSWORD, alt.get(PASSWORD));
+        }
+        
+        if (setup.containsKey(PRIVATE_KEY_DATA)) {
+            sshConfig.put(SshTool.PROP_PRIVATE_KEY_DATA, setup.get(PRIVATE_KEY_DATA));
+        } else if (setup.containsKey(PRIVATE_KEY_FILE)) {
+            sshConfig.put(SshTool.PROP_PRIVATE_KEY_FILE, setup.get(PRIVATE_KEY_FILE));
+        } else if (alt.containsKey(PRIVATE_KEY_DATA)) {
+            sshConfig.put(SshTool.PROP_PRIVATE_KEY_DATA, alt.get(PRIVATE_KEY_DATA));
+        }
+        
+        if (setup.containsKey(PRIVATE_KEY_PASSPHRASE)) {
+            // NB: not supported in jclouds (but it is by our ssh tool)
+            sshConfig.put(SshTool.PROP_PRIVATE_KEY_PASSPHRASE, setup.get(PRIVATE_KEY_PASSPHRASE));
+        }
+
+        // TODO extract other SshTool properties ?
+        
+        return sshConfig;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java b/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java
new file mode 100644
index 0000000..1580440
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.cloud;
+
+import java.util.List;
+
+import brooklyn.entity.group.DynamicCluster;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.MultiLocation;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Predicate;
+
+/**
+ * For a location that has sub-zones within it (e.g. an AWS region has availability zones that can be
+ * mapped as sub-locations), this extension interface allows those to be accessed and used.
+ * For some well-known clouds, the availability zones are automatically set, although for others they may
+ * have to be configured explicitly. The "multi:(locs,...)" location descriptor (cf {@link MultiLocation}) allows
+ * this to be down at runtime.
+ * <p>
+ * Note that only entities which are explicitly aware of the {@link AvailabilityZoneExtension}
+ * will use availability zone information. For example {@link DynamicCluster} 
+ * <p>
+ * Implementers are strongly encouraged to extend {@link AbstractAvailabilityZoneExtension}
+ * which has useful behaviour, rather than attempt to implement this interface directly.
+ * 
+ * @since 0.6.0
+ */
+@Beta
+public interface AvailabilityZoneExtension {
+
+    List<Location> getAllSubLocations();
+
+    List<Location> getSubLocations(int max);
+
+    List<Location> getSubLocationsByName(Predicate<? super String> namePredicate, int max);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java b/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java
new file mode 100644
index 0000000..9682994
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java
@@ -0,0 +1,116 @@
+/*
+ * 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.apache.brooklyn.location.cloud;
+
+import java.util.Collection;
+
+import com.google.common.annotations.Beta;
+import com.google.common.reflect.TypeToken;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.event.basic.BasicConfigKey;
+import org.apache.brooklyn.location.MachineLocationCustomizer;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import brooklyn.util.flags.SetFromFlag;
+
+public interface CloudLocationConfig {
+
+    public static final ConfigKey<String> CLOUD_ENDPOINT = LocationConfigKeys.CLOUD_ENDPOINT;
+    public static final ConfigKey<String> CLOUD_REGION_ID = LocationConfigKeys.CLOUD_REGION_ID;
+    public static final ConfigKey<String> CLOUD_AVAILABILITY_ZONE_ID = LocationConfigKeys.CLOUD_AVAILABILITY_ZONE_ID;
+        
+    @SetFromFlag("identity")
+    public static final ConfigKey<String> ACCESS_IDENTITY = LocationConfigKeys.ACCESS_IDENTITY;
+    @SetFromFlag("credential")
+    public static final ConfigKey<String> ACCESS_CREDENTIAL = LocationConfigKeys.ACCESS_CREDENTIAL;
+
+    public static final ConfigKey<String> USER = LocationConfigKeys.USER;
+    
+    public static final ConfigKey<String> PASSWORD = LocationConfigKeys.PASSWORD;
+    public static final ConfigKey<String> PUBLIC_KEY_FILE = LocationConfigKeys.PUBLIC_KEY_FILE;
+    public static final ConfigKey<String> PUBLIC_KEY_DATA = LocationConfigKeys.PUBLIC_KEY_DATA;
+    public static final ConfigKey<String> PRIVATE_KEY_FILE = LocationConfigKeys.PRIVATE_KEY_FILE;
+    public static final ConfigKey<String> PRIVATE_KEY_DATA = LocationConfigKeys.PRIVATE_KEY_DATA;
+    public static final ConfigKey<String> PRIVATE_KEY_PASSPHRASE = LocationConfigKeys.PRIVATE_KEY_PASSPHRASE;
+
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PUBLIC_KEY_FILE = LocationConfigKeys.LEGACY_PUBLIC_KEY_FILE;
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PUBLIC_KEY_DATA = LocationConfigKeys.LEGACY_PUBLIC_KEY_DATA;
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_FILE = LocationConfigKeys.LEGACY_PRIVATE_KEY_FILE;
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_DATA = LocationConfigKeys.LEGACY_PRIVATE_KEY_DATA;
+    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
+    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_PASSPHRASE = LocationConfigKeys.LEGACY_PRIVATE_KEY_PASSPHRASE;
+
+    // default is just shy of common 64-char boundary, leaving 4 chars plus our salt allowance (default 4+1) which allows up to -12345678 by jclouds
+    public static final ConfigKey<Integer> VM_NAME_MAX_LENGTH = ConfigKeys.newIntegerConfigKey(
+        "vmNameMaxLength", "Maximum length of VM name", 60);
+
+    public static final ConfigKey<Integer> VM_NAME_SALT_LENGTH = ConfigKeys.newIntegerConfigKey(
+        "vmNameSaltLength", "Number of characters to use for a random identifier inserted in hostname "
+            + "to uniquely identify machines", 4);
+
+    public static final ConfigKey<String> WAIT_FOR_SSHABLE = ConfigKeys.newStringConfigKey("waitForSshable", 
+            "Whether and how long to wait for a newly provisioned VM to be accessible via ssh; " +
+            "if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '5m' (the default) or a number of milliseconds", "5m");
+
+    public static final ConfigKey<String> WAIT_FOR_WINRM_AVAILABLE = ConfigKeys.newStringConfigKey("waitForWinRmAvailable",
+            "Whether and how long to wait for a newly provisioned VM to be accessible via WinRm; " +
+                    "if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '30m' (the default) or a number of milliseconds", "30m");
+
+    public static final ConfigKey<Boolean> LOG_CREDENTIALS = ConfigKeys.newBooleanConfigKey(
+            "logCredentials", 
+            "Whether to log credentials of a new VM - strongly recommended never be used in production, as it is a big security hole!",
+            false);
+
+    public static final ConfigKey<Object> CALLER_CONTEXT = LocationConfigKeys.CALLER_CONTEXT;
+
+    public static final ConfigKey<Boolean> DESTROY_ON_FAILURE = ConfigKeys.newBooleanConfigKey("destroyOnFailure", "Whether to destroy the VM if provisioningLocation.obtain() fails", true);
+    
+    public static final ConfigKey<Object> INBOUND_PORTS = new BasicConfigKey<Object>(Object.class, "inboundPorts", 
+        "Inbound ports to be applied when creating a VM, on supported clouds " +
+            "(either a single port as a String, or an Iterable<Integer> or Integer[])", null);
+    @Beta
+    public static final ConfigKey<Object> ADDITIONAL_INBOUND_PORTS = new BasicConfigKey<Object>(Object.class, "required.ports", 
+            "Required additional ports to be applied when creating a VM, on supported clouds " +
+                    "(either a single port as an Integer, or an Iterable<Integer> or Integer[])", null);
+    
+    public static final ConfigKey<Boolean> OS_64_BIT = ConfigKeys.newBooleanConfigKey("os64Bit", 
+        "Whether to require 64-bit OS images (true), 32-bit images (false), or either (null)");
+    
+    public static final ConfigKey<Object> MIN_RAM = new BasicConfigKey<Object>(Object.class, "minRam",
+        "Minimum amount of RAM, either as string (4gb) or number of MB (4096), for use in selecting the machine/hardware profile", null);
+    
+    public static final ConfigKey<Integer> MIN_CORES = new BasicConfigKey<Integer>(Integer.class, "minCores",
+        "Minimum number of cores, for use in selecting the machine/hardware profile", null);
+    
+    public static final ConfigKey<Object> MIN_DISK = new BasicConfigKey<Object>(Object.class, "minDisk",
+        "Minimum size of disk, either as string (100gb) or number of GB (100), for use in selecting the machine/hardware profile", null);
+
+    public static final ConfigKey<String> DOMAIN_NAME = new BasicConfigKey<String>(String.class, "domainName",
+        "DNS domain where the host should be created, e.g. yourdomain.com (selected clouds only)", null);
+
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Collection<MachineLocationCustomizer>> MACHINE_LOCATION_CUSTOMIZERS = ConfigKeys.newConfigKey(
+            new TypeToken<Collection<MachineLocationCustomizer>>() {},
+            "machineCustomizers", "Optional machine customizers");
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java
new file mode 100644
index 0000000..b06b88a
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java
@@ -0,0 +1,151 @@
+/*
+ * 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.apache.brooklyn.location.cloud.names;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.trait.HasShortName;
+
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.text.Strings;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.CharMatcher;
+
+/** 
+ * Implements <b>most</b> of {@link CloudMachineNamer},
+ * leaving just one method -- {@link #generateNewIdOfLength(int)} --
+ * for subclasses to provide.
+ * <p>
+ * {@link CloudLocationConfig#VM_NAME_MAX_LENGTH} is used to find the VM length, 
+ * unless {@link #getCustomMaxNameLength(ConfigBag)} is overridden or
+ * {@link #setDefaultMachineNameMaxLength(int)} invoked on the instance supplied.
+ */
+public abstract class AbstractCloudMachineNamer implements CloudMachineNamer {
+
+    int defaultMachineNameMaxLength = CloudLocationConfig.VM_NAME_MAX_LENGTH.getDefaultValue();
+    int defaultMachineNameSaltLength = CloudLocationConfig.VM_NAME_SALT_LENGTH.getDefaultValue();
+    protected String separator = "-";
+
+    public String generateNewMachineUniqueName(ConfigBag setup) {
+        return generateNewIdReservingLength(setup, 0);
+    }
+    
+    public String generateNewMachineUniqueNameFromGroupId(ConfigBag setup, String groupId) {
+        int availSaltLength = getMaxNameLength(setup) - (groupId.length() + separator.length());
+        int requestedSaltLength = getLengthForMachineUniqueNameSalt(setup, false);
+        if (availSaltLength <= 0 || requestedSaltLength <= 0) {
+            return groupId;
+        }
+            
+        return sanitize(groupId + separator + Identifiers.makeRandomId(Math.min(requestedSaltLength, availSaltLength))).toLowerCase();
+    }
+
+    public String generateNewGroupId(ConfigBag setup) {
+        return sanitize(generateNewIdReservingLength(setup, getLengthForMachineUniqueNameSalt(setup, true))).toLowerCase();
+    }
+
+    protected String generateNewIdReservingLength(ConfigBag setup, int lengthToReserve) {
+        int len = getMaxNameLength(setup);
+        // decrement by e.g. 9 chars because jclouds adds that (dash plus 8 for hex id)
+        len -= lengthToReserve;
+        if (len<=0) return "";
+        return Strings.maxlen(generateNewIdOfLength(setup, len), len);
+    }
+    
+    /** Method for subclasses to provide to construct the context-specific part of an identifier,
+     * for use in {@link #generateNewGroupId()} and {@link #generateNewMachineUniqueName()}.
+     * 
+     * @param maxLengthHint an indication of the maximum length permitted for the ID generated,
+     * supplied for implementations which wish to use this information to decide what to truncate.
+     * (This class will truncate any return values longer than this.) 
+     */
+    protected abstract String generateNewIdOfLength(ConfigBag setup, int maxLengthHint);
+
+    /** Returns the max length of a VM name for the cloud specified in setup;
+     * this value is typically decremented by 9 to make room for jclouds labels;
+     * delegates to {@link #getCustomMaxNameLength()} when 
+     * {@link CloudLocationConfig#VM_NAME_MAX_LENGTH} is not set */
+    public int getMaxNameLength(ConfigBag setup) {
+        if (setup.containsKey(CloudLocationConfig.VM_NAME_MAX_LENGTH)) {
+            // if a length is set explicitly, use that (but intercept default behaviour)
+            return setup.get(CloudLocationConfig.VM_NAME_MAX_LENGTH);
+        }
+        
+        Integer custom = getCustomMaxNameLength(setup);
+        if (custom!=null) return custom;
+        
+        // return the default
+        return defaultMachineNameMaxLength;  
+    }
+    
+    // sometimes we create salt string, sometimes jclouds does
+    public int getLengthForMachineUniqueNameSalt(ConfigBag setup, boolean includeSeparator) {
+        int saltLen;
+        if (setup.containsKey(CloudLocationConfig.VM_NAME_SALT_LENGTH)) {
+            saltLen = setup.get(CloudLocationConfig.VM_NAME_SALT_LENGTH);
+        } else {
+            // default value comes from key, but custom default can be set
+            saltLen = defaultMachineNameSaltLength;
+        }
+        
+        if (saltLen>0 && includeSeparator)
+            saltLen += separator.length();
+        
+        return saltLen;
+    }
+    
+    public AbstractCloudMachineNamer setDefaultMachineNameMaxLength(int defaultMaxLength) {
+        this.defaultMachineNameMaxLength = defaultMaxLength;
+        return this;
+    }
+
+    /** Number of chars to use or reserve for the machine identifier when constructing a group identifier;
+     * jclouds for instance uses "-" plus 8 */
+    public AbstractCloudMachineNamer setDefaultMachineNameSeparatorAndSaltLength(String separator, int defaultMachineUniqueNameSaltLength) {
+        this.separator = separator;
+        this.defaultMachineNameSaltLength = defaultMachineUniqueNameSaltLength;
+        return this;
+    }
+    
+    /** Method for overriding to provide custom logic when an explicit config key is not set for the machine length. */
+    public Integer getCustomMaxNameLength(ConfigBag setup) {
+        return null;
+    }
+
+    protected static String shortName(Object x) {
+        if (x instanceof HasShortName) {
+            return ((HasShortName)x).getShortName();
+        }
+        if (x instanceof Entity) {
+            return ((Entity)x).getDisplayName();
+        }
+        return x.toString();
+    }
+
+    @Beta //probably won't live here long-term
+    public static String sanitize(String s) {
+        return CharMatcher.inRange('A', 'Z')
+                .or(CharMatcher.inRange('a', 'z'))
+                .or(CharMatcher.inRange('0', '9'))
+                .negate()
+                .trimAndCollapseFrom(s, '-');
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/cloud/names/BasicCloudMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/BasicCloudMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/BasicCloudMachineNamer.java
new file mode 100644
index 0000000..818053d
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/names/BasicCloudMachineNamer.java
@@ -0,0 +1,92 @@
+/*
+ * 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.apache.brooklyn.location.cloud.names;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.Entity;
+
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.text.StringShortener;
+import brooklyn.util.text.Strings;
+
+/** 
+ * Standard implementation of {@link CloudMachineNamer},
+ * which looks at several of the properties of the context (entity)
+ * and is clever about abbreviating them. */
+public class BasicCloudMachineNamer extends AbstractCloudMachineNamer {
+
+    @Override
+    protected String generateNewIdOfLength(ConfigBag setup, int len) {
+        Object context = setup.peek(CloudLocationConfig.CALLER_CONTEXT);
+        Entity entity = null;
+        if (context instanceof Entity) entity = (Entity) context;
+        
+        StringShortener shortener = Strings.shortener().separator("-");
+        shortener.append("system", "brooklyn");
+        
+        // randId often not necessary, as an 8-char hex identifier is added later (in jclouds? can we override?)
+        // however it can be useful to have this early in the string, to prevent collisions in places where it is abbreviated 
+        shortener.append("randId", Identifiers.makeRandomId(4));
+        
+        String user = System.getProperty("user.name");
+        if (!"brooklyn".equals(user))
+            // include user; unless the user is 'brooklyn', as 'brooklyn-brooklyn-' is just silly!
+            shortener.append("user", user);
+        
+        if (entity!=null) {
+            Application app = entity.getApplication();
+            if (app!=null) {
+                shortener.append("app", shortName(app))
+                        .append("appId", app.getId());
+            }
+            shortener.append("entity", shortName(entity))
+                    .append("entityId", entity.getId());
+        } else if (context!=null) {
+            shortener.append("context", context.toString());
+        }
+        
+        shortener.truncate("user", 12)
+                .truncate("app", 16)
+                .truncate("entity", 16)
+                .truncate("appId", 4)
+                .truncate("entityId", 4)
+                .truncate("context", 12);
+        
+        shortener.canTruncate("user", 8)
+                .canTruncate("app", 5)
+                .canTruncate("entity", 5)
+                .canTruncate("system", 2)
+                .canTruncate("app", 3)
+                .canTruncate("entity", 3)
+                .canRemove("app")
+                .canTruncate("user", 4)
+                .canRemove("entity")
+                .canTruncate("context", 4)
+                .canTruncate("randId", 2)
+                .canRemove("user")
+                .canTruncate("appId", 2)
+                .canRemove("appId");
+        
+        String s = shortener.getStringOfMaxLength(len);
+        return sanitize(s).toLowerCase();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java
new file mode 100644
index 0000000..eaf7198
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java
@@ -0,0 +1,62 @@
+/*
+ * 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.apache.brooklyn.location.cloud.names;
+
+import org.apache.brooklyn.api.entity.Entity;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.util.config.ConfigBag;
+
+/**
+ * Interface used to construct names for individual cloud machines and for groups of machines.
+ * <p>
+ * Implementations <b>must</b> provide a constructor which takes a single argument,
+ * being the {@link ConfigBag} for the context where the machine is being created
+ * (usually a {@link Location}).
+ * <p>
+ * With that bag, the config key {@link CloudLocationConfig#CALLER_CONTEXT}
+ * typically contains the {@link Entity} for which the machine is being created.   
+ */
+public interface CloudMachineNamer {
+
+    /**
+     * Generate a name for a new machine, based on context.
+     * <p>
+     * The name should normally be unique, as a context might produce multiple machines,
+     * for example basing it partially on information from the context but also including some random salt.
+     */
+    public String generateNewMachineUniqueName(ConfigBag setup);
+    /**
+     * Generate a name stem for a group of machines, based on context.
+     * <p>
+     * The name does not need to be unique, as uniqueness will be applied by {@link #generateNewMachineUniqueNameFromGroupId(String)}.
+     */
+    public String generateNewGroupId(ConfigBag setup);
+    
+    /**
+     * Generate a unique name from the given name stem.
+     * <p>
+     * The name stem is normally based on context information so the usual
+     * function of this method is to apply a suffix which helps to uniquely distinguish between machines
+     * in cases where the same name stem ({@link #generateNewGroupId()}) is used for multiple machines.
+     */
+    public String generateNewMachineUniqueNameFromGroupId(ConfigBag setup, String groupId);
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/cloud/names/CustomMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CustomMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/CustomMachineNamer.java
new file mode 100644
index 0000000..472adde
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/names/CustomMachineNamer.java
@@ -0,0 +1,73 @@
+/*
+ * 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.apache.brooklyn.location.cloud.names;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.Entity;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.EntityInternal;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.text.Strings;
+import brooklyn.util.text.TemplateProcessor;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
+
+/** Provides a machine namer which looks at a location config key {@link #MACHINE_NAME_TEMPLATE}
+ * to construct the hostname.
+ * For instance, setting this to <code>${config.entity_hostname}</code>
+ * will take the hostname from an <code>entity_hostname</code> key passed as entity <code>brooklyn.config</code>.
+ * <p>
+ * Note that this is not jclouds aware, so jclouds-specific cloud max lengths are not observed with this class.
+ */
+public class CustomMachineNamer extends BasicCloudMachineNamer {
+    
+    public static final ConfigKey<String> MACHINE_NAME_TEMPLATE = ConfigKeys.newStringConfigKey("custom.machine.namer.machine", 
+            "Freemarker template format for custom machine name", "${entity.displayName}");
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Map<String, ?>> EXTRA_SUBSTITUTIONS = ConfigKeys.newConfigKey(new TypeToken<Map<String, ?>>() {}, 
+            "custom.machine.namer.substitutions", "Additional substitutions to be used in the template", ImmutableMap.<String, Object>of());
+    
+    @Override
+    protected String generateNewIdOfLength(ConfigBag setup, int len) {
+        Object context = setup.peek(CloudLocationConfig.CALLER_CONTEXT);
+        Entity entity = null;
+        if (context instanceof Entity) {
+            entity = (Entity) context;
+        }
+        
+        String template = setup.get(MACHINE_NAME_TEMPLATE);
+        
+        String processed;
+        if (entity == null) {
+            processed = TemplateProcessor.processTemplateContents(template, setup.get(EXTRA_SUBSTITUTIONS));
+        } else {
+            processed = TemplateProcessor.processTemplateContents(template, (EntityInternal)entity, setup.get(EXTRA_SUBSTITUTIONS));
+        }
+        
+        processed = Strings.removeFromStart(processed, "#ftl\n");
+        
+        return sanitize(processed);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java b/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java
new file mode 100644
index 0000000..78e6d87
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java
@@ -0,0 +1,51 @@
+/*
+ * 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.apache.brooklyn.location.dynamic;
+
+import org.apache.brooklyn.api.entity.Entity;
+
+import com.google.common.annotations.Beta;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import org.apache.brooklyn.location.Location;
+import brooklyn.util.flags.SetFromFlag;
+
+/**
+ * A location that is created and owned by an entity at runtime.
+ * <p>
+ * The lifecycle of the location is managed by the owning entity.
+ *
+ * @param E the entity type
+ * @param L the location type
+ */
+@Beta
+public interface DynamicLocation<E extends Entity & LocationOwner<L, E>, L extends Location & DynamicLocation<E, L>> {
+
+    @SetFromFlag("owner")
+    ConfigKey<Entity> OWNER =
+            ConfigKeys.newConfigKey(Entity.class, "owner", "The entity owning this location");
+
+    @SetFromFlag("maxLocations")
+    ConfigKey<Integer> MAX_SUB_LOCATIONS =
+            ConfigKeys.newIntegerConfigKey("maxLocations", "The maximum number of sub-locations that can be created; 0 for unlimited", 0);
+
+    E getOwner();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java b/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java
new file mode 100644
index 0000000..a2b0bfb
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java
@@ -0,0 +1,86 @@
+/*
+ * 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.apache.brooklyn.location.dynamic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.event.AttributeSensor;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
+import brooklyn.event.basic.Sensors;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import brooklyn.util.flags.SetFromFlag;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * An entity that owns a particular location.
+ * <p>
+ * The entity should be able to dynamically create an instance of the required type of location, and will manage
+ * the lifecycle of the location in parallel with its own.
+ *
+ * @param L the location type
+ * @param E the entity type
+ */
+@Beta
+public interface LocationOwner<L extends Location & DynamicLocation<E, L>, E extends Entity & LocationOwner<L, E>> {
+
+    @SetFromFlag("locationPrefix")
+    ConfigKey<String> LOCATION_NAME_PREFIX = ConfigKeys.newStringConfigKey(
+            "entity.dynamicLocation.prefix", "The name prefix for the location owned by this entity", "dynamic");
+
+    @SetFromFlag("locationSuffix")
+    ConfigKey<String> LOCATION_NAME_SUFFIX = ConfigKeys.newStringConfigKey(
+            "entity.dynamicLocation.suffix", "The name suffix for the location owned by this entity");
+
+    @SetFromFlag("locationName")
+    BasicAttributeSensorAndConfigKey<String> LOCATION_NAME = new BasicAttributeSensorAndConfigKey<String>(String.class,
+            "entity.dynamicLocation.name", "The name of the location owned by this entity (default is auto-generated using prefix and suffix keys)");
+
+    ConfigKey<Map<String, Object>> LOCATION_FLAGS = ConfigKeys.newConfigKey(new TypeToken<Map<String, Object>>() { },
+            "entity.dynamicLocation.flags", "Extra creation flags for the Location owned by this entity",
+            ImmutableMap.<String, Object>of());
+
+    AttributeSensor<Location> DYNAMIC_LOCATION = Sensors.newSensor(Location.class,
+            "entity.dynamicLocation", "The location owned by this entity");
+
+    AttributeSensor<String> LOCATION_SPEC = Sensors.newStringSensor(
+            "entity.dynamicLocation.spec", "The specification string for the location owned by this entity");
+
+    AttributeSensor<Boolean> DYNAMIC_LOCATION_STATUS = Sensors.newBooleanSensor(
+            "entity.dynamicLocation.status", "The status of the location owned by this entity");
+
+    AttributeSensor<LocationDefinition> LOCATION_DEFINITION = Sensors.newSensor(
+        LocationDefinition.class, "entity.dynamicLocation.definition", "The location definition for the location owned by this entity");
+
+    L getDynamicLocation();
+
+    L createLocation(Map<String, ?> flags);
+
+    boolean isLocationAvailable();
+
+    void deleteLocation();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/geo/GeoBytesHostGeoLookup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/geo/GeoBytesHostGeoLookup.java b/core/src/main/java/org/apache/brooklyn/location/geo/GeoBytesHostGeoLookup.java
new file mode 100644
index 0000000..0ff6e8c
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/geo/GeoBytesHostGeoLookup.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.geo;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.net.Networking;
+
+/** @deprecated Mar 2015 - the API has changed; GetLocation now discouraged for free access, and valuepairs.txt not supported */
+@Deprecated
+public class GeoBytesHostGeoLookup implements HostGeoLookup {
+
+    public static final Logger log = LoggerFactory.getLogger(GeoBytesHostGeoLookup.class);
+    
+    /*
+    curl "http://www.geobytes.com/IpLocator.htm?GetLocation&template=valuepairs.txt&IpAddress=geobytes.com"
+    known=1
+    countryid=254
+    country=United States
+    fips104=US
+    iso2=US
+    iso3=USA
+    ison=840
+    internet=US
+    comment=
+    regionid=142
+    region=Maryland
+    code=MD
+    adm1code=    
+    cityid=8909
+    city=Baltimore
+    latitude=39.2894
+    longitude=-76.6384
+    timezone=-05:00
+    dmaid=512
+    dma=512
+    market=Baltimore
+    certainty=78
+    isproxy=false
+    mapbytesremaining=Free
+    */
+    
+    public String getPropertiesLookupUrlForPublicIp(String ip) {
+        return "http://www.geobytes.com/IpLocator.htm?GetLocation&template=valuepairs.txt&IpAddress="+ip.trim();
+    }
+
+    public String getPropertiesLookupUrlForLocalhost() {
+        return "http://www.geobytes.com/IpLocator.htm?GetLocation&template=valuepairs.txt";
+    }
+
+    /** returns URL to get properties for the given address (assuming localhost if address is on a subnet) */
+    public String getPropertiesLookupUrlFor(InetAddress address) {
+        if (Networking.isPrivateSubnet(address)) return getPropertiesLookupUrlForLocalhost();
+        return getPropertiesLookupUrlForPublicIp(address.getHostAddress());
+    }
+    
+    private static boolean LOGGED_GEO_LOOKUP_UNAVAILABLE = false;
+    
+    public HostGeoInfo getHostGeoInfo(InetAddress address) throws MalformedURLException, IOException {
+        String url = getPropertiesLookupUrlFor(address);
+        if (log.isDebugEnabled())
+            log.debug("Geo info lookup for "+address+" at "+url);
+        Properties props = new Properties();
+        try {
+            props.load( new URL(url).openStream() );
+            HostGeoInfo geo = new HostGeoInfo(address.getHostName(), props.getProperty("city")+" ("+props.getProperty("iso2")+")", 
+                Double.parseDouble(props.getProperty("latitude")), Double.parseDouble(props.getProperty("longitude")));
+            log.info("Geo info lookup for "+address+" returned: "+geo);
+            return geo;
+        } catch (Exception e) {
+            // may be web not available, or gateway giving us funny crap
+            if (log.isDebugEnabled())
+                log.debug("Geo info lookup for "+address+" failed: "+e);
+            if (!LOGGED_GEO_LOOKUP_UNAVAILABLE) {
+                LOGGED_GEO_LOOKUP_UNAVAILABLE = true;
+                log.info("Geo info lookup unavailable (for "+address+"; cause "+e+")");
+            }
+            return null;
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/geo/HasHostGeoInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/geo/HasHostGeoInfo.java b/core/src/main/java/org/apache/brooklyn/location/geo/HasHostGeoInfo.java
new file mode 100644
index 0000000..9d3c630
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/geo/HasHostGeoInfo.java
@@ -0,0 +1,25 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+public interface HasHostGeoInfo {
+
+    HostGeoInfo getHostGeoInfo();
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java b/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java
new file mode 100644
index 0000000..d159a95
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java
@@ -0,0 +1,206 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.location.AddressableLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.internal.BrooklynSystemProperties;
+
+import com.google.common.base.Objects;
+
+/**
+ * Encapsulates geo-IP information for a given host.
+ */
+public class HostGeoInfo implements Serializable {
+    
+    private static final long serialVersionUID = -5866759901535266181L;
+
+    public static final Logger log = LoggerFactory.getLogger(HostGeoInfo.class);
+
+    /** the IP address */
+    public final String address;
+    
+    public final String displayName;
+    
+    public final double latitude;
+    public final double longitude;
+    
+    private static Maybe<HostGeoLookup> cachedLookup = null;
+
+    public static HostGeoInfo create(String address, String displayName, double latitude, double longitude) {
+        return new HostGeoInfo(address, displayName, latitude, longitude);
+    }
+    
+    public static HostGeoInfo fromIpAddress(InetAddress address) {
+        try {
+            HostGeoLookup lookup = getDefaultLookup();
+            if (lookup!=null)
+                return lookup.getHostGeoInfo(address);
+        } catch (Exception e) {
+            if (log.isDebugEnabled())
+                log.debug("unable to look up geo DNS info for "+address, e);
+        }
+        return null;
+    }
+
+    @Nullable
+    public static HostGeoLookup getDefaultLookup() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        if (cachedLookup==null) {
+            cachedLookup = Maybe.of(findHostGeoLookupImpl());
+        }                
+        return cachedLookup.get();
+    }
+    
+    public static void clearCachedLookup() {
+        cachedLookup = null;
+    }
+    
+    /** returns null if cannot be set */
+    public static HostGeoInfo fromLocation(Location l) {
+        if (l==null) return null;
+        
+        Location la = l;
+        HostGeoInfo resultFromLocation = null;
+        while (la!=null) {
+            if (la instanceof HasHostGeoInfo) {
+                resultFromLocation = ((HasHostGeoInfo)l).getHostGeoInfo();
+                if (resultFromLocation!=null) break;
+            }
+            la = la.getParent();
+        }
+        if (resultFromLocation!=null && l==la) {
+            // from the location
+            return resultFromLocation;
+        }
+        // resultFromLocation may be inherited, in which case we will copy it later
+        
+        InetAddress address = findIpAddress(l);
+        Object latitude = l.getConfig(LocationConfigKeys.LATITUDE);
+        Object longitude = l.getConfig(LocationConfigKeys.LONGITUDE);
+
+        if (resultFromLocation!=null && (latitude == null || longitude == null)) {
+            latitude = resultFromLocation.latitude;
+            longitude = resultFromLocation.longitude;            
+        }
+        if (address!=null && (latitude == null || longitude == null)) {
+            HostGeoInfo geo = fromIpAddress(address);
+            if (geo==null) return null;
+            latitude = geo.latitude;
+            longitude = geo.longitude;
+        }
+        
+        if (latitude==null || longitude==null)
+            return null;
+        
+        Exception error=null;
+        try {
+            latitude = TypeCoercions.castPrimitive(latitude, Double.class);
+            longitude = TypeCoercions.castPrimitive(longitude, Double.class);
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            error = e;
+        }
+        if (error!=null || !(latitude instanceof Double) || !(longitude instanceof Double))
+            throw new IllegalArgumentException("Location "+l+" specifies invalid type of lat/long: " +
+                    "lat="+latitude+" (type "+(latitude==null ? null : latitude.getClass())+"); " +
+                    "lon="+longitude+" (type "+(longitude==null ? null : longitude.getClass())+")", error);
+        
+        HostGeoInfo result = new HostGeoInfo(address!=null ? address.getHostAddress() : null, l.getDisplayName(), (Double) latitude, (Double) longitude);
+        if (l instanceof AbstractLocation) {
+            ((AbstractLocation)l).setHostGeoInfo(result);
+        }
+        return result;
+    }
+    
+    private static HostGeoLookup findHostGeoLookupImpl() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        String type = BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getValue();
+        /* utrace seems more accurate than geobytes, and it gives a report of how many tokens are left;
+         * but maxmind if it's installed locally is even better (does not require remote lookup),
+         * so use it if available */
+        if (type==null) {
+            if (MaxMind2HostGeoLookup.getDatabaseReader()!=null)
+                return new MaxMind2HostGeoLookup();
+            log.debug("Using Utrace remote for geo lookup because MaxMind2 is not available");
+            return new UtraceHostGeoLookup();
+        }
+        if (type.isEmpty()) return null;
+        return (HostGeoLookup) Class.forName(type).newInstance();
+    }
+
+    public static HostGeoInfo fromEntity(Entity e) {
+        for (Location l : e.getLocations()) {
+            HostGeoInfo hgi = fromLocation(l);
+            if (hgi != null)
+                return hgi;
+        }
+        return null;
+    }
+    
+    public static InetAddress findIpAddress(Location l) {
+        if (l == null)
+            return null;
+        if (l instanceof AddressableLocation)
+            return ((AddressableLocation) l).getAddress();
+        return findIpAddress(l.getParent());
+    }
+    
+    public HostGeoInfo(String address, String displayName, double latitude, double longitude) {
+        this.address = address;
+        this.displayName = displayName==null ? "" : displayName;
+        this.latitude = latitude;
+        this.longitude = longitude;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+    
+    @Override
+    public String toString() {
+        return "HostGeoInfo["+displayName+": "+(address!=null ? address : "(no-address)")+" at ("+latitude+","+longitude+")]";
+    }
+    
+    @Override
+    public boolean equals(Object o) {
+        // Slight cheat: only includes the address + displayName field (displayName to allow overloading localhost etc)
+        return (o instanceof HostGeoInfo) && Objects.equal(address, ((HostGeoInfo) o).address)
+                && Objects.equal(displayName, ((HostGeoInfo) o).displayName);
+    }
+    
+    @Override
+    public int hashCode() {
+        // Slight cheat: only includes the address + displayName field (displayName to allow overloading localhost etc)
+        return Objects.hashCode(address, displayName);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoLookup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoLookup.java b/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoLookup.java
new file mode 100644
index 0000000..db58276
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoLookup.java
@@ -0,0 +1,27 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+import java.net.InetAddress;
+
+public interface HostGeoLookup {
+
+    public HostGeoInfo getHostGeoInfo(InetAddress address) throws Exception;
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/geo/LocalhostExternalIpLoader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/geo/LocalhostExternalIpLoader.java b/core/src/main/java/org/apache/brooklyn/location/geo/LocalhostExternalIpLoader.java
new file mode 100644
index 0000000..1d31f0f
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/geo/LocalhostExternalIpLoader.java
@@ -0,0 +1,178 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.text.StringPredicates;
+import brooklyn.util.time.Duration;
+import brooklyn.util.time.Durations;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Predicates;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+public class LocalhostExternalIpLoader {
+
+    public static final Logger LOG = LoggerFactory.getLogger(LocalhostExternalIpLoader.class);
+
+    private static final AtomicBoolean retrievingLocalExternalIp = new AtomicBoolean(false);
+    private static final CountDownLatch triedLocalExternalIp = new CountDownLatch(1);
+    private static volatile String localExternalIp;
+
+    private static class IpLoader implements Callable<String> {
+        private static final Pattern ipPattern = Pattern.compile(
+                "\\b((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\b");
+        final String url;
+
+        protected IpLoader(String url) {
+            this.url = url;
+        }
+
+        @Override
+        public String call() {
+            String response = ResourceUtils.create(LocalhostExternalIpLoader.class)
+                    .getResourceAsString(url).trim();
+            return postProcessResponse(response);
+        }
+
+        String postProcessResponse(String response) {
+            Matcher matcher = ipPattern.matcher(response);
+            boolean matched = matcher.find();
+            if (!matched) {
+                LOG.error("No IP address matched in output from {}: {}", url, response);
+                return null;
+            } else {
+                return matcher.group();
+            }
+        }
+    }
+
+    @VisibleForTesting
+    static List<String> getIpAddressWebsites() {
+        String file = new ResourceUtils(LocalhostExternalIpLoader.class)
+                .getResourceAsString("classpath://brooklyn/location/geo/external-ip-address-resolvers.txt");
+        Iterable<String> lines = Splitter.on('\n')
+                .omitEmptyStrings()
+                .trimResults()
+                .split(file);
+        List<String> urls = Lists.newArrayList(Iterables.filter(lines, Predicates.not(StringPredicates.startsWith("#"))));
+        Collections.shuffle(urls);
+        return urls;
+    }
+
+    @VisibleForTesting
+    static String getIpAddressFrom(String url) {
+        return new IpLoader(url).call();
+    }
+    
+    /** As {@link #getLocalhostIpWithin(Duration)} but returning 127.0.0.1 if not accessible */
+    public static String getLocalhostIpQuicklyOrDefault() {
+        String result = doLoad(Duration.seconds(2));
+        if (result==null) return "127.0.0.1";
+        return result;
+    }
+
+    /** As {@link #getLocalhostIpWithin(Duration)} but without the time limit cut-off, failing if the load gives an error. */
+    public static String getLocalhostIpWaiting() {
+        return getLocalhostIpWithin(null);
+    }
+
+    /**
+     * Attempts to load the public IP address of localhost, failing if the load
+     * does not complete within the given duration.
+     * @return The public IP address of localhost
+     */
+    public static String getLocalhostIpWithin(Duration timeout) {
+        String result = doLoad(timeout);
+        if (result == null) {
+            throw new IllegalStateException("Unable to retrieve external IP for localhost; network may be down or slow or remote service otherwise not responding");
+        }
+        return result;
+    }
+
+    /**
+     * Requests URLs returned by {@link #getIpAddressWebsites()} until one returns an IP address.
+     * The address is assumed to be the external IP address of localhost.
+     * @param blockFor The maximum duration to wait for the IP address to be resolved.
+     *                 An indefinite way if null.
+     * @return A string in IPv4 format, or null if no such address could be ascertained.
+     */
+    private static String doLoad(Duration blockFor) {
+        if (localExternalIp != null) {
+            return localExternalIp;
+        }
+
+        final List<String> candidateUrls = getIpAddressWebsites();
+        if (candidateUrls.isEmpty()) {
+            LOG.debug("No candidate URLs to use to determine external IP of localhost");
+            return null;
+        }
+
+        // do in private thread, otherwise blocks for 30s+ on dodgy network!
+        // (we can skip it if someone else is doing it, we have synch lock so we'll get notified)
+        if (retrievingLocalExternalIp.compareAndSet(false, true)) {
+            new Thread() {
+                public void run() {
+                    for (String url : candidateUrls) {
+                        try {
+                            LOG.debug("Looking up external IP of this host from {} in private thread {}", url, Thread.currentThread());
+                            localExternalIp = new IpLoader(url).call();
+                            LOG.debug("Finished looking up external IP of this host from {} in private thread, result {}", url, localExternalIp);
+                            break;
+                        } catch (Throwable t) {
+                            LOG.debug("Unable to look up external IP of this host from {}, probably offline {})", url, t);
+                        } finally {
+                            retrievingLocalExternalIp.set(false);
+                            triedLocalExternalIp.countDown();
+                        }
+                    }
+                }
+            }.start();
+        }
+
+        try {
+            if (blockFor!=null) {
+                Durations.await(triedLocalExternalIp, blockFor);
+            } else {
+                triedLocalExternalIp.await();
+            }
+        } catch (InterruptedException e) {
+            throw Exceptions.propagate(e);
+        }
+        if (localExternalIp == null) {
+            return null;
+        }
+        return localExternalIp;
+    }
+
+}


[22/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationPerformanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationPerformanceTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationPerformanceTest.java
new file mode 100644
index 0000000..93e33a1
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationPerformanceTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.brooklyn.test.PerformanceTestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.internal.ssh.SshTool;
+import brooklyn.util.net.Networking;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.time.Time;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+/**
+ * Test the performance of different variants of invoking the sshj tool.
+ * 
+ * Intended for human-invocation and inspection, to see which parts are most expensive.
+ */
+public class SshMachineLocationPerformanceTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SshMachineLocationPerformanceTest.class);
+    
+    private SshMachineLocation machine;
+    private ListeningExecutorService executor;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        machine = new SshMachineLocation(MutableMap.of("address", "localhost"));
+        executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void afterMethod() throws Exception {
+        if (executor != null) executor.shutdownNow();
+        Streams.closeQuietly(machine);
+    }
+
+    @Test(groups = {"Integration"})
+    public void testConsecutiveSmallCommands() throws Exception {
+        runExecManyCommands(ImmutableList.of("true"), "small-cmd", 10);
+    }
+
+    // Mimics SshSensorAdapter's polling
+    @Test(groups = {"Integration"})
+    public void testConsecutiveSmallCommandsWithCustomStdoutAndErr() throws Exception {
+        final ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+        final ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+        
+        Runnable task = new Runnable() {
+            @Override public void run() {
+                machine.execScript(ImmutableMap.of("out", stdout, "err", stderr), "test", ImmutableList.of("true"));
+            }};
+        runMany(task, "small-cmd-custom-stdout", 1, 10);
+    }
+
+    @Test(groups = {"Integration"})
+    public void testConcurrentSmallCommands() throws Exception {
+        runExecManyCommands(ImmutableList.of("true"), "small-cmd", 10, 10);
+    }
+
+    @Test(groups = {"Integration"})
+    public void testConsecutiveBigStdoutCommands() throws Exception {
+        runExecManyCommands(ImmutableList.of("head -c 100000 /dev/urandom"), "big-stdout", 10);
+    }
+
+    @Test(groups = {"Integration"})
+    public void testConsecutiveBigStdinCommands() throws Exception {
+        String bigstr = Identifiers.makeRandomId(100000);
+        runExecManyCommands(ImmutableList.of("echo "+bigstr+" | wc -c"), "big-stdin", 10);
+    }
+
+    @Test(groups = {"Integration"})
+    public void testConsecutiveSmallCommandsWithDifferentProperties() throws Exception {
+        final Map<String, ?> emptyProperties = Collections.emptyMap();
+        final Map<String, ?> customProperties = MutableMap.of(
+                "address", Networking.getLocalHost(),
+                SshTool.PROP_SESSION_TIMEOUT.getName(), 20000,
+                SshTool.PROP_CONNECT_TIMEOUT.getName(), 50000,
+                SshTool.PROP_SCRIPT_HEADER.getName(), "#!/bin/bash");
+
+        Runnable task = new Runnable() {
+            @Override public void run() {
+                if (Math.random() < 0.5) {
+                    machine.execScript(emptyProperties, "test", ImmutableList.of("true"));
+                } else {
+                    machine.execScript(customProperties, "test", ImmutableList.of("true"));
+                }
+            }};
+        runMany(task, "small-cmd-custom-ssh-properties", 1, 10);
+    }
+
+    private void runExecManyCommands(final List<String> cmds, String context, int iterations) throws Exception {
+        runExecManyCommands(cmds, context, 1, iterations);
+    }
+    
+    private void runExecManyCommands(final List<String> cmds, String context, int concurrentRuns, int iterations) throws Exception {
+        Runnable task = new Runnable() {
+                @Override public void run() {
+                    execScript(cmds);
+                }};
+        runMany(task, context, concurrentRuns, iterations);
+    }
+    
+    private void runMany(final Runnable task, final String context, int concurrentRuns, int iterations) throws Exception {
+        long preCpuTime = PerformanceTestUtils.getProcessCpuTime();
+        Stopwatch stopwatch = Stopwatch.createStarted();
+
+        for (int i = 0; i < iterations; i++) {
+            List<ListenableFuture<?>> futures = Lists.newArrayList();
+            for (int j = 0; j < concurrentRuns; j++) {
+                futures.add(executor.submit(new Runnable() {
+                    public void run() {
+                        try {
+                            task.run();
+                        } catch (Exception e) {
+                            LOG.error("Error for "+context+", executing "+task, e);
+                            throw Throwables.propagate(e);
+                        }
+                    }}));
+            }
+            Futures.allAsList(futures).get();
+            
+            long postCpuTime = PerformanceTestUtils.getProcessCpuTime();
+            long elapsedTime = stopwatch.elapsed(TimeUnit.MILLISECONDS);
+            double fractionCpu = (elapsedTime > 0) ? ((double)postCpuTime-preCpuTime) / TimeUnit.MILLISECONDS.toNanos(elapsedTime) : -1;
+            LOG.info("Executing {}; completed {}; took {}; fraction cpu {}",
+                    new Object[] {context, (i+1), Time.makeTimeStringRounded(elapsedTime), fractionCpu});
+        }
+    }
+
+    private int execScript(List<String> cmds) {
+        return machine.execScript("mysummary", cmds);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
new file mode 100644
index 0000000..27731e5
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.LocationSpec;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.internal.ssh.SshTool;
+import brooklyn.util.internal.ssh.sshj.SshjTool;
+import brooklyn.util.net.Networking;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.time.Duration;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Tests the re-use of SshTools in SshMachineLocation
+ */
+public class SshMachineLocationReuseIntegrationTest {
+
+    public static class RecordingSshjTool extends SshjTool {
+        public static final AtomicBoolean forbidden = new AtomicBoolean(false); 
+        public static final AtomicInteger connectionCount = new AtomicInteger(0);
+        public static final AtomicInteger disconnectionCount = new AtomicInteger();
+        
+        public RecordingSshjTool(Map<String, ?> map) {
+            super(map);
+        }
+
+        @Override
+        public void connect() {
+            if (forbidden.get()) throw new IllegalStateException("forbidden at this time");
+            connectionCount.incrementAndGet();
+            super.connect();
+        }
+
+        @Override
+        public void disconnect() {
+            disconnectionCount.incrementAndGet();
+            super.disconnect();
+        }
+
+        public static void reset() {
+            forbidden.set(false);
+            connectionCount.set(0);
+            disconnectionCount.set(0);
+        }
+
+        @Override
+        public int execCommands(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+            if (forbidden.get()) throw new IllegalStateException("forbidden at this time");
+            return super.execCommands(props, commands, env);
+        }
+        
+        @Override
+        public int execScript(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+            if (forbidden.get()) throw new IllegalStateException("forbidden at this time");
+            return super.execScript(props, commands, env);
+        }
+        
+        @Override
+        public int execShellDirect(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+            if (forbidden.get()) throw new IllegalStateException("forbidden at this time");
+            return super.execShellDirect(props, commands, env);
+        }
+    }
+
+    private SshMachineLocation host;
+    private LocalManagementContext managementContext;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = new LocalManagementContext();
+        host = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getLocalHost())
+                .configure(SshTool.PROP_TOOL_CLASS, RecordingSshjTool.class.getName()));
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (host != null) Streams.closeQuietly(host);
+        if (managementContext != null) Entities.destroyAll(managementContext);
+        RecordingSshjTool.reset();
+    }
+
+    @Test(groups = "Integration")
+    public void testBasicReuse() throws Exception {
+        host.execScript("mysummary", ImmutableList.of("exit"));
+        host.execScript("mysummary", ImmutableList.of("exit"));
+        assertEquals(RecordingSshjTool.connectionCount.get(), 1, "Expected one SSH connection to have been recorded");
+    }
+
+    @Test(groups = "Integration")
+    public void testReuseWithInterestingProps() throws Exception {
+        host.execScript(customSshConfigKeys(), "mysummary", ImmutableList.of("exit"));
+        host.execScript(customSshConfigKeys(), "mysummary", ImmutableList.of("exit"));
+        assertEquals(RecordingSshjTool.connectionCount.get(), 1, "Expected one SSH connection to have been recorded");
+    }
+
+    @Test(groups = "Integration")
+    public void testNewConnectionForDifferentProps() throws Exception {
+        host.execScript("mysummary", ImmutableList.of("exit"));
+        host.execScript(customSshConfigKeys(), "mysummary", ImmutableList.of("exit"));
+        assertEquals(RecordingSshjTool.connectionCount.get(), 2, "Expected two SSH connections to have been recorded");
+    }
+
+    @Test(groups = "Integration")
+    public void testSshToolReusedWhenConfigDiffers() throws Exception {
+        Map<String, Object> props = customSshConfigKeys();
+        host.execScript(props, "mysummary", ImmutableList.of("exit"));
+
+        // Use another output stream for second request
+        props.put(SshTool.PROP_SCRIPT_HEADER.getName(), "#!/bin/bash -e\n");
+        host.execScript(props, "mysummary", ImmutableList.of("exit"));
+        assertEquals(RecordingSshjTool.connectionCount.get(), 1, "Expected one SSH connection to have been recorded even though out script header differed.");
+    }
+
+    @Test(groups = "Integration")
+    public void testSshCacheExpiresEvenIfNotUsed() throws Exception {
+        SshMachineLocation host2 = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", InetAddress.getLocalHost())
+                .configure(SshMachineLocation.SSH_CACHE_EXPIRY_DURATION, Duration.ONE_SECOND)
+                .configure(SshTool.PROP_TOOL_CLASS, RecordingSshjTool.class.getName()));
+        
+        Map<String, Object> props = customSshConfigKeys();
+        host2.execScript(props, "mysummary", ImmutableList.of("exit"));
+
+        Asserts.succeedsEventually(new Runnable() {
+            @Override public void run() {
+                assertEquals(RecordingSshjTool.disconnectionCount.get(), 1);
+            }});
+    }
+
+    public Map<String, Object> customSshConfigKeys() throws UnknownHostException {
+        return MutableMap.<String, Object>of(
+                "address", Networking.getLocalHost(),
+                SshTool.PROP_SESSION_TIMEOUT.getName(), 20000,
+                SshTool.PROP_CONNECT_TIMEOUT.getName(), 50000,
+                SshTool.PROP_SCRIPT_HEADER.getName(), "#!/bin/bash");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java
new file mode 100644
index 0000000..37f3b32
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java
@@ -0,0 +1,340 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.api.entity.Effector;
+import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.entity.proxying.EntityInitializer;
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.BrooklynConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.effector.EffectorBody;
+import brooklyn.entity.effector.EffectorTaskTest;
+import brooklyn.entity.effector.Effectors;
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.file.ArchiveUtils;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.internal.ssh.RecordingSshTool;
+import brooklyn.util.internal.ssh.SshException;
+import brooklyn.util.internal.ssh.SshTool;
+import brooklyn.util.net.Networking;
+import brooklyn.util.net.Urls;
+import brooklyn.util.os.Os;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.task.BasicExecutionContext;
+import brooklyn.util.task.BasicExecutionManager;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.Files;
+
+/**
+ * Test the {@link SshMachineLocation} implementation of the {@link Location} interface.
+ */
+public class SshMachineLocationTest {
+
+    private SshMachineLocation host;
+    private ManagementContext mgmt;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        mgmt = LocalManagementContextForTests.newInstance();
+        host = new SshMachineLocation(MutableMap.of("address", Networking.getLocalHost()));
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (host != null) Streams.closeQuietly(host);
+        if (mgmt != null) Entities.destroyAll(mgmt);
+    }
+    
+    @Test(groups = "Integration")
+    public void testGetMachineDetails() throws Exception {
+        BasicExecutionManager execManager = new BasicExecutionManager("mycontextid");
+        BasicExecutionContext execContext = new BasicExecutionContext(execManager);
+        try {
+            MachineDetails details = execContext.submit(new Callable<MachineDetails>() {
+                public MachineDetails call() {
+                    return host.getMachineDetails();
+                }}).get();
+            assertNotNull(details);
+        } finally {
+            execManager.shutdownNow();
+        }
+    }
+    
+    @Test
+    public void testSupplyingMachineDetails() throws Exception {
+        MachineDetails machineDetails = new BasicMachineDetails(new BasicHardwareDetails(1, 1024), new BasicOsDetails("myname", "myarch", "myversion"));
+        SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure(SshMachineLocation.MACHINE_DETAILS, machineDetails));
+        
+        assertSame(host2.getMachineDetails(), machineDetails);
+    }
+    
+    @Test
+    public void testConfigurePrivateAddresses() throws Exception {
+        SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getLocalHost())
+                .configure(SshMachineLocation.PRIVATE_ADDRESSES, ImmutableList.of("1.2.3.4"))
+                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
+
+        assertEquals(host2.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
+    }
+    
+    // Wow, this is hard to test (until I accepted creating the entity + effector)! Code smell?
+    // Need to call getMachineDetails in a DynamicSequentialTask so that the "innessential" takes effect,
+    // to not fail its caller. But to get one of those outside of an effector is non-obvious.
+    @Test(groups = "Integration")
+    public void testGetMachineIsInessentialOnFailure() throws Exception {
+        SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", Networking.getLocalHost())
+                .configure(SshTool.PROP_TOOL_CLASS, FailingSshTool.class.getName()));
+
+        final Effector<MachineDetails> GET_MACHINE_DETAILS = Effectors.effector(MachineDetails.class, "getMachineDetails")
+                .impl(new EffectorBody<MachineDetails>() {
+                    public MachineDetails call(ConfigBag parameters) {
+                        Maybe<MachineLocation> machine = Machines.findUniqueMachineLocation(entity().getLocations());
+                        try {
+                            machine.get().getMachineDetails();
+                            throw new IllegalStateException("Expected failure in ssh");
+                        } catch (RuntimeException e) {
+                            return null;
+                        }
+                    }})
+                .build();
+
+        EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class)
+                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true)
+                .addInitializer(new EntityInitializer() {
+                        public void apply(EntityLocal entity) {
+                            ((EntityInternal)entity).getMutableEntityType().addEffector(EffectorTaskTest.DOUBLE_1);
+                        }});
+
+        TestApplication app = ApplicationBuilder.newManagedApp(appSpec, mgmt);
+
+        app.start(ImmutableList.of(host2));
+        
+        MachineDetails details = app.invoke(GET_MACHINE_DETAILS, ImmutableMap.<String, Object>of()).get();
+        assertNull(details);
+    }
+    public static class FailingSshTool extends RecordingSshTool {
+        public FailingSshTool(Map<?, ?> props) {
+            super(props);
+        }
+        @Override public int execScript(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+            throw new RuntimeException("Simulating failure of ssh: cmds="+commands);
+        }
+        @Override public int execCommands(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
+            throw new RuntimeException("Simulating failure of ssh: cmds="+commands);
+        }
+    }
+    
+    // Note: requires `ssh localhost` to be setup such that no password is required    
+    @Test(groups = "Integration")
+    public void testSshExecScript() throws Exception {
+        OutputStream outStream = new ByteArrayOutputStream();
+        String expectedName = Os.user();
+        host.execScript(MutableMap.of("out", outStream), "mysummary", ImmutableList.of("whoami; exit"));
+        String outString = outStream.toString();
+        
+        assertTrue(outString.contains(expectedName), outString);
+    }
+    
+    // Note: requires `ssh localhost` to be setup such that no password is required    
+    @Test(groups = "Integration")
+    public void testSshExecCommands() throws Exception {
+        OutputStream outStream = new ByteArrayOutputStream();
+        String expectedName = Os.user();
+        host.execCommands(MutableMap.of("out", outStream), "mysummary", ImmutableList.of("whoami; exit"));
+        String outString = outStream.toString();
+        
+        assertTrue(outString.contains(expectedName), outString);
+    }
+    
+    // For issue #230
+    @Test(groups = "Integration")
+    public void testOverridingPropertyOnExec() throws Exception {
+        SshMachineLocation host = new SshMachineLocation(MutableMap.of("address", Networking.getLocalHost(), "sshPrivateKeyData", "wrongdata"));
+        
+        OutputStream outStream = new ByteArrayOutputStream();
+        String expectedName = Os.user();
+        host.execCommands(MutableMap.of("sshPrivateKeyData", null, "out", outStream), "my summary", ImmutableList.of("whoami"));
+        String outString = outStream.toString();
+        
+        assertTrue(outString.contains(expectedName), "outString="+outString);
+    }
+
+    @Test(groups = "Integration", expectedExceptions={IllegalStateException.class, SshException.class})
+    public void testSshRunWithInvalidUserFails() throws Exception {
+        SshMachineLocation badHost = new SshMachineLocation(MutableMap.of("user", "doesnotexist", "address", Networking.getLocalHost()));
+        badHost.execScript("mysummary", ImmutableList.of("whoami; exit"));
+    }
+    
+    // Note: requires `ssh localhost` to be setup such that no password is required    
+    @Test(groups = "Integration")
+    public void testCopyFileTo() throws Exception {
+        File dest = Os.newTempFile(getClass(), ".dest.tmp");
+        File src = Os.newTempFile(getClass(), ".src.tmp");
+        try {
+            Files.write("abc", src, Charsets.UTF_8);
+            host.copyTo(src, dest);
+            assertEquals("abc", Files.readFirstLine(dest, Charsets.UTF_8));
+        } finally {
+            src.delete();
+            dest.delete();
+        }
+    }
+
+    // Note: requires `ssh localhost` to be setup such that no password is required    
+    @Test(groups = "Integration")
+    public void testCopyStreamTo() throws Exception {
+        String contents = "abc";
+        File dest = new File(Os.tmp(), "sssMachineLocationTest_dest.tmp");
+        try {
+            host.copyTo(Streams.newInputStreamWithContents(contents), dest.getAbsolutePath());
+            assertEquals("abc", Files.readFirstLine(dest, Charsets.UTF_8));
+        } finally {
+            dest.delete();
+        }
+    }
+
+    @Test(groups = "Integration")
+    public void testInstallUrlTo() throws Exception {
+        File dest = new File(Os.tmp(), "sssMachineLocationTest_dir/");
+        dest.mkdir();
+        try {
+            int result = host.installTo("https://raw.github.com/brooklyncentral/brooklyn/master/README.md", Urls.mergePaths(dest.getAbsolutePath(), "README.md"));
+            assertEquals(result, 0);
+            String contents = ArchiveUtils.readFullyString(new File(dest, "README.md"));
+            assertTrue(contents.contains("http://brooklyncentral.github.com"), "contents missing expected phrase; contains:\n"+contents);
+        } finally {
+            dest.delete();
+        }
+    }
+    
+    @Test(groups = "Integration")
+    public void testInstallClasspathCopyTo() throws Exception {
+        File dest = new File(Os.tmp(), "sssMachineLocationTest_dir/");
+        dest.mkdir();
+        try {
+            int result = host.installTo("classpath://brooklyn/config/sample.properties", Urls.mergePaths(dest.getAbsolutePath(), "sample.properties"));
+            assertEquals(result, 0);
+            String contents = ArchiveUtils.readFullyString(new File(dest, "sample.properties"));
+            assertTrue(contents.contains("Property 1"), "contents missing expected phrase; contains:\n"+contents);
+        } finally {
+            dest.delete();
+        }
+    }
+
+    // Note: requires `ssh localhost` to be setup such that no password is required    
+    @Test(groups = "Integration")
+    public void testIsSshableWhenTrue() throws Exception {
+        assertTrue(host.isSshable());
+    }
+    
+    // Note: on some (home/airport) networks, `ssh 123.123.123.123` hangs seemingly forever.
+    // Make sure we fail, waiting for longer than the 70 second TCP timeout.
+    //
+    // Times out in 2m7s on Ubuntu Vivid (syn retries set to 6)
+    @Test(groups = "Integration")
+    public void testIsSshableWhenFalse() throws Exception {
+        byte[] unreachableIp = new byte[] {123,123,123,123};
+        final SshMachineLocation unreachableHost = new SshMachineLocation(MutableMap.of("address", InetAddress.getByAddress("unreachablename", unreachableIp)));
+        Asserts.assertReturnsEventually(new Runnable() {
+            public void run() {
+                assertFalse(unreachableHost.isSshable());
+            }},
+            Duration.minutes(3));
+    }
+    
+    @Test
+    public void obtainSpecificPortGivesOutPortOnlyOnce() {
+        int port = 2345;
+        assertTrue(host.obtainSpecificPort(port));
+        assertFalse(host.obtainSpecificPort(port));
+        host.releasePort(port);
+        assertTrue(host.obtainSpecificPort(port));
+    }
+    
+    @Test
+    public void obtainPortInRangeGivesBackRequiredPortOnlyIfAvailable() {
+        int port = 2345;
+        assertEquals(host.obtainPort(new PortRanges.LinearPortRange(port, port)), port);
+        assertEquals(host.obtainPort(new PortRanges.LinearPortRange(port, port)), -1);
+        host.releasePort(port);
+        assertEquals(host.obtainPort(new PortRanges.LinearPortRange(port, port)), port);
+    }
+    
+    @Test
+    public void obtainPortInWideRange() {
+        int lowerPort = 2345;
+        int upperPort = 2350;
+        PortRange range = new PortRanges.LinearPortRange(lowerPort, upperPort);
+        for (int i = lowerPort; i <= upperPort; i++) {
+            assertEquals(host.obtainPort(range), i);
+        }
+        assertEquals(host.obtainPort(range), -1);
+        
+        host.releasePort(lowerPort);
+        assertEquals(host.obtainPort(range), lowerPort);
+        assertEquals(host.obtainPort(range), -1);
+    }
+    
+    @Test
+    public void testObtainPortDoesNotUsePreReservedPorts() {
+        host = new SshMachineLocation(MutableMap.of("address", Networking.getLocalHost(), "usedPorts", ImmutableSet.of(8000)));
+        assertEquals(host.obtainPort(PortRanges.fromString("8000")), -1);
+        assertEquals(host.obtainPort(PortRanges.fromString("8000+")), 8001);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/TestPortSupplierLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/TestPortSupplierLocation.java b/core/src/test/java/org/apache/brooklyn/location/basic/TestPortSupplierLocation.java
new file mode 100644
index 0000000..a8b9354
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/TestPortSupplierLocation.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.test.entity.TestEntity;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.BrooklynAppUnitTestSupport;
+import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
+import brooklyn.event.feed.ConfigToAttributes;
+
+import com.google.common.collect.ImmutableList;
+
+public class TestPortSupplierLocation extends BrooklynAppUnitTestSupport {
+
+    SimulatedLocation loc;
+    PortAttributeSensorAndConfigKey ps;
+    TestEntity entity;
+    
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        loc = app.newSimulatedLocation();
+        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        app.start(ImmutableList.of(loc));
+        
+        ps = new PortAttributeSensorAndConfigKey("some.port", "for testing", "1234+");
+    }
+
+    @Test
+    public void testObtainsPort() throws Exception {
+        ConfigToAttributes.apply(entity, ps);
+        
+        int p = entity.getAttribute(ps);
+        assertEquals(p, 1234);
+        
+        //sensor access should keep the same value
+        p = entity.getAttribute(ps);
+        assertEquals(p, 1234);
+    }
+    
+    @Test
+    public void testRepeatedConvertAccessIncrements() throws Exception {
+        int p = ps.getAsSensorValue(entity);
+        assertEquals(p, 1234);
+
+        //but direct access should see it as being reserved (not required behaviour, but it is the current behaviour)
+        int p2 = ps.getAsSensorValue(entity);
+        assertEquals(p2, 1235);
+    }
+
+    @Test
+    public void testNullBeforeSetting() throws Exception {
+        // currently getting the attribute before explicitly setting return null; i.e. no "auto-set" -- 
+        // but this behaviour may be changed
+        Integer p = entity.getAttribute(ps);
+        assertEquals(p, null);
+    }
+
+    @Test
+    public void testSimulatedRestrictedPermitted() throws Exception {
+        loc.setPermittedPorts(PortRanges.fromString("1240+"));
+        
+        ConfigToAttributes.apply(entity, ps);
+        int p = entity.getAttribute(ps);
+        assertEquals((int)p, 1240);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/cloud/CloudMachineNamerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/cloud/CloudMachineNamerTest.java b/core/src/test/java/org/apache/brooklyn/location/cloud/CloudMachineNamerTest.java
new file mode 100644
index 0000000..9d4acad
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/cloud/CloudMachineNamerTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.apache.brooklyn.location.cloud;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.location.cloud.names.AbstractCloudMachineNamer;
+import org.apache.brooklyn.location.cloud.names.CloudMachineNamer;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.apache.brooklyn.test.entity.TestEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.cloud.names.BasicCloudMachineNamer;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.text.Strings;
+public class CloudMachineNamerTest {
+
+    private static final Logger log = LoggerFactory.getLogger(CloudMachineNamerTest.class);
+    
+    private TestApplication app;
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+    }
+
+    @Test
+    public void testGenerateGroupIdWithEntity() {
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
+        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
+
+        ConfigBag cfg = new ConfigBag()
+            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
+
+        String result = new BasicCloudMachineNamer().generateNewGroupId(cfg);
+
+        log.info("test entity child group id gives: "+result);
+        // e.g. brooklyn-alex-tistapp-uube-testent-xisg-rwad
+        Assert.assertTrue(result.length() <= 60);
+
+        String user = Strings.maxlen(System.getProperty("user.name"), 4).toLowerCase();
+        Assert.assertTrue(result.indexOf(user) >= 0);
+        Assert.assertTrue(result.indexOf("-tistapp-") >= 0);
+        Assert.assertTrue(result.indexOf("-testent-") >= 0);
+        Assert.assertTrue(result.indexOf("-"+Strings.maxlen(app.getId(), 4).toLowerCase()) >= 0);
+        Assert.assertTrue(result.indexOf("-"+Strings.maxlen(child.getId(), 4).toLowerCase()) >= 0);
+    }
+    
+    @Test
+    public void testGenerateNewMachineName() {
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
+        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
+
+        ConfigBag cfg = new ConfigBag()
+            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
+        BasicCloudMachineNamer namer = new BasicCloudMachineNamer();
+        
+        String result = namer.generateNewMachineUniqueName(cfg);
+        Assert.assertTrue(result.length() <= namer.getMaxNameLength(cfg));
+        String user = Strings.maxlen(System.getProperty("user.name"), 4).toLowerCase();
+        Assert.assertTrue(result.indexOf(user) >= 0);
+        Assert.assertTrue(result.indexOf("-tistapp-") >= 0);
+        Assert.assertTrue(result.indexOf("-testent-") >= 0);
+        Assert.assertTrue(result.indexOf("-"+Strings.maxlen(app.getId(), 4).toLowerCase()) >= 0);
+        Assert.assertTrue(result.indexOf("-"+Strings.maxlen(child.getId(), 4).toLowerCase()) >= 0);
+    }
+    
+    @Test
+    public void testGenerateNewMachineUniqueNameFromGroupId() {
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
+        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
+
+        ConfigBag cfg = new ConfigBag()
+            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
+        CloudMachineNamer namer = new BasicCloudMachineNamer();
+        
+        String groupId = namer.generateNewGroupId(cfg);
+        String result = namer.generateNewMachineUniqueNameFromGroupId(cfg, groupId);
+        Assert.assertTrue(result.startsWith(groupId));
+        Assert.assertTrue(result.length() == groupId.length() + 5);
+    }
+    
+    @Test
+    public void testLengthMaxPermittedForMachineName() {
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
+        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
+        
+        ConfigBag cfg = new ConfigBag()
+            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
+        BasicCloudMachineNamer namer = new BasicCloudMachineNamer();
+        namer.setDefaultMachineNameMaxLength(10);
+        String result = namer.generateNewMachineUniqueName(cfg);
+        Assert.assertEquals(result.length(), 10);
+    }
+    
+    @Test
+    public void testLengthReservedForNameInGroup() {
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
+        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
+        
+        ConfigBag cfg = new ConfigBag()
+            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
+        BasicCloudMachineNamer namer = new BasicCloudMachineNamer();
+        namer.setDefaultMachineNameMaxLength(20);
+        namer.setDefaultMachineNameSeparatorAndSaltLength(":I", 5);
+        String groupId = namer.generateNewGroupId(cfg);
+        Assert.assertEquals(13, groupId.length(), "groupId="+groupId);
+        String machineId = namer.generateNewMachineUniqueNameFromGroupId(cfg, groupId);
+        Assert.assertEquals(20, machineId.length(), "machineId="+machineId);
+        // separator is not sanitized -- caller should know what they are doing there!
+        Assert.assertTrue(machineId.startsWith(groupId+"-i"), "machineId="+machineId);
+    }
+
+    @Test
+    public void testSanitizesNewMachineName() {
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("T_%$()\r\n\t[]*.!App"), LocalManagementContextForTests.newInstance());
+        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("ent"));
+
+        ConfigBag cfg = new ConfigBag()
+            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
+        CloudMachineNamer namer = new BasicCloudMachineNamer();
+        
+        String result = namer.generateNewMachineUniqueName(cfg);
+        assertTrue(result.indexOf("t-ap") >= 0, "result="+result);
+        for (int c : "_%$()\r\n\t[]*.!".getBytes()) {
+            assertFalse(result.contains(new String(new char [] {(char)c})), "result="+result);
+        }
+    }
+    
+    @Test
+    public void testSanitize() {
+        Assert.assertEquals(AbstractCloudMachineNamer.sanitize(
+                        "me & you like alphanumeric but not _ or !!! or dots...dots...dots %$()\r\n\t[]*etc"),
+                "me-you-like-alphanumeric-but-not-or-or-dots-dots-dots-etc");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/cloud/CustomMachineNamerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/cloud/CustomMachineNamerTest.java b/core/src/test/java/org/apache/brooklyn/location/cloud/CustomMachineNamerTest.java
new file mode 100644
index 0000000..f0e7d11
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/cloud/CustomMachineNamerTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.apache.brooklyn.location.cloud;
+
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.apache.brooklyn.test.entity.TestEntity;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.cloud.names.CustomMachineNamer;
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.collect.ImmutableMap;
+
+public class CustomMachineNamerTest {
+    
+    private TestApplication app;
+    private TestEntity child;
+    private ConfigBag config;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() {
+        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TestApp"), LocalManagementContextForTests.newInstance());
+        child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
+        config = new ConfigBag()
+            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (app != null) Entities.destroyAll(app.getManagementContext());
+    }
+
+    @Test
+    public void testMachineNameNoConfig() {
+        config.configure(CloudLocationConfig.CALLER_CONTEXT, child);
+        Assert.assertEquals(new CustomMachineNamer().generateNewMachineUniqueName(config), "TestEnt");
+    }
+    
+    @Test
+    public void testMachineNameWithConfig() {
+        child.setSequenceValue(999);
+        config.configure(CustomMachineNamer.MACHINE_NAME_TEMPLATE, "number${entity.sequenceValue}");
+        Assert.assertEquals(new CustomMachineNamer().generateNewMachineUniqueName(config), "number999");
+    }
+    
+    @Test
+    public void testMachineNameWithExtraSubstitutions() {
+        config.configure(CustomMachineNamer.MACHINE_NAME_TEMPLATE, "foo-${fooName}-bar-${barName}-baz-${bazName.substitution}")
+            .configure(CustomMachineNamer.EXTRA_SUBSTITUTIONS, ImmutableMap.of("fooName", "foo", "barName", "bar", "bazName", this));
+        Assert.assertEquals(new CustomMachineNamer().generateNewMachineUniqueName(config), "foo-foo-bar-bar-baz-baz");
+    }
+    
+    public String getSubstitution() {
+        return "baz";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java b/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java
new file mode 100644
index 0000000..f288bee
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.testng.annotations.Test;
+
+import brooklyn.util.collections.MutableMap;
+
+public class HostGeoInfoTest {
+    private static final String IP = "192.168.0.1";
+    
+    private static final Location CUSTOM_LOCATION = new SimulatedLocation(MutableMap.of("name", "custom", "latitude", 50d, "longitude", 0d));
+    private static final Location CUSTOM_LOCATION_CHILD = new SimulatedLocation(MutableMap.of("name", "custom-child", "address", IP, "parentLocation", CUSTOM_LOCATION));
+        
+    @Test
+    public void testCustomLocationCoordinates() {
+        HostGeoInfo hgi = HostGeoInfo.fromLocation(CUSTOM_LOCATION);
+        assertNotNull(hgi);
+        assertEquals(50.0d, hgi.latitude);
+        assertEquals(0.0d, hgi.longitude);
+    }
+    
+    @Test
+    public void testCustomLocationChildCoordinates() {
+        HostGeoInfo hgi = HostGeoInfo.fromLocation(CUSTOM_LOCATION_CHILD);
+        assertNotNull(hgi);
+        assertEquals(50.0d, hgi.latitude);
+        assertEquals(0.0d, hgi.longitude);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoLookupIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoLookupIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoLookupIntegrationTest.java
new file mode 100644
index 0000000..129a46d
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoLookupIntegrationTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+import java.net.InetAddress;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Objects;
+
+public class HostGeoLookupIntegrationTest {
+
+    public static final Logger log = LoggerFactory.getLogger(HostGeoLookupIntegrationTest.class);
+    
+    // Needs fast network connectivity to figure out the external IP. If response not returned in 2s fails.
+    @Test(groups = "Integration")
+    public void testLocalhostGetsLocation() throws Exception {
+        LocalhostMachineProvisioningLocation ll = new LocalhostMachineProvisioningLocation();
+        SshMachineLocation l = ll.obtain();
+        HostGeoInfo geo = HostGeoInfo.fromLocation(l);
+        Assert.assertNotNull(geo, "host lookup unavailable - is the maxmind database installed? or else network unavailable or too slow?");
+        log.info("localhost is in "+geo);
+        Assert.assertNotNull(geo, "couldn't load data; must have a valid HostGeoLookup impl (e.g. MaxMind installed, or online and with Utrace credit)");
+        Assert.assertTrue(-90 <= geo.latitude && geo.latitude <= 90); 
+        ll.close();
+    }
+
+    @Deprecated // see GeoBytesHostGeoLookup - their API changed
+    @Test(groups = "Integration", enabled=false)
+    public void testGeobytesLookup() throws Exception {
+        HostGeoInfo geo = new GeoBytesHostGeoLookup().getHostGeoInfo(InetAddress.getByName("geobytes.com"));
+        Assert.assertNotNull(geo, "host lookup unavailable");
+        Assert.assertEquals(geo.displayName, "Baltimore (US)");
+        Assert.assertEquals(geo.latitude, 39.2894, 0.1);
+        Assert.assertEquals(geo.longitude, -76.6384, 0.1);
+    }
+
+    @Test(groups = "Integration")
+    public void testUtraceLookup() throws Exception {
+        // The test times out in a VM - VirtualBox + Ubuntu Vivid, possibly due to proxy usage?
+        // Increase the timeout so we can actually test it's working correctly, regardless of test environment.
+        HostGeoInfo geo = new UtraceHostGeoLookup().getHostGeoInfo(InetAddress.getByName("utrace.de"), Duration.THIRTY_SECONDS);
+        Assert.assertNotNull(geo, "host lookup unavailable - maybe network not available ");
+        Assert.assertTrue(geo.displayName.contains("(DE)"));
+        Assert.assertEquals(geo.latitude, 51, 2);
+        Assert.assertEquals(geo.longitude, 9, 5);
+    }
+
+    @Test(groups = "Integration")  // only works if maxmind database is installed to ~/.brooklyn/
+    public void testMaxmindLookup() throws Exception {
+        HostGeoInfo geo = new MaxMind2HostGeoLookup().getHostGeoInfo(InetAddress.getByName("maxmind.com"));
+        Assert.assertNotNull(geo, "host lookup unavailable - is the maxmind database installed?");
+        log.info("maxmind.com at "+geo);
+        
+        // used to be Washington; now Dallas - in case this changes again, we will accept either!
+        // also have seen variation in lat/lon reported, so happy to within one degree now
+        Assert.assertTrue(Objects.equal(geo.displayName, "Washington, DC (US)") || Objects.equal(geo.displayName, "Dallas, TX (US)"), "name="+geo.displayName);
+        Assert.assertTrue(Math.abs(geo.latitude - 38.90) <= 1 || Math.abs(geo.latitude - 32.78) <= 1, "lat="+geo.latitude);
+        Assert.assertTrue(Math.abs(geo.longitude - -77.02) <= 1 || Math.abs(geo.longitude - -96.82) <= 1, "lon="+geo.longitude);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/geo/LocalhostExternalIpLoaderIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/geo/LocalhostExternalIpLoaderIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/geo/LocalhostExternalIpLoaderIntegrationTest.java
new file mode 100644
index 0000000..e686985
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/geo/LocalhostExternalIpLoaderIntegrationTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.apache.brooklyn.location.geo;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Sets;
+
+public class LocalhostExternalIpLoaderIntegrationTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LocalhostExternalIpLoaderIntegrationTest.class);
+
+    @Test(groups = "Integration")
+    public void testHostsAgreeOnExternalIp() {
+        Set<String> ips = Sets.newHashSet();
+        for (String url : LocalhostExternalIpLoader.getIpAddressWebsites()) {
+            String ip = LocalhostExternalIpLoader.getIpAddressFrom(url);
+            LOG.debug("IP from {}: {}", url, ip);
+            ips.add(ip);
+        }
+        assertEquals(ips.size(), 1, "Expected all IP suppliers to agree on the external IP address of Brooklyn. " +
+                "Check logs for source responses. ips=" + ips);
+    }
+
+    @Test(groups = "Integration")
+    public void testLoadExternalIp() {
+        assertNotNull(LocalhostExternalIpLoader.getLocalhostIpWaiting());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java b/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java
index cd94a22..8dbb21d 100644
--- a/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java
+++ b/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.test.entity;
 import java.util.Collection;
 import java.util.concurrent.CountDownLatch;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Throwables;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/test/entity/TestApplication.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/test/entity/TestApplication.java b/core/src/test/java/org/apache/brooklyn/test/entity/TestApplication.java
index 545094c..4a4cb94 100644
--- a/core/src/test/java/org/apache/brooklyn/test/entity/TestApplication.java
+++ b/core/src/test/java/org/apache/brooklyn/test/entity/TestApplication.java
@@ -30,8 +30,8 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.StartableApplication;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 
 /**
  * Mock application for testing.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java b/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java
index 70904e6..33c52ed 100644
--- a/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java
+++ b/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java
@@ -30,9 +30,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractApplication;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.logging.LoggingSetup;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java b/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java
index 0cb2dd5..c444b51 100644
--- a/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java
+++ b/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java
@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.Lists;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/resources/brooklyn/location/basic/sample_id_rsa
----------------------------------------------------------------------
diff --git a/core/src/test/resources/brooklyn/location/basic/sample_id_rsa b/core/src/test/resources/brooklyn/location/basic/sample_id_rsa
deleted file mode 100644
index bfeef4a..0000000
--- a/core/src/test/resources/brooklyn/location/basic/sample_id_rsa
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEA0rPOuv1rVXhrSaZSnA2fShSFp8/3knG/Uuss8ZojUW4k+ETj
-dVuYzoH/tvAaYqTUuxqB5OpNgOgUpS02hqOWtN/3iYcfJtBHe4eu/dMSfcQXKasU
-ZalQtv2zF955EMH7jZ0q4TPikOS/tR/gPBDe6xHGjwPpB7Jd2daU0VgJD7M9SOIL
-bRDbilw1XpgyOs4C6I3ftlcH1nA9tQKcdFQ0wmWAXr0ulizYMoAy3VOm34XAwT/o
-w1sgpGK7YwPLbBv1QI4SKfvHi9OhcNBBOoXTE3G3vg6EiKGaam3Kp17EO60iq4CE
-Ec+3FBk5JQ0pAX2SsfxqASHY7QcpbQphF+jlRwIDAQABAoIBAQCqjnZXku+hfhqK
-waG5RKWeV8JhNs0WtBDFVC1LXRQdxGUUut7MjtrAvyZ5tR4Gn5q74hcncCpQoIyl
-sFWk4yMJQwqjPseOqaZTbl/Og19CgsqlJiEasdXuaqrgNWwWjo/L8F9XcKKD20b7
-nNPsi1OHQRpThjzJyC6EOVi5pOOg2mL+cWBJEJy6AIOWVkidw/x+IX6P/6eppc+C
-JM9AVRvSkCYBmTXTCM4OZq6WV53V/m/SaAlG/LcC4ykZBDdhq8T3lNp/sACvWVzL
-JKVcQuBAv7ABBbMcyTgIFpKrx7siUTA+7QGkdG1IbR55S57iSgGGytUV4qv02pBr
-bCJUokZRAoGBAPx/XZ0ig9lYVF7Z4ayASS7j5na4A/MZyHeBZ8hPynIHpjbGvRrG
-+r61XEcSsS4vj6ptCBhuxzYRq6t1yX/6wecFmWdSxcjoS4grMKdGPoWSoOBnV85I
-4/Ctd+NiFtXDqd1abGH3NKtkSwwKr/FX3IK2ePiGpoBNYWbGFMRO2LJrAoGBANWg
-BlLjnZwZ71+8cKb3ozCaLmE8fMG/vw6idTEPRk6iyvto9rpjnpz7Sd12z/d35U32
-6QM+3MsGZ3B1NTJoba7l7cuVtwfIHBc0Q3VQSHBp5PDuM5bNhDb38jt0/Dtv/bMD
-NMVletmrc2Hfx8uqUdr21LKrWO42AwYsLFsMAGeVAoGAObXWrKqN3ihdKEy+UtID
-aA84xpuqc27KLd5K3TK3f7aV2+EyqaMe/mWvUKNKEddXC8nd1s/DAm2pggfq5TBo
-Dyhtdnspr5DAasAMX78jXR41XPTh0clBJ+pOA4+QzozpDymyqfV5eU70BC2RJyVA
-xjN0lMEZ3ytQfs/5QSEQUD8CgYBwipOKS3uW51riVsYKUF/alP9mHpWjBL9EmHWg
-2OkzODQzasLAwwamsQPi9lrthm55OmDbYtyy4LbR2g2idr2B7IPwQvlf0h5qYxA+
-14KyJjeEbhkjkzXaN5mXlTPkpEVFb6T3cVTdI6PvphL9ysbA0lSPpBF/vViugcsE
-VDhKWQKBgQCwaNQ07sHKRqc22SFNgcOv0KOMx7CbaSRxGoEwtpvvdAPlUXuIYMs+
-pueK5scHKJvtcHZQb82j6o84OC37ut+8tUe2XkasyAbONZqqm+Oes1xseKrNcF8J
-+thFmGvZc8O3xdflT87OXDLGzufGJXUDDvZctJwrC5AYPClwj6wd0A==
------END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/resources/brooklyn/location/basic/sample_id_rsa.pub
----------------------------------------------------------------------
diff --git a/core/src/test/resources/brooklyn/location/basic/sample_id_rsa.pub b/core/src/test/resources/brooklyn/location/basic/sample_id_rsa.pub
deleted file mode 100644
index f137be8..0000000
--- a/core/src/test/resources/brooklyn/location/basic/sample_id_rsa.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSs866/WtVeGtJplKcDZ9KFIWnz/eScb9S6yzxmiNRbiT4RON1W5jOgf+28BpipNS7GoHk6k2A6BSlLTaGo5a03/eJhx8m0Ed7h6790xJ9xBcpqxRlqVC2/bMX3nkQwfuNnSrhM+KQ5L+1H+A8EN7rEcaPA+kHsl3Z1pTRWAkPsz1I4gttENuKXDVemDI6zgLojd+2VwfWcD21Apx0VDTCZYBevS6WLNgygDLdU6bfhcDBP+jDWyCkYrtjA8tsG/VAjhIp+8eL06Fw0EE6hdMTcbe+DoSIoZpqbcqnXsQ7rSKrgIQRz7cUGTklDSkBfZKx/GoBIdjtByltCmEX6OVH alex@almacretin.local

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/resources/org/apache/brooklyn/location/basic/sample_id_rsa
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/brooklyn/location/basic/sample_id_rsa b/core/src/test/resources/org/apache/brooklyn/location/basic/sample_id_rsa
new file mode 100644
index 0000000..bfeef4a
--- /dev/null
+++ b/core/src/test/resources/org/apache/brooklyn/location/basic/sample_id_rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA0rPOuv1rVXhrSaZSnA2fShSFp8/3knG/Uuss8ZojUW4k+ETj
+dVuYzoH/tvAaYqTUuxqB5OpNgOgUpS02hqOWtN/3iYcfJtBHe4eu/dMSfcQXKasU
+ZalQtv2zF955EMH7jZ0q4TPikOS/tR/gPBDe6xHGjwPpB7Jd2daU0VgJD7M9SOIL
+bRDbilw1XpgyOs4C6I3ftlcH1nA9tQKcdFQ0wmWAXr0ulizYMoAy3VOm34XAwT/o
+w1sgpGK7YwPLbBv1QI4SKfvHi9OhcNBBOoXTE3G3vg6EiKGaam3Kp17EO60iq4CE
+Ec+3FBk5JQ0pAX2SsfxqASHY7QcpbQphF+jlRwIDAQABAoIBAQCqjnZXku+hfhqK
+waG5RKWeV8JhNs0WtBDFVC1LXRQdxGUUut7MjtrAvyZ5tR4Gn5q74hcncCpQoIyl
+sFWk4yMJQwqjPseOqaZTbl/Og19CgsqlJiEasdXuaqrgNWwWjo/L8F9XcKKD20b7
+nNPsi1OHQRpThjzJyC6EOVi5pOOg2mL+cWBJEJy6AIOWVkidw/x+IX6P/6eppc+C
+JM9AVRvSkCYBmTXTCM4OZq6WV53V/m/SaAlG/LcC4ykZBDdhq8T3lNp/sACvWVzL
+JKVcQuBAv7ABBbMcyTgIFpKrx7siUTA+7QGkdG1IbR55S57iSgGGytUV4qv02pBr
+bCJUokZRAoGBAPx/XZ0ig9lYVF7Z4ayASS7j5na4A/MZyHeBZ8hPynIHpjbGvRrG
++r61XEcSsS4vj6ptCBhuxzYRq6t1yX/6wecFmWdSxcjoS4grMKdGPoWSoOBnV85I
+4/Ctd+NiFtXDqd1abGH3NKtkSwwKr/FX3IK2ePiGpoBNYWbGFMRO2LJrAoGBANWg
+BlLjnZwZ71+8cKb3ozCaLmE8fMG/vw6idTEPRk6iyvto9rpjnpz7Sd12z/d35U32
+6QM+3MsGZ3B1NTJoba7l7cuVtwfIHBc0Q3VQSHBp5PDuM5bNhDb38jt0/Dtv/bMD
+NMVletmrc2Hfx8uqUdr21LKrWO42AwYsLFsMAGeVAoGAObXWrKqN3ihdKEy+UtID
+aA84xpuqc27KLd5K3TK3f7aV2+EyqaMe/mWvUKNKEddXC8nd1s/DAm2pggfq5TBo
+Dyhtdnspr5DAasAMX78jXR41XPTh0clBJ+pOA4+QzozpDymyqfV5eU70BC2RJyVA
+xjN0lMEZ3ytQfs/5QSEQUD8CgYBwipOKS3uW51riVsYKUF/alP9mHpWjBL9EmHWg
+2OkzODQzasLAwwamsQPi9lrthm55OmDbYtyy4LbR2g2idr2B7IPwQvlf0h5qYxA+
+14KyJjeEbhkjkzXaN5mXlTPkpEVFb6T3cVTdI6PvphL9ysbA0lSPpBF/vViugcsE
+VDhKWQKBgQCwaNQ07sHKRqc22SFNgcOv0KOMx7CbaSRxGoEwtpvvdAPlUXuIYMs+
+pueK5scHKJvtcHZQb82j6o84OC37ut+8tUe2XkasyAbONZqqm+Oes1xseKrNcF8J
++thFmGvZc8O3xdflT87OXDLGzufGJXUDDvZctJwrC5AYPClwj6wd0A==
+-----END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/resources/org/apache/brooklyn/location/basic/sample_id_rsa.pub
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/brooklyn/location/basic/sample_id_rsa.pub b/core/src/test/resources/org/apache/brooklyn/location/basic/sample_id_rsa.pub
new file mode 100644
index 0000000..f137be8
--- /dev/null
+++ b/core/src/test/resources/org/apache/brooklyn/location/basic/sample_id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSs866/WtVeGtJplKcDZ9KFIWnz/eScb9S6yzxmiNRbiT4RON1W5jOgf+28BpipNS7GoHk6k2A6BSlLTaGo5a03/eJhx8m0Ed7h6790xJ9xBcpqxRlqVC2/bMX3nkQwfuNnSrhM+KQ5L+1H+A8EN7rEcaPA+kHsl3Z1pTRWAkPsz1I4gttENuKXDVemDI6zgLojd+2VwfWcD21Apx0VDTCZYBevS6WLNgygDLdU6bfhcDBP+jDWyCkYrtjA8tsG/VAjhIp+8eL06Fw0EE6hdMTcbe+DoSIoZpqbcqnXsQ7rSKrgIQRz7cUGTklDSkBfZKx/GoBIdjtByltCmEX6OVH alex@almacretin.local

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/_extra/big_examples/global-web-fabric/index.md
----------------------------------------------------------------------
diff --git a/docs/_extra/big_examples/global-web-fabric/index.md b/docs/_extra/big_examples/global-web-fabric/index.md
index cd9a29b..d163611 100644
--- a/docs/_extra/big_examples/global-web-fabric/index.md
+++ b/docs/_extra/big_examples/global-web-fabric/index.md
@@ -73,7 +73,7 @@ unpack it, and copy it to `~/.brooklyn/GeoLite2-City.mmdb`.
 This will be picked up automatically if it is installed.
 You can instead specify to use an online lookup service, such as 
 [utrace.de](http://www.utrace.de) by specifying
-`-Dbrooklyn.location.geo.HostGeoLookup=brooklyn.location.geo.UtraceHostGeoLookup`;
+`-Dbrooklyn.location.geo.HostGeoLookup=UtraceHostGeoLookup`;
 but note this has a cap of 100 per day.
 
 This information is also used to display locations on the map
@@ -210,7 +210,7 @@ import brooklyn.entity.group.DynamicFabric;
 import brooklyn.entity.proxy.AbstractController;
 import brooklyn.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.webapp.ElasticJavaWebAppService;
-import brooklyn.location.basic.PortRanges;
+import PortRanges;
 {% endhighlight %}
 
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/guide/ops/locations/index.md
----------------------------------------------------------------------
diff --git a/docs/guide/ops/locations/index.md b/docs/guide/ops/locations/index.md
index 767ca72..c9b41db 100644
--- a/docs/guide/ops/locations/index.md
+++ b/docs/guide/ops/locations/index.md
@@ -133,7 +133,7 @@ For more keys and more detail on the keys below, see
   For more sophisticated control over host naming, you can supply a custom 
   {% include java_link.html class_name="CloudMachineNamer" package_path="brooklyn/location/cloud/names" project_subpath="core" %},
   for example
-  `cloudMachineNamer: brooklyn.location.cloud.names.CustomMachineNamer`.
+  `cloudMachineNamer: CustomMachineNamer`.
   {% include java_link.html class_name="CustomMachineNamer" package_path="brooklyn/location/cloud/names" project_subpath="core" %}
   will use the entity's name or following a template you supply.
   On many clouds, a random suffix will be appended to help guarantee uniqueness;
@@ -425,7 +425,7 @@ The BYON location also supports a machine chooser, using the config key `byon.ma
 This allows one to plugin logic to choose from the set of available machines in the pool. For
 example, additional config could be supplied for each machine. This could be used (during the call
 to `location.obtain()`) to find the config that matches the requirements of the entity being
-provisioned. See `brooklyn.location.basic.FixedListMachineProvisioningLocation.MACHINE_CHOOSER`.
+provisioned. See `FixedListMachineProvisioningLocation.MACHINE_CHOOSER`.
 
 
 ### Other Location Topics

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.AddressableLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.AddressableLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.AddressableLocation.html
index 857a635..bb484c2 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.AddressableLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.AddressableLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.AddressableLocation</title>
+    <title>Brooklyn Location - AddressableLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.AddressableLocation</h1>
+        <h1>AddressableLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.AddressableLocation";
+            return entity.type == "AddressableLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.MachineLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.MachineLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.MachineLocation.html
index dbd9455..edb16fd 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.MachineLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.MachineLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.MachineLocation</title>
+    <title>Brooklyn Location - MachineLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.MachineLocation</h1>
+        <h1>MachineLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.MachineLocation";
+            return entity.type == "MachineLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.MachineManagementMixins$RichMachineProvisioningLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.MachineManagementMixins$RichMachineProvisioningLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.MachineManagementMixins$RichMachineProvisioningLocation.html
index fdf531b..09ffd3f 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.MachineManagementMixins$RichMachineProvisioningLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.MachineManagementMixins$RichMachineProvisioningLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.MachineManagementMixins$RichMachineProvisioningLocation</title>
+    <title>Brooklyn Location - MachineManagementMixins$RichMachineProvisioningLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.MachineManagementMixins$RichMachineProvisioningLocation</h1>
+        <h1>MachineManagementMixins$RichMachineProvisioningLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.MachineManagementMixins$RichMachineProvisioningLocation";
+            return entity.type == "MachineManagementMixins$RichMachineProvisioningLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.MachineProvisioningLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.MachineProvisioningLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.MachineProvisioningLocation.html
index d63dc8b..f0a8282 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.MachineProvisioningLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.MachineProvisioningLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.MachineProvisioningLocation</title>
+    <title>Brooklyn Location - MachineProvisioningLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.MachineProvisioningLocation</h1>
+        <h1>MachineProvisioningLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.MachineProvisioningLocation";
+            return entity.type == "MachineProvisioningLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AbstractLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AbstractLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AbstractLocation.html
index 6861236..05ad96f 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AbstractLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AbstractLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.AbstractLocation</title>
+    <title>Brooklyn Location - AbstractLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.AbstractLocation</h1>
+        <h1>AbstractLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.AbstractLocation";
+            return entity.type == "AbstractLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AggregatingMachineProvisioningLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AggregatingMachineProvisioningLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AggregatingMachineProvisioningLocation.html
index 790d261..75c4101 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AggregatingMachineProvisioningLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.AggregatingMachineProvisioningLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.AggregatingMachineProvisioningLocation</title>
+    <title>Brooklyn Location - AggregatingMachineProvisioningLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.AggregatingMachineProvisioningLocation</h1>
+        <h1>AggregatingMachineProvisioningLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.AggregatingMachineProvisioningLocation";
+            return entity.type == "AggregatingMachineProvisioningLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.FixedListMachineProvisioningLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.FixedListMachineProvisioningLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.FixedListMachineProvisioningLocation.html
index 989c8ee..bfedb11 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.FixedListMachineProvisioningLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.FixedListMachineProvisioningLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.FixedListMachineProvisioningLocation</title>
+    <title>Brooklyn Location - FixedListMachineProvisioningLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.FixedListMachineProvisioningLocation</h1>
+        <h1>FixedListMachineProvisioningLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.FixedListMachineProvisioningLocation";
+            return entity.type == "FixedListMachineProvisioningLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation$LocalhostMachine.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation$LocalhostMachine.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation$LocalhostMachine.html
index 2a26d53..b39bc4c 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation$LocalhostMachine.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation$LocalhostMachine.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.LocalhostMachineProvisioningLocation$LocalhostMachine</title>
+    <title>Brooklyn Location - LocalhostMachineProvisioningLocation$LocalhostMachine</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.LocalhostMachineProvisioningLocation$LocalhostMachine</h1>
+        <h1>LocalhostMachineProvisioningLocation$LocalhostMachine</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.LocalhostMachineProvisioningLocation$LocalhostMachine";
+            return entity.type == "LocalhostMachineProvisioningLocation$LocalhostMachine";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation.html
----------------------------------------------------------------------
diff --git a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation.html b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation.html
index 47af495..97f25e8 100644
--- a/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation.html
+++ b/docs/website/learnmore/catalog/locations/brooklyn.location.basic.LocalhostMachineProvisioningLocation.html
@@ -18,7 +18,7 @@ under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
 <head>
-    <title>Brooklyn Location - brooklyn.location.basic.LocalhostMachineProvisioningLocation</title>
+    <title>Brooklyn Location - LocalhostMachineProvisioningLocation</title>
     <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
     <link rel="stylesheet" href="../items.css" type="text/css" media="screen"/>
 </head>
@@ -30,7 +30,7 @@ under the License.
         </div>
     </div>
     <div id="content" class="objectContent">
-        <h1>brooklyn.location.basic.LocalhostMachineProvisioningLocation</h1>
+        <h1>LocalhostMachineProvisioningLocation</h1>
         <h2 class="typeLabel">Type:</h2><span id="type"></span>
 
         <h2>Config Keys</h2>
@@ -50,7 +50,7 @@ under the License.
 <script type="text/javascript">
     $(document).ready(function () {
         var item = $.grep((items.locations), function (entity) {
-            return entity.type == "brooklyn.location.basic.LocalhostMachineProvisioningLocation";
+            return entity.type == "LocalhostMachineProvisioningLocation";
         })[0];
         $("#type").html(item.type);
         item.config.forEach(function (element) {



[32/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java b/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java
new file mode 100644
index 0000000..6a17c1a
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java
@@ -0,0 +1,257 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.brooklyn.location.PortRange;
+import brooklyn.util.flags.TypeCoercions;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class PortRanges {
+
+    public static final int MAX_PORT = 65535;
+    public static final PortRange ANY_HIGH_PORT = new LinearPortRange(1024, MAX_PORT);
+    
+    public static class SinglePort implements PortRange, Serializable {
+        private static final long serialVersionUID = 7446781416534230401L;
+        
+        final int port;
+        private SinglePort(int port) { this.port = port; }
+        
+        @Override
+        public Iterator<Integer> iterator() {
+            return Collections.singletonList(port).iterator();
+        }
+        @Override
+        public boolean isEmpty() {
+            return false;
+        }
+        @Override
+        public boolean asBoolean() {
+            return true;
+        }
+        @Override
+        public String toString() {
+            return //getClass().getName()+"["+
+                    ""+port; //+"]";
+        }
+        public int hashCode() {
+            return Objects.hashCode(port);
+        }
+        @Override
+        public boolean equals(Object obj) {
+            return (obj instanceof SinglePort) && port == ((SinglePort)obj).port;
+        }
+    }
+
+    public static class LinearPortRange implements PortRange, Serializable {
+        private static final long serialVersionUID = -9165280509363743508L;
+        
+        final int start, end, delta;
+        private LinearPortRange(int start, int end, int delta) {
+            this.start = start;
+            this.end = end;
+            this.delta = delta;
+            checkArgument(start > 0 && start <= MAX_PORT, "start port %s out of range", start);
+            checkArgument(end > 0 && end <= MAX_PORT, "end port %s out of range", end);
+            checkArgument(delta > 0 ? start <= end : start >= end, "start and end out of order: %s to %s, delta %s", start, end, delta);
+            checkArgument(delta != 0, "delta must be non-zero");
+        }
+        public LinearPortRange(int start, int end) {
+            this(start, end, (start<=end?1:-1));
+        }
+        
+        @Override
+        public Iterator<Integer> iterator() {
+            return new Iterator<Integer>() {
+                int next = start;
+                boolean hasNext = true;
+                
+                @Override
+                public boolean hasNext() {
+                    return hasNext;
+                }
+
+                @Override
+                public Integer next() {
+                    if (!hasNext)
+                        throw new NoSuchElementException("Exhausted available ports");
+                    int result = next;
+                    next += delta;
+                    if ((delta>0 && next>end) || (delta<0 && next<end)) hasNext = false;
+                    return result;
+                }
+                
+                @Override
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+            };
+        }
+        
+        @Override
+        public boolean isEmpty() {
+            return false;
+        }
+        @Override
+        public boolean asBoolean() {
+            return true;
+        }
+        @Override
+        public String toString() {
+            return //getClass().getName()+"["+
+                    start+"-"+end; //+"]";
+        }
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(start, end, delta);
+        }
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof LinearPortRange)) return false;
+            LinearPortRange o = (LinearPortRange) obj;
+            return start == o.start && end == o.end && delta == o.delta;
+        }
+    }
+    
+    public static class AggregatePortRange implements PortRange, Serializable {
+        private static final long serialVersionUID = 7332682500816739660L;
+        
+        final List<PortRange> ranges;
+        private AggregatePortRange(List<PortRange> ranges) {
+            this.ranges = ImmutableList.copyOf(ranges);
+        }
+        @Override
+        public Iterator<Integer> iterator() {
+            return Iterables.concat(ranges).iterator();
+        }
+        @Override
+        public boolean isEmpty() {
+            for (PortRange r: ranges)
+                if (!r.isEmpty()) return false;
+            return true;
+        }
+        @Override
+        public boolean asBoolean() {
+            return !isEmpty();
+        }
+        @Override
+        public String toString() {
+            String s = "";
+            for (PortRange r: ranges) {
+                if (s.length()>0) s+=",";
+                s += r;
+            }
+            return //getClass().getName()+"["+
+                s; //+"]";
+        }
+        public int hashCode() {
+            return Objects.hashCode(ranges);
+        }
+        @Override
+        public boolean equals(Object obj) {
+            return (obj instanceof AggregatePortRange) && ranges.equals(((AggregatePortRange)obj).ranges);
+        }
+    }
+
+    public static PortRange fromInteger(int x) {
+        return new SinglePort(x);
+    }
+    
+    public static PortRange fromCollection(Collection<?> c) {
+        List<PortRange> l = new ArrayList<PortRange>();
+        for (Object o: c) {
+            if (o instanceof Integer) l.add(fromInteger((Integer)o));
+            else if (o instanceof String) l.add(fromString((String)o));
+            else if (o instanceof Collection) l.add(fromCollection((Collection<?>)o));
+            else l.add(TypeCoercions.coerce(o, PortRange.class));
+        }
+        return new AggregatePortRange(l);
+    }
+
+    /** parses a string representation of ports, as "80,8080,8000,8080-8099" */
+    public static PortRange fromString(String s) {
+        List<PortRange> l = new ArrayList<PortRange>();
+        for (String si: s.split(",")) {
+            si = si.trim();
+            int start, end;
+            if (si.endsWith("+")) {
+                String si2 = si.substring(0, si.length()-1).trim();
+                start = Integer.parseInt(si2);
+                end = MAX_PORT;
+            } else if (si.indexOf('-')>0) {
+                int v = si.indexOf('-');
+                start = Integer.parseInt(si.substring(0, v).trim());
+                end = Integer.parseInt(si.substring(v+1).trim());
+            } else if (si.length()==0) {
+                //nothing, ie empty range, just continue
+                continue;
+            } else {
+                //should be number on its own
+                l.add(new SinglePort(Integer.parseInt(si)));
+                continue;
+            }
+            l.add(new LinearPortRange(start, end));
+        }
+        if (l.size() == 1) {
+            return l.get(0);
+        } else {
+            return new AggregatePortRange(l);
+        }
+    }
+
+    private static AtomicBoolean initialized = new AtomicBoolean(false); 
+    /** performs the language extensions required for this project */
+    @SuppressWarnings("rawtypes")
+    public static void init() {
+        if (initialized.get()) return;
+        synchronized (initialized) {
+            if (initialized.get()) return;
+            TypeCoercions.registerAdapter(Integer.class, PortRange.class, new Function<Integer,PortRange>() {
+                public PortRange apply(Integer x) { return fromInteger(x); }
+            });
+            TypeCoercions.registerAdapter(String.class, PortRange.class, new Function<String,PortRange>() {
+                public PortRange apply(String x) { return fromString(x); }
+            });
+            TypeCoercions.registerAdapter(Collection.class, PortRange.class, new Function<Collection,PortRange>() {
+                public PortRange apply(Collection x) { return fromCollection(x); }
+            });
+            initialized.set(true);
+        }
+    }
+    
+    static {
+        init();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java
new file mode 100644
index 0000000..06558cb
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java
@@ -0,0 +1,42 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationRegistry;
+
+/**
+ * Extension to LocationResolver which can take a registry.
+ * 
+ * @deprecated since 0.6; the LocationResolver always takes the LocationRegistry now
+ */
+@Deprecated
+public interface RegistryLocationResolver extends LocationResolver {
+
+    @Override
+    @SuppressWarnings("rawtypes")
+    Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry);
+
+    @Override
+    boolean accepts(String spec, LocationRegistry registry);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java
new file mode 100644
index 0000000..4be135f
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java
@@ -0,0 +1,77 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationSpec;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.guava.Maybe.Absent;
+
+public class SingleMachineLocationResolver extends AbstractLocationResolver {
+    
+    private static final String SINGLE = "single";
+    
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Override
+    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        ConfigBag config = extractConfig(locationFlags, spec, registry);
+        Map globalProperties = registry.getProperties();
+        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
+        
+        if (registry != null) {
+            LocationPropertiesFromBrooklynProperties.setLocalTempDir(globalProperties, config);
+        }
+
+        if (config.getStringKey("target") == null) {
+            throw new IllegalArgumentException("target must be specified in single-machine spec");
+        }
+        String target = config.getStringKey("target").toString();
+        config.remove("target");
+        Maybe<Location> testResolve = managementContext.getLocationRegistry().resolve(target, false, null);
+        if (!testResolve.isPresent()) {
+            throw new IllegalArgumentException("Invalid target location '" + target + "' for location '"+SINGLE+"': "+
+                Exceptions.collapseText( ((Absent<?>)testResolve).getException() ));
+        }
+        
+        return managementContext.getLocationManager().createLocation(LocationSpec.create(SingleMachineProvisioningLocation.class)
+                .configure("location", target)
+                .configure("locationFlags", config.getAllConfig())
+                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+    }
+    
+    @Override
+    public String getPrefix() {
+        return SINGLE;
+    }
+    
+    @Override
+    protected Class<? extends Location> getLocationType() {
+        return SingleMachineProvisioningLocation.class;
+    }
+
+    @Override
+    protected SpecParser getSpecParser() {
+        return new SpecParser(getPrefix()).setExampleUsage("\"single(target=jclouds:aws-ec2:us-east-1)\"");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java
new file mode 100644
index 0000000..6c40ba3
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java
@@ -0,0 +1,92 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import brooklyn.util.flags.SetFromFlag;
+
+import com.google.common.collect.ImmutableMap;
+
+public class SingleMachineProvisioningLocation<T extends MachineLocation> extends FixedListMachineProvisioningLocation<T> {
+    private static final long serialVersionUID = -4216528515792151062L;
+
+    private static final Logger log = LoggerFactory.getLogger(SingleMachineProvisioningLocation.class);
+    
+    @SetFromFlag(nullable=false)
+    private String location;
+    
+    @SetFromFlag(nullable=false)
+    private Map<?,?> locationFlags;
+    
+    private T singleLocation;
+    private int referenceCount;
+    private MachineProvisioningLocation<T> provisioningLocation;
+
+
+    public SingleMachineProvisioningLocation() {
+    }
+
+    @SuppressWarnings("rawtypes")
+    public SingleMachineProvisioningLocation(String location, Map locationFlags) {
+        this.locationFlags = locationFlags;
+        this.location = location;
+    }
+
+    @SuppressWarnings("rawtypes")
+    @Override
+    public synchronized T obtain(Map flags) throws NoMachinesAvailableException {
+        log.info("Flags {} passed to newLocationFromString will be ignored, using {}", flags, locationFlags);
+        return obtain();
+    }
+
+    @Override
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public synchronized T obtain() throws NoMachinesAvailableException {
+        if (singleLocation == null) {
+            if (provisioningLocation == null) {
+                provisioningLocation = (MachineProvisioningLocation) getManagementContext().getLocationRegistry().resolve(
+                    location, locationFlags);
+            }
+            singleLocation = provisioningLocation.obtain(ImmutableMap.of());
+            inUse.add(singleLocation);
+        }
+        referenceCount++;
+        return singleLocation;
+    }
+
+    @Override
+    public synchronized void release(T machine) {
+        if (!machine.equals(singleLocation)) {
+            throw new IllegalArgumentException("Invalid machine " + machine + " passed to release, expecting: " + singleLocation);
+        }
+        if (--referenceCount == 0) {
+            provisioningLocation.release(machine);
+            singleLocation = null;
+        }
+        inUse.remove(machine);
+    };
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java
new file mode 100644
index 0000000..e83712e
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java
@@ -0,0 +1,1031 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static brooklyn.util.GroovyJavaMethods.truth;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.security.KeyPair;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.PortRange;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Throwables;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.net.HostAndPort;
+import com.google.common.reflect.TypeToken;
+
+import brooklyn.config.BrooklynLogging;
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import brooklyn.config.ConfigUtils;
+import brooklyn.entity.basic.BrooklynConfigKeys;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.event.basic.MapConfigKey;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.PortSupplier;
+import org.apache.brooklyn.location.access.PortForwardManager;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.crypto.SecureKeys;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.exceptions.RuntimeInterruptedException;
+import brooklyn.util.file.ArchiveUtils;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.guava.KeyTransformingLoadingCache.KeyTransformingSameTypeLoadingCache;
+import brooklyn.util.internal.ssh.ShellTool;
+import brooklyn.util.internal.ssh.SshException;
+import brooklyn.util.internal.ssh.SshTool;
+import brooklyn.util.internal.ssh.sshj.SshjTool;
+import brooklyn.util.mutex.MutexSupport;
+import brooklyn.util.mutex.WithMutexes;
+import brooklyn.util.net.Urls;
+import brooklyn.util.pool.BasicPool;
+import brooklyn.util.pool.Pool;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.stream.KnownSizeInputStream;
+import brooklyn.util.stream.ReaderInputStream;
+import brooklyn.util.stream.StreamGobbler;
+import brooklyn.util.task.ScheduledTask;
+import brooklyn.util.task.Tasks;
+import brooklyn.util.task.system.internal.ExecWithLoggingHelpers;
+import brooklyn.util.task.system.internal.ExecWithLoggingHelpers.ExecRunner;
+import brooklyn.util.text.Strings;
+import brooklyn.util.time.Duration;
+import groovy.lang.Closure;
+
+/**
+ * Operations on a machine that is accessible via ssh.
+ * <p>
+ * We expose two ways of running scripts.
+ * The execCommands method passes lines to bash and is lightweight but fragile.
+ * The execScript method creates a script on the remote machine. It is portable but heavier.
+ * <p>
+ * Additionally there are routines to copyTo, copyFrom; and installTo (which tries a curl, and falls back to copyTo
+ * in event the source is accessible by the caller only).
+ */
+public class SshMachineLocation extends AbstractLocation implements MachineLocation, PortSupplier, WithMutexes, Closeable {
+
+    /** @deprecated since 0.7.0 shouldn't be public */
+    public static final Logger LOG = LoggerFactory.getLogger(SshMachineLocation.class);
+    /** @deprecated since 0.7.0 shouldn't be public */
+    public static final Logger logSsh = LoggerFactory.getLogger(BrooklynLogging.SSH_IO);
+    
+    // Use a sane timeout when doing a connectivity test
+    private static final int SSHABLE_CONNECT_TIMEOUT = (int)Duration.minutes(2).toMilliseconds();
+
+    public static final ConfigKey<Duration> SSH_CACHE_EXPIRY_DURATION = ConfigKeys.newConfigKey(Duration.class,
+            "sshCacheExpiryDuration", "Expiry time for unused cached ssh connections", Duration.FIVE_MINUTES);
+
+    public static final ConfigKey<MachineDetails> MACHINE_DETAILS = ConfigKeys.newConfigKey(
+            MachineDetails.class,
+            "machineDetails");
+
+    public static final ConfigKey<Boolean> DETECT_MACHINE_DETAILS = ConfigKeys.newBooleanConfigKey("detectMachineDetails",
+            "Attempt to detect machine details automatically. Works with SSH-accessible Linux instances.", true);
+
+    public static final ConfigKey<Iterable<String>> PRIVATE_ADDRESSES = ConfigKeys.newConfigKey(
+            new TypeToken<Iterable<String>>() {},
+            "privateAddresses",
+            "Private addresses of this machine, e.g. those within the private network", 
+            null);
+
+    public static final ConfigKey<Map<Integer, String>> TCP_PORT_MAPPINGS = ConfigKeys.newConfigKey(
+            new TypeToken<Map<Integer, String>>() {},
+            "tcpPortMappings",
+            "NAT'ed ports, giving the mapping from private TCP port to a public host:port", 
+            null);
+
+    @SetFromFlag
+    protected String user;
+
+    @SetFromFlag(nullable = false)
+    protected InetAddress address;
+
+    // TODO should not allow this to be set from flag; it is not persisted so that will be lost
+    // (mainly used for localhost currently so not a big problem)
+    @Nullable  // lazily initialized; use getMutexSupport()
+    @SetFromFlag
+    private transient WithMutexes mutexSupport;
+
+    @SetFromFlag
+    private Set<Integer> usedPorts;
+
+    private volatile MachineDetails machineDetails;
+    private final Object machineDetailsLock = new Object();
+
+    public static final ConfigKey<String> SSH_HOST = BrooklynConfigKeys.SSH_CONFIG_HOST;
+    public static final ConfigKey<Integer> SSH_PORT = BrooklynConfigKeys.SSH_CONFIG_PORT;
+
+    public static final ConfigKey<String> SSH_EXECUTABLE = ConfigKeys.newStringConfigKey("sshExecutable",
+            "Allows an `ssh` executable file to be specified, to be used in place of the default (programmatic) java ssh client");
+    public static final ConfigKey<String> SCP_EXECUTABLE = ConfigKeys.newStringConfigKey("scpExecutable",
+            "Allows an `scp` executable file to be specified, to be used in place of the default (programmatic) java ssh client");
+
+    // TODO remove
+    public static final ConfigKey<String> PASSWORD = SshTool.PROP_PASSWORD;
+    public static final ConfigKey<String> PRIVATE_KEY_FILE = SshTool.PROP_PRIVATE_KEY_FILE;
+    public static final ConfigKey<String> PRIVATE_KEY_DATA = SshTool.PROP_PRIVATE_KEY_DATA;
+    public static final ConfigKey<String> PRIVATE_KEY_PASSPHRASE = SshTool.PROP_PRIVATE_KEY_PASSPHRASE;
+
+    public static final ConfigKey<String> SCRIPT_DIR = ConfigKeys.newStringConfigKey(
+            "scriptDir", "directory where scripts should be placed and executed on the SSH target machine");
+    public static final ConfigKey<Map<String,Object>> SSH_ENV_MAP = new MapConfigKey<Object>(
+            Object.class, "env", "environment variables to pass to the remote SSH shell session");
+
+    public static final ConfigKey<Boolean> ALLOCATE_PTY = SshTool.PROP_ALLOCATE_PTY;
+
+    public static final ConfigKey<OutputStream> STDOUT = new BasicConfigKey<OutputStream>(OutputStream.class, "out");
+    public static final ConfigKey<OutputStream> STDERR = new BasicConfigKey<OutputStream>(OutputStream.class, "err");
+    public static final ConfigKey<Boolean> NO_STDOUT_LOGGING = ConfigKeys.newBooleanConfigKey(
+            "noStdoutLogging", "whether to disable logging of stdout from SSH commands (e.g. for verbose commands)", false);
+    public static final ConfigKey<Boolean> NO_STDERR_LOGGING = ConfigKeys.newBooleanConfigKey(
+            "noStderrLogging", "whether to disable logging of stderr from SSH commands (e.g. for verbose commands)", false);
+    public static final ConfigKey<String> LOG_PREFIX = ConfigKeys.newStringConfigKey("logPrefix");
+
+    public static final ConfigKey<String> LOCAL_TEMP_DIR = SshTool.PROP_LOCAL_TEMP_DIR;
+
+    public static final ConfigKey<Boolean> CLOSE_CONNECTION = ConfigKeys.newBooleanConfigKey("close", "Close the SSH connection after use", false);
+    public static final ConfigKey<String> UNIQUE_ID = ConfigKeys.newStringConfigKey("unique", "Unique ID for the SSH connection");
+
+    /**
+     * Specifies config keys where a change in the value does not require a new SshTool instance,
+     * i.e. they can be specified per command on the tool
+     */
+    // TODO: Fully specify.
+    public static final Set<ConfigKey<?>> REUSABLE_SSH_PROPS = ImmutableSet.of(
+            STDOUT, STDERR, SCRIPT_DIR, CLOSE_CONNECTION,
+            SshTool.PROP_SCRIPT_HEADER, SshTool.PROP_PERMISSIONS, SshTool.PROP_LAST_MODIFICATION_DATE,
+            SshTool.PROP_LAST_ACCESS_DATE, SshTool.PROP_OWNER_UID, SshTool.PROP_SSH_RETRY_DELAY);
+
+    public static final Set<HasConfigKey<?>> ALL_SSH_CONFIG_KEYS =
+            ImmutableSet.<HasConfigKey<?>>builder()
+                    .addAll(ConfigUtils.getStaticKeysOnClass(SshMachineLocation.class))
+                    .addAll(ConfigUtils.getStaticKeysOnClass(SshTool.class))
+                    .build();
+
+    public static final Set<String> ALL_SSH_CONFIG_KEY_NAMES =
+            ImmutableSet.copyOf(Iterables.transform(ALL_SSH_CONFIG_KEYS, new Function<HasConfigKey<?>,String>() {
+                @Override
+                public String apply(HasConfigKey<?> input) {
+                    return input.getConfigKey().getName();
+                }
+            }));
+
+    /**
+     * The set of config keys on this location which become default values for properties when invoking an SSH
+     * operation.
+     */
+    @Beta
+    public static final Set<ConfigKey<?>> SSH_CONFIG_GIVEN_TO_PROPS = ImmutableSet.<ConfigKey<?>>of(
+            SCRIPT_DIR);
+
+    private Task<?> cleanupTask;
+    /** callers should use {@link #getSshPoolCache()} */
+    @Nullable 
+    private transient LoadingCache<Map<String, ?>, Pool<SshTool>> sshPoolCacheOrNull;
+
+    public SshMachineLocation() {
+        this(MutableMap.of());
+    }
+
+    public SshMachineLocation(Map properties) {
+        super(properties);
+        usedPorts = (usedPorts != null) ? Sets.newLinkedHashSet(usedPorts) : Sets.<Integer>newLinkedHashSet();
+    }
+
+    @Override
+    public void init() {
+        super.init();
+
+        // Register any pre-existing port-mappings with the PortForwardManager
+        Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
+        if (tcpPortMappings != null) {
+            PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
+            for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
+                int targetPort = entry.getKey();
+                HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
+                if (!publicEndpoint.hasPort()) {
+                    throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
+                }
+                pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
+            }
+        }
+    }
+    
+    private final transient Object poolCacheMutex = new Object();
+    @Nonnull
+    private LoadingCache<Map<String, ?>, Pool<SshTool>> getSshPoolCache() {
+        synchronized (poolCacheMutex) {
+            if (sshPoolCacheOrNull==null) {
+                sshPoolCacheOrNull = buildSshToolPoolCacheLoader();
+                addSshPoolCacheCleanupTask();
+            }
+        }
+        return sshPoolCacheOrNull;
+    }
+
+    private LoadingCache<Map<String, ?>, Pool<SshTool>> buildSshToolPoolCacheLoader() {
+        // TODO: Appropriate numbers for maximum size and expire after access
+        // At the moment every SshMachineLocation instance creates its own pool.
+        // It might make more sense to create one pool and inject it into all SshMachineLocations.
+        Duration expiryDuration = getConfig(SSH_CACHE_EXPIRY_DURATION);
+        
+        LoadingCache<Map<String, ?>, Pool<SshTool>> delegate = CacheBuilder.newBuilder()
+                .maximumSize(10)
+                .expireAfterAccess(expiryDuration.toMilliseconds(), TimeUnit.MILLISECONDS)
+                .recordStats()
+                .removalListener(new RemovalListener<Map<String, ?>, Pool<SshTool>>() {
+                    // TODO: Does it matter that this is synchronous? - Can closing pools cause long delays?
+                    @Override
+                    public void onRemoval(RemovalNotification<Map<String, ?>, Pool<SshTool>> notification) {
+                        Pool<SshTool> removed = notification.getValue();
+                        if (removed == null) {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("Pool evicted from SshTool cache is null so we can't call pool.close(). " +
+                                        "It's probably already been garbage collected. Eviction cause: {} ",
+                                        notification.getCause().name());
+                            }
+                        } else {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("{} evicted from SshTool cache. Eviction cause: {}",
+                                        removed, notification.getCause().name());
+                            }
+                            try {
+                                removed.close();
+                            } catch (IOException e) {
+                                if (LOG.isDebugEnabled()) {
+                                    LOG.debug("Exception closing "+removed, e);
+                                }
+                            }
+                        }
+                    }
+                })
+                .build(new CacheLoader<Map<String, ?>, Pool<SshTool>>() {
+                    public Pool<SshTool> load(Map<String, ?> properties) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("{} building ssh pool for {} with properties: {}",
+                                    new Object[] {this, getSshHostAndPort(), properties});
+                        }
+                        return buildPool(properties);
+                    }
+                });
+
+        final Set<String> reusableSshProperties = ImmutableSet.copyOf(
+                Iterables.transform(REUSABLE_SSH_PROPS, new Function<ConfigKey<?>, String>() {
+                    @Override public String apply(ConfigKey<?> input) {
+                        return input.getName();
+                    }
+                }));
+        // Groovy-eclipse compiler refused to compile `KeyTransformingSameTypeLoadingCache.from(...)`
+        return new KeyTransformingSameTypeLoadingCache<Map<String, ?>, Pool<SshTool>>(
+                delegate,
+                new Function<Map<String, ?>, Map<String, ?>>() {
+                    @Override
+                    public Map<String, ?> apply(@Nullable Map<String, ?> input) {
+                        Map<String, Object> copy = new HashMap<String, Object>(input);
+                        copy.keySet().removeAll(reusableSshProperties);
+                        return copy;
+                    }
+                });
+    }
+
+    private BasicPool<SshTool> buildPool(final Map<String, ?> properties) {
+        return BasicPool.<SshTool>builder()
+                .name(getDisplayName()+"@"+address+":"+getPort()+
+                        (config().getRaw(SSH_HOST).isPresent() ? "("+getConfig(SSH_HOST)+":"+getConfig(SSH_PORT)+")" : "")+
+                        ":hash"+System.identityHashCode(this))
+                .supplier(new Supplier<SshTool>() {
+                        @Override public SshTool get() {
+                            return connectSsh(properties);
+                        }})
+                .viabilityChecker(new Predicate<SshTool>() {
+                        @Override public boolean apply(SshTool input) {
+                            return input != null && input.isConnected();
+                        }})
+                .closer(new Function<SshTool,Void>() {
+                        @Override public Void apply(SshTool input) {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("{} closing pool for {}", this, input);
+                            }
+                            try {
+                                input.disconnect();
+                            } catch (Exception e) {
+                                if (logSsh.isDebugEnabled()) logSsh.debug("On machine "+SshMachineLocation.this+", ssh-disconnect failed", e);
+                            }
+                            return null;
+                        }})
+                .build();
+    }
+
+    @Override
+    public SshMachineLocation configure(Map<?,?> properties) {
+        super.configure(properties);
+
+        // TODO Note that check for addresss!=null is done automatically in super-constructor, in FlagUtils.checkRequiredFields
+        // Yikes, dangerous code for accessing fields of sub-class in super-class' constructor! But getting away with it so far!
+
+        boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
+        if (!deferConstructionChecks) {
+            if (getDisplayName() == null) {
+                setDisplayName((truth(user) ? user+"@" : "") + address.getHostName());
+            }
+        }
+        return this;
+    }
+    
+    private transient final Object mutexSupportCreationLock = new Object();
+    protected WithMutexes getMutexSupport() {
+        synchronized (mutexSupportCreationLock) {
+            // create on demand so that it is not null after serialization
+            if (mutexSupport == null) {
+                mutexSupport = new MutexSupport();
+            }
+            return mutexSupport;
+        }
+    }
+    
+    protected void addSshPoolCacheCleanupTask() {
+        if (cleanupTask!=null && !cleanupTask.isDone()) {
+            return;
+        }
+        if (getManagementContext()==null || getManagementContext().getExecutionManager()==null) {
+            LOG.debug("No management context for "+this+"; ssh-pool cache will only be closed when machine is closed");
+            return;
+        }
+        
+        Callable<Task<?>> cleanupTaskFactory = new Callable<Task<?>>() {
+            @Override public Task<Void> call() {
+                return Tasks.<Void>builder().dynamic(false).tag(BrooklynTaskTags.TRANSIENT_TASK_TAG)
+                    .name("ssh-location cache cleaner").body(new Callable<Void>() {
+                    @Override public Void call() {
+                        try {
+                            if (sshPoolCacheOrNull != null) sshPoolCacheOrNull.cleanUp();
+                            if (!SshMachineLocation.this.isManaged()) {
+                                if (sshPoolCacheOrNull != null) sshPoolCacheOrNull.invalidateAll();
+                                cleanupTask.cancel(false);
+                                sshPoolCacheOrNull = null;
+                            }
+                            return null;
+                        } catch (Exception e) {
+                            // Don't rethrow: the behaviour of executionManager is different from a scheduledExecutorService,
+                            // if we throw an exception, then our task will never get executed again
+                            LOG.warn("Problem cleaning up ssh-pool-cache", e);
+                            return null;
+                        } catch (Throwable t) {
+                            LOG.warn("Problem cleaning up ssh-pool-cache (rethrowing)", t);
+                            throw Exceptions.propagate(t);
+                        }
+                    }}).build();
+            }
+        };
+        
+        Duration expiryDuration = getConfig(SSH_CACHE_EXPIRY_DURATION);
+        cleanupTask = getManagementContext().getExecutionManager().submit(new ScheduledTask(
+            MutableMap.of("displayName", "scheduled[ssh-location cache cleaner]"), cleanupTaskFactory).period(expiryDuration));
+    }
+    
+    // TODO close has been used for a long time to perform clean-up wanted on unmanagement, but that's not clear; 
+    // we should probably expose a mechanism such as that in Entity (or re-use Entity for locations!)
+    @Override
+    public void close() throws IOException {
+        if (sshPoolCacheOrNull != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("{} invalidating all entries in ssh pool cache. Final stats: {}", this, sshPoolCacheOrNull.stats());
+            }
+            sshPoolCacheOrNull.invalidateAll();
+        }
+        if (cleanupTask != null) {
+            cleanupTask.cancel(false);
+            cleanupTask = null;
+            sshPoolCacheOrNull = null;
+        }
+    }
+
+    // should not be necessary, and causes objects to be kept around a lot longer than desired
+//    @Override
+//    protected void finalize() throws Throwable {
+//        try {
+//            close();
+//        } finally {
+//            super.finalize();
+//        }
+//    }
+
+    @Override
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    @Override
+    public String getHostname() {
+        String hostname = address.getHostName();
+        return (hostname == null || hostname.equals(address.getHostAddress())) ? null : hostname;
+    }
+    
+    @Override
+    public Set<String> getPublicAddresses() {
+        return ImmutableSet.of(address.getHostAddress());
+    }
+    
+    @Override
+    public Set<String> getPrivateAddresses() {
+        Iterable<String> result = getConfig(PRIVATE_ADDRESSES);
+        return (result == null) ? ImmutableSet.<String>of() : ImmutableSet.copyOf(result);
+    }
+
+    public HostAndPort getSshHostAndPort() {
+        String host = getConfig(SSH_HOST);
+        if (host == null || Strings.isEmpty(host))
+            host = address.getHostName();
+        Integer port = getConfig(SSH_PORT);
+        if (port == null || port == 0)
+            port = 22;
+        return HostAndPort.fromParts(host, port);
+    }
+
+    public String getUser() {
+        if (!truth(user)) {
+            if (config().getLocalRaw(SshTool.PROP_USER).isPresent()) {
+                LOG.warn("User configuration for "+this+" set after deployment; deprecated behaviour may not be supported in future versions");
+            }
+            return getConfig(SshTool.PROP_USER);
+        }
+        return user;
+    }
+
+    /** port for SSHing */
+    public int getPort() {
+        return getConfig(SshTool.PROP_PORT);
+    }
+
+    protected <T> T execSsh(final Map<String, ?> props, final Function<ShellTool, T> task) {
+        final LoadingCache<Map<String, ?>, Pool<SshTool>> sshPoolCache = getSshPoolCache();
+        Pool<SshTool> pool = sshPoolCache.getUnchecked(props);
+        if (LOG.isTraceEnabled()) {
+            LOG.trace("{} execSsh got pool: {}", this, pool);
+        }
+
+        if (truth(props.get(CLOSE_CONNECTION.getName()))) {
+            Function<SshTool, T> close = new Function<SshTool, T>() {
+                @Override
+                public T apply(SshTool input) {
+                    T result = task.apply(input);
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("{} invalidating all sshPoolCache entries: {}", SshMachineLocation.this, sshPoolCache.stats().toString());
+                    }
+                    sshPoolCache.invalidateAll();
+                    sshPoolCache.cleanUp();
+                    return result;
+                }
+            };
+            return pool.exec(close);
+        } else {
+            return pool.exec(task);
+        }
+    }
+
+    protected SshTool connectSsh() {
+        return connectSsh(ImmutableMap.of());
+    }
+
+    protected boolean previouslyConnected = false;
+    protected SshTool connectSsh(Map props) {
+        try {
+            if (!truth(user)) {
+                String newUser = getUser();
+                if (LOG.isTraceEnabled()) LOG.trace("For "+this+", setting user in connectSsh: oldUser="+user+"; newUser="+newUser);
+                user = newUser;
+            }
+
+            ConfigBag args = new ConfigBag()
+                .configure(SshTool.PROP_USER, user)
+                // default value of host, overridden if SSH_HOST is supplied
+                .configure(SshTool.PROP_HOST, address.getHostName());
+
+            for (Map.Entry<String,Object> entry: config().getBag().getAllConfig().entrySet()) {
+                String key = entry.getKey();
+                if (key.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
+                    key = Strings.removeFromStart(key, SshTool.BROOKLYN_CONFIG_KEY_PREFIX);
+                } else if (ALL_SSH_CONFIG_KEY_NAMES.contains(entry.getKey())) {
+                    // key should be included, and does not need to be changed
+
+                    // TODO make this config-setting mechanism more universal
+                    // currently e.g. it will not admit a tool-specific property.
+                    // thinking either we know about the tool here,
+                    // or we don't allow unadorned keys to be set
+                    // (require use of BROOKLYN_CONFIG_KEY_PREFIX)
+                } else {
+                    // this key is not applicable here; ignore it
+                    continue;
+                }
+                args.putStringKey(key, entry.getValue());
+            }
+
+            // Explicit props trump all.
+            args.putAll(props);
+
+            if (LOG.isTraceEnabled()) LOG.trace("creating ssh session for "+args);
+            if (!user.equals(args.get(SshTool.PROP_USER))) {
+                LOG.warn("User mismatch configuring ssh for "+this+": preferring user "+args.get(SshTool.PROP_USER)+" over "+user);
+                user = args.get(SshTool.PROP_USER);
+            }
+
+            // look up tool class
+            String sshToolClass = args.get(SshTool.PROP_TOOL_CLASS);
+            if (sshToolClass==null) sshToolClass = SshjTool.class.getName();
+            SshTool ssh = (SshTool) Class.forName(sshToolClass).getConstructor(Map.class).newInstance(args.getAllConfig());
+
+            if (LOG.isTraceEnabled()) LOG.trace("using ssh-tool {} (of type {}); props ", ssh, sshToolClass);
+
+            Tasks.setBlockingDetails("Opening ssh connection");
+            try { ssh.connect(); } finally { Tasks.setBlockingDetails(null); }
+            previouslyConnected = true;
+            return ssh;
+        } catch (Exception e) {
+            if (previouslyConnected) throw Throwables.propagate(e);
+            // subsequence connection (above) most likely network failure, our remarks below won't help
+            // on first connection include additional information if we can't connect, to help with debugging
+            String rootCause = Throwables.getRootCause(e).getMessage();
+            throw new IllegalStateException("Cannot establish ssh connection to "+user+" @ "+this+
+                    (rootCause!=null && !rootCause.isEmpty() ? " ("+rootCause+")" : "")+". \n"+
+                    "Ensure that passwordless and passphraseless ssh access is enabled using standard keys from ~/.ssh or " +
+                    "as configured in brooklyn.properties. " +
+                    "Check that the target host is accessible, " +
+                    "that credentials are correct (location and permissions if using a key), " +
+                    "that the SFTP subsystem is available on the remote side, " +
+                    "and that there is sufficient random noise in /dev/random on both ends. " +
+                    "To debug less common causes, see the original error in the trace or log, and/or enable 'net.schmizz' (sshj) logging."
+                    , e);
+        }
+    }
+
+    // TODO submitCommands and submitScript which submit objects we can subsequently poll (cf JcloudsSshMachineLocation.submitRunScript)
+
+    /**
+     * Executes a set of commands, directly on the target machine (no wrapping in script).
+     * Joined using {@literal ;} by default.
+     * <p>
+     * Stdout and stderr will be logged automatically to brooklyn.SSH logger, unless the
+     * flags 'noStdoutLogging' and 'noStderrLogging' are set. To set a logging prefix, use
+     * the flag 'logPrefix'.
+     * <p>
+     * Currently runs the commands in an interactive/login shell
+     * by passing each as a line to bash. To terminate early, use:
+     * <pre>
+     * foo || exit 1
+     * </pre>
+     * It may be desirable instead, in some situations, to wrap as:
+     * <pre>
+     * { line1 ; } && { line2 ; } ...
+     * </pre>
+     * and run as a single command (possibly not as an interacitve/login
+     * shell) causing the script to exit on the first command which fails.
+     * <p>
+     * Currently this has to be done by the caller.
+     * (If desired we can add a flag {@code exitIfAnyNonZero} to support this mode,
+     * and/or {@code commandPrepend} and {@code commandAppend} similar to
+     * (currently supported in SshjTool) {@code separator}.)
+     */
+    public int execCommands(String summaryForLogging, List<String> commands) {
+        return execCommands(MutableMap.<String,Object>of(), summaryForLogging, commands, MutableMap.<String,Object>of());
+    }
+    public int execCommands(Map<String,?> props, String summaryForLogging, List<String> commands) {
+        return execCommands(props, summaryForLogging, commands, MutableMap.<String,Object>of());
+    }
+    public int execCommands(String summaryForLogging, List<String> commands, Map<String,?> env) {
+        return execCommands(MutableMap.<String,Object>of(), summaryForLogging, commands, env);
+    }
+    public int execCommands(Map<String,?> props, String summaryForLogging, List<String> commands, Map<String,?> env) {
+        return newExecWithLoggingHelpers().execCommands(augmentPropertiesWithSshConfigGivenToProps(props), summaryForLogging, commands, env);
+    }
+
+    /**
+     * Executes a set of commands, wrapped as a script sent to the remote machine.
+     * <p>
+     * Stdout and stderr will be logged automatically to brooklyn.SSH logger, unless the
+     * flags 'noStdoutLogging' and 'noStderrLogging' are set. To set a logging prefix, use
+     * the flag 'logPrefix'.
+     */
+    public int execScript(String summaryForLogging, List<String> commands) {
+        return execScript(MutableMap.<String,Object>of(), summaryForLogging, commands, MutableMap.<String,Object>of());
+    }
+    public int execScript(Map<String,?> props, String summaryForLogging, List<String> commands) {
+        return execScript(props, summaryForLogging, commands, MutableMap.<String,Object>of());
+    }
+    public int execScript(String summaryForLogging, List<String> commands, Map<String,?> env) {
+        return execScript(MutableMap.<String,Object>of(), summaryForLogging, commands, env);
+    }
+    public int execScript(Map<String,?> props, String summaryForLogging, List<String> commands, Map<String,?> env) {
+        return newExecWithLoggingHelpers().execScript(augmentPropertiesWithSshConfigGivenToProps(props), summaryForLogging, commands, env);
+    }
+
+    private Map<String, Object> augmentPropertiesWithSshConfigGivenToProps(Map<String, ?> props) {
+        Map<String,Object> augmentedProps = Maps.newHashMap(props);
+        for (ConfigKey<?> config : SSH_CONFIG_GIVEN_TO_PROPS) {
+            if (!augmentedProps.containsKey(config.getName()) && hasConfig(config, true))
+                augmentedProps.put(config.getName(), getConfig(config));
+        }
+        return augmentedProps;
+    }
+
+    protected ExecWithLoggingHelpers newExecWithLoggingHelpers() {
+        return new ExecWithLoggingHelpers("SSH") {
+            @Override
+            protected <T> T execWithTool(MutableMap<String, Object> props, Function<ShellTool, T> function) {
+                return execSsh(props, function);
+            }
+            @Override
+            protected void preExecChecks() {
+                Preconditions.checkNotNull(address, "host address must be specified for ssh");
+            }
+            @Override
+            protected String constructDefaultLoggingPrefix(ConfigBag execFlags) {
+                String hostname = getAddress().getHostName();
+                Integer port = execFlags.peek(SshTool.PROP_PORT);
+                if (port == null) port = getConfig(ConfigUtils.prefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, SshTool.PROP_PORT));
+                return (user != null ? user+"@" : "") + hostname + (port != null ? ":"+port : "");
+            }
+            @Override
+            protected String getTargetName() {
+                return ""+SshMachineLocation.this;
+            }
+        }.logger(logSsh);
+    }
+
+    /**
+     * @deprecated since 0.7.0; use {@link #execCommands(Map, String, List, Map), and rely on that calling the execWithLogging
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    @Deprecated
+    protected int execWithLogging(Map<String,?> props, String summaryForLogging, List<String> commands, Map env, final Closure<Integer> execCommand) {
+        return newExecWithLoggingHelpers().execWithLogging(props, summaryForLogging, commands, env, new ExecRunner() {
+                @Override public int exec(ShellTool ssh, Map<String, ?> flags, List<String> cmds, Map<String, ?> env) {
+                    return execCommand.call(ssh, flags, cmds, env);
+                }});
+    }
+
+    public int copyTo(File src, File destination) {
+        return copyTo(MutableMap.<String,Object>of(), src, destination);
+    }
+    public int copyTo(Map<String,?> props, File src, File destination) {
+        return copyTo(props, src, destination.getPath());
+    }
+
+    public int copyTo(File src, String destination) {
+        return copyTo(MutableMap.<String,Object>of(), src, destination);
+    }
+    public int copyTo(Map<String,?> props, File src, String destination) {
+        Preconditions.checkNotNull(address, "Host address must be specified for scp");
+        Preconditions.checkArgument(src.exists(), "File %s must exist for scp", src.getPath());
+        try {
+            return copyTo(props, new FileInputStream(src), src.length(), destination);
+        } catch (FileNotFoundException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+    public int copyTo(Reader src, String destination) {
+        return copyTo(MutableMap.<String,Object>of(), src, destination);
+    }
+    public int copyTo(Map<String,?> props, Reader src, String destination) {
+        return copyTo(props, new ReaderInputStream(src), destination);
+    }
+    public int copyTo(InputStream src, String destination) {
+        return copyTo(MutableMap.<String,Object>of(), src, destination);
+    }
+    public int copyTo(InputStream src, long filesize, String destination) {
+        return copyTo(MutableMap.<String,Object>of(), src, filesize, destination);
+    }
+    // FIXME the return code is not a reliable indicator of success or failure
+    public int copyTo(final Map<String,?> props, final InputStream src, final long filesize, final String destination) {
+        if (filesize == -1) {
+            return copyTo(props, src, destination);
+        } else {
+            return execSsh(props, new Function<ShellTool,Integer>() {
+                public Integer apply(ShellTool ssh) {
+                    return ((SshTool) ssh).copyToServer(props, new KnownSizeInputStream(src, filesize), destination);
+                }});
+        }
+    }
+    // FIXME the return code is not a reliable indicator of success or failure
+    // Closes input stream before returning
+    public int copyTo(final Map<String,?> props, final InputStream src, final String destination) {
+        return execSsh(props, new Function<ShellTool,Integer>() {
+            public Integer apply(ShellTool ssh) {
+                return ((SshTool)ssh).copyToServer(props, src, destination);
+            }});
+    }
+
+    // FIXME the return code is not a reliable indicator of success or failure
+    public int copyFrom(String remote, String local) {
+        return copyFrom(MutableMap.<String,Object>of(), remote, local);
+    }
+    public int copyFrom(final Map<String,?> props, final String remote, final String local) {
+        return execSsh(props, new Function<ShellTool,Integer>() {
+            public Integer apply(ShellTool ssh) {
+                return ((SshTool)ssh).copyFromServer(props, remote, new File(local));
+            }});
+    }
+
+    public int installTo(String url, String destPath) {
+        return installTo(MutableMap.<String, Object>of(), url, destPath);
+    }
+
+    public int installTo(Map<String,?> props, String url, String destPath) {
+        return installTo(ResourceUtils.create(this), props, url, destPath);
+    }
+
+    public int installTo(ResourceUtils loader, String url, String destPath) {
+        return installTo(loader, MutableMap.<String, Object>of(), url, destPath);
+    }
+
+    /**
+     * Installs the given URL at the indicated destination path.
+     * <p>
+     * Attempts to curl the source URL on the remote machine,
+     * then if that fails, loads locally (from classpath or file) and transfers.
+     * <p>
+     * Use {@link ArchiveUtils} to handle directories and their contents properly.
+     *
+     * TODO allow s3://bucket/file URIs for AWS S3 resources
+     * TODO use PAX-URL style URIs for maven artifacts
+     * TODO use subtasks here for greater visibility?; deprecate in favour of SshTasks.installFromUrl?
+     *
+     * @param utils A {@link ResourceUtils} that can resolve the source URLs
+     * @param url The source URL to be installed
+     * @param destPath The file to be created on the destination
+     *
+     * @see ArchiveUtils#deploy(String, SshMachineLocation, String)
+     * @see ArchiveUtils#deploy(String, SshMachineLocation, String, String)
+     * @see ResourceUtils#getResourceFromUrl(String)
+     */
+    public int installTo(ResourceUtils utils, Map<String,?> props, String url, String destPath) {
+        LOG.debug("installing {} to {} on {}, attempting remote curl", new Object[] { url, destPath, this });
+
+        try {
+            PipedInputStream insO = new PipedInputStream(); OutputStream outO = new PipedOutputStream(insO);
+            PipedInputStream insE = new PipedInputStream(); OutputStream outE = new PipedOutputStream(insE);
+            StreamGobbler sgsO = new StreamGobbler(insO, null, LOG); sgsO.setLogPrefix("[curl @ "+address+":stdout] ").start();
+            StreamGobbler sgsE = new StreamGobbler(insE, null, LOG); sgsE.setLogPrefix("[curl @ "+address+":stdout] ").start();
+            Map<String, ?> sshProps = MutableMap.<String, Object>builder().putAll(props).put("out", outO).put("err", outE).build();
+            int result = execScript(sshProps, "copying remote resource "+url+" to server",  ImmutableList.of(
+                    BashCommands.INSTALL_CURL, // TODO should hold the 'installing' mutex
+                    "mkdir -p `dirname '"+destPath+"'`",
+                    "curl "+url+" -L --silent --insecure --show-error --fail --connect-timeout 60 --max-time 600 --retry 5 -o '"+destPath+"'"));
+            sgsO.close();
+            sgsE.close();
+            if (result != 0) {
+                LOG.debug("installing {} to {} on {}, curl failed, attempting local fetch and copy", new Object[] { url, destPath, this });
+                try {
+                    Tasks.setBlockingDetails("retrieving resource "+url+" for copying across");
+                    InputStream stream = utils.getResourceFromUrl(url);
+                    Tasks.setBlockingDetails("copying resource "+url+" to server");
+                    result = copyTo(props, stream, destPath);
+                } finally {
+                    Tasks.setBlockingDetails(null);
+                }
+            }
+            if (result == 0) {
+                LOG.debug("installing {} complete; {} on {}", new Object[] { url, destPath, this });
+            } else {
+                LOG.warn("installing {} failed; {} on {}: {}", new Object[] { url, destPath, this, result });
+            }
+            return result;
+        } catch (IOException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "SshMachineLocation["+getDisplayName()+":"+address+":"+getPort()+"@"+getId()+"]";
+    }
+
+    @Override
+    public String toVerboseString() {
+        return Objects.toStringHelper(this).omitNullValues()
+                .add("id", getId()).add("name", getDisplayName())
+                .add("user", getUser()).add("address", getAddress()).add("port", getPort())
+                .add("parentLocation", getParent())
+                .toString();
+    }
+
+    /**
+     * @see #obtainPort(PortRange)
+     * @see PortRanges#ANY_HIGH_PORT
+     */
+    @Override
+    public boolean obtainSpecificPort(int portNumber) {
+        synchronized (usedPorts) {
+            // TODO Does not yet check if the port really is free on this machine
+            if (usedPorts.contains(portNumber)) {
+                return false;
+            } else {
+                usedPorts.add(portNumber);
+                return true;
+            }
+        }
+    }
+
+    @Override
+    public int obtainPort(PortRange range) {
+        synchronized (usedPorts) {
+            for (int p: range)
+                if (obtainSpecificPort(p)) return p;
+            if (LOG.isDebugEnabled()) LOG.debug("unable to find port in {} on {}; returning -1", range, this);
+            return -1;
+        }
+    }
+
+    @Override
+    public void releasePort(int portNumber) {
+        synchronized (usedPorts) {
+            usedPorts.remove((Object) portNumber);
+        }
+    }
+
+    public boolean isSshable() {
+        String cmd = "date";
+        try {
+            try {
+                Socket s = new Socket();
+                s.connect(new InetSocketAddress(getAddress(), getPort()), SSHABLE_CONNECT_TIMEOUT);
+                s.close();
+            } catch (IOException e) {
+                if (LOG.isDebugEnabled()) LOG.debug(""+this+" not [yet] reachable (socket "+getAddress()+":"+getPort()+"): "+e);
+                return false;
+            }
+            // this should do execCommands because sftp subsystem might not be available (or sometimes seems to take a while for it to become so?)
+            int result = execCommands(MutableMap.<String,Object>of(), "isSshable", ImmutableList.of(cmd));
+            if (result == 0) {
+                return true;
+            } else {
+                if (LOG.isDebugEnabled()) LOG.debug("Not reachable: {}, executing `{}`, exit code {}", new Object[] {this, cmd, result});
+                return false;
+            }
+        } catch (SshException e) {
+            if (LOG.isDebugEnabled()) LOG.debug("Exception checking if "+this+" is reachable; assuming not", e);
+            return false;
+        } catch (IllegalStateException e) {
+            if (LOG.isDebugEnabled()) LOG.debug("Exception checking if "+this+" is reachable; assuming not", e);
+            return false;
+        } catch (RuntimeException e) {
+            if (Exceptions.getFirstThrowableOfType(e, IOException.class) != null) {
+                if (LOG.isDebugEnabled()) LOG.debug("Exception checking if "+this+" is reachable; assuming not", e);
+                return false;
+            } else {
+                throw e;
+            }
+        }
+    }
+
+    @Override
+    public OsDetails getOsDetails() {
+        return getMachineDetails().getOsDetails();
+    }
+
+    @Override
+    public MachineDetails getMachineDetails() {
+        synchronized (machineDetailsLock) {
+            if (machineDetails == null) {
+                machineDetails = getConfig(MACHINE_DETAILS);
+            }
+            if (machineDetails == null) {
+                machineDetails = inferMachineDetails();
+            }
+        }
+        return machineDetails;
+    }
+
+    protected MachineDetails inferMachineDetails() {
+        boolean detectionEnabled = getConfig(DETECT_MACHINE_DETAILS);
+        if (!detectionEnabled)
+            return new BasicMachineDetails(new BasicHardwareDetails(-1, -1), new BasicOsDetails("UNKNOWN", "UNKNOWN", "UNKNOWN"));
+
+        Tasks.setBlockingDetails("Waiting for machine details");
+        try {
+            return BasicMachineDetails.forSshMachineLocation(this);
+        } finally {
+            Tasks.resetBlockingDetails();
+        }
+    }
+
+    @Override
+    public void acquireMutex(String mutexId, String description) throws RuntimeInterruptedException {
+        try {
+            getMutexSupport().acquireMutex(mutexId, description);
+        } catch (InterruptedException ie) {
+            throw new RuntimeInterruptedException("Interrupted waiting for mutex: " + mutexId, ie);
+        }
+    }
+
+    @Override
+    public boolean tryAcquireMutex(String mutexId, String description) {
+        return getMutexSupport().tryAcquireMutex(mutexId, description);
+    }
+
+    @Override
+    public void releaseMutex(String mutexId) {
+        getMutexSupport().releaseMutex(mutexId);
+    }
+
+    @Override
+    public boolean hasMutex(String mutexId) {
+        return getMutexSupport().hasMutex(mutexId);
+    }
+
+    //We want the SshMachineLocation to be serializable and therefore the pool needs to be dealt with correctly.
+    //In this case we are not serializing the pool (we made the field transient) and create a new pool when deserialized.
+    //This fix is currently needed for experiments, but isn't used in normal Brooklyn usage.
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        getSshPoolCache();
+    }
+
+    /** returns the un-passphrased key-pair info if a key is being used, or else null */
+    public KeyPair findKeyPair() {
+        String fn = getConfig(SshTool.PROP_PRIVATE_KEY_FILE);
+        ResourceUtils r = ResourceUtils.create(this);
+        if (fn!=null) return SecureKeys.readPem(r.getResourceFromUrl(fn), getConfig(SshTool.PROP_PRIVATE_KEY_PASSPHRASE));
+        String data = getConfig(SshTool.PROP_PRIVATE_KEY_DATA);
+        if (data!=null) return SecureKeys.readPem(new ReaderInputStream(new StringReader(data)), getConfig(SshTool.PROP_PRIVATE_KEY_PASSPHRASE));
+        if (findPassword()!=null)
+            // if above not specified, and password is, use password
+            return null;
+        // fall back to id_rsa and id_dsa
+        if (new File( Urls.mergePaths(System.getProperty("user.home"), ".ssh/id_rsa") ).exists() )
+            return SecureKeys.readPem(r.getResourceFromUrl("~/.ssh/id_rsa"), getConfig(SshTool.PROP_PRIVATE_KEY_PASSPHRASE));
+        if (new File( Urls.mergePaths(System.getProperty("user.home"), ".ssh/id_dsa") ).exists() )
+            return SecureKeys.readPem(r.getResourceFromUrl("~/.ssh/id_dsa"), getConfig(SshTool.PROP_PRIVATE_KEY_PASSPHRASE));
+        LOG.warn("Unable to extract any key or passphrase data in request to findKeyPair for "+this);
+        return null;
+    }
+
+    /** returns the password being used to log in, if a password is being used, or else null */
+    public String findPassword() {
+        return getConfig(SshTool.PROP_PASSWORD);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/SupportsPortForwarding.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/SupportsPortForwarding.java b/core/src/main/java/org/apache/brooklyn/location/basic/SupportsPortForwarding.java
new file mode 100644
index 0000000..8c26506
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/SupportsPortForwarding.java
@@ -0,0 +1,39 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import brooklyn.util.net.Cidr;
+
+import com.google.common.net.HostAndPort;
+
+public interface SupportsPortForwarding {
+
+    /** returns an endpoint suitable for contacting the indicated private port on this object,
+     * from the given Cidr, creating it if necessary and possible; 
+     * may return null if forwarding not available 
+     */
+    public HostAndPort getSocketEndpointFor(Cidr accessor, int privatePort);
+    
+    /** marker on a location to indicate that port forwarding should be done automatically
+     * for attempts to access from Brooklyn
+     */
+    public interface RequiresPortForwarding extends SupportsPortForwarding {
+    }
+    
+}


[17/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java
deleted file mode 100644
index e5696c2..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.templates;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.OsFamily;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.options.TemplateOptions;
-
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-
-public abstract class AbstractPortableTemplateBuilder<T extends AbstractPortableTemplateBuilder<?>> implements TemplateBuilder {
-
-    /** list of commands supplied by user, excluding options */
-    protected List<Function<TemplateBuilder,TemplateBuilder>> commands = new ArrayList<Function<TemplateBuilder,TemplateBuilder>>();
-    
-    private Hardware hardware;
-    private Image image;
-    private Template template;
-    private String locationId;
-    private String imageId;
-    private String hardwareId;
-    private OsFamily os;
-    private String osNameRegex;
-    private String osDescriptionRegex;
-    private String osVersionRegex;
-    private String osArchitectureRegex;
-    private String hypervisorRegex;
-    private Boolean is64bit;
-    private String imageNameRegex;
-    private String imageDescriptionRegex;
-    private String imageVersionRegex;
-    private Double minCores;
-    private Integer minRam;
-    private Double minDisk;
-    private Predicate<Image> imageCondition;
-    private Function<Iterable<? extends Image>, Image> imageChooserFunction;
-    /** this is the last options instance set by a call to options(TemplateOptions) */
-    private TemplateOptions options;
-    /** these are extra options that we want _added_, in order, on top of the last options set */
-    private List<TemplateOptions> additionalOptions = new ArrayList<TemplateOptions>();
-    
-    @Override
-    public T any() {
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.any(); }});
-        return (T)this;
-    }
-
-    @Override
-    public T fromHardware(final Hardware hardware) {
-        this.hardware = hardware;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.fromHardware(hardware); }});
-        return (T)this;
-    }
-
-    public Hardware getHardware() {
-        return hardware;
-    }
-
-    @Override
-    public T fromImage(final Image image) {
-        this.image = image;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.fromImage(image); }});
-        return (T)this;
-    }
-    
-    public Image getImage() {
-        return image;
-    }
-
-    @Override
-    public T fromTemplate(final Template template) {
-        this.template = template;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.fromTemplate(template); }});
-        return (T)this;
-    }
-    
-    public Template getTemplate() {
-        return template;
-    }
-
-    @Override
-    public T smallest() {
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.smallest(); }});
-        return (T)this;
-    }
-
-    @Override
-    public T fastest() {
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.fastest(); }});
-        return (T)this;
-    }
-
-    @Override
-    public T biggest() {
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.biggest(); }});
-        return (T)this;
-    }
-
-    @Override
-    public T locationId(final String locationId) {
-        this.locationId = locationId;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.locationId(locationId); }});
-        return (T)this;
-    }
-    
-    public String getLocationId() {
-        return locationId;
-    }
-
-    @Override
-    public T imageId(final String imageId) {
-        this.imageId = imageId;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.imageId(imageId); }});
-        return (T)this;
-    }
-    
-    public String getImageId() {
-        return imageId;
-    }
-
-    @Override
-    public T hardwareId(final String hardwareId) {
-        this.hardwareId = hardwareId;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.hardwareId(hardwareId); }});
-        return (T)this;
-    }
-    
-    public String getHardwareId() {
-        return hardwareId;
-    }
-
-    @Override
-    public T osNameMatches(final String osNameRegex) {
-        this.osNameRegex = osNameRegex;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.osNameMatches(osNameRegex); }});
-        return (T)this;
-    }
-    
-    public String getOsNameMatchesRegex() {
-        return osNameRegex;
-    }
-
-    @Override
-    public T osDescriptionMatches(final String osDescriptionRegex) {
-        this.osDescriptionRegex = osDescriptionRegex;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.osDescriptionMatches(osDescriptionRegex); }});
-        return (T)this;
-    }
-    
-    public String getOsDescriptionMatchesRegex() {
-        return osDescriptionRegex;
-    }
-
-    @Override
-    public T osVersionMatches(final String osVersionRegex) {
-        this.osVersionRegex = osVersionRegex;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.osVersionMatches(osVersionRegex); }});
-        return (T)this;
-    }
-    
-    public String getOsVersionMatchesRegex() {
-        return osVersionRegex;
-    }
-
-    @Override
-    public T osArchMatches(final String osArchitectureRegex) {
-        this.osArchitectureRegex = osArchitectureRegex;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.osArchMatches(osArchitectureRegex); }});
-        return (T)this;
-    }
-    
-    public String getOsArchitectureMatchesRegex() {
-        return osArchitectureRegex;
-    }
-
-    @Override
-    public T os64Bit(final boolean is64bit) {
-        this.is64bit = is64bit;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.os64Bit(is64bit); }});
-        return (T)this;
-    }
-    
-    public Boolean getIs64bit() {
-        return is64bit;
-    }
-
-    @Override
-    public T osFamily(final OsFamily os) {
-        this.os = os;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.osFamily(os); }});
-        return (T)this;
-    }
-    
-    public OsFamily getOsFamily() {
-        return os;
-    }
-
-    @Override
-    public T hypervisorMatches(final String hypervisorRegex) {
-        this.hypervisorRegex = hypervisorRegex;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.hypervisorMatches(hypervisorRegex); }});
-        return (T)this;
-    }
-    
-    public String getHypervisorMatchesRegex() {
-        return hypervisorRegex;
-    }
-
-    @Override
-    public T imageNameMatches(final String imageNameRegex) {
-        this.imageNameRegex = imageNameRegex;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.imageNameMatches(imageNameRegex); }});
-        return (T)this;
-    }
-    
-    public String getImageNameMatchesRegex() {
-        return imageNameRegex;
-    }
-
-    @Override
-    public T imageDescriptionMatches(final String imageDescriptionRegex) {
-        this.imageDescriptionRegex = imageDescriptionRegex;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.imageDescriptionMatches(imageDescriptionRegex); }});
-        return (T)this;
-    }
-    
-    public String getImageDescriptionMatchesRegex() {
-        return imageDescriptionRegex;
-    }
-
-    @Override
-    public T imageVersionMatches(final String imageVersionRegex) {
-        this.imageVersionRegex = imageVersionRegex;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.imageVersionMatches(imageVersionRegex); }});
-        return (T)this;
-    }
-    
-    public String getImageVersionMatchesRegex() {
-        return imageVersionRegex;
-    }
-    
-    @Override
-    public T imageMatches(final Predicate<Image> condition) {
-        this.imageCondition = condition;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.imageMatches(condition); }});
-        return (T)this;
-    }
-    
-    public Predicate<Image> getImageMatchesCondition() {
-        return imageCondition;
-    }
-
-    @Override
-    public T minCores(final double minCores) {
-        this.minCores = minCores;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.minCores(minCores); }});
-        return (T)this;
-    }
-    
-    public Double getMinCores() {
-        return minCores;
-    }
-
-    @Override
-    public T minRam(final int megabytes) {
-        this.minRam = megabytes;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.minRam(megabytes); }});
-        return (T)this;
-    }
-    
-    /** megabytes */
-    public Integer getMinRam() {
-        return minRam;
-    }
-    
-    @Override
-    public T minDisk(final double gigabytes) {
-        this.minDisk = gigabytes;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.minDisk(gigabytes); }});
-        return (T)this;
-    }
-
-    /** megabytes */
-    public Double getMinDisk() {
-        return minDisk;
-    }
-
-    public T imageChooser(final Function<Iterable<? extends Image>, Image> imageChooserFunction) {
-        this.imageChooserFunction = imageChooserFunction;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.imageChooser(imageChooserFunction); }});
-        return (T)this;
-    }
-    
-    public Function<Iterable<? extends Image>, Image> imageChooser() {
-        return imageChooserFunction;
-    }
-
-    /** clears everything set in this template, including any default from the compute service */
-    // not sure this is that useful, as the default is only applied if there are no changes
-    public T blank() {
-        hardware = null;
-        image = null;
-        template = null;
-        hypervisorRegex = null;
-        os = null;
-        locationId = null;
-        imageId = null;
-        hardwareId = null;
-        osNameRegex = null;
-        osDescriptionRegex = null;
-        osVersionRegex = null;
-        osArchitectureRegex = null;
-        is64bit = null;
-        imageNameRegex = null;
-        imageDescriptionRegex = null;
-        imageVersionRegex = null;
-        imageCondition = null;
-        minCores = null;
-        minRam = null;
-        options = null;
-        additionalOptions.clear();
-
-        // clear all fields, and commands
-        commands.clear();
-        // then add a command to clear osName + Version + 64bit
-        osFamily(null);
-        osVersionMatches(null);
-        // no way to turn off 64-bitness, but it won't usually be turned on
-//        os64bit(null);
-        // set _something_ to prevent the default from applying
-        minRam(1);
-
-        return (T)this;
-    }
-    
-    /** true if the templateBuilder spec is blank (ignoring customization options e.g. tags for the resulting instance) */
-    public boolean isBlank() {
-        if (commands.isEmpty()) return true;
-        //also "blank" if we've blanked it
-        if (commands.size()==1 && (minRam!=null && minRam==1)) return true;
-        return false;
-    }
-    
-    @Override
-    public T options(final TemplateOptions options) {
-        this.options = options;
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.options(options); }});
-        return (T)this;
-    }
-
-    /** sets customization options; may be null if not set. use addOptions(new TemplateOptions()) to set new ones. */
-    public TemplateOptions getOptions() {
-        return options;
-    }
-    
-    /** adds customization options; if options have already been set, this will additively set selected options
-     * (but not all, see addTemplateOptions for more info)
-     */
-    public T addOptions(final TemplateOptions options) {
-        this.additionalOptions.add(options);
-        commands.add(new Function<TemplateBuilder,TemplateBuilder>() { 
-            public TemplateBuilder apply(TemplateBuilder b) { return b.options(options); }});
-        return (T)this;
-    }
-
-    public List<TemplateOptions> getAdditionalOptions() {
-        return ImmutableList.copyOf(additionalOptions);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(
-                hypervisorRegex,
-                os,
-                locationId,
-                hardwareId,
-                imageId,
-                imageDescriptionRegex,
-                imageNameRegex,
-                imageVersionRegex,
-                // might not be implement hashCode, so ignore
-//                imageCondition,
-//                imageChooserFunction,
-                is64bit,
-                locationId,
-                osArchitectureRegex,
-                osDescriptionRegex,
-                osNameRegex,
-                osVersionRegex,
-                minCores,
-                minRam,
-                minDisk,
-                options,
-                additionalOptions,
-                // might not implement hashCode, so ignore
-//                template,
-                0);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        AbstractPortableTemplateBuilder other = (AbstractPortableTemplateBuilder) obj;
-        if (!Objects.equal(additionalOptions, other.additionalOptions)) return false;
-        if (!Objects.equal(commands, other.commands)) return false;
-        if (!Objects.equal(locationId, other.locationId)) return false;
-        if (!Objects.equal(hardware, other.hardware)) return false;
-        if (!Objects.equal(hardwareId, other.hardwareId)) return false;
-        if (!Objects.equal(image, other.image)) return false;
-        if (!Objects.equal(imageId, other.imageId)) return false;
-        if (!Objects.equal(imageDescriptionRegex, other.imageDescriptionRegex)) return false;
-        if (!Objects.equal(imageNameRegex, other.imageNameRegex)) return false;
-        if (!Objects.equal(imageVersionRegex, other.imageVersionRegex)) return false;
-        if (!Objects.equal(imageCondition, other.imageCondition)) return false;
-        if (!Objects.equal(imageChooserFunction, other.imageChooserFunction)) return false;
-        if (!Objects.equal(os, other.os)) return false;
-        if (!Objects.equal(osArchitectureRegex, other.osArchitectureRegex)) return false;
-        if (!Objects.equal(osDescriptionRegex, other.osDescriptionRegex)) return false;
-        if (!Objects.equal(osNameRegex, other.osNameRegex)) return false;
-        if (!Objects.equal(osVersionRegex, other.osVersionRegex)) return false;
-        if (!Objects.equal(is64bit, other.is64bit)) return false;
-        if (!Objects.equal(hypervisorRegex, other.hypervisorRegex)) return false;
-        if (!Objects.equal(minCores, other.minCores)) return false;
-        if (!Objects.equal(minRam, other.minRam)) return false;
-        if (!Objects.equal(minDisk, other.minDisk)) return false;
-        if (!Objects.equal(options, other.options)) return false;
-        if (!Objects.equal(template, other.template)) return false;
-        return true;
-    }
-    
-    @Override
-    public String toString() {
-        return getClass().getSimpleName()+"["+makeNonTrivialArgumentsString()+"]";
-    }
-
-    protected String makeNonTrivialArgumentsString() {
-        String s =
-                  (hardware != null ? "hardware=" + hardware + ", " : "")
-                + (image != null ? "image=" + image + ", " : "")
-                + (template != null ? "template=" + template + ", " : "")
-                + (hypervisorRegex != null ? "hypervisorRegex="
-                        + hypervisorRegex + ", " : "")
-                + (os != null ? "os=" + os + ", " : "")
-                + (locationId != null ? "locationId=" + locationId + ", " : "")
-                + (imageId != null ? "imageId=" + imageId + ", " : "")
-                + (hardwareId != null ? "hardwareId=" + hardwareId + ", " : "")
-                + (osNameRegex != null ? "osNameRegex=" + osNameRegex + ", "
-                        : "")
-                + (osDescriptionRegex != null ? "osDescriptionRegex="
-                        + osDescriptionRegex + ", " : "")
-                + (osVersionRegex != null ? "osVersionRegex=" + osVersionRegex
-                        + ", " : "")
-                + (osArchitectureRegex != null ? "osArchictectureRegex="
-                        + osArchitectureRegex + ", " : "")
-                + (is64bit != null ? "is64bit=" + is64bit + ", " : "")
-                + (imageNameRegex != null ? "imageNameRegex=" + imageNameRegex
-                        + ", " : "")
-                + (imageDescriptionRegex != null ? "imageDescriptionRegex="
-                        + imageDescriptionRegex + ", " : "")
-                + (imageVersionRegex != null ? "imageVersionRegex="
-                        + imageVersionRegex + ", " : "")
-                + (imageCondition != null ? "imageCondition=" + imageCondition
-                        + ", " : "")
-                + (imageChooserFunction != null ? "imageChooserFunction=" + imageChooserFunction
-                        + ", " : "")
-                + (minCores != null ? "minCores=" + minCores + ", " : "")
-                + (minRam != null ? "minRam=" + minRam + ", " : "")
-                + (minDisk != null ? "minDisk=" + minDisk + ", " : "");
-        if (s.endsWith(", ")) s = s.substring(0, s.length()-2);
-        return s;
-    }    
-
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java
deleted file mode 100644
index 3baa003..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.templates;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.domain.TemplateBuilderSpec;
-import org.jclouds.compute.options.TemplateOptions;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.primitives.Ints;
-
-
-public class PortableTemplateBuilder<T extends PortableTemplateBuilder<?>> extends AbstractPortableTemplateBuilder<T> {
-    
-    ComputeService svc;
-    List<TemplateOptions> additionalOptionalOptions = new ArrayList<TemplateOptions>();
-
-    @Override
-    public synchronized Template build() {
-        if (svc!=null) return newJcloudsTemplate(svc);
-        throw new IllegalStateException("Cannot build a portable template until a compute service is attached");
-    }
-    
-    public synchronized ComputeService attachComputeService(ComputeService svc) {
-        ComputeService old = this.svc;
-        this.svc = svc;
-        return old;
-    }
-
-    public TemplateBuilder newJcloudsTemplateBuilder(ComputeService svc) {
-        TemplateBuilder tb = svc.templateBuilder();
-        for (Function<TemplateBuilder,TemplateBuilder> c: commands) {
-            tb = c.apply(tb);
-        }
-        
-        tb.options(computeAggregatedOptions(true));
-        
-        return tb;
-    }
-
-    public Template newJcloudsTemplate(ComputeService svc) {
-        return newJcloudsTemplateBuilder(svc).build();
-    }
-
-    /** Adds template options which are used for building, but not for matching/filtering. 
-     * (eg tags added here will be set on any machine created by this template,
-     * but will not be required when matching this template to existing machines) */
-    @SuppressWarnings("unchecked")
-    public T addOptionalOptions(TemplateOptions options) {
-        additionalOptionalOptions.add(options);
-        return (T)this;
-    }
-    
-    protected TemplateOptions computeAggregatedOptions(boolean includeOptional) {
-        TemplateOptions result;
-        if (getOptions()!=null) result = getOptions().clone();
-        else result = new TemplateOptions();
-        if (includeOptional)
-            for (TemplateOptions moreOptions: getAdditionalOptionalOptions()) result = addTemplateOptions(result, moreOptions);
-        for (TemplateOptions moreOptions: getAdditionalOptions()) result = addTemplateOptions(result, moreOptions);
-        return result;
-    }
-    
-    public List<TemplateOptions> getAdditionalOptionalOptions() {
-        return ImmutableList.copyOf(additionalOptionalOptions);
-    }
-    
-    /** like TemplateOptions.copyTo but additive wrt arrays, collections, and maps,
-     * putting moreOptions in on top of / at the end of options.
-     * currently applies to inboundPorts, tags, and userMetadata. */
-    public static TemplateOptions addTemplateOptions(TemplateOptions options, TemplateOptions moreOptions) {
-        TemplateOptions result = options.clone();
-        moreOptions.copyTo(result);
-        
-        Set<String> tags = new LinkedHashSet<String>(options.getTags());
-        tags.addAll(moreOptions.getTags());
-        result.tags(tags);
-
-        Map<String,String> userMetadata = new LinkedHashMap<String,String>(options.getUserMetadata());
-        userMetadata.putAll(moreOptions.getUserMetadata());
-        result.userMetadata(userMetadata);
-        
-        Set<Integer> inboundPorts = new TreeSet<Integer>();
-        for (int port: options.getInboundPorts()) inboundPorts.add(port);
-        for (int port: moreOptions.getInboundPorts()) inboundPorts.add(port);
-        int[] inboundPortsArray = new int[inboundPorts.size()];
-        int i=0;
-        for (Iterator<Integer> portI=inboundPorts.iterator(); portI.hasNext();) {
-            inboundPortsArray[i++] = portI.next();
-        }
-        result.inboundPorts(inboundPortsArray);
-        
-        return result;
-    }
-
-    protected String makeNonTrivialArgumentsString() {
-        String s = super.makeNonTrivialArgumentsString();
-        TemplateOptions aggr = computeAggregatedOptions(false);
-        if (aggr.getInboundPorts().length>0) s = "ports="+Ints.asList(aggr.getInboundPorts())+(s!=null && s.length()>0 ? ", "+s : "");
-        if (!aggr.getUserMetadata().isEmpty()) s = "metadata="+aggr.getUserMetadata()+(s!=null && s.length()>0 ? ", "+s : "");
-        if (!aggr.getTags().isEmpty()) s = "tags="+aggr.getTags()+(s!=null && s.length()>0 ? ", "+s : "");
-        return s;
-    }
-    
-    @Override
-    public TemplateBuilder from(TemplateBuilderSpec spec) {
-        TemplateOptions options = new TemplateOptions();
-        addOptionalOptions(options);
-        TemplateBuilder result = spec.copyTo(this, options);
-        return result;
-    }
-
-    @Override
-    public TemplateBuilder from(String spec) {
-        return from(TemplateBuilderSpec.parse(spec));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
deleted file mode 100644
index 20bfb4c..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.zone;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-import java.util.Set;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.jclouds.aws.ec2.AWSEC2Api;
-import org.jclouds.ec2.domain.AvailabilityZoneInfo;
-
-import brooklyn.location.Location;
-import brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
-import brooklyn.location.cloud.AvailabilityZoneExtension;
-import brooklyn.location.jclouds.JcloudsLocation;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-
-public class AwsAvailabilityZoneExtension extends AbstractAvailabilityZoneExtension implements AvailabilityZoneExtension {
-
-    private final JcloudsLocation loc;
-    
-    public AwsAvailabilityZoneExtension(ManagementContext managementContext, JcloudsLocation loc) {
-        super(managementContext);
-        this.loc = checkNotNull(loc, "loc");
-        checkArgument(loc.getProvider().equals("aws-ec2"), "provider not aws-ec2 (%s)", loc.getProvider());
-    }
-
-    @Override
-    protected List<Location> doGetAllSubLocations() {
-        List<Location> result = Lists.newArrayList();
-        Set<AvailabilityZoneInfo> zones = getAvailabilityZones();
-        for (AvailabilityZoneInfo zone : zones) {
-            result.add(newSubLocation(loc, zone));
-        }
-        return result;
-    }
-    
-    @Override
-    protected boolean isNameMatch(Location loc, Predicate<? super String> namePredicate) {
-        return namePredicate.apply(((JcloudsLocation)loc).getRegion());
-    }
-    
-    protected Set<AvailabilityZoneInfo> getAvailabilityZones() {
-        String regionName = loc.getRegion();
-        AWSEC2Api ec2Client = loc.getComputeService().getContext().unwrapApi(AWSEC2Api.class);
-        return ec2Client.getAvailabilityZoneAndRegionApi().get().describeAvailabilityZonesInRegion(regionName);
-    }
-    
-    protected JcloudsLocation newSubLocation(Location parent, AvailabilityZoneInfo zone) {
-        return loc.newSubLocation(ImmutableMap.of(JcloudsLocation.CLOUD_REGION_ID, zone.getZone()));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java b/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java
index f0d1140..bd02f60 100644
--- a/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java
+++ b/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java
@@ -28,8 +28,8 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 import brooklyn.policy.basic.AbstractPolicy;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java b/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java
index 2459187..4e2f68c 100644
--- a/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java
+++ b/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java
@@ -37,8 +37,8 @@ import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.internal.ssh.SshTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsSubnetSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsSubnetSshMachineLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsSubnetSshMachineLocation.java
new file mode 100644
index 0000000..c21810d
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/AbstractJcloudsSubnetSshMachineLocation.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.jclouds;
+
+import java.util.Map;
+
+import org.jclouds.compute.domain.NodeMetadata;
+
+import org.apache.brooklyn.location.basic.SupportsPortForwarding.RequiresPortForwarding;
+
+public abstract class AbstractJcloudsSubnetSshMachineLocation extends JcloudsSshMachineLocation implements RequiresPortForwarding {
+
+    public AbstractJcloudsSubnetSshMachineLocation() {
+    }
+
+    /** @deprecated since 0.6.0 use no-arg constructor, as per parent */
+    @Deprecated
+    public AbstractJcloudsSubnetSshMachineLocation(Map flags, JcloudsLocation parent, NodeMetadata node) {
+        super(flags, parent, node);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BasicJcloudsLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BasicJcloudsLocationCustomizer.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BasicJcloudsLocationCustomizer.java
new file mode 100644
index 0000000..e73d5f7
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BasicJcloudsLocationCustomizer.java
@@ -0,0 +1,99 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.annotations.Beta;
+
+
+/**
+ * A default no-op implementation, which can be extended to override the appropriate methods.
+ * 
+ * Sub-classing will give the user some protection against future API changes - note that 
+ * {@link JcloudsLocationCustomizer} is marked {@link Beta}.
+ * 
+ * @author aled
+ */
+public class BasicJcloudsLocationCustomizer implements JcloudsLocationCustomizer {
+
+    @Override
+    public void customize(JcloudsLocation location, ComputeService computeService, TemplateBuilder templateBuilder) {
+        // no-op
+    }
+
+    @Override
+    public void customize(JcloudsLocation location, ComputeService computeService, Template template) {
+        // no-op
+    }
+
+    @Override
+    public void customize(JcloudsLocation location, ComputeService computeService, TemplateOptions templateOptions) {
+        // no-op
+    }
+
+    @Override
+    public void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine) {
+        if (machine instanceof JcloudsSshMachineLocation) {
+            customize(location, computeService, (JcloudsSshMachineLocation)machine);
+        } else {
+            // no-op
+        }
+    }
+    
+    @Override
+    public void preRelease(JcloudsMachineLocation machine) {
+        if (machine instanceof JcloudsSshMachineLocation) {
+            preRelease((JcloudsSshMachineLocation)machine);
+        } else {
+            // no-op
+        }
+    }
+
+    @Override
+    public void postRelease(JcloudsMachineLocation machine) {
+        if (machine instanceof JcloudsSshMachineLocation) {
+            postRelease((JcloudsSshMachineLocation)machine);
+        } else {
+            // no-op
+        }
+    }
+    
+    @Override
+    @Deprecated
+    public void customize(JcloudsLocation location, ComputeService computeService, JcloudsSshMachineLocation machine) {
+        // no-op
+    }
+
+    @Override
+    @Deprecated
+    public void preRelease(JcloudsSshMachineLocation machine) {
+        // no-op
+    }
+
+    @Override
+    @Deprecated
+    public void postRelease(JcloudsSshMachineLocation machine) {
+        // no-op
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynImageChooser.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynImageChooser.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynImageChooser.java
new file mode 100644
index 0000000..62cf003
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynImageChooser.java
@@ -0,0 +1,367 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.collections.MutableList;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.Ordering;
+import com.google.common.math.DoubleMath;
+
+@Beta
+/** NB: subclasses must implement {@link #clone()} */
+public class BrooklynImageChooser implements Cloneable {
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynImageChooser.class);
+    
+    protected ComputeService computeService;
+    protected String cloudProviderName;
+    
+    protected static int compare(double left, double right) {
+        return DoubleMath.fuzzyCompare(left, right, 0.00000001);
+    }
+    
+    protected static boolean imageNameContains(Image img, String pattern) {
+        if (img.getName()==null) return false;
+        return img.getName().contains(pattern);
+    }
+    
+    protected static boolean imageNameContainsCaseInsensitive(Image img, String pattern) {
+        if (img.getName()==null) return false;
+        return img.getName().toLowerCase().contains(pattern.toLowerCase());
+    }
+    
+    protected static boolean imageNameContainsWordCaseInsensitive(Image img, String pattern) {
+        if (img.getName()==null) return false;
+        return img.getName().toLowerCase().matches("(.*[^a-z])?"+pattern.toLowerCase()+"([^a-z].*)?");
+    }
+    
+    public double punishmentForOldOsVersions(Image img, OsFamily family, double minVersion) {
+        OperatingSystem os = img.getOperatingSystem();
+        if (os!=null && family.equals(os.getFamily())) {
+            String v = os.getVersion();
+            if (v!=null) {
+                try {
+                    double vd = Double.parseDouble(v);
+                    // punish older versions, with a -log function (so 0.5 version behind is -log(1.5)=-0.5 and 2 versions behind is -log(3)=-1.2  
+                    if (vd < minVersion) return -Math.log(1+(minVersion - vd));
+                } catch (Exception e) {
+                    /* ignore unparseable versions */
+                }
+            }
+        }
+        return 0;
+    }
+    
+    public List<String> blackListedImageIds() {
+        return Arrays.asList(
+                // bad natty image - causes 403 on attempts to apt-get; https://bugs.launchpad.net/ubuntu/+bug/987182
+                "us-east-1/ami-1cb30875",
+                // wrong login user advertised, causes "Error Invalid packet: indicated length 1349281121 too large"
+                // from sshj due to message coming back "Plea"(se log in as another user), according to https://github.com/jclouds/legacy-jclouds/issues/748
+                "us-east-1/ami-08faa660"
+            );
+    }
+
+    public List<String> whilelistedImageIds() {
+        return Arrays.asList(
+        // these are the ones we recommend in brooklyn.properties, but now autodetection should be more reliable
+//                "us-east-1/ami-d0f89fb9",
+//                "us-west-1/ami-fe002cbb",
+//                "us-west-2/ami-70f96e40",
+//                "eu-west-1/ami-ce7b6fba",
+//                "sa-east-1/ami-a3da00be",
+//                "ap-southeast-1/ami-64084736",
+//                "ap-southeast-2/ami-04ea7a3e",
+//                "ap-northeast-1/ami-fe6ceeff"
+            );
+    }
+    
+    public double score(Image img) {
+        double score = 0;
+
+        if (blackListedImageIds().contains(img.getId()))
+            score -= 50;
+
+        if (whilelistedImageIds().contains(img.getId()))
+            // NB: this should be less than deprecated punishment to catch deprecation of whitelisted items
+            score += 20;
+
+        score += punishmentForDeprecation(img);
+
+    
+        // prefer these guys, in stock brooklyn provisioning
+        score += punishmentForOldOsVersions(img, OsFamily.UBUNTU, 11);
+        score += punishmentForOldOsVersions(img, OsFamily.CENTOS, 6);
+
+        OperatingSystem os = img.getOperatingSystem();
+        if (os!=null) {
+            if (os.getFamily()!=null) {
+                // preference for these open, popular OS (but only wrt versions above) 
+                if (os.getFamily().equals(OsFamily.CENTOS)) score += 2;
+                else if (os.getFamily().equals(OsFamily.UBUNTU)) {
+                    score += 2;
+
+                    // prefer these LTS releases slightly above others (including above CentOS)
+                    // (but note in AWS Virginia, at least, version is empty for the 14.04 images for some reason, as of Aug 2014)
+                    if ("14.04".equals(os.getVersion())) score += 0.2;
+                    else if ("12.04".equals(os.getVersion())) score += 0.1;
+
+                    // NB some 13.10 images take 20m+ before they are sshable on AWS
+                    // with "vesafb: module verification error" showing in the AWS system log
+                }
+
+                // slight preference for these 
+                else if (os.getFamily().equals(OsFamily.RHEL)) score += 1;
+                else if (os.getFamily().equals(OsFamily.AMZN_LINUX)) score += 1;
+                else if (os.getFamily().equals(OsFamily.DEBIAN)) score += 1;
+
+                // prefer to take our chances with unknown / unlabelled linux than something explicitly windows
+                else if (os.getFamily().equals(OsFamily.WINDOWS)) score -= 1;
+                
+                if ("softlayer".equals(cloudProviderName)) {
+                    // on softlayer, prefer images where family is part of the image id
+                    // (this is the only way to identiy official images; but in other clouds
+                    // it can cause not-so-good images to get selected!)
+                    if (img.getId().toLowerCase().indexOf(os.getFamily().toString().toLowerCase()) >= 0)
+                        score += 0.5;
+                }
+            }
+            // prefer 64-bit
+            if (os.is64Bit()) score += 0.5;
+        }
+
+        // TODO prefer known providerIds
+
+        if (log.isTraceEnabled())
+            log.trace("initial score "+score+" for "+img);
+        
+        return score;
+    }
+
+    protected double punishmentForDeprecation(Image img) {
+        // google deprecation strategy
+        //        userMetadata={deprecatedState=DEPRECATED}}
+        String deprecated = img.getUserMetadata().get("deprecatedState");
+        if (deprecated!=null) {
+            if ("deprecated".equalsIgnoreCase(deprecated))
+                return -30;
+            log.warn("Unrecognised 'deprecatedState' value '"+deprecated+"' when scoring "+img+"; ignoring that metadata");
+        }
+        
+        // common strategies
+        if (imageNameContainsWordCaseInsensitive(img, "deprecated")) return -30;
+        if (imageNameContainsWordCaseInsensitive(img, "alpha")) return -10;
+        if (imageNameContainsWordCaseInsensitive(img, "beta")) return -5;
+        if (imageNameContainsWordCaseInsensitive(img, "testing")) return -5;
+        if (imageNameContainsWordCaseInsensitive(img, "rc")) return -3;
+
+        // no indication this is deprecated
+        return 0;
+    }
+
+    public BrooklynImageChooser clone() {
+        return new BrooklynImageChooser();
+    }
+    
+    protected void use(ComputeService service) {
+        if (this.computeService!=null && !this.computeService.equals(service))
+            throw new IllegalStateException("ImageChooser must be cloned to set a compute service");
+        this.computeService = service;
+        if (computeService!=null) {
+            cloudProviderName = computeService.getContext().unwrap().getId();
+        }
+    }
+    
+    public BrooklynImageChooser cloneFor(ComputeService service) {
+        BrooklynImageChooser result = clone();
+        result.use(service);
+        return result;
+    }
+    
+    public static class OrderingScoredWithoutDefaults extends Ordering<Image> implements ComputeServiceAwareChooser<OrderingScoredWithoutDefaults> {
+        private BrooklynImageChooser chooser;
+        public OrderingScoredWithoutDefaults(BrooklynImageChooser chooser) {
+            this.chooser = chooser;
+        }
+        public int compare(Image left, Image right) {
+            return BrooklynImageChooser.compare(chooser.score(left), chooser.score(right));
+        }
+        @Override
+        public OrderingScoredWithoutDefaults cloneFor(ComputeService service) {
+            return new OrderingScoredWithoutDefaults(chooser.cloneFor(service));
+        }        
+    }
+    
+    public Ordering<Image> orderingScoredWithoutDefaults() {
+        return new OrderingScoredWithoutDefaults(this);
+    }
+    
+    /** @deprecated since 0.7.0 kept in case persisted */
+    @Deprecated
+    public Ordering<Image> orderingScoredWithoutDefaultsDeprecated() {
+        return new Ordering<Image>() {
+            @Override
+            public int compare(Image left, Image right) {
+                return BrooklynImageChooser.compare(score(left), score(right));
+            }
+        };
+    }
+    
+    public static class OrderingWithDefaults extends Ordering<Image> implements ComputeServiceAwareChooser<OrderingWithDefaults> {
+        Ordering<Image> primaryOrdering;
+        public OrderingWithDefaults(final Ordering<Image> primaryOrdering) {
+            this.primaryOrdering = primaryOrdering;
+        }
+        @Override
+        public int compare(Image left, Image right) {
+            return ComparisonChain.start()
+                .compare(left, right, primaryOrdering)
+                // fall back to default strategy otherwise, except preferring *non*-null values
+                // TODO use AlphaNum string comparator
+                .compare(left.getName(), right.getName(), Ordering.<String> natural().nullsFirst())
+                .compare(left.getVersion(), right.getVersion(), Ordering.<String> natural().nullsFirst())
+                .compare(left.getDescription(), right.getDescription(), Ordering.<String> natural().nullsFirst())
+                .compare(left.getOperatingSystem().getName(), right.getOperatingSystem().getName(), Ordering.<String> natural().nullsFirst())
+                .compare(left.getOperatingSystem().getVersion(), right.getOperatingSystem().getVersion(), Ordering.<String> natural().nullsFirst())
+                .compare(left.getOperatingSystem().getDescription(), right.getOperatingSystem().getDescription(), Ordering.<String> natural().nullsFirst())
+                .compare(left.getOperatingSystem().getArch(), right.getOperatingSystem().getArch(), Ordering.<String> natural().nullsFirst()).result();
+        }    
+        @Override
+        public OrderingWithDefaults cloneFor(ComputeService service) {
+            if (primaryOrdering instanceof ComputeServiceAwareChooser) {
+                return new OrderingWithDefaults( BrooklynImageChooser.cloneFor(primaryOrdering, service) );
+            }
+            return this;
+        }        
+    }
+    
+    public static Ordering<Image> orderingWithDefaults(final Ordering<Image> primaryOrdering) {
+        return new OrderingWithDefaults(primaryOrdering);
+    }
+    
+    /** @deprecated since 0.7.0 kept in case persisted */
+    @Deprecated
+    public static Ordering<Image> orderingWithDefaultsDeprecated(final Ordering<Image> primaryOrdering) {
+        return new Ordering<Image>() {
+            @Override
+            public int compare(Image left, Image right) {
+                return ComparisonChain.start()
+                    .compare(left, right, primaryOrdering)
+                    // fall back to default strategy otherwise, except preferring *non*-null values
+                    // TODO use AlphaNum string comparator
+                    .compare(left.getName(), right.getName(), Ordering.<String> natural().nullsFirst())
+                    .compare(left.getVersion(), right.getVersion(), Ordering.<String> natural().nullsFirst())
+                    .compare(left.getDescription(), right.getDescription(), Ordering.<String> natural().nullsFirst())
+                    .compare(left.getOperatingSystem().getName(), right.getOperatingSystem().getName(), Ordering.<String> natural().nullsFirst())
+                    .compare(left.getOperatingSystem().getVersion(), right.getOperatingSystem().getVersion(), Ordering.<String> natural().nullsFirst())
+                    .compare(left.getOperatingSystem().getDescription(), right.getOperatingSystem().getDescription(), Ordering.<String> natural().nullsFirst())
+                    .compare(left.getOperatingSystem().getArch(), right.getOperatingSystem().getArch(), Ordering.<String> natural().nullsFirst()).result();
+            }
+        };
+    }
+    
+    public static class ImageChooserFromOrdering implements Function<Iterable<? extends Image>, Image>, ComputeServiceAwareChooser<ImageChooserFromOrdering> {
+        final Ordering<Image> ordering;
+        public ImageChooserFromOrdering(final Ordering<Image> ordering) { this.ordering = ordering; }
+        @Override
+        public Image apply(Iterable<? extends Image> input) {
+            List<? extends Image> maxImages = multiMax(ordering, input);
+            return maxImages.get(maxImages.size() - 1);
+        }
+        @Override
+        public ImageChooserFromOrdering cloneFor(ComputeService service) {
+            if (ordering instanceof ComputeServiceAwareChooser) {
+                return new ImageChooserFromOrdering( BrooklynImageChooser.cloneFor(ordering, service) );
+            }
+            return this;
+        }        
+    }
+
+    public static Function<Iterable<? extends Image>, Image> imageChooserFromOrdering(final Ordering<Image> ordering) {
+        return new ImageChooserFromOrdering(ordering);
+    }
+    
+    /** @deprecated since 0.7.0 kept in case persisted */
+    @Deprecated
+    public static Function<Iterable<? extends Image>, Image> imageChooserFromOrderingDeprecated(final Ordering<Image> ordering) {
+        return new Function<Iterable<? extends Image>, Image>() {
+            @Override
+            public Image apply(Iterable<? extends Image> input) {
+                List<? extends Image> maxImages = multiMax(ordering, input);
+                return maxImages.get(maxImages.size() - 1);
+            }
+        };
+    }
+    
+    protected interface ComputeServiceAwareChooser<T> {
+        public T cloneFor(ComputeService service);
+    }
+
+    /** Attempts to clone the given item for use with the given {@link ComputeService}, if
+     * the item is {@link ComputeServiceAwareChooser}; otherwise it returns the item unchanged */
+    @SuppressWarnings("unchecked")
+    public static <T> T cloneFor(T item, ComputeService service) {
+        if (item instanceof ComputeServiceAwareChooser) {
+            return ((ComputeServiceAwareChooser<T>)item).cloneFor(service);
+        }
+        return item;
+    }
+    
+    // from jclouds
+    static <T, E extends T> List<E> multiMax(Comparator<T> ordering, Iterable<E> iterable) {
+        Iterator<E> iterator = iterable.iterator();
+        List<E> maxes = MutableList.of(iterator.next());
+        E maxSoFar = maxes.get(0);
+        while (iterator.hasNext()) {
+           E current = iterator.next();
+           int comparison = ordering.compare(maxSoFar, current);
+           if (comparison == 0) {
+              maxes.add(current);
+           } else if (comparison < 0) {
+              maxes = MutableList.of(current);
+              maxSoFar = current;
+           }
+        }
+        return maxes;
+     }
+    
+    public Ordering<Image> ordering() {
+        return orderingWithDefaults(orderingScoredWithoutDefaults());
+    }
+
+    public Function<Iterable<? extends Image>,Image> chooser() {
+        return imageChooserFromOrdering(ordering());
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java
new file mode 100644
index 0000000..e857e93
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.jclouds;
+
+import static org.apache.brooklyn.location.jclouds.pool.MachinePoolPredicates.matching;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.management.Task;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.trait.Startable;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.pool.MachinePool;
+import org.apache.brooklyn.location.jclouds.pool.MachineSet;
+import org.apache.brooklyn.location.jclouds.pool.ReusableMachineTemplate;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.task.BasicExecutionContext;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+
+/**
+ * @deprecated since 0.6.0; never used in production setting, and thus of dubious value; best avoided as unlikely to be supported in future versions
+ */
+@Deprecated
+public class BrooklynMachinePool extends MachinePool {
+
+    private static final Logger log = LoggerFactory.getLogger(BrooklynMachinePool.class);
+    
+    protected final JcloudsLocation location;
+    final List<Task<?>> activeTasks = new ArrayList<Task<?>>();
+    final String providerLocationId;
+    
+    public BrooklynMachinePool(JcloudsLocation l) {
+        super(l.getComputeService());
+        providerLocationId = l.getRegion();
+        this.location = l;
+    }
+    
+    /** claims a machine with the indicated spec, creating if necessary */
+    public SshMachineLocation obtain(ReusableMachineTemplate t) {
+        MachineSet previous = unclaimed(matching(t));
+        
+        while (true) {
+            NodeMetadata m = claim(1, t).iterator().next();
+            // TODO ideally shouldn't have to rebind
+            SshMachineLocation result = null;
+            try {
+                result = toSshMachineLocation( m );
+            } catch (Exception e) {
+                if (previous.contains(m)) {
+                    log.debug("attempt to bind to previous existing machine "+m+" failed (will blacklist and retry another): "+e);
+                } else {
+                    log.warn("attempt to bind to machine "+m+" failed: "+e);
+                    throw Throwables.propagate(e);
+                }
+            }
+            if (result!=null) return result;
+            if (previous.contains(m)) {
+                log.debug("could not bind to previous existing machine "+m+"; blacklisting and trying a new one");
+                addToBlacklist(new MachineSet(m));
+            } else {
+                throw new IllegalStateException("cannot bind/connect to newly created machine; error in configuration");
+            }
+        }
+    }
+    
+    protected MachineSet filterForAllowedMachines(MachineSet input) {
+        MachineSet result = super.filterForAllowedMachines(input);
+        if (providerLocationId!=null) {
+            result = result.filtered(matching( new ReusableMachineTemplate().locationId(providerLocationId).strict(false) ));
+        }
+        return result;
+    }
+
+    /** returns an SshMachineLocation, if one can be created and accessed; returns null if it cannot be created */
+    protected SshMachineLocation toSshMachineLocation(NodeMetadata m) {
+        try {
+            JcloudsSshMachineLocation sshM = location.rebindMachine(m);
+            if (sshM.execCommands("check-reachable", Arrays.asList("whoami")) != 0) {
+                log.warn("cannot bind to machine "+m);
+                return null;
+            }
+            return sshM;
+        } catch (Exception e) {
+            throw Throwables.propagate(e);
+        }
+    }
+    
+    @Override
+    public MachineSet create(int count, ReusableMachineTemplate template) {
+        List<NodeMetadata> nodes = new ArrayList<NodeMetadata>();
+        for (int i=0; i<count; i++) {
+            // TODO this in parallel
+            JcloudsSshMachineLocation m;
+            try {
+                MachineLocation machineLocation = location.obtain(MutableMap.of("callerContext", ""+this+"("+template+")"), template);
+                // Class has been deprecated since 0.6.0, and prior to that, obtain would have returned a JcloudsSshMachineLocation
+                if (machineLocation instanceof JcloudsSshMachineLocation) {
+                    m = (JcloudsSshMachineLocation) machineLocation;
+                } else {
+                    throw new UnsupportedOperationException("Cannot create WinRmMachineLocation");
+                }
+            } catch (Exception e) {
+                throw Throwables.propagate(e);
+            }
+            nodes.add(m.getNode());
+        }
+        MachineSet result = new MachineSet(nodes);
+        registerNewNodes(result, template);
+        return result;
+    }
+
+    public boolean unclaim(SshMachineLocation location) {
+        init();
+        if (location instanceof JcloudsSshMachineLocation)
+            return unclaim(new MachineSet( ((JcloudsSshMachineLocation)location).getNode()) ) > 0;
+        return false;
+    }
+    public boolean destroy(SshMachineLocation location) {
+        init();
+        if (location instanceof JcloudsSshMachineLocation)
+            return destroy(new MachineSet( ((JcloudsSshMachineLocation)location).getNode()) ) > 0;
+        return false;
+    }
+
+    // TODO we need to remove stale tasks somewhere
+    protected <T> Task<T> addTask(Task<T> t) {
+        synchronized (activeTasks) { activeTasks.add(t); }
+        return t;
+    }
+    
+    public List<Task<?>> getActiveTasks() {
+        List<Task<?>> result;
+        synchronized (activeTasks) { result = ImmutableList.<Task<?>>copyOf(activeTasks); }
+        return result;
+    }
+
+    public void blockUntilTasksEnded() {
+        while (true) {
+            boolean allDone = true;
+            List<Task<?>> tt = getActiveTasks();
+            for (Task<?> t: tt) {
+                if (!t.isDone()) {
+                    allDone = false;
+                    if (log.isDebugEnabled()) log.debug("Pool "+this+", blocking for completion of: "+t);
+                    t.blockUntilEnded();
+                }
+            }
+            synchronized (activeTasks) {
+                List<Task> newTT = new ArrayList<Task>(getActiveTasks());
+                newTT.removeAll(tt);
+                if (allDone && tt.isEmpty()) {
+                    //task list has stabilized, and there are no active tasks; clear and exit
+                    if (log.isDebugEnabled()) log.debug("Pool "+this+", all known tasks have completed, clearing list");
+                    activeTasks.clear();
+                    break;
+                }
+                if (log.isDebugEnabled()) log.debug("Pool "+this+", all previously known tasks have completed, but there are new tasks ("+newTT+") checking them");
+            }
+        }
+    }
+
+    /** starts the given template; for use only within a task (e.g. application's start effector).
+     * returns a child task of the current task.
+     * <p>
+     * throws exception if not in a task. (you will have to claim, then invoke the effectors manually.) */
+    public Task<?> start(final ReusableMachineTemplate template, final List<? extends Startable> entities) {
+        BasicExecutionContext ctx = BasicExecutionContext.getCurrentExecutionContext();
+        if (ctx==null) throw new IllegalStateException("Pool.start is only permitted within a task (effector)");
+        final AtomicReference<Task<?>> t = new AtomicReference<Task<?>>();
+        synchronized (t) {
+            t.set(ctx.submit(new Runnable() {
+                public void run() {
+                    synchronized (t) {
+                        if (log.isDebugEnabled()) log.debug("Pool "+this+", task "+t.get()+" claiming a "+template);
+                        SshMachineLocation m = obtain(template);
+                        if (log.isDebugEnabled()) log.debug("Pool "+this+", task "+t.get()+" got "+m+"; starting "+entities);
+                        for (Startable entity: entities)
+                            addTask( ((Entity)entity).invoke(Startable.START, MutableMap.of("locations", Arrays.asList(m))) );
+                    }
+                }
+            }));
+        }
+        addTask(t.get());
+        return t.get();
+    }
+
+    /** @see #start(ReusableMachineTemplate, List) */
+    public Task<?> start(ReusableMachineTemplate template, Startable ...entities) {
+        return start(template, Arrays.asList(entities));
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ComputeServiceRegistry.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ComputeServiceRegistry.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ComputeServiceRegistry.java
new file mode 100644
index 0000000..a835e2c
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ComputeServiceRegistry.java
@@ -0,0 +1,28 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import org.jclouds.compute.ComputeService;
+
+import brooklyn.util.config.ConfigBag;
+
+public interface ComputeServiceRegistry {
+    
+    public ComputeService findComputeService(ConfigBag conf, boolean allowReuse);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ComputeServiceRegistryImpl.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ComputeServiceRegistryImpl.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ComputeServiceRegistryImpl.java
new file mode 100644
index 0000000..f3f39bb
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ComputeServiceRegistryImpl.java
@@ -0,0 +1,183 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_AMI_QUERY;
+import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMI_QUERY;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import org.jclouds.Constants;
+import org.jclouds.ContextBuilder;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.ec2.reference.EC2Constants;
+import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.basic.Sanitizer;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.inject.Module;
+
+public class ComputeServiceRegistryImpl implements ComputeServiceRegistry, JcloudsLocationConfig {
+    
+    private static final Logger LOG = LoggerFactory.getLogger(ComputeServiceRegistryImpl.class);
+
+    public static final ComputeServiceRegistryImpl INSTANCE = new ComputeServiceRegistryImpl();
+        
+    protected ComputeServiceRegistryImpl() {
+    }
+    
+    protected final Map<Map<?,?>,ComputeService> cachedComputeServices = new ConcurrentHashMap<Map<?,?>,ComputeService>();
+
+    protected final Object createComputeServicesMutex = new Object();
+
+    @Override
+    public ComputeService findComputeService(ConfigBag conf, boolean allowReuse) {
+        String provider = checkNotNull(conf.get(CLOUD_PROVIDER), "provider must not be null");
+        String identity = checkNotNull(conf.get(CloudLocationConfig.ACCESS_IDENTITY), "identity must not be null");
+        String credential = checkNotNull(conf.get(CloudLocationConfig.ACCESS_CREDENTIAL), "credential must not be null");
+        
+        Properties properties = new Properties();
+        properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
+        properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
+        properties.setProperty("jclouds.ssh.max-retries", conf.getStringKey("jclouds.ssh.max-retries") != null ? 
+                conf.getStringKey("jclouds.ssh.max-retries").toString() : "50");
+        // Enable aws-ec2 lazy image fetching, if given a specific imageId; otherwise customize for specific owners; or all as a last resort
+        // See https://issues.apache.org/jira/browse/WHIRR-416
+        if ("aws-ec2".equals(provider)) {
+            // TODO convert AWS-only flags to config keys
+            if (groovyTruth(conf.get(IMAGE_ID))) {
+                properties.setProperty(PROPERTY_EC2_AMI_QUERY, "");
+                properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, "");
+            } else if (groovyTruth(conf.getStringKey("imageOwner"))) {
+                properties.setProperty(PROPERTY_EC2_AMI_QUERY, "owner-id="+conf.getStringKey("imageOwner")+";state=available;image-type=machine");
+            } else if (groovyTruth(conf.getStringKey("anyOwner"))) {
+                // set `anyOwner: true` to override the default query (which is restricted to certain owners as per below), 
+                // allowing the AMI query to bind to any machine
+                // (note however, we sometimes pick defaults in JcloudsLocationFactory);
+                // (and be careful, this can give a LOT of data back, taking several minutes,
+                // and requiring extra memory allocated on the command-line)
+                properties.setProperty(PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine");
+                /*
+                 * by default the following filters are applied:
+                 * Filter.1.Name=owner-id&Filter.1.Value.1=137112412989&
+                 * Filter.1.Value.2=063491364108&
+                 * Filter.1.Value.3=099720109477&
+                 * Filter.1.Value.4=411009282317&
+                 * Filter.2.Name=state&Filter.2.Value.1=available&
+                 * Filter.3.Name=image-type&Filter.3.Value.1=machine&
+                 */
+            }
+            
+            // occasionally can get com.google.common.util.concurrent.UncheckedExecutionException: java.lang.RuntimeException: 
+            //     security group eu-central-1/jclouds#brooklyn-bxza-alex-eu-central-shoul-u2jy-nginx-ielm is not available after creating
+            // the default timeout was 500ms so let's raise it in case that helps
+            properties.setProperty(EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT, ""+Duration.seconds(30).toMilliseconds());
+        }
+
+        // FIXME Deprecated mechanism, should have a ConfigKey for overrides
+        Map<String, Object> extra = Maps.filterKeys(conf.getAllConfig(), Predicates.containsPattern("^jclouds\\."));
+        if (extra.size() > 0) {
+            LOG.warn("Jclouds using deprecated property overrides: "+Sanitizer.sanitize(extra));
+        }
+        properties.putAll(extra);
+
+        String endpoint = conf.get(CloudLocationConfig.CLOUD_ENDPOINT);
+        if (!groovyTruth(endpoint)) endpoint = getDeprecatedProperty(conf, Constants.PROPERTY_ENDPOINT);
+        if (groovyTruth(endpoint)) properties.setProperty(Constants.PROPERTY_ENDPOINT, endpoint);
+
+        Map<?,?> cacheKey = MutableMap.builder()
+                .putAll(properties)
+                .put("provider", provider)
+                .put("identity", identity)
+                .put("credential", credential)
+                .putIfNotNull("endpoint", endpoint)
+                .build()
+                .asUnmodifiable();
+
+        if (allowReuse) {
+            ComputeService result = cachedComputeServices.get(cacheKey);
+            if (result!=null) {
+                LOG.trace("jclouds ComputeService cache hit for compute service, for "+Sanitizer.sanitize(properties));
+                return result;
+            }
+            LOG.debug("jclouds ComputeService cache miss for compute service, creating, for "+Sanitizer.sanitize(properties));
+        }
+
+        Iterable<Module> modules = getCommonModules();
+
+        // Synchronizing to avoid deadlock from sun.reflect.annotation.AnnotationType.
+        // See https://github.com/brooklyncentral/brooklyn/issues/974
+        ComputeServiceContext computeServiceContext;
+        synchronized (createComputeServicesMutex) {
+            computeServiceContext = ContextBuilder.newBuilder(provider)
+                    .modules(modules)
+                    .credentials(identity, credential)
+                    .overrides(properties)
+                    .build(ComputeServiceContext.class);
+        }
+        final ComputeService computeService = computeServiceContext.getComputeService();
+        if (allowReuse) {
+            synchronized (cachedComputeServices) {
+                ComputeService result = cachedComputeServices.get(cacheKey);
+                if (result != null) {
+                    LOG.debug("jclouds ComputeService cache recovery for compute service, for "+Sanitizer.sanitize(cacheKey));
+                    //keep the old one, discard the new one
+                    computeService.getContext().close();
+                    return result;
+                }
+                LOG.debug("jclouds ComputeService created "+computeService+", adding to cache, for "+Sanitizer.sanitize(properties));
+                cachedComputeServices.put(cacheKey, computeService);
+            }
+        }
+        return computeService;
+     }
+
+    /** returns the jclouds modules we typically install */ 
+    protected ImmutableSet<Module> getCommonModules() {
+        return ImmutableSet.<Module> of(
+                new SshjSshClientModule(), 
+                new SLF4JLoggingModule(),
+                new BouncyCastleCryptoModule());
+    }
+     
+    protected String getDeprecatedProperty(ConfigBag conf, String key) {
+        if (conf.containsKey(key)) {
+            LOG.warn("Jclouds using deprecated brooklyn-jclouds property "+key+": "+Sanitizer.sanitize(conf.getAllConfig()));
+            return (String) conf.getStringKey(key);
+        } else {
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
new file mode 100644
index 0000000..5aa026d
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
@@ -0,0 +1,184 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
+import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.basic.LocationConfigUtils;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.basic.LocationPropertiesFromBrooklynProperties;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.text.KeyValueParser;
+import brooklyn.util.text.Strings;
+import brooklyn.util.text.WildcardGlobs;
+import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Examples of valid specs:
+ *   <ul>
+ *     <li>byon:(hosts=myhost)
+ *     <li>byon:(hosts="myhost, myhost2")
+ *     <li>byon:(hosts="myhost, myhost2", name="my location name")
+ *   </ul>
+ * 
+ * @author aled
+ */
+@SuppressWarnings({"unchecked","rawtypes"})
+public class JcloudsByonLocationResolver implements LocationResolver {
+
+    public static final Logger log = LoggerFactory.getLogger(JcloudsByonLocationResolver.class);
+    
+    public static final String BYON = "jcloudsByon";
+
+    private static final Pattern PATTERN = Pattern.compile("("+BYON+"|"+BYON.toUpperCase()+")" + ":" + "\\((.*)\\)$");
+
+    private ManagementContext managementContext;
+
+    @Override
+    public void init(ManagementContext managementContext) {
+        this.managementContext = checkNotNull(managementContext, "managementContext");
+    }
+    
+    // TODO Remove some duplication from JcloudsResolver; needs more careful review
+    @Override
+    public FixedListMachineProvisioningLocation<JcloudsSshMachineLocation> newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        Map globalProperties = registry.getProperties();
+
+        Matcher matcher = PATTERN.matcher(spec);
+        if (!matcher.matches()) {
+            throw new IllegalArgumentException("Invalid location '"+spec+"'; must specify something like jcloudsByon(provider=\"aws-ec2\",region=\"us-east-1\",hosts=\"i-f2014593,i-d1234567\")");
+        }
+        
+        String argsPart = matcher.group(2);
+        Map<String, String> argsMap = KeyValueParser.parseMap(argsPart);
+        
+        // prefer args map over location flags
+        
+        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
+
+        String providerOrApi = argsMap.containsKey("provider") ? argsMap.get("provider") : (String)locationFlags.get("provider");
+
+        String regionName = argsMap.containsKey("region") ? argsMap.get("region") : (String)locationFlags.get("region");
+        
+        String endpoint = argsMap.containsKey("endpoint") ? argsMap.get("endpoint") : (String)locationFlags.get("endpoint");
+        
+        String name = argsMap.containsKey("name") ? argsMap.get("name") : (String)locationFlags.get("name");
+
+        String user = argsMap.containsKey("user") ? argsMap.get("user") : (String)locationFlags.get("user");
+
+        String privateKeyFile = argsMap.containsKey("privateKeyFile") ? argsMap.get("privateKeyFile") : (String)locationFlags.get("privateKeyFile");
+        
+        String hosts = argsMap.get("hosts");
+        
+        if (Strings.isEmpty(providerOrApi)) {
+            throw new IllegalArgumentException("Invalid location '"+spec+"'; provider must be defined");
+        }
+        if (hosts == null || hosts.isEmpty()) {
+            throw new IllegalArgumentException("Invalid location '"+spec+"'; at least one host must be defined");
+        }
+        if (argsMap.containsKey("name") && (Strings.isEmpty(name))) {
+            throw new IllegalArgumentException("Invalid location '"+spec+"'; if name supplied then value must be non-empty");
+        }
+
+        // For everything in brooklyn.properties, only use things with correct prefix (and remove that prefix).
+        // But for everything passed in via locationFlags, pass those as-is.
+        // TODO Should revisit the locationFlags: where are these actually used? Reason accepting properties without
+        //      full prefix is that the map's context is explicitly this location, rather than being generic properties.
+        Map allProperties = getAllProperties(registry, globalProperties);
+        Map jcloudsProperties = new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties(providerOrApi, regionName, namedLocation, allProperties);
+        jcloudsProperties.putAll(locationFlags);
+        jcloudsProperties.putAll(argsMap);
+        
+        String jcloudsSpec = "jclouds:"+providerOrApi + (regionName != null ? ":"+regionName : "") + (endpoint != null ? ":"+endpoint : "");
+        JcloudsLocation jcloudsLocation = (JcloudsLocation) registry.resolve(jcloudsSpec, jcloudsProperties);
+
+        List<String> hostIdentifiers = WildcardGlobs.getGlobsAfterBraceExpansion("{"+hosts+"}",
+                true /* numeric */, /* no quote support though */ PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR);
+        List<JcloudsSshMachineLocation> machines = Lists.newArrayList();
+        
+        for (String hostIdentifier : hostIdentifiers) {
+            Map<?, ?> machineFlags = MutableMap.builder()
+                    .put("id", hostIdentifier)
+                    .putIfNotNull("user", user)
+                    .putIfNotNull("privateKeyFile", privateKeyFile)
+                    .build();
+            try {
+                JcloudsSshMachineLocation machine = jcloudsLocation.rebindMachine(jcloudsLocation.config().getBag().putAll(machineFlags));
+                machines.add(machine);
+            } catch (NoMachinesAvailableException e) {
+                log.warn("Error rebinding to jclouds machine "+hostIdentifier+" in "+jcloudsLocation, e);
+                Exceptions.propagate(e);
+            }
+        }
+        
+        ConfigBag flags = ConfigBag.newInstance(jcloudsProperties);
+
+        flags.putStringKey("machines", machines);
+        flags.putIfNotNull(LocationConfigKeys.USER, user);
+        flags.putStringKeyIfNotNull("name", name);
+        
+        if (registry != null) 
+            LocationPropertiesFromBrooklynProperties.setLocalTempDir(registry.getProperties(), flags);
+
+        log.debug("Created Jclouds BYON location "+name+": "+machines);
+        
+        return managementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .configure(flags.getAllConfig())
+                .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+    }
+    
+    private Map getAllProperties(LocationRegistry registry, Map<?,?> properties) {
+        Map<Object,Object> allProperties = Maps.newHashMap();
+        if (registry!=null) allProperties.putAll(registry.getProperties());
+        allProperties.putAll(properties);
+        return allProperties;
+    }
+    
+    @Override
+    public String getPrefix() {
+        return BYON;
+    }
+    
+    @Override
+    public boolean accepts(String spec, LocationRegistry registry) {
+        return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true);
+    }
+}
\ No newline at end of file



[26/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/SshMachineLocationPerformanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/SshMachineLocationPerformanceTest.java b/core/src/test/java/brooklyn/location/basic/SshMachineLocationPerformanceTest.java
deleted file mode 100644
index 5f265ee..0000000
--- a/core/src/test/java/brooklyn/location/basic/SshMachineLocationPerformanceTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.io.ByteArrayOutputStream;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.test.PerformanceTestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.net.Networking;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.time.Time;
-
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
-/**
- * Test the performance of different variants of invoking the sshj tool.
- * 
- * Intended for human-invocation and inspection, to see which parts are most expensive.
- */
-public class SshMachineLocationPerformanceTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SshMachineLocationPerformanceTest.class);
-    
-    private SshMachineLocation machine;
-    private ListeningExecutorService executor;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        machine = new SshMachineLocation(MutableMap.of("address", "localhost"));
-        executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void afterMethod() throws Exception {
-        if (executor != null) executor.shutdownNow();
-        Streams.closeQuietly(machine);
-    }
-
-    @Test(groups = {"Integration"})
-    public void testConsecutiveSmallCommands() throws Exception {
-        runExecManyCommands(ImmutableList.of("true"), "small-cmd", 10);
-    }
-
-    // Mimics SshSensorAdapter's polling
-    @Test(groups = {"Integration"})
-    public void testConsecutiveSmallCommandsWithCustomStdoutAndErr() throws Exception {
-        final ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        final ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-        
-        Runnable task = new Runnable() {
-            @Override public void run() {
-                machine.execScript(ImmutableMap.of("out", stdout, "err", stderr), "test", ImmutableList.of("true"));
-            }};
-        runMany(task, "small-cmd-custom-stdout", 1, 10);
-    }
-
-    @Test(groups = {"Integration"})
-    public void testConcurrentSmallCommands() throws Exception {
-        runExecManyCommands(ImmutableList.of("true"), "small-cmd", 10, 10);
-    }
-
-    @Test(groups = {"Integration"})
-    public void testConsecutiveBigStdoutCommands() throws Exception {
-        runExecManyCommands(ImmutableList.of("head -c 100000 /dev/urandom"), "big-stdout", 10);
-    }
-
-    @Test(groups = {"Integration"})
-    public void testConsecutiveBigStdinCommands() throws Exception {
-        String bigstr = Identifiers.makeRandomId(100000);
-        runExecManyCommands(ImmutableList.of("echo "+bigstr+" | wc -c"), "big-stdin", 10);
-    }
-
-    @Test(groups = {"Integration"})
-    public void testConsecutiveSmallCommandsWithDifferentProperties() throws Exception {
-        final Map<String, ?> emptyProperties = Collections.emptyMap();
-        final Map<String, ?> customProperties = MutableMap.of(
-                "address", Networking.getLocalHost(),
-                SshTool.PROP_SESSION_TIMEOUT.getName(), 20000,
-                SshTool.PROP_CONNECT_TIMEOUT.getName(), 50000,
-                SshTool.PROP_SCRIPT_HEADER.getName(), "#!/bin/bash");
-
-        Runnable task = new Runnable() {
-            @Override public void run() {
-                if (Math.random() < 0.5) {
-                    machine.execScript(emptyProperties, "test", ImmutableList.of("true"));
-                } else {
-                    machine.execScript(customProperties, "test", ImmutableList.of("true"));
-                }
-            }};
-        runMany(task, "small-cmd-custom-ssh-properties", 1, 10);
-    }
-
-    private void runExecManyCommands(final List<String> cmds, String context, int iterations) throws Exception {
-        runExecManyCommands(cmds, context, 1, iterations);
-    }
-    
-    private void runExecManyCommands(final List<String> cmds, String context, int concurrentRuns, int iterations) throws Exception {
-        Runnable task = new Runnable() {
-                @Override public void run() {
-                    execScript(cmds);
-                }};
-        runMany(task, context, concurrentRuns, iterations);
-    }
-    
-    private void runMany(final Runnable task, final String context, int concurrentRuns, int iterations) throws Exception {
-        long preCpuTime = PerformanceTestUtils.getProcessCpuTime();
-        Stopwatch stopwatch = Stopwatch.createStarted();
-
-        for (int i = 0; i < iterations; i++) {
-            List<ListenableFuture<?>> futures = Lists.newArrayList();
-            for (int j = 0; j < concurrentRuns; j++) {
-                futures.add(executor.submit(new Runnable() {
-                    public void run() {
-                        try {
-                            task.run();
-                        } catch (Exception e) {
-                            LOG.error("Error for "+context+", executing "+task, e);
-                            throw Throwables.propagate(e);
-                        }
-                    }}));
-            }
-            Futures.allAsList(futures).get();
-            
-            long postCpuTime = PerformanceTestUtils.getProcessCpuTime();
-            long elapsedTime = stopwatch.elapsed(TimeUnit.MILLISECONDS);
-            double fractionCpu = (elapsedTime > 0) ? ((double)postCpuTime-preCpuTime) / TimeUnit.MILLISECONDS.toNanos(elapsedTime) : -1;
-            LOG.info("Executing {}; completed {}; took {}; fraction cpu {}",
-                    new Object[] {context, (i+1), Time.makeTimeStringRounded(elapsedTime), fractionCpu});
-        }
-    }
-
-    private int execScript(List<String> cmds) {
-        return machine.execScript("mysummary", cmds);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java b/core/src/test/java/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
deleted file mode 100644
index cf9c058..0000000
--- a/core/src/test/java/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.internal.ssh.sshj.SshjTool;
-import brooklyn.util.net.Networking;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.time.Duration;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * Tests the re-use of SshTools in SshMachineLocation
- */
-public class SshMachineLocationReuseIntegrationTest {
-
-    public static class RecordingSshjTool extends SshjTool {
-        public static final AtomicBoolean forbidden = new AtomicBoolean(false); 
-        public static final AtomicInteger connectionCount = new AtomicInteger(0);
-        public static final AtomicInteger disconnectionCount = new AtomicInteger();
-        
-        public RecordingSshjTool(Map<String, ?> map) {
-            super(map);
-        }
-
-        @Override
-        public void connect() {
-            if (forbidden.get()) throw new IllegalStateException("forbidden at this time");
-            connectionCount.incrementAndGet();
-            super.connect();
-        }
-
-        @Override
-        public void disconnect() {
-            disconnectionCount.incrementAndGet();
-            super.disconnect();
-        }
-
-        public static void reset() {
-            forbidden.set(false);
-            connectionCount.set(0);
-            disconnectionCount.set(0);
-        }
-
-        @Override
-        public int execCommands(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
-            if (forbidden.get()) throw new IllegalStateException("forbidden at this time");
-            return super.execCommands(props, commands, env);
-        }
-        
-        @Override
-        public int execScript(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
-            if (forbidden.get()) throw new IllegalStateException("forbidden at this time");
-            return super.execScript(props, commands, env);
-        }
-        
-        @Override
-        public int execShellDirect(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
-            if (forbidden.get()) throw new IllegalStateException("forbidden at this time");
-            return super.execShellDirect(props, commands, env);
-        }
-    }
-
-    private SshMachineLocation host;
-    private LocalManagementContext managementContext;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = new LocalManagementContext();
-        host = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", Networking.getLocalHost())
-                .configure(SshTool.PROP_TOOL_CLASS, RecordingSshjTool.class.getName()));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (host != null) Streams.closeQuietly(host);
-        if (managementContext != null) Entities.destroyAll(managementContext);
-        RecordingSshjTool.reset();
-    }
-
-    @Test(groups = "Integration")
-    public void testBasicReuse() throws Exception {
-        host.execScript("mysummary", ImmutableList.of("exit"));
-        host.execScript("mysummary", ImmutableList.of("exit"));
-        assertEquals(RecordingSshjTool.connectionCount.get(), 1, "Expected one SSH connection to have been recorded");
-    }
-
-    @Test(groups = "Integration")
-    public void testReuseWithInterestingProps() throws Exception {
-        host.execScript(customSshConfigKeys(), "mysummary", ImmutableList.of("exit"));
-        host.execScript(customSshConfigKeys(), "mysummary", ImmutableList.of("exit"));
-        assertEquals(RecordingSshjTool.connectionCount.get(), 1, "Expected one SSH connection to have been recorded");
-    }
-
-    @Test(groups = "Integration")
-    public void testNewConnectionForDifferentProps() throws Exception {
-        host.execScript("mysummary", ImmutableList.of("exit"));
-        host.execScript(customSshConfigKeys(), "mysummary", ImmutableList.of("exit"));
-        assertEquals(RecordingSshjTool.connectionCount.get(), 2, "Expected two SSH connections to have been recorded");
-    }
-
-    @Test(groups = "Integration")
-    public void testSshToolReusedWhenConfigDiffers() throws Exception {
-        Map<String, Object> props = customSshConfigKeys();
-        host.execScript(props, "mysummary", ImmutableList.of("exit"));
-
-        // Use another output stream for second request
-        props.put(SshTool.PROP_SCRIPT_HEADER.getName(), "#!/bin/bash -e\n");
-        host.execScript(props, "mysummary", ImmutableList.of("exit"));
-        assertEquals(RecordingSshjTool.connectionCount.get(), 1, "Expected one SSH connection to have been recorded even though out script header differed.");
-    }
-
-    @Test(groups = "Integration")
-    public void testSshCacheExpiresEvenIfNotUsed() throws Exception {
-        SshMachineLocation host2 = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", InetAddress.getLocalHost())
-                .configure(SshMachineLocation.SSH_CACHE_EXPIRY_DURATION, Duration.ONE_SECOND)
-                .configure(SshTool.PROP_TOOL_CLASS, RecordingSshjTool.class.getName()));
-        
-        Map<String, Object> props = customSshConfigKeys();
-        host2.execScript(props, "mysummary", ImmutableList.of("exit"));
-
-        Asserts.succeedsEventually(new Runnable() {
-            @Override public void run() {
-                assertEquals(RecordingSshjTool.disconnectionCount.get(), 1);
-            }});
-    }
-
-    public Map<String, Object> customSshConfigKeys() throws UnknownHostException {
-        return MutableMap.<String, Object>of(
-                "address", Networking.getLocalHost(),
-                SshTool.PROP_SESSION_TIMEOUT.getName(), 20000,
-                SshTool.PROP_CONNECT_TIMEOUT.getName(), 50000,
-                SshTool.PROP_SCRIPT_HEADER.getName(), "#!/bin/bash");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java b/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java
deleted file mode 100644
index 03df8fc..0000000
--- a/core/src/test/java/brooklyn/location/basic/SshMachineLocationTest.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.entity.Effector;
-import org.apache.brooklyn.api.entity.basic.EntityLocal;
-import org.apache.brooklyn.api.entity.proxying.EntityInitializer;
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.BrooklynConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.entity.effector.EffectorBody;
-import brooklyn.entity.effector.EffectorTaskTest;
-import brooklyn.entity.effector.Effectors;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.PortRanges.LinearPortRange;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.file.ArchiveUtils;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.internal.ssh.RecordingSshTool;
-import brooklyn.util.internal.ssh.SshException;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.net.Networking;
-import brooklyn.util.net.Urls;
-import brooklyn.util.os.Os;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.task.BasicExecutionContext;
-import brooklyn.util.task.BasicExecutionManager;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.io.Files;
-
-/**
- * Test the {@link SshMachineLocation} implementation of the {@link brooklyn.location.Location} interface.
- */
-public class SshMachineLocationTest {
-
-    private SshMachineLocation host;
-    private ManagementContext mgmt;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        mgmt = LocalManagementContextForTests.newInstance();
-        host = new SshMachineLocation(MutableMap.of("address", Networking.getLocalHost()));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (host != null) Streams.closeQuietly(host);
-        if (mgmt != null) Entities.destroyAll(mgmt);
-    }
-    
-    @Test(groups = "Integration")
-    public void testGetMachineDetails() throws Exception {
-        BasicExecutionManager execManager = new BasicExecutionManager("mycontextid");
-        BasicExecutionContext execContext = new BasicExecutionContext(execManager);
-        try {
-            MachineDetails details = execContext.submit(new Callable<MachineDetails>() {
-                public MachineDetails call() {
-                    return host.getMachineDetails();
-                }}).get();
-            assertNotNull(details);
-        } finally {
-            execManager.shutdownNow();
-        }
-    }
-    
-    @Test
-    public void testSupplyingMachineDetails() throws Exception {
-        MachineDetails machineDetails = new BasicMachineDetails(new BasicHardwareDetails(1, 1024), new BasicOsDetails("myname", "myarch", "myversion"));
-        SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure(SshMachineLocation.MACHINE_DETAILS, machineDetails));
-        
-        assertSame(host2.getMachineDetails(), machineDetails);
-    }
-    
-    @Test
-    public void testConfigurePrivateAddresses() throws Exception {
-        SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", Networking.getLocalHost())
-                .configure(SshMachineLocation.PRIVATE_ADDRESSES, ImmutableList.of("1.2.3.4"))
-                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
-
-        assertEquals(host2.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
-    }
-    
-    // Wow, this is hard to test (until I accepted creating the entity + effector)! Code smell?
-    // Need to call getMachineDetails in a DynamicSequentialTask so that the "innessential" takes effect,
-    // to not fail its caller. But to get one of those outside of an effector is non-obvious.
-    @Test(groups = "Integration")
-    public void testGetMachineIsInessentialOnFailure() throws Exception {
-        SshMachineLocation host2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", Networking.getLocalHost())
-                .configure(SshTool.PROP_TOOL_CLASS, FailingSshTool.class.getName()));
-
-        final Effector<MachineDetails> GET_MACHINE_DETAILS = Effectors.effector(MachineDetails.class, "getMachineDetails")
-                .impl(new EffectorBody<MachineDetails>() {
-                    public MachineDetails call(ConfigBag parameters) {
-                        Maybe<MachineLocation> machine = Machines.findUniqueMachineLocation(entity().getLocations());
-                        try {
-                            machine.get().getMachineDetails();
-                            throw new IllegalStateException("Expected failure in ssh");
-                        } catch (RuntimeException e) {
-                            return null;
-                        }
-                    }})
-                .build();
-
-        EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class)
-                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true)
-                .addInitializer(new EntityInitializer() {
-                        public void apply(EntityLocal entity) {
-                            ((EntityInternal)entity).getMutableEntityType().addEffector(EffectorTaskTest.DOUBLE_1);
-                        }});
-
-        TestApplication app = ApplicationBuilder.newManagedApp(appSpec, mgmt);
-
-        app.start(ImmutableList.of(host2));
-        
-        MachineDetails details = app.invoke(GET_MACHINE_DETAILS, ImmutableMap.<String, Object>of()).get();
-        assertNull(details);
-    }
-    public static class FailingSshTool extends RecordingSshTool {
-        public FailingSshTool(Map<?, ?> props) {
-            super(props);
-        }
-        @Override public int execScript(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
-            throw new RuntimeException("Simulating failure of ssh: cmds="+commands);
-        }
-        @Override public int execCommands(Map<String, ?> props, List<String> commands, Map<String, ?> env) {
-            throw new RuntimeException("Simulating failure of ssh: cmds="+commands);
-        }
-    }
-    
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
-    public void testSshExecScript() throws Exception {
-        OutputStream outStream = new ByteArrayOutputStream();
-        String expectedName = Os.user();
-        host.execScript(MutableMap.of("out", outStream), "mysummary", ImmutableList.of("whoami; exit"));
-        String outString = outStream.toString();
-        
-        assertTrue(outString.contains(expectedName), outString);
-    }
-    
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
-    public void testSshExecCommands() throws Exception {
-        OutputStream outStream = new ByteArrayOutputStream();
-        String expectedName = Os.user();
-        host.execCommands(MutableMap.of("out", outStream), "mysummary", ImmutableList.of("whoami; exit"));
-        String outString = outStream.toString();
-        
-        assertTrue(outString.contains(expectedName), outString);
-    }
-    
-    // For issue #230
-    @Test(groups = "Integration")
-    public void testOverridingPropertyOnExec() throws Exception {
-        SshMachineLocation host = new SshMachineLocation(MutableMap.of("address", Networking.getLocalHost(), "sshPrivateKeyData", "wrongdata"));
-        
-        OutputStream outStream = new ByteArrayOutputStream();
-        String expectedName = Os.user();
-        host.execCommands(MutableMap.of("sshPrivateKeyData", null, "out", outStream), "my summary", ImmutableList.of("whoami"));
-        String outString = outStream.toString();
-        
-        assertTrue(outString.contains(expectedName), "outString="+outString);
-    }
-
-    @Test(groups = "Integration", expectedExceptions={IllegalStateException.class, SshException.class})
-    public void testSshRunWithInvalidUserFails() throws Exception {
-        SshMachineLocation badHost = new SshMachineLocation(MutableMap.of("user", "doesnotexist", "address", Networking.getLocalHost()));
-        badHost.execScript("mysummary", ImmutableList.of("whoami; exit"));
-    }
-    
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
-    public void testCopyFileTo() throws Exception {
-        File dest = Os.newTempFile(getClass(), ".dest.tmp");
-        File src = Os.newTempFile(getClass(), ".src.tmp");
-        try {
-            Files.write("abc", src, Charsets.UTF_8);
-            host.copyTo(src, dest);
-            assertEquals("abc", Files.readFirstLine(dest, Charsets.UTF_8));
-        } finally {
-            src.delete();
-            dest.delete();
-        }
-    }
-
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
-    public void testCopyStreamTo() throws Exception {
-        String contents = "abc";
-        File dest = new File(Os.tmp(), "sssMachineLocationTest_dest.tmp");
-        try {
-            host.copyTo(Streams.newInputStreamWithContents(contents), dest.getAbsolutePath());
-            assertEquals("abc", Files.readFirstLine(dest, Charsets.UTF_8));
-        } finally {
-            dest.delete();
-        }
-    }
-
-    @Test(groups = "Integration")
-    public void testInstallUrlTo() throws Exception {
-        File dest = new File(Os.tmp(), "sssMachineLocationTest_dir/");
-        dest.mkdir();
-        try {
-            int result = host.installTo("https://raw.github.com/brooklyncentral/brooklyn/master/README.md", Urls.mergePaths(dest.getAbsolutePath(), "README.md"));
-            assertEquals(result, 0);
-            String contents = ArchiveUtils.readFullyString(new File(dest, "README.md"));
-            assertTrue(contents.contains("http://brooklyncentral.github.com"), "contents missing expected phrase; contains:\n"+contents);
-        } finally {
-            dest.delete();
-        }
-    }
-    
-    @Test(groups = "Integration")
-    public void testInstallClasspathCopyTo() throws Exception {
-        File dest = new File(Os.tmp(), "sssMachineLocationTest_dir/");
-        dest.mkdir();
-        try {
-            int result = host.installTo("classpath://brooklyn/config/sample.properties", Urls.mergePaths(dest.getAbsolutePath(), "sample.properties"));
-            assertEquals(result, 0);
-            String contents = ArchiveUtils.readFullyString(new File(dest, "sample.properties"));
-            assertTrue(contents.contains("Property 1"), "contents missing expected phrase; contains:\n"+contents);
-        } finally {
-            dest.delete();
-        }
-    }
-
-    // Note: requires `ssh localhost` to be setup such that no password is required    
-    @Test(groups = "Integration")
-    public void testIsSshableWhenTrue() throws Exception {
-        assertTrue(host.isSshable());
-    }
-    
-    // Note: on some (home/airport) networks, `ssh 123.123.123.123` hangs seemingly forever.
-    // Make sure we fail, waiting for longer than the 70 second TCP timeout.
-    //
-    // Times out in 2m7s on Ubuntu Vivid (syn retries set to 6)
-    @Test(groups = "Integration")
-    public void testIsSshableWhenFalse() throws Exception {
-        byte[] unreachableIp = new byte[] {123,123,123,123};
-        final SshMachineLocation unreachableHost = new SshMachineLocation(MutableMap.of("address", InetAddress.getByAddress("unreachablename", unreachableIp)));
-        Asserts.assertReturnsEventually(new Runnable() {
-            public void run() {
-                assertFalse(unreachableHost.isSshable());
-            }},
-            Duration.minutes(3));
-    }
-    
-    @Test
-    public void obtainSpecificPortGivesOutPortOnlyOnce() {
-        int port = 2345;
-        assertTrue(host.obtainSpecificPort(port));
-        assertFalse(host.obtainSpecificPort(port));
-        host.releasePort(port);
-        assertTrue(host.obtainSpecificPort(port));
-    }
-    
-    @Test
-    public void obtainPortInRangeGivesBackRequiredPortOnlyIfAvailable() {
-        int port = 2345;
-        assertEquals(host.obtainPort(new LinearPortRange(port, port)), port);
-        assertEquals(host.obtainPort(new LinearPortRange(port, port)), -1);
-        host.releasePort(port);
-        assertEquals(host.obtainPort(new LinearPortRange(port, port)), port);
-    }
-    
-    @Test
-    public void obtainPortInWideRange() {
-        int lowerPort = 2345;
-        int upperPort = 2350;
-        PortRange range = new LinearPortRange(lowerPort, upperPort);
-        for (int i = lowerPort; i <= upperPort; i++) {
-            assertEquals(host.obtainPort(range), i);
-        }
-        assertEquals(host.obtainPort(range), -1);
-        
-        host.releasePort(lowerPort);
-        assertEquals(host.obtainPort(range), lowerPort);
-        assertEquals(host.obtainPort(range), -1);
-    }
-    
-    @Test
-    public void testObtainPortDoesNotUsePreReservedPorts() {
-        host = new SshMachineLocation(MutableMap.of("address", Networking.getLocalHost(), "usedPorts", ImmutableSet.of(8000)));
-        assertEquals(host.obtainPort(PortRanges.fromString("8000")), -1);
-        assertEquals(host.obtainPort(PortRanges.fromString("8000+")), 8001);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.java b/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.java
deleted file mode 100644
index 193a31b..0000000
--- a/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.event.feed.ConfigToAttributes;
-
-import com.google.common.collect.ImmutableList;
-
-public class TestPortSupplierLocation extends BrooklynAppUnitTestSupport {
-
-    SimulatedLocation loc;
-    PortAttributeSensorAndConfigKey ps;
-    TestEntity entity;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        loc = app.newSimulatedLocation();
-        entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-        app.start(ImmutableList.of(loc));
-        
-        ps = new PortAttributeSensorAndConfigKey("some.port", "for testing", "1234+");
-    }
-
-    @Test
-    public void testObtainsPort() throws Exception {
-        ConfigToAttributes.apply(entity, ps);
-        
-        int p = entity.getAttribute(ps);
-        assertEquals(p, 1234);
-        
-        //sensor access should keep the same value
-        p = entity.getAttribute(ps);
-        assertEquals(p, 1234);
-    }
-    
-    @Test
-    public void testRepeatedConvertAccessIncrements() throws Exception {
-        int p = ps.getAsSensorValue(entity);
-        assertEquals(p, 1234);
-
-        //but direct access should see it as being reserved (not required behaviour, but it is the current behaviour)
-        int p2 = ps.getAsSensorValue(entity);
-        assertEquals(p2, 1235);
-    }
-
-    @Test
-    public void testNullBeforeSetting() throws Exception {
-        // currently getting the attribute before explicitly setting return null; i.e. no "auto-set" -- 
-        // but this behaviour may be changed
-        Integer p = entity.getAttribute(ps);
-        assertEquals(p, null);
-    }
-
-    @Test
-    public void testSimulatedRestrictedPermitted() throws Exception {
-        loc.setPermittedPorts(PortRanges.fromString("1240+"));
-        
-        ConfigToAttributes.apply(entity, ps);
-        int p = entity.getAttribute(ps);
-        assertEquals((int)p, 1240);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/cloud/CloudMachineNamerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/cloud/CloudMachineNamerTest.java b/core/src/test/java/brooklyn/location/cloud/CloudMachineNamerTest.java
deleted file mode 100644
index a39c9dc..0000000
--- a/core/src/test/java/brooklyn/location/cloud/CloudMachineNamerTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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 brooklyn.location.cloud;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.cloud.names.AbstractCloudMachineNamer;
-import brooklyn.location.cloud.names.BasicCloudMachineNamer;
-import brooklyn.location.cloud.names.CloudMachineNamer;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.text.Strings;
-public class CloudMachineNamerTest {
-
-    private static final Logger log = LoggerFactory.getLogger(CloudMachineNamerTest.class);
-    
-    private TestApplication app;
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
-    @Test
-    public void testGenerateGroupIdWithEntity() {
-        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
-        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
-
-        ConfigBag cfg = new ConfigBag()
-            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
-
-        String result = new BasicCloudMachineNamer().generateNewGroupId(cfg);
-
-        log.info("test entity child group id gives: "+result);
-        // e.g. brooklyn-alex-tistapp-uube-testent-xisg-rwad
-        Assert.assertTrue(result.length() <= 60);
-
-        String user = Strings.maxlen(System.getProperty("user.name"), 4).toLowerCase();
-        Assert.assertTrue(result.indexOf(user) >= 0);
-        Assert.assertTrue(result.indexOf("-tistapp-") >= 0);
-        Assert.assertTrue(result.indexOf("-testent-") >= 0);
-        Assert.assertTrue(result.indexOf("-"+Strings.maxlen(app.getId(), 4).toLowerCase()) >= 0);
-        Assert.assertTrue(result.indexOf("-"+Strings.maxlen(child.getId(), 4).toLowerCase()) >= 0);
-    }
-    
-    @Test
-    public void testGenerateNewMachineName() {
-        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
-        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
-
-        ConfigBag cfg = new ConfigBag()
-            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
-        BasicCloudMachineNamer namer = new BasicCloudMachineNamer();
-        
-        String result = namer.generateNewMachineUniqueName(cfg);
-        Assert.assertTrue(result.length() <= namer.getMaxNameLength(cfg));
-        String user = Strings.maxlen(System.getProperty("user.name"), 4).toLowerCase();
-        Assert.assertTrue(result.indexOf(user) >= 0);
-        Assert.assertTrue(result.indexOf("-tistapp-") >= 0);
-        Assert.assertTrue(result.indexOf("-testent-") >= 0);
-        Assert.assertTrue(result.indexOf("-"+Strings.maxlen(app.getId(), 4).toLowerCase()) >= 0);
-        Assert.assertTrue(result.indexOf("-"+Strings.maxlen(child.getId(), 4).toLowerCase()) >= 0);
-    }
-    
-    @Test
-    public void testGenerateNewMachineUniqueNameFromGroupId() {
-        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
-        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
-
-        ConfigBag cfg = new ConfigBag()
-            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
-        CloudMachineNamer namer = new BasicCloudMachineNamer();
-        
-        String groupId = namer.generateNewGroupId(cfg);
-        String result = namer.generateNewMachineUniqueNameFromGroupId(cfg, groupId);
-        Assert.assertTrue(result.startsWith(groupId));
-        Assert.assertTrue(result.length() == groupId.length() + 5);
-    }
-    
-    @Test
-    public void testLengthMaxPermittedForMachineName() {
-        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
-        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
-        
-        ConfigBag cfg = new ConfigBag()
-            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
-        BasicCloudMachineNamer namer = new BasicCloudMachineNamer();
-        namer.setDefaultMachineNameMaxLength(10);
-        String result = namer.generateNewMachineUniqueName(cfg);
-        Assert.assertEquals(result.length(), 10);
-    }
-    
-    @Test
-    public void testLengthReservedForNameInGroup() {
-        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TistApp"), LocalManagementContextForTests.newInstance());
-        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
-        
-        ConfigBag cfg = new ConfigBag()
-            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
-        BasicCloudMachineNamer namer = new BasicCloudMachineNamer();
-        namer.setDefaultMachineNameMaxLength(20);
-        namer.setDefaultMachineNameSeparatorAndSaltLength(":I", 5);
-        String groupId = namer.generateNewGroupId(cfg);
-        Assert.assertEquals(13, groupId.length(), "groupId="+groupId);
-        String machineId = namer.generateNewMachineUniqueNameFromGroupId(cfg, groupId);
-        Assert.assertEquals(20, machineId.length(), "machineId="+machineId);
-        // separator is not sanitized -- caller should know what they are doing there!
-        Assert.assertTrue(machineId.startsWith(groupId+"-i"), "machineId="+machineId);
-    }
-
-    @Test
-    public void testSanitizesNewMachineName() {
-        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("T_%$()\r\n\t[]*.!App"), LocalManagementContextForTests.newInstance());
-        TestEntity child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("ent"));
-
-        ConfigBag cfg = new ConfigBag()
-            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
-        CloudMachineNamer namer = new BasicCloudMachineNamer();
-        
-        String result = namer.generateNewMachineUniqueName(cfg);
-        assertTrue(result.indexOf("t-ap") >= 0, "result="+result);
-        for (int c : "_%$()\r\n\t[]*.!".getBytes()) {
-            assertFalse(result.contains(new String(new char [] {(char)c})), "result="+result);
-        }
-    }
-    
-    @Test
-    public void testSanitize() {
-        Assert.assertEquals(AbstractCloudMachineNamer.sanitize(
-                "me & you like alphanumeric but not _ or !!! or dots...dots...dots %$()\r\n\t[]*etc"),
-                "me-you-like-alphanumeric-but-not-or-or-dots-dots-dots-etc");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/cloud/CustomMachineNamerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/cloud/CustomMachineNamerTest.java b/core/src/test/java/brooklyn/location/cloud/CustomMachineNamerTest.java
deleted file mode 100644
index e901e33..0000000
--- a/core/src/test/java/brooklyn/location/cloud/CustomMachineNamerTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 brooklyn.location.cloud;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.cloud.names.CustomMachineNamer;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.collect.ImmutableMap;
-
-public class CustomMachineNamerTest {
-    
-    private TestApplication app;
-    private TestEntity child;
-    private ConfigBag config;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() {
-        app = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class).displayName("TestApp"), LocalManagementContextForTests.newInstance());
-        child = app.createAndManageChild(EntitySpec.create(TestEntity.class).displayName("TestEnt"));
-        config = new ConfigBag()
-            .configure(CloudLocationConfig.CALLER_CONTEXT, child);
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (app != null) Entities.destroyAll(app.getManagementContext());
-    }
-
-    @Test
-    public void testMachineNameNoConfig() {
-        config.configure(CloudLocationConfig.CALLER_CONTEXT, child);
-        Assert.assertEquals(new CustomMachineNamer().generateNewMachineUniqueName(config), "TestEnt");
-    }
-    
-    @Test
-    public void testMachineNameWithConfig() {
-        child.setSequenceValue(999);
-        config.configure(CustomMachineNamer.MACHINE_NAME_TEMPLATE, "number${entity.sequenceValue}");
-        Assert.assertEquals(new CustomMachineNamer().generateNewMachineUniqueName(config), "number999");
-    }
-    
-    @Test
-    public void testMachineNameWithExtraSubstitutions() {
-        config.configure(CustomMachineNamer.MACHINE_NAME_TEMPLATE, "foo-${fooName}-bar-${barName}-baz-${bazName.substitution}")
-            .configure(CustomMachineNamer.EXTRA_SUBSTITUTIONS, ImmutableMap.of("fooName", "foo", "barName", "bar", "bazName", this));
-        Assert.assertEquals(new CustomMachineNamer().generateNewMachineUniqueName(config), "foo-foo-bar-bar-baz-baz");
-    }
-    
-    public String getSubstitution() {
-        return "baz";
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/geo/HostGeoInfoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/geo/HostGeoInfoTest.java b/core/src/test/java/brooklyn/location/geo/HostGeoInfoTest.java
deleted file mode 100644
index 1f82275..0000000
--- a/core/src/test/java/brooklyn/location/geo/HostGeoInfoTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertNotNull;
-
-import org.testng.annotations.Test;
-
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
-import brooklyn.util.collections.MutableMap;
-
-public class HostGeoInfoTest {
-    private static final String IP = "192.168.0.1";
-    
-    private static final Location CUSTOM_LOCATION = new SimulatedLocation(MutableMap.of("name", "custom", "latitude", 50d, "longitude", 0d));
-    private static final Location CUSTOM_LOCATION_CHILD = new SimulatedLocation(MutableMap.of("name", "custom-child", "address", IP, "parentLocation", CUSTOM_LOCATION));
-        
-    @Test
-    public void testCustomLocationCoordinates() {
-        HostGeoInfo hgi = HostGeoInfo.fromLocation(CUSTOM_LOCATION);
-        assertNotNull(hgi);
-        assertEquals(50.0d, hgi.latitude);
-        assertEquals(0.0d, hgi.longitude);
-    }
-    
-    @Test
-    public void testCustomLocationChildCoordinates() {
-        HostGeoInfo hgi = HostGeoInfo.fromLocation(CUSTOM_LOCATION_CHILD);
-        assertNotNull(hgi);
-        assertEquals(50.0d, hgi.latitude);
-        assertEquals(0.0d, hgi.longitude);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/geo/HostGeoLookupIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/geo/HostGeoLookupIntegrationTest.java b/core/src/test/java/brooklyn/location/geo/HostGeoLookupIntegrationTest.java
deleted file mode 100644
index c362ab4..0000000
--- a/core/src/test/java/brooklyn/location/geo/HostGeoLookupIntegrationTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import java.net.InetAddress;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.time.Duration;
-
-import com.google.common.base.Objects;
-
-public class HostGeoLookupIntegrationTest {
-
-    public static final Logger log = LoggerFactory.getLogger(HostGeoLookupIntegrationTest.class);
-    
-    // Needs fast network connectivity to figure out the external IP. If response not returned in 2s fails.
-    @Test(groups = "Integration")
-    public void testLocalhostGetsLocation() throws Exception {
-        LocalhostMachineProvisioningLocation ll = new LocalhostMachineProvisioningLocation();
-        SshMachineLocation l = ll.obtain();
-        HostGeoInfo geo = HostGeoInfo.fromLocation(l);
-        Assert.assertNotNull(geo, "host lookup unavailable - is the maxmind database installed? or else network unavailable or too slow?");
-        log.info("localhost is in "+geo);
-        Assert.assertNotNull(geo, "couldn't load data; must have a valid HostGeoLookup impl (e.g. MaxMind installed, or online and with Utrace credit)");
-        Assert.assertTrue(-90 <= geo.latitude && geo.latitude <= 90); 
-        ll.close();
-    }
-
-    @Deprecated // see GeoBytesHostGeoLookup - their API changed
-    @Test(groups = "Integration", enabled=false)
-    public void testGeobytesLookup() throws Exception {
-        HostGeoInfo geo = new GeoBytesHostGeoLookup().getHostGeoInfo(InetAddress.getByName("geobytes.com"));
-        Assert.assertNotNull(geo, "host lookup unavailable");
-        Assert.assertEquals(geo.displayName, "Baltimore (US)");
-        Assert.assertEquals(geo.latitude, 39.2894, 0.1);
-        Assert.assertEquals(geo.longitude, -76.6384, 0.1);
-    }
-
-    @Test(groups = "Integration")
-    public void testUtraceLookup() throws Exception {
-        // The test times out in a VM - VirtualBox + Ubuntu Vivid, possibly due to proxy usage?
-        // Increase the timeout so we can actually test it's working correctly, regardless of test environment.
-        HostGeoInfo geo = new UtraceHostGeoLookup().getHostGeoInfo(InetAddress.getByName("utrace.de"), Duration.THIRTY_SECONDS);
-        Assert.assertNotNull(geo, "host lookup unavailable - maybe network not available ");
-        Assert.assertTrue(geo.displayName.contains("(DE)"));
-        Assert.assertEquals(geo.latitude, 51, 2);
-        Assert.assertEquals(geo.longitude, 9, 5);
-    }
-
-    @Test(groups = "Integration")  // only works if maxmind database is installed to ~/.brooklyn/
-    public void testMaxmindLookup() throws Exception {
-        HostGeoInfo geo = new MaxMind2HostGeoLookup().getHostGeoInfo(InetAddress.getByName("maxmind.com"));
-        Assert.assertNotNull(geo, "host lookup unavailable - is the maxmind database installed?");
-        log.info("maxmind.com at "+geo);
-        
-        // used to be Washington; now Dallas - in case this changes again, we will accept either!
-        // also have seen variation in lat/lon reported, so happy to within one degree now
-        Assert.assertTrue(Objects.equal(geo.displayName, "Washington, DC (US)") || Objects.equal(geo.displayName, "Dallas, TX (US)"), "name="+geo.displayName);
-        Assert.assertTrue(Math.abs(geo.latitude - 38.90) <= 1 || Math.abs(geo.latitude - 32.78) <= 1, "lat="+geo.latitude);
-        Assert.assertTrue(Math.abs(geo.longitude - -77.02) <= 1 || Math.abs(geo.longitude - -96.82) <= 1, "lon="+geo.longitude);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/geo/LocalhostExternalIpLoaderIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/geo/LocalhostExternalIpLoaderIntegrationTest.java b/core/src/test/java/brooklyn/location/geo/LocalhostExternalIpLoaderIntegrationTest.java
deleted file mode 100644
index 6ec9b00..0000000
--- a/core/src/test/java/brooklyn/location/geo/LocalhostExternalIpLoaderIntegrationTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.Sets;
-
-public class LocalhostExternalIpLoaderIntegrationTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(LocalhostExternalIpLoaderIntegrationTest.class);
-
-    @Test(groups = "Integration")
-    public void testHostsAgreeOnExternalIp() {
-        Set<String> ips = Sets.newHashSet();
-        for (String url : LocalhostExternalIpLoader.getIpAddressWebsites()) {
-            String ip = LocalhostExternalIpLoader.getIpAddressFrom(url);
-            LOG.debug("IP from {}: {}", url, ip);
-            ips.add(ip);
-        }
-        assertEquals(ips.size(), 1, "Expected all IP suppliers to agree on the external IP address of Brooklyn. " +
-                "Check logs for source responses. ips=" + ips);
-    }
-
-    @Test(groups = "Integration")
-    public void testLoadExternalIp() {
-        assertNotNull(LocalhostExternalIpLoader.getLocalhostIpWaiting());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
index 361c636..018641e 100644
--- a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
+++ b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
@@ -36,10 +36,7 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.management.entitlement.Entitlements;
-import brooklyn.management.entitlement.NotEntitledException;
-import brooklyn.management.entitlement.WebEntitlementContext;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
 import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java b/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
index 6aa9167..c4c8956 100644
--- a/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
+++ b/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
@@ -34,7 +34,7 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
 import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.management.internal.LocalManagementContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
index b4d4def..1062229 100644
--- a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
+++ b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
@@ -34,10 +34,10 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.persister.InMemoryObjectStore;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.location.Location;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
index d085acf..ea99621 100644
--- a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
+++ b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
@@ -50,7 +50,7 @@ import brooklyn.entity.rebind.persister.ListeningObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.ha.TestEntityFailingRebind.RebindException;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.test.Asserts;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java b/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java
index 192a649..ae9e3b4 100644
--- a/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java
+++ b/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java
@@ -58,9 +58,9 @@ import brooklyn.entity.rebind.persister.InMemoryObjectStore;
 import brooklyn.entity.rebind.persister.ListeningObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
 import brooklyn.management.internal.AbstractManagementContext;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java b/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java
index e4ab1ca..4afc78c 100644
--- a/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java
+++ b/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java
@@ -42,7 +42,7 @@ import brooklyn.entity.rebind.persister.InMemoryObjectStore;
 import brooklyn.entity.rebind.persister.ListeningObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java b/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java
index 4faf676..59d92c7 100644
--- a/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java
+++ b/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java
@@ -33,9 +33,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.ImmutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java b/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java
index 2d1f296..a648c74 100644
--- a/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java
+++ b/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java
@@ -33,7 +33,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.config.BrooklynProperties.Factory.Builder;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.os.Os;
 
 import com.google.common.base.Charsets;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.java b/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.java
index 3981af7..e3b2dc8 100644
--- a/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.java
+++ b/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.java
@@ -31,7 +31,7 @@ import org.apache.brooklyn.entity.basic.RecordingSensorEventListener;
 import org.apache.brooklyn.test.entity.TestEntity;
 
 import brooklyn.event.basic.BasicSensorEvent;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java
index 4e2cb24..6b8f87c 100644
--- a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java
+++ b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java
@@ -20,8 +20,8 @@ package brooklyn.qa.longevity;
 
 import org.testng.annotations.Test;
 
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.javalang.JavaClassNames;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
index a6843e4..225dc08 100644
--- a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
+++ b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
@@ -39,8 +39,8 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.internal.storage.DataGrid;
 import brooklyn.internal.storage.impl.BrooklynStorageImpl;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.management.internal.AbstractManagementContext;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java
index 1e3898c..2313e08 100644
--- a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java
+++ b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java
@@ -20,8 +20,8 @@ package brooklyn.qa.longevity;
 
 import org.testng.annotations.Test;
 
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.javalang.JavaClassNames;
 
 public class EntityCleanupTest extends EntityCleanupLongevityTestFixture {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/qa/performance/AbstractPerformanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/performance/AbstractPerformanceTest.java b/core/src/test/java/brooklyn/qa/performance/AbstractPerformanceTest.java
index 87784f0..ec6553d 100644
--- a/core/src/test/java/brooklyn/qa/performance/AbstractPerformanceTest.java
+++ b/core/src/test/java/brooklyn/qa/performance/AbstractPerformanceTest.java
@@ -31,7 +31,7 @@ import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.internal.DoubleSystemProperty;
 
 import com.google.common.base.Stopwatch;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java b/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java
index 84ce2f1..1f8b669 100644
--- a/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java
+++ b/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java
@@ -30,8 +30,8 @@ import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.policy.TestPolicy;
 import brooklyn.util.repeat.Repeater;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/test/HttpService.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/test/HttpService.java b/core/src/test/java/brooklyn/test/HttpService.java
index 6b9aa94..8a73541 100644
--- a/core/src/test/java/brooklyn/test/HttpService.java
+++ b/core/src/test/java/brooklyn/test/HttpService.java
@@ -39,8 +39,8 @@ import org.eclipse.jetty.webapp.WebAppContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.crypto.SecureKeys;
 import brooklyn.util.javalang.Threads;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/test/location/TestPaasLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/test/location/TestPaasLocation.java b/core/src/test/java/brooklyn/test/location/TestPaasLocation.java
index be2ba56..0021d89 100644
--- a/core/src/test/java/brooklyn/test/location/TestPaasLocation.java
+++ b/core/src/test/java/brooklyn/test/location/TestPaasLocation.java
@@ -18,11 +18,11 @@
  */
 package brooklyn.test.location;
 
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.paas.PaasLocation;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.paas.PaasLocation;
 
 /**
- * Mock {@link brooklyn.location.paas.PaasLocation} for test purposes
+ * Mock {@link PaasLocation} for test purposes
  */
 public class TestPaasLocation extends AbstractLocation implements PaasLocation {
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/util/file/ArchiveUtilsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/file/ArchiveUtilsTest.java b/core/src/test/java/brooklyn/util/file/ArchiveUtilsTest.java
index dba8410..6715444 100644
--- a/core/src/test/java/brooklyn/util/file/ArchiveUtilsTest.java
+++ b/core/src/test/java/brooklyn/util/file/ArchiveUtilsTest.java
@@ -32,7 +32,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.os.Os;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/util/http/HttpToolIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/http/HttpToolIntegrationTest.java b/core/src/test/java/brooklyn/util/http/HttpToolIntegrationTest.java
index f6fc1cd..dc9fc31 100644
--- a/core/src/test/java/brooklyn/util/http/HttpToolIntegrationTest.java
+++ b/core/src/test/java/brooklyn/util/http/HttpToolIntegrationTest.java
@@ -27,7 +27,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.test.HttpService;
 
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/util/ssh/BashCommandsIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/ssh/BashCommandsIntegrationTest.java b/core/src/test/java/brooklyn/util/ssh/BashCommandsIntegrationTest.java
index 1f8ba28..accac56 100644
--- a/core/src/test/java/brooklyn/util/ssh/BashCommandsIntegrationTest.java
+++ b/core/src/test/java/brooklyn/util/ssh/BashCommandsIntegrationTest.java
@@ -44,8 +44,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java b/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
index 1f31447..6fd7560 100644
--- a/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
+++ b/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
@@ -32,9 +32,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
new file mode 100644
index 0000000..da69b24
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.apache.brooklyn.location.access;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+
+public class PortForwardManagerLocationResolverTest {
+
+    private LocalManagementContext managementContext;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testReturnsSameInstanceBasedOnScope() {
+        Location global1 = resolve("portForwardManager()"); // defaults to global
+        Location global2 = resolve("portForwardManager()");
+        Location global3 = resolve("portForwardManager(scope=global)");
+        assertSame(global1, global2);
+        assertSame(global1, global3);
+        
+        Location a1 = resolve("portForwardManager(scope=a)");
+        Location a2 = resolve("portForwardManager(scope=a)");
+        assertSame(a1, a2);
+        assertNotSame(global1, a1);
+        
+        Location b1 = resolve("portForwardManager(scope=b)");
+        assertNotSame(global1, b1);
+        assertNotSame(a1, b1);
+    }
+
+    private Location resolve(String val) {
+        Location l = managementContext.getLocationRegistry().resolve(val);
+        Assert.assertNotNull(l);
+        return l;
+    }
+    
+    private void assertSame(Location loc1, Location loc2) {
+        Assert.assertNotNull(loc1);
+        Assert.assertTrue(loc1 instanceof PortForwardManager, "loc1="+loc1);
+        Assert.assertSame(loc1, loc2);
+    }
+    
+    private void assertNotSame(Location loc1, Location loc2) {
+        Assert.assertNotNull(loc1);
+        Assert.assertNotNull(loc2);
+        Assert.assertTrue(loc1 instanceof PortForwardManager, "loc1="+loc1);
+        Assert.assertTrue(loc2 instanceof PortForwardManager, "loc2="+loc2);
+        Assert.assertNotSame(loc1, loc2);
+        Assert.assertNotEquals(((PortForwardManager)loc1).getId(), ((PortForwardManager)loc2).getId());
+    }
+}


[23/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java
new file mode 100644
index 0000000..1b5b743
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java
@@ -0,0 +1,186 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class LocationExtensionsTest {
+
+    public static class ConcreteLocation extends AbstractLocation {
+        private static final long serialVersionUID = 2407231019435442876L;
+
+        public ConcreteLocation() {
+            super();
+        }
+    }
+
+    public interface MyExtension {
+    }
+    
+    public static class MyExtensionImpl implements MyExtension {
+    }
+    
+    private ManagementContext mgmt;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        mgmt = new LocalManagementContextForTests();
+    }
+    
+    @AfterMethod(alwaysRun = true)
+    public void tearDown(){
+        if (mgmt!=null) Entities.destroyAll(mgmt);
+    }
+
+    private ConcreteLocation createConcrete() {
+        return mgmt.getLocationManager().createLocation(LocationSpec.create(ConcreteLocation.class));
+    }
+    
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    private ConcreteLocation createConcrete(Class<?> extensionType, Object extension) {
+        // this cast is needed to make IntelliJ happy
+        return (ConcreteLocation) mgmt.getLocationManager().createLocation(LocationSpec.create(ConcreteLocation.class).extension((Class)extensionType, extension));
+    }
+    
+    @Test
+    public void testHasExtensionWhenMissing() {
+        Location loc = createConcrete();
+        assertFalse(loc.hasExtension(MyExtension.class));
+    }
+
+    @Test
+    public void testWhenExtensionPresent() {
+        MyExtension extension = new MyExtensionImpl();
+        ConcreteLocation loc = createConcrete();
+        loc.addExtension(MyExtension.class, extension);
+        
+        assertTrue(loc.hasExtension(MyExtension.class));
+        assertEquals(loc.getExtension(MyExtension.class), extension);
+    }
+
+    @Test
+    public void testAddExtensionThroughLocationSpec() {
+        MyExtension extension = new MyExtensionImpl();
+        Location loc = createConcrete(MyExtension.class, extension);
+        
+        assertTrue(loc.hasExtension(MyExtension.class));
+        assertEquals(loc.getExtension(MyExtension.class), extension);
+    }
+
+    @Test
+    public void testGetExtensionWhenMissing() {
+        Location loc = createConcrete();
+
+        try {
+            loc.getExtension(MyExtension.class);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+        
+        try {
+            loc.getExtension(null);
+            fail();
+        } catch (NullPointerException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testWhenExtensionDifferent() {
+        MyExtension extension = new MyExtensionImpl();
+        ConcreteLocation loc = createConcrete();
+        loc.addExtension(MyExtension.class, extension);
+        
+        assertFalse(loc.hasExtension(Object.class));
+        
+        try {
+            loc.getExtension(Object.class);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+    }
+
+    @Test
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public void testAddExtensionIllegally() {
+        MyExtension extension = new MyExtensionImpl();
+        ConcreteLocation loc = createConcrete();
+        
+        try {
+            loc.addExtension((Class)MyExtension.class, "not an extension");
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+        
+        try {
+            loc.addExtension(MyExtension.class, null);
+            fail();
+        } catch (NullPointerException e) {
+            // success
+        }
+        
+        try {
+            loc.addExtension(null, extension);
+            fail();
+        } catch (NullPointerException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testAddExtensionThroughLocationSpecIllegally() {
+        MyExtension extension = new MyExtensionImpl();
+        
+        try {
+            Location loc = createConcrete(MyExtension.class, "not an extension");
+            fail("loc="+loc);
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+        
+        try {
+            Location loc = createConcrete(MyExtension.class, null);
+            fail("loc="+loc);
+        } catch (NullPointerException e) {
+            // success
+        }
+        
+        try {
+            Location loc = createConcrete(null, extension);
+            fail("loc="+loc);
+        } catch (NullPointerException e) {
+            // success
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java
new file mode 100644
index 0000000..be68557
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import org.apache.brooklyn.api.management.LocationManager;
+import org.apache.brooklyn.location.LocationSpec;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.BrooklynAppUnitTestSupport;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public class LocationManagementTest extends BrooklynAppUnitTestSupport {
+
+    private LocationManager locationManager;
+
+    @BeforeMethod(alwaysRun=true)
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        locationManager = mgmt.getLocationManager();
+    }
+    
+    @Test
+    public void testCreateLocationUsingSpec() {
+        SshMachineLocation loc = locationManager.createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", "1.2.3.4"));
+        
+        assertEquals(loc.getAddress().getHostAddress(), "1.2.3.4");
+        assertSame(locationManager.getLocation(loc.getId()), loc);
+    }
+    
+    @Test
+    public void testCreateLocationUsingResolver() {
+        String spec = "byon:(hosts=\"1.1.1.1\")";
+        FixedListMachineProvisioningLocation<SshMachineLocation> loc = (FixedListMachineProvisioningLocation<SshMachineLocation>) mgmt.getLocationRegistry().resolve(spec);
+        SshMachineLocation machine = Iterables.getOnlyElement(loc.getAllMachines());
+        
+        assertSame(locationManager.getLocation(loc.getId()), loc);
+        assertSame(locationManager.getLocation(machine.getId()), machine);
+    }
+    
+    @Test
+    public void testChildrenOfManagedLocationAutoManaged() {
+        String spec = "byon:(hosts=\"1.1.1.1\")";
+        FixedListMachineProvisioningLocation<SshMachineLocation> loc = (FixedListMachineProvisioningLocation<SshMachineLocation>) mgmt.getLocationRegistry().resolve(spec);
+        SshMachineLocation machine = new SshMachineLocation(ImmutableMap.of("address", "1.2.3.4"));
+
+        loc.addChild(machine);
+        assertSame(locationManager.getLocation(machine.getId()), machine);
+        assertTrue(machine.isManaged());
+        
+        loc.removeChild(machine);
+        assertNull(locationManager.getLocation(machine.getId()));
+        assertFalse(machine.isManaged());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java
new file mode 100644
index 0000000..3324477
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.test.entity.TestEntity;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+
+public class LocationPredicatesTest {
+
+    private LocalManagementContext managementContext;
+    private LocalhostMachineProvisioningLocation loc;
+    private SshMachineLocation childLoc;
+    private Location grandchildLoc;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+        loc = (LocalhostMachineProvisioningLocation) managementContext.getLocationRegistry().resolve("localhost:(name=mydisplayname)");
+        childLoc = loc.obtain();
+        grandchildLoc = managementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class).parent(childLoc));
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testIdEqualTo() throws Exception {
+        assertTrue(LocationPredicates.idEqualTo(loc.getId()).apply(loc));
+        assertFalse(LocationPredicates.idEqualTo("wrongid").apply(loc));
+    }
+    
+    @Test
+    public void testConfigEqualTo() throws Exception {
+        loc.setConfig(TestEntity.CONF_NAME, "myname");
+        assertTrue(LocationPredicates.configEqualTo(TestEntity.CONF_NAME, "myname").apply(loc));
+        assertFalse(LocationPredicates.configEqualTo(TestEntity.CONF_NAME, "wrongname").apply(loc));
+    }
+    
+    @Test
+    public void testDisplayNameEqualTo() throws Exception {
+        assertTrue(LocationPredicates.displayNameEqualTo("mydisplayname").apply(loc));
+        assertFalse(LocationPredicates.displayNameEqualTo("wrongname").apply(loc));
+    }
+    
+    @Test
+    public void testIsChildOf() throws Exception {
+        assertTrue(LocationPredicates.isChildOf(loc).apply(childLoc));
+        assertFalse(LocationPredicates.isChildOf(loc).apply(loc));
+        assertFalse(LocationPredicates.isChildOf(childLoc).apply(loc));
+    }
+    
+    @Test
+    public void testIsDescendantOf() throws Exception {
+        assertTrue(LocationPredicates.isDescendantOf(loc).apply(grandchildLoc));
+        assertTrue(LocationPredicates.isDescendantOf(loc).apply(childLoc));
+        assertFalse(LocationPredicates.isDescendantOf(loc).apply(loc));
+        assertFalse(LocationPredicates.isDescendantOf(childLoc).apply(loc));
+    }
+    
+    @Test
+    public void testManaged() throws Exception {
+        // TODO get exception in LocalhostMachineProvisioningLocation.removeChild because childLoc is "in use";
+        // this happens from the call to unmanage(loc), which first unmanaged the children.
+        loc.release(childLoc);
+        
+        assertTrue(LocationPredicates.managed().apply(loc));
+        Locations.unmanage(loc);
+        assertFalse(LocationPredicates.managed().apply(loc));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocationPropertiesFromBrooklynPropertiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationPropertiesFromBrooklynPropertiesTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationPropertiesFromBrooklynPropertiesTest.java
new file mode 100644
index 0000000..8be1689
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationPropertiesFromBrooklynPropertiesTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Maps;
+
+public class LocationPropertiesFromBrooklynPropertiesTest {
+
+    private LocationPropertiesFromBrooklynProperties parser;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        parser = new LocationPropertiesFromBrooklynProperties();
+    }
+    
+    @Test
+    public void testExtractProviderProperties() throws Exception {
+        String provider = "myprovider";
+        String namedLocation = null;
+        
+        Map<String, String> properties = Maps.newLinkedHashMap();
+        
+        // prefer those in "named" over everything else
+        properties.put("brooklyn.location.myprovider.privateKeyFile", "privateKeyFile-inProviderSpecific");
+        properties.put("brooklyn.location.privateKeyFile", "privateKeyFile-inLocationGeneric");
+
+        // prefer location-generic if nothing else
+        properties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inLocationGeneric");
+        
+        Map<String, Object> conf = parser.getLocationProperties(provider, namedLocation, properties);
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inProviderSpecific");
+        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inLocationGeneric");
+    }
+
+    @Test
+    public void testExtractNamedLocationProperties() throws Exception {
+        String provider = "myprovider";
+        String namedLocation = "mynamed";
+        
+        Map<String, String> properties = Maps.newLinkedHashMap();
+        
+        properties.put("brooklyn.location.named.mynamed", "myprovider");
+        
+        // prefer those in "named" over everything else
+        properties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
+        properties.put("brooklyn.location.myprovider.privateKeyFile", "privateKeyFile-inProviderSpecific");
+        properties.put("brooklyn.location.privateKeyFile", "privateKeyFile-inGeneric");
+
+        // prefer those in provider-specific over generic
+        properties.put("brooklyn.location.myprovider.publicKeyFile", "publicKeyFile-inProviderSpecific");
+        properties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inGeneric");
+
+        // prefer location-generic if nothing else
+        properties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
+
+        Map<String, Object> conf = parser.getLocationProperties(provider, namedLocation, properties);
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
+        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
+        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
+    }
+
+    @Test
+    public void testConvertsDeprecatedFormats() throws Exception {
+        String provider = "myprovider";
+        String namedLocation = "mynamed";
+        
+        Map<String, String> properties = Maps.newLinkedHashMap();
+        
+        properties.put("brooklyn.location.named.mynamed", "myprovider");
+        
+        // prefer those in "named" over everything else
+        properties.put("brooklyn.location.named.mynamed.private-key-file", "privateKeyFile-inNamed");
+        properties.put("brooklyn.location.myprovider.public-key-file", "publicKeyFile-inProviderSpecific");
+        properties.put("brooklyn.location.private-key-data", "privateKeyData-inGeneric");
+
+        Map<String, Object> conf = parser.getLocationProperties(provider, namedLocation, properties);
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
+        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
+        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
+    }
+    
+
+    @Test
+    public void testThrowsIfProviderDoesNotMatchNamed() throws Exception {
+        String provider = "myprovider";
+        String namedLocation = "mynamed";
+        
+        Map<String, String> properties = Maps.newLinkedHashMap();
+        
+        properties.put("brooklyn.location.named.mynamed", "completelydifferent");
+
+        try {
+            Map<String, Object> conf = parser.getLocationProperties(provider, namedLocation, properties);
+        } catch (IllegalStateException e) {
+            if (!e.toString().contains("Conflicting configuration")) throw e;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java
new file mode 100644
index 0000000..ed8a96d
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.LocationDefinition;
+import brooklyn.management.internal.LocalManagementContext;
+
+public class LocationRegistryTest {
+    
+    private static final Logger log = LoggerFactory.getLogger(LocationRegistryTest.class);
+    
+    private LocalManagementContext mgmt;
+    private LocationDefinition locdef;
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown(){
+        if (mgmt != null) Entities.destroyAll(mgmt);
+    }
+
+    @Test
+    public void testNamedLocationsPropertyDefinedLocations() {
+        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
+        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
+        properties.put("brooklyn.location.named.foo.privateKeyFile", "~/.ssh/foo.id_rsa");
+        mgmt = LocalManagementContextForTests.newInstance(properties);
+        log.info("foo properties gave defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
+        locdef = mgmt.getLocationRegistry().getDefinedLocationByName("foo");
+        Assert.assertNotNull(locdef, "Expected 'foo' location; but had "+mgmt.getLocationRegistry().getDefinedLocations());
+        Assert.assertEquals(locdef.getConfig().get("privateKeyFile"), "~/.ssh/foo.id_rsa");
+    }
+    
+    @Test(dependsOnMethods="testNamedLocationsPropertyDefinedLocations")
+    public void testResolvesByNamedAndId() {
+        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
+        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
+        properties.put("brooklyn.location.named.foo.privateKeyFile", "~/.ssh/foo.id_rsa");
+        mgmt = LocalManagementContextForTests.newInstance(properties);
+
+        locdef = mgmt.getLocationRegistry().getDefinedLocationByName("foo");
+        log.info("testResovlesBy has defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
+        
+        Location l = mgmt.getLocationRegistry().resolve("named:foo");
+        Assert.assertNotNull(l);
+        Assert.assertEquals(l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), "~/.ssh/foo.id_rsa");
+        
+        l = mgmt.getLocationRegistry().resolve("foo");
+        Assert.assertNotNull(l);
+        Assert.assertEquals(l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), "~/.ssh/foo.id_rsa");
+        
+        l = mgmt.getLocationRegistry().resolve("id:"+locdef.getId());
+        Assert.assertNotNull(l);
+        Assert.assertEquals(l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), "~/.ssh/foo.id_rsa");
+        
+        l = mgmt.getLocationRegistry().resolve(locdef.getId());
+        Assert.assertNotNull(l);
+        Assert.assertEquals(l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), "~/.ssh/foo.id_rsa");
+    }
+
+    @Test
+    public void testLocationGetsDisplayName() {
+        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
+        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
+        properties.put("brooklyn.location.named.foo.displayName", "My Foo");
+        mgmt = LocalManagementContextForTests.newInstance(properties);
+        Location l = mgmt.getLocationRegistry().resolve("foo");
+        Assert.assertEquals(l.getDisplayName(), "My Foo");
+    }
+    
+    @Test
+    public void testLocationGetsDefaultDisplayName() {
+        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
+        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
+        mgmt = LocalManagementContextForTests.newInstance(properties);
+        Location l = mgmt.getLocationRegistry().resolve("foo");
+        Assert.assertNotNull(l.getDisplayName());
+        Assert.assertTrue(l.getDisplayName().startsWith(FixedListMachineProvisioningLocation.class.getSimpleName()), "name="+l.getDisplayName());
+        // TODO currently it gives default name; it would be nice to use 'foo', 
+        // or at least to have access to the spec (and use it e.g. in places such as DynamicFabric)
+        // Assert.assertEquals(l.getDisplayName(), "foo");
+    }
+    
+    @Test
+    public void testSetupForTesting() {
+        mgmt = LocalManagementContextForTests.newInstance();
+        BasicLocationRegistry.setupLocationRegistryForTesting(mgmt);
+        Assert.assertNotNull(mgmt.getLocationRegistry().getDefinedLocationByName("localhost"));
+    }
+
+    @Test
+    public void testCircularReference() {
+        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
+        properties.put("brooklyn.location.named.bar", "named:bar");
+        mgmt = LocalManagementContextForTests.newInstance(properties);
+        log.info("bar properties gave defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
+        boolean resolved = false;
+        try {
+            mgmt.getLocationRegistry().resolve("bar");
+            resolved = true;
+        } catch (IllegalStateException e) {
+            //expected
+            log.info("bar properties correctly caught circular reference: "+e);
+        }
+        if (resolved)
+            // probably won't happen, if test fails will loop endlessly above
+            Assert.fail("Circular reference resolved location");
+    }
+
+    protected boolean findLocationMatching(String regex) {
+        for (LocationDefinition d: mgmt.getLocationRegistry().getDefinedLocations().values()) {
+            if (d.getName()!=null && d.getName().matches(regex)) return true;
+        }
+        return false;
+    }
+    
+    @Test
+    public void testLocalhostEnabled() {
+        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
+        properties.put("brooklyn.location.localhost.enabled", true);
+        mgmt = LocalManagementContextForTests.newInstance(properties);
+        Assert.assertTrue( findLocationMatching("localhost") );
+    }
+
+    @Test
+    public void testLocalhostDisabled() {
+        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
+        properties.put("brooklyn.location.localhost.enabled", false);
+        mgmt = LocalManagementContextForTests.newInstance(properties);
+        log.info("RESOLVERS: "+mgmt.getLocationRegistry().getDefinedLocations());
+        log.info("DEFINED LOCATIONS: "+mgmt.getLocationRegistry().getDefinedLocations());
+        Assert.assertFalse( findLocationMatching("localhost") );
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java
new file mode 100644
index 0000000..7b36172
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+import java.util.Arrays;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+
+public class MachineDetailsTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SshMachineLocationTest.class);
+
+    TestApplication app;
+    ManagementContext mgmt;
+    SshMachineLocation host;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setup() throws Exception {
+        app = TestApplication.Factory.newManagedInstanceForTests();
+        mgmt = app.getManagementContext();
+
+        LocalhostMachineProvisioningLocation localhost = mgmt.getLocationManager().createLocation(
+                LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+        host = localhost.obtain();
+        app.start(Arrays.asList(host));
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (mgmt != null) Entities.destroyAll(mgmt);
+        mgmt = null;
+    }
+
+    @Test(groups = "Integration")
+    public void testGetMachineDetails() {
+        Task<BasicMachineDetails> detailsTask = app.getExecutionContext().submit(
+                BasicMachineDetails.taskForSshMachineLocation(host));
+        MachineDetails machine = detailsTask.getUnchecked();
+        LOG.info("Found the following on localhost: {}", machine);
+        assertNotNull(machine);
+        OsDetails details = machine.getOsDetails();
+        assertNotNull(details);
+        assertNotNull(details.getArch());
+        assertNotNull(details.getName());
+        assertNotNull(details.getVersion());
+        assertFalse(details.getArch().startsWith("architecture:"), "architecture prefix not removed from details");
+        assertFalse(details.getName().startsWith("name:"), "name prefix not removed from details");
+        assertFalse(details.getVersion().startsWith("version:"), "version prefix not removed from details");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java
new file mode 100644
index 0000000..25c2e9e
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.rebind.RebindTestUtils;
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.net.Networking;
+import brooklyn.util.os.Os;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class MultiLocationRebindTest {
+
+    private ClassLoader classLoader = getClass().getClassLoader();
+    private ManagementContext origManagementContext;
+    private ManagementContext newManagementContext;
+    private File mementoDir;
+    
+    private TestApplication origApp;
+    private TestApplication newApp;
+    private SshMachineLocation mac1a;
+    private SshMachineLocation mac2a;
+    private FixedListMachineProvisioningLocation<SshMachineLocation> loc1;
+    private FixedListMachineProvisioningLocation<SshMachineLocation> loc2;
+    private MultiLocation<SshMachineLocation> multiLoc;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        mementoDir = Os.newTempDir(getClass());
+        origManagementContext = RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
+        origApp = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class), origManagementContext);
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (origManagementContext != null) Entities.destroyAll(origManagementContext);
+        if (newApp != null) Entities.destroyAll(newApp.getManagementContext());
+        if (newManagementContext != null) Entities.destroyAll(newManagementContext);
+        if (mementoDir != null) RebindTestUtils.deleteMementoDir(mementoDir);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRebindsMultiLocation() throws Exception {
+        mac1a = origManagementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .displayName("mac1a")
+                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.1")));
+        mac2a = origManagementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .displayName("mac2a")
+                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.3")));
+        loc1 = origManagementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .displayName("loc1")
+                .configure("machines", MutableSet.of(mac1a)));
+        loc2 = origManagementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .displayName("loc2")
+                .configure("machines", MutableSet.of(mac2a)));
+        multiLoc = origManagementContext.getLocationManager().createLocation(LocationSpec.create(MultiLocation.class)
+                        .displayName("multiLoc")
+                        .configure("subLocations", ImmutableList.of(loc1, loc2)));
+        
+        newApp = rebind();
+        newManagementContext = newApp.getManagementContext();
+        
+        MultiLocation newMultiLoc = (MultiLocation) Iterables.find(newManagementContext.getLocationManager().getLocations(), Predicates.instanceOf(MultiLocation.class));
+        AvailabilityZoneExtension azExtension = newMultiLoc.getExtension(AvailabilityZoneExtension.class);
+        List<Location> newSublLocs = azExtension.getAllSubLocations();
+        Iterable<String> newSubLocNames = Iterables.transform(newSublLocs, new Function<Location, String>() {
+            @Override public String apply(Location input) {
+                return (input == null) ? null : input.getDisplayName();
+            }});
+        Asserts.assertEqualsIgnoringOrder(newSubLocNames, ImmutableList.of("loc1", "loc2"));
+    }
+    
+    private TestApplication rebind() throws Exception {
+        return rebind(true);
+    }
+    
+    private TestApplication rebind(boolean checkSerializable) throws Exception {
+        RebindTestUtils.waitForPersisted(origApp);
+        if (checkSerializable) {
+            RebindTestUtils.checkCurrentMementoSerializable(origApp);
+        }
+        return (TestApplication) RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java
new file mode 100644
index 0000000..6fbf54e
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java
@@ -0,0 +1,199 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.net.InetAddress;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public class MultiLocationResolverTest {
+
+    private BrooklynProperties brooklynProperties;
+    private LocalManagementContext managementContext;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+        brooklynProperties = managementContext.getBrooklynProperties();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testThrowsOnInvalid() throws Exception {
+        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
+        assertThrowsIllegalArgument("single");
+    }
+    
+    @Test
+    public void testThrowsOnInvalidTarget() throws Exception {
+        assertThrowsIllegalArgument("multi:()");
+        assertThrowsIllegalArgument("multi:(wrongprefix:(hosts=\"1.1.1.1\"))");
+        assertThrowsIllegalArgument("multi:(foo:bar)");
+    }
+
+    @Test
+    public void testCleansUpOnInvalidTarget() {
+        assertThrowsNoSuchElement("multi:(targets=\"localhost:(name=testCleansUpOnInvalidTarget),thisNamedLocationDoesNotExist\")");
+        Optional<Location> subtarget = Iterables.tryFind(managementContext.getLocationManager().getLocations(), LocationPredicates.displayNameEqualTo("testCleansUpOnInvalidTarget"));
+        assertFalse(subtarget.isPresent(), "subtarget="+subtarget);
+    }
+
+
+    @Test
+    public void testResolvesSubLocs() {
+        assertMultiLocation(resolve("multi:(targets=localhost)"), 1, ImmutableList.of(Predicates.instanceOf(LocalhostMachineProvisioningLocation.class)));
+        assertMultiLocation(resolve("multi:(targets=\"localhost,localhost\")"), 2, Collections.nCopies(2, Predicates.instanceOf(LocalhostMachineProvisioningLocation.class)));
+        assertMultiLocation(resolve("multi:(targets=\"localhost,localhost,localhost\")"), 3, Collections.nCopies(3, Predicates.instanceOf(LocalhostMachineProvisioningLocation.class)));
+        assertMultiLocation(resolve("multi:(targets=\"localhost:(name=mysubname)\")"), 1, ImmutableList.of(displayNameEqualTo("mysubname")));
+        assertMultiLocation(resolve("multi:(targets=byon:(hosts=\"1.1.1.1\"))"), 1, ImmutableList.of(Predicates.and(
+                Predicates.instanceOf(FixedListMachineProvisioningLocation.class),
+                new Predicate<MachineProvisioningLocation>() {
+                    @Override public boolean apply(MachineProvisioningLocation input) {
+                        SshMachineLocation machine;
+                        try {
+                            machine = (SshMachineLocation) input.obtain(ImmutableMap.of());
+                        } catch (NoMachinesAvailableException e) {
+                            throw Exceptions.propagate(e);
+                        }
+                        try {
+                            String addr = ((SshMachineLocation)machine).getAddress().getHostAddress();
+                            return addr != null && addr.equals("1.1.1.1");
+                        } finally {
+                            input.release(machine);
+                        }
+                    }
+                })));
+        assertMultiLocation(resolve("multi:(targets=\"byon:(hosts=1.1.1.1),byon:(hosts=1.1.1.2)\")"), 2, Collections.nCopies(2, Predicates.instanceOf(FixedListMachineProvisioningLocation.class)));
+    }
+
+    @Test
+    public void testResolvesName() {
+        MultiLocation<SshMachineLocation> multiLoc = resolve("multi:(name=myname,targets=localhost)");
+        assertEquals(multiLoc.getDisplayName(), "myname");
+    }
+    
+    @Test
+    public void testNamedByonLocation() throws Exception {
+        brooklynProperties.put("brooklyn.location.named.mynamed", "multi:(targets=byon:(hosts=\"1.1.1.1\"))");
+        
+        MultiLocation<SshMachineLocation> loc = resolve("named:mynamed");
+        assertEquals(loc.obtain(ImmutableMap.of()).getAddress(), InetAddress.getByName("1.1.1.1"));
+    }
+
+    @Test
+    public void testResolvesFromMap() throws NoMachinesAvailableException {
+        Location l = managementContext.getLocationRegistry().resolve("multi", MutableMap.of("targets", 
+            MutableList.of("localhost", MutableMap.of("byon", MutableMap.of("hosts", "127.0.0.127")))));
+        MultiLocation<?> ml = (MultiLocation<?>)l;
+        Iterator<MachineProvisioningLocation<?>> ci = ml.getSubLocations().iterator();
+        
+        l = ci.next();
+        Assert.assertTrue(l instanceof LocalhostMachineProvisioningLocation, "Expected localhost, got "+l);
+        
+        l = ci.next();
+        Assert.assertTrue(l instanceof FixedListMachineProvisioningLocation, "Expected fixed, got "+l);
+        MachineLocation sl = ((FixedListMachineProvisioningLocation<?>)l).obtain();
+        Assert.assertEquals(sl.getAddress().getHostAddress(), "127.0.0.127");
+        
+        Assert.assertFalse(ci.hasNext());
+    }
+
+
+    private void assertThrowsNoSuchElement(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (NoSuchElementException e) {
+            // success
+        }
+    }
+    
+    private void assertThrowsIllegalArgument(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private MultiLocation<SshMachineLocation> resolve(String val) {
+        return (MultiLocation<SshMachineLocation>) managementContext.getLocationRegistry().resolve(val);
+    }
+    
+    @SuppressWarnings("rawtypes")
+    private void assertMultiLocation(MultiLocation<?> multiLoc, int expectedSize, List<? extends Predicate> expectedSubLocationPredicates) {
+        AvailabilityZoneExtension zones = multiLoc.getExtension(AvailabilityZoneExtension.class);
+        List<Location> subLocs = zones.getAllSubLocations();
+        assertEquals(subLocs.size(), expectedSize, "zones="+subLocs);
+        for (int i = 0; i < subLocs.size(); i++) {
+            MachineProvisioningLocation subLoc = (MachineProvisioningLocation) subLocs.get(i);
+            assertTrue(expectedSubLocationPredicates.get(i).apply(subLoc), "index="+i+"; subLocs="+subLocs);
+        }
+    }
+    
+    public static <T> Predicate<Location> displayNameEqualTo(final T val) {
+        return new Predicate<Location>() {
+            @Override
+            public boolean apply(@Nullable Location input) {
+                return Objects.equal(input.getDisplayName(), val);
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java
new file mode 100644
index 0000000..57d6c79
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertTrue;
+
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.net.Networking;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class MultiLocationTest {
+
+    private static final Logger log = LoggerFactory.getLogger(MultiLocationTest.class);
+    
+    private LocalManagementContext managementContext;
+    private SshMachineLocation mac1a;
+    private SshMachineLocation mac1b;
+    private SshMachineLocation mac2a;
+    private SshMachineLocation mac2b;
+    private FixedListMachineProvisioningLocation<SshMachineLocation> loc1;
+    private FixedListMachineProvisioningLocation<SshMachineLocation> loc2;
+    private MultiLocation<SshMachineLocation> multiLoc;
+    
+    @SuppressWarnings("unchecked")
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+        mac1a = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .displayName("mac1a")
+                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.1")));
+        mac1b = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .displayName("mac1b")
+                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.2")));
+        mac2a = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .displayName("mac2a")
+                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.3")));
+        mac2b = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .displayName("mac2b")
+                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.4")));
+        loc1 = managementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .displayName("loc1")
+                .configure("machines", MutableSet.of(mac1a, mac1b)));
+        loc2 = managementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
+                .displayName("loc2")
+                .configure("machines", MutableSet.of(mac2a, mac2b)));
+        multiLoc = managementContext.getLocationManager().createLocation(LocationSpec.create(MultiLocation.class)
+                        .displayName("multiLoc")
+                        .configure("subLocations", ImmutableList.of(loc1, loc2)));
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testHasAvailabilityZonesAsSubLocations() throws Exception {
+        multiLoc.hasExtension(AvailabilityZoneExtension.class);
+        AvailabilityZoneExtension extension = multiLoc.getExtension(AvailabilityZoneExtension.class);
+        Asserts.assertEqualsIgnoringOrder(extension.getAllSubLocations(), ImmutableList.of(loc1, loc2));
+        Asserts.assertEqualsIgnoringOrder(extension.getSubLocations(2), ImmutableList.of(loc1, loc2));
+        assertTrue(ImmutableList.of(loc1, loc2).containsAll(extension.getSubLocations(1)));
+    }
+    
+    @Test
+    public void testObtainAndReleaseDelegateToSubLocation() throws Exception {
+        SshMachineLocation obtained = multiLoc.obtain(ImmutableMap.of());
+        assertTrue(ImmutableList.of(mac1a, mac1b, mac2a, mac2b).contains(obtained));
+        multiLoc.release(obtained);
+    }
+    
+    @Test
+    public void testObtainsMovesThroughSubLocations() throws Exception {
+        Assert.assertEquals(multiLoc.obtain().getAddress().getHostAddress(), "1.1.1.1");
+        Assert.assertEquals(multiLoc.obtain().getAddress().getHostAddress(), "1.1.1.2");
+        Assert.assertEquals(multiLoc.obtain().getAddress().getHostAddress(), "1.1.1.3");
+        Assert.assertEquals(multiLoc.obtain().getAddress().getHostAddress(), "1.1.1.4");
+        try {
+            multiLoc.obtain();
+            Assert.fail();
+        } catch (NoMachinesAvailableException e) {
+            log.info("Error when no machines available across locations is: "+e);
+            Assert.assertTrue(e.toString().contains("loc1"), "Message should have referred to sub-location message: "+e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/PaasLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/PaasLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/PaasLocationTest.java
new file mode 100644
index 0000000..1b841d3
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/PaasLocationTest.java
@@ -0,0 +1,35 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import org.apache.brooklyn.location.paas.PaasLocation;
+import brooklyn.test.location.TestPaasLocation;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class PaasLocationTest {
+
+    private PaasLocation location;
+    
+    @Test
+    public void testProviderName(){
+        location = new TestPaasLocation();
+        Assert.assertEquals(location.getPaasProviderName(), "TestPaas");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java
new file mode 100644
index 0000000..3e4812f
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Iterator;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import org.apache.brooklyn.location.PortRange;
+import brooklyn.util.flags.TypeCoercions;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+public class PortRangesTest {
+
+    @Test
+    public void testSingleRange() {
+        PortRange r = PortRanges.fromInteger(1234);
+        assertContents(r, 1234);
+    }
+
+    @Test
+    public void testFromCollection() {
+        PortRange r = PortRanges.fromCollection(ImmutableList.of(1234, 2345));
+        assertContents(r, 1234, 2345);
+    }
+
+    @Test
+    public void testFromString() {
+        PortRange r = PortRanges.fromString("80,8080,8000,8080-8099");
+        assertContents(r, 80, 8080, 8000, 
+                8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089,
+                8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099);
+    }
+
+    @Test
+    public void testFromStringWithSpaces() {
+        PortRange r = PortRanges.fromString(" 80 , 8080  , 8000 , 8080  - 8099 ");
+        assertContents(r, 80, 8080, 8000, 
+                8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089,
+                8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099);
+    }
+
+    @Test
+    public void testFromStringWithSpacesToString() {
+        PortRange r = PortRanges.fromString(" 80 , 8080  , 8000 , 8080  - 8099 ");
+        Assert.assertEquals(r.toString(), "80,8080,8000,8080-8099");
+    }
+    
+    @Test
+    public void testFromStringThrowsIllegalArgumentException() {
+        assertFromStringThrowsIllegalArgumentException("80-100000");
+        assertFromStringThrowsIllegalArgumentException("0-80");
+    }
+
+    @Test
+    public void testCoercion() {
+        PortRanges.init();
+        PortRange r = TypeCoercions.coerce("80", PortRange.class);
+        assertContents(r, 80);
+    }
+
+    @Test
+    public void testCoercionInt() {
+        PortRanges.init();
+        PortRange r = TypeCoercions.coerce(80, PortRange.class);
+        assertContents(r, 80);
+    }
+    
+    @Test
+    public void testLinearRangeOfSizeOne() throws Exception {
+        PortRanges.LinearPortRange range = new PortRanges.LinearPortRange(80, 80);
+        assertEquals(Lists.newArrayList(range), ImmutableList.of(80));
+    }
+
+    @Test
+    public void testLinearRangeCountingUpwards() throws Exception {
+        PortRanges.LinearPortRange range = new PortRanges.LinearPortRange(80, 81);
+        assertEquals(Lists.newArrayList(range), ImmutableList.of(80, 81));
+    }
+    
+    @Test
+    public void testLinearRangeCountingDownwards() throws Exception {
+        PortRanges.LinearPortRange range = new PortRanges.LinearPortRange(80, 79);
+        assertEquals(Lists.newArrayList(range), ImmutableList.of(80, 79));
+    }
+    
+    protected void assertFromStringThrowsIllegalArgumentException(String range) {
+        try {
+            PortRanges.fromString(range);
+            Assert.fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+    }
+
+    private static <T> void assertContents(Iterable<T> actual, T ...expected) {
+        Iterator<T> i = actual.iterator();
+        int c = 0;
+        while (i.hasNext()) {
+            if (expected.length<=c) {
+                Assert.fail("Iterable contained more than the "+c+" expected elements");
+            }
+            Assert.assertEquals(i.next(), expected[c++]);
+        }
+        if (expected.length>c) {
+            Assert.fail("Iterable contained only "+c+" elements, "+expected.length+" expected");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.java b/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
new file mode 100644
index 0000000..a30d6e1
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineLocationCustomizer;
+
+public class RecordingMachineLocationCustomizer implements MachineLocationCustomizer {
+    public static class Call {
+        public final String methodName;
+        public final List<?> args;
+        
+        Call(String methodName, List<?> args) {
+            this.methodName = checkNotNull(methodName);
+            this.args = checkNotNull(args);
+        }
+        
+        @Override
+        public String toString() {
+            return methodName+args;
+        }
+        
+        @Override
+        public int hashCode() {
+            return Objects.hashCode(methodName, args);
+        }
+        
+        @Override
+        public boolean equals(Object other) {
+            return (other instanceof RecordingMachineLocationCustomizer.Call) && 
+                    methodName.equals(((RecordingMachineLocationCustomizer.Call)other).methodName) && 
+                    args.equals(((RecordingMachineLocationCustomizer.Call)other).args);
+        }
+    }
+    
+    public final List<RecordingMachineLocationCustomizer.Call> calls = Lists.newCopyOnWriteArrayList();
+    
+    @Override
+    public void customize(MachineLocation machine) {
+        calls.add(new Call("customize", ImmutableList.of(machine)));
+    }
+
+    @Override
+    public void preRelease(MachineLocation machine) {
+        calls.add(new Call("preRelease", ImmutableList.of(machine)));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java b/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java
new file mode 100644
index 0000000..c904619
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.location.basic;
+
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.location.HardwareDetails;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.PortSupplier;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Networking;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+
+
+/** Location for use in dev/test, defining custom start/stop support, and/or tweaking the ports which are permitted to be available
+ * (using setPermittedPorts(Iterable))
+ */
+public class SimulatedLocation extends AbstractLocation implements MachineProvisioningLocation<MachineLocation>, MachineLocation, PortSupplier {
+
+    private static final long serialVersionUID = 1L;
+    
+    private static final InetAddress address;
+    static {
+        address = Networking.getLocalHost();
+    }
+
+    Iterable<Integer> permittedPorts = PortRanges.fromString("1+");
+    Set<Integer> usedPorts = Sets.newLinkedHashSet();
+
+    public SimulatedLocation() {
+        this(MutableMap.<String,Object>of());
+    }
+    public SimulatedLocation(Map<String,? extends Object> flags) {
+        super(flags);
+    }
+    
+    @Override
+    public SimulatedLocation newSubLocation(Map<?,?> newFlags) {
+        // TODO shouldn't have to copy config bag as it should be inherited (but currently it is not used inherited everywhere; just most places)
+        return getManagementContext().getLocationManager().createLocation(LocationSpec.create(getClass())
+                .parent(this)
+                .configure(config().getLocalBag().getAllConfig())  // FIXME Should this just be inherited?
+                .configure(newFlags));
+    }
+
+    public MachineLocation obtain(Map<?,?> flags) {
+        return this;
+    }
+
+    public void release(MachineLocation machine) {
+    }
+
+    public Map<String,Object> getProvisioningFlags(Collection<String> tags) {
+        return MutableMap.<String,Object>of();
+    }
+    
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    @Override
+    public String getHostname() {
+        String hostname = address.getHostName();
+        return (hostname == null || hostname.equals(address.getHostAddress())) ? null : hostname;
+    }
+    
+    @Override
+    public Set<String> getPublicAddresses() {
+        return ImmutableSet.of(address.getHostAddress());
+    }
+    
+    @Override
+    public Set<String> getPrivateAddresses() {
+        return ImmutableSet.of();
+    }
+
+    public synchronized boolean obtainSpecificPort(int portNumber) {
+        if (!Iterables.contains(permittedPorts, portNumber)) return false;
+        if (usedPorts.contains(portNumber)) return false;
+        usedPorts.add(portNumber);
+        return true;
+    }
+
+    public synchronized int obtainPort(PortRange range) {
+        for (int p: range)
+            if (obtainSpecificPort(p)) return p;
+        return -1;
+    }
+
+    public synchronized void releasePort(int portNumber) {
+        usedPorts.remove(portNumber);
+    }
+    
+    public synchronized void setPermittedPorts(Iterable<Integer> ports) {
+        permittedPorts  = ports;
+    }
+
+    @Override
+    public OsDetails getOsDetails() {
+        return getMachineDetails().getOsDetails();
+    }
+
+    @Override
+    public MachineDetails getMachineDetails() {
+        HardwareDetails hardwareDetails = new BasicHardwareDetails(null, null);
+        OsDetails osDetails = BasicOsDetails.Factory.ANONYMOUS_LINUX;
+        return new BasicMachineDetails(hardwareDetails, osDetails);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolverTest.java
new file mode 100644
index 0000000..a9da0dd
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolverTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import java.net.InetAddress;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+
+import com.google.common.collect.ImmutableMap;
+
+public class SingleMachineLocationResolverTest {
+
+    private BrooklynProperties brooklynProperties;
+    private LocalManagementContext managementContext;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+        brooklynProperties = managementContext.getBrooklynProperties();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) Entities.destroyAll(managementContext);
+    }
+    
+    @Test
+    public void testThrowsOnInvalid() throws Exception {
+        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
+        assertThrowsIllegalArgument("single");
+    }
+    
+    @Test
+    public void testThrowsOnInvalidTarget() throws Exception {
+        assertThrowsIllegalArgument("single()");
+        assertThrowsIllegalArgument("single(wrongprefix:(hosts=\"1.1.1.1\"))");
+        assertThrowsIllegalArgument("single(foo:bar)");
+    }
+
+    @Test
+    public void resolveHosts() {
+        resolve("single(target=localhost)");
+        resolve("single(target=byon(hosts=\"1.1.1.1\"))");
+
+        brooklynProperties.put("brooklyn.location.named.mynamed", "single(target=byon:(hosts=\"1.1.1.1\"))");
+        managementContext.clearLocationRegistry();
+        resolve("single(target=named:mynamed)");
+    }
+    
+    @Test
+    public void resolveWithOldColonFormat() {
+        resolve("single:(target=localhost)");
+    }
+    
+    @Test
+    public void testNamedByonLocation() throws Exception {
+        brooklynProperties.put("brooklyn.location.named.mynamed", "single(target=byon:(hosts=\"1.1.1.1\"))");
+        
+        SingleMachineProvisioningLocation<SshMachineLocation> loc = resolve("named:mynamed");
+        assertEquals(loc.obtain(ImmutableMap.of()).getAddress(), InetAddress.getByName("1.1.1.1"));
+    }
+
+    @Test
+    public void testPropertyScopePrescedence() throws Exception {
+        brooklynProperties.put("brooklyn.location.named.mynamed", "single(target=byon:(hosts=\"1.1.1.1\"))");
+        
+        // prefer those in "named" over everything else
+        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
+        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
+
+        // prefer location-generic if nothing else
+        brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
+
+        Map<String, Object> conf = resolve("named:mynamed").obtain(ImmutableMap.of()).config().getBag().getAllConfig();
+        
+        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
+        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
+    }
+
+    private void assertThrowsNoSuchElement(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (NoSuchElementException e) {
+            // success
+        }
+    }
+    
+    private void assertThrowsIllegalArgument(String val) {
+        try {
+            resolve(val);
+            fail();
+        } catch (IllegalArgumentException e) {
+            // success
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private SingleMachineProvisioningLocation<SshMachineLocation> resolve(String val) {
+        return (SingleMachineProvisioningLocation<SshMachineLocation>) managementContext.getLocationRegistry().resolve(val);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocationTest.java
new file mode 100644
index 0000000..7d42e88
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocationTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertNotNull;
+
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.management.internal.LocalManagementContext;
+
+public class SingleMachineProvisioningLocationTest {
+    
+    private static final Logger log = LoggerFactory.getLogger(SingleMachineProvisioningLocation.class);
+    
+    private LocalManagementContext managementContext;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        managementContext = LocalManagementContextForTests.newInstance();
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (managementContext != null) managementContext.terminate();
+    }
+    
+    @SuppressWarnings("unchecked") 
+    @Test
+    public void testLocalhostSingle() throws Exception {
+        SingleMachineProvisioningLocation<SshMachineLocation> l = (SingleMachineProvisioningLocation<SshMachineLocation>) 
+            managementContext.getLocationRegistry().resolve("single:(target='localhost')");
+        l.setManagementContext(managementContext);
+        
+        SshMachineLocation m1 = l.obtain();
+        
+        assertNotNull(m1);
+
+        log.info("GOT "+m1);
+        
+        l.release(m1);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationIntegrationTest.java
new file mode 100644
index 0000000..68a53c5
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationIntegrationTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.io.ByteArrayOutputStream;
+import java.security.KeyPair;
+import java.util.Arrays;
+import java.util.Map;
+
+import brooklyn.util.internal.ssh.SshTool;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.test.entity.TestApplication;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.crypto.SecureKeys;
+import brooklyn.util.internal.ssh.sshj.SshjTool;
+import brooklyn.util.internal.ssh.sshj.SshjTool.SshjToolBuilder;
+
+import com.google.common.base.Preconditions;
+
+import static org.testng.Assert.assertEquals;
+
+public class SshMachineLocationIntegrationTest {
+
+    protected TestApplication app;
+    protected ManagementContext mgmt;
+
+    @BeforeMethod(alwaysRun=true)
+    public void setup() throws Exception {
+        mgmt = LocalManagementContextForTests.builder(true)
+            .useDefaultProperties()
+            .build();
+        app = TestApplication.Factory.newManagedInstanceForTests(mgmt);
+    }
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (mgmt != null) Entities.destroyAll(mgmt);
+        mgmt = null;
+    }
+
+    // Note: requires `named:localhost-passphrase` set up with a key whose passphrase is "localhost"
+    // * create the key with:
+    //      ssh-keygen -t rsa -N "brooklyn" -f ~/.ssh/id_rsa_passphrase
+    //      ssh-copy-id localhost
+    // * create brooklyn.properties, containing:
+    //      brooklyn.location.named.localhost-passphrase=localhost
+    //      brooklyn.location.named.localhost-passphrase.privateKeyFile=~/.ssh/id_rsa_passphrase
+    //      brooklyn.location.named.localhost-passphrase.privateKeyPassphrase=brooklyn
+    @Test(groups = "Integration")
+    public void testExtractingConnectablePassphraselessKey() throws Exception {
+        LocalhostMachineProvisioningLocation lhp = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("named:localhost-passphrase", true, null).orNull();
+        Preconditions.checkNotNull(lhp, "This test requires a localhost named location called 'localhost-passphrase' (which should have a passphrase set)");
+        SshMachineLocation sm = lhp.obtain();
+        
+        SshjToolBuilder builder = SshjTool.builder().host(sm.getAddress().getHostName()).user(sm.getUser());
+        
+        KeyPair data = sm.findKeyPair();
+        if (data!=null) builder.privateKeyData(SecureKeys.toPem(data));
+        String password = sm.findPassword();
+        if (password!=null) builder.password(password);
+        SshjTool tool = builder.build();
+        tool.connect();
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int result = tool.execCommands(MutableMap.<String,Object>of("out", out), Arrays.asList("date"));
+        Assert.assertTrue(out.toString().contains(" 20"), "out="+out);
+        assertEquals(result, 0);
+    }
+
+    @Test(groups = "Integration")
+    public void testExecScriptScriptDirFlagIsRespected() throws Exception {
+        // For explanation of (some of) the magic behind this command, see http://stackoverflow.com/a/229606/68898
+        final String command = "if [[ \"$0\" == \"/var/tmp/\"* ]]; then true; else false; fi";
+
+        LocalhostMachineProvisioningLocation lhp = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("localhost", true, null).orNull();
+        SshMachineLocation sm = lhp.obtain();
+
+        Map<String, Object> props = ImmutableMap.<String, Object>builder()
+                .put(SshTool.PROP_SCRIPT_DIR.getName(), "/var/tmp")
+                .build();
+        int rc = sm.execScript(props, "Test script directory execution", ImmutableList.of(command));
+        assertEquals(rc, 0);
+    }
+
+    @Test(groups = "Integration")
+    public void testLocationScriptDirConfigIsRespected() throws Exception {
+        // For explanation of (some of) the magic behind this command, see http://stackoverflow.com/a/229606/68898
+        final String command = "if [[ \"$0\" == \"/var/tmp/\"* ]]; then true; else false; fi";
+
+        Map<String, Object> locationConfig = ImmutableMap.<String, Object>builder()
+                .put(SshMachineLocation.SCRIPT_DIR.getName(), "/var/tmp")
+                .build();
+
+        LocalhostMachineProvisioningLocation lhp = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("localhost", locationConfig);
+        SshMachineLocation sm = lhp.obtain();
+
+        int rc = sm.execScript("Test script directory execution", ImmutableList.of(command));
+        assertEquals(rc, 0);
+    }
+    
+    @Test(groups = "Integration")
+    public void testMissingLocationScriptDirIsAlsoOkay() throws Exception {
+        final String command = "echo hello";
+
+        Map<String, Object> locationConfig = ImmutableMap.<String, Object>builder()
+//                .put(SshMachineLocation.SCRIPT_DIR.getName(), "/var/tmp")
+                .build();
+
+        LocalhostMachineProvisioningLocation lhp = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("localhost", locationConfig);
+        SshMachineLocation sm = lhp.obtain();
+
+        int rc = sm.execScript("Test script directory execution", ImmutableList.of(command));
+        assertEquals(rc, 0);
+    }
+}


[20/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
deleted file mode 100644
index ed3ed2a..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocation.java
+++ /dev/null
@@ -1,2863 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static brooklyn.util.JavaGroovyEquivalents.elvis;
-import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideLoginCredentials;
-import static org.jclouds.scriptbuilder.domain.Statements.exec;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.KeyPair;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.management.AccessController;
-import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
-import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.RunNodesException;
-import org.jclouds.compute.config.AdminAccessConfiguration;
-import org.jclouds.compute.domain.ComputeMetadata;
-import org.jclouds.compute.domain.ExecResponse;
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.NodeMetadata.Status;
-import org.jclouds.compute.domain.NodeMetadataBuilder;
-import org.jclouds.compute.domain.OperatingSystem;
-import org.jclouds.compute.domain.OsFamily;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.domain.TemplateBuilder;
-import org.jclouds.compute.domain.TemplateBuilderSpec;
-import org.jclouds.compute.functions.Sha512Crypt;
-import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.domain.Credentials;
-import org.jclouds.domain.LocationScope;
-import org.jclouds.domain.LoginCredentials;
-import org.jclouds.ec2.compute.options.EC2TemplateOptions;
-import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
-import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
-import org.jclouds.rest.AuthorizationException;
-import org.jclouds.scriptbuilder.domain.LiteralStatement;
-import org.jclouds.scriptbuilder.domain.Statement;
-import org.jclouds.scriptbuilder.domain.StatementList;
-import org.jclouds.scriptbuilder.domain.Statements;
-import org.jclouds.scriptbuilder.functions.InitAdminAccess;
-import org.jclouds.scriptbuilder.statements.login.AdminAccess;
-import org.jclouds.scriptbuilder.statements.login.ReplaceShadowPasswordEntry;
-import org.jclouds.scriptbuilder.statements.ssh.AuthorizeRSAPublicKeys;
-import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Charsets;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Splitter;
-import com.google.common.base.Stopwatch;
-import com.google.common.base.Supplier;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Sets.SetView;
-import com.google.common.io.Files;
-import com.google.common.net.HostAndPort;
-import com.google.common.primitives.Ints;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.config.ConfigKey.HasConfigKey;
-import brooklyn.config.ConfigUtils;
-import brooklyn.entity.basic.Sanitizer;
-import brooklyn.entity.rebind.persister.LocationWithObjectStore;
-import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import brooklyn.entity.rebind.persister.jclouds.JcloudsBlobStoreBasedObjectStore;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineLocationCustomizer;
-import brooklyn.location.MachineManagementMixins.MachineMetadata;
-import brooklyn.location.MachineManagementMixins.RichMachineProvisioningLocation;
-import brooklyn.location.MachineManagementMixins.SuspendsMachines;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.access.PortForwardManager;
-import brooklyn.location.access.PortMapping;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.BasicMachineMetadata;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.LocationConfigUtils;
-import brooklyn.location.basic.LocationConfigUtils.OsCredential;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.basic.WinRmMachineLocation;
-import brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation;
-import brooklyn.location.cloud.AvailabilityZoneExtension;
-import brooklyn.location.cloud.names.AbstractCloudMachineNamer;
-import brooklyn.location.cloud.names.CloudMachineNamer;
-import brooklyn.location.jclouds.JcloudsPredicates.NodeInLocation;
-import brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension;
-import brooklyn.location.jclouds.templates.PortableTemplateBuilder;
-import brooklyn.location.jclouds.zone.AwsAvailabilityZoneExtension;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.crypto.SecureKeys;
-import brooklyn.util.exceptions.CompoundRuntimeException;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.exceptions.ReferenceWithError;
-import brooklyn.util.flags.MethodCoercions;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.internal.ssh.ShellTool;
-import brooklyn.util.internal.ssh.SshTool;
-import brooklyn.util.javalang.Enums;
-import brooklyn.util.javalang.Reflections;
-import brooklyn.util.net.Cidr;
-import brooklyn.util.net.Networking;
-import brooklyn.util.net.Protocol;
-import brooklyn.util.os.Os;
-import brooklyn.util.repeat.Repeater;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.ssh.IptablesCommands;
-import brooklyn.util.ssh.IptablesCommands.Chain;
-import brooklyn.util.ssh.IptablesCommands.Policy;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.text.ByteSizeStrings;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.text.KeyValueParser;
-import brooklyn.util.text.Strings;
-import brooklyn.util.text.TemplateProcessor;
-import brooklyn.util.time.Duration;
-import brooklyn.util.time.Time;
-import io.cloudsoft.winrm4j.pywinrm.Session;
-import io.cloudsoft.winrm4j.pywinrm.WinRMFactory;
-
-/**
- * For provisioning and managing VMs in a particular provider/region, using jclouds.
- * Configuration flags are defined in {@link JcloudsLocationConfig}.
- */
-@SuppressWarnings("serial")
-public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation implements
-        JcloudsLocationConfig, RichMachineProvisioningLocation<MachineLocation>,
-        LocationWithObjectStore, SuspendsMachines {
-
-    // TODO After converting from Groovy to Java, this is now very bad code! It relies entirely on putting
-    // things into and taking them out of maps; it's not type-safe, and it's thus very error-prone.
-    // In Groovy, that's considered ok but not in Java.
-
-    // TODO test (and fix) ability to set config keys from flags
-
-    // TODO we say config is inherited, but it isn't the case for many "deep" / jclouds properties
-    // e.g. when we pass getRawLocalConfigBag() in and decorate it with additional flags
-    // (inheritance only works when we call getConfig in this class)
-
-    public static final Logger LOG = LoggerFactory.getLogger(JcloudsLocation.class);
-
-    public static final String ROOT_USERNAME = "root";
-    /** these userNames are known to be the preferred/required logins in some common/default images
-     *  where root@ is not allowed to log in */
-    public static final List<String> ROOT_ALIASES = ImmutableList.of("ubuntu", "ec2-user");
-    public static final List<String> COMMON_USER_NAMES_TO_TRY = ImmutableList.<String>builder().add(ROOT_USERNAME).addAll(ROOT_ALIASES).add("admin").build();
-
-    private static final Pattern LIST_PATTERN = Pattern.compile("^\\[(.*)\\]$");
-    private static final Pattern INTEGER_PATTERN = Pattern.compile("^\\d*$");
-
-    private static final int NOTES_MAX_LENGTH = 1000;
-
-    private final AtomicBoolean loggedSshKeysHint = new AtomicBoolean(false);
-    private final AtomicBoolean listedAvailableTemplatesOnNoSuchTemplate = new AtomicBoolean(false);
-
-    private final Map<String,Map<String, ? extends Object>> tagMapping = Maps.newLinkedHashMap();
-
-    @SetFromFlag // so it's persisted
-    private final Map<MachineLocation,String> vmInstanceIds = Maps.newLinkedHashMap();
-    
-    static { Networking.init(); }
-
-    public JcloudsLocation() {
-        super();
-    }
-
-    /** typically wants at least ACCESS_IDENTITY and ACCESS_CREDENTIAL */
-    public JcloudsLocation(Map<?,?> conf) {
-       super(conf);
-    }
-
-    @Override
-    @Deprecated
-    public JcloudsLocation configure(Map<?,?> properties) {
-        super.configure(properties);
-
-        if (config().getLocalBag().containsKey("providerLocationId")) {
-            LOG.warn("Using deprecated 'providerLocationId' key in "+this);
-            if (!config().getLocalBag().containsKey(CLOUD_REGION_ID))
-                config().addToLocalBag(MutableMap.of(CLOUD_REGION_ID.getName(), (String)config().getLocalBag().getStringKey("providerLocationId")));
-        }
-
-        if (isDisplayNameAutoGenerated() || !groovyTruth(getDisplayName())) {
-            setDisplayName(elvis(getProvider(), "unknown") +
-                   (groovyTruth(getRegion()) ? ":"+getRegion() : "") +
-                   (groovyTruth(getEndpoint()) ? ":"+getEndpoint() : ""));
-        }
-
-        setCreationString(config().getLocalBag());
-
-        if (getConfig(MACHINE_CREATION_SEMAPHORE) == null) {
-            Integer maxConcurrent = getConfig(MAX_CONCURRENT_MACHINE_CREATIONS);
-            if (maxConcurrent == null || maxConcurrent < 1) {
-                throw new IllegalStateException(MAX_CONCURRENT_MACHINE_CREATIONS.getName() + " must be >= 1, but was "+maxConcurrent);
-            }
-            config().set(MACHINE_CREATION_SEMAPHORE, new Semaphore(maxConcurrent, true));
-        }
-        return this;
-    }
-
-    @Override
-    public void init() {
-        super.init();
-        if ("aws-ec2".equals(getProvider())) {
-            addExtension(AvailabilityZoneExtension.class, new AwsAvailabilityZoneExtension(getManagementContext(), this));
-        }
-    }
-
-    @Override
-    public JcloudsLocation newSubLocation(Map<?,?> newFlags) {
-        return newSubLocation(getClass(), newFlags);
-    }
-
-    @Override
-    public JcloudsLocation newSubLocation(Class<? extends AbstractCloudMachineProvisioningLocation> type, Map<?,?> newFlags) {
-        // TODO should be able to use ConfigBag.newInstanceExtending; would require moving stuff around to api etc
-        return (JcloudsLocation) getManagementContext().getLocationManager().createLocation(LocationSpec.create(type)
-                .parent(this)
-                .configure(config().getLocalBag().getAllConfig())  // FIXME Should this just be inherited?
-                .configure(MACHINE_CREATION_SEMAPHORE, getMachineCreationSemaphore())
-                .configure(newFlags));
-    }
-
-    @Override
-    public String toString() {
-        Object identity = getIdentity();
-        String configDescription = config().getLocalBag().getDescription();
-        if (configDescription!=null && configDescription.startsWith(getClass().getSimpleName()))
-            return configDescription;
-        return getClass().getSimpleName()+"["+getDisplayName()+":"+(identity != null ? identity : null)+
-                (configDescription!=null ? "/"+configDescription : "") + "@" + getId() + "]";
-    }
-
-    @Override
-    public String toVerboseString() {
-        return Objects.toStringHelper(this).omitNullValues()
-                .add("id", getId()).add("name", getDisplayName()).add("identity", getIdentity())
-                .add("description", config().getLocalBag().getDescription()).add("provider", getProvider())
-                .add("region", getRegion()).add("endpoint", getEndpoint())
-                .toString();
-    }
-
-    public String getProvider() {
-        return getConfig(CLOUD_PROVIDER);
-    }
-
-    public String getIdentity() {
-        return getConfig(ACCESS_IDENTITY);
-    }
-
-    public String getCredential() {
-        return getConfig(ACCESS_CREDENTIAL);
-    }
-
-    /** returns the location ID used by the provider, if set, e.g. us-west-1 */
-    public String getRegion() {
-        return getConfig(CLOUD_REGION_ID);
-    }
-
-    public String getEndpoint() {
-        return (String) config().getBag().getWithDeprecation(CLOUD_ENDPOINT, JCLOUDS_KEY_ENDPOINT);
-    }
-
-    public String getUser(ConfigBag config) {
-        return (String) config.getWithDeprecation(USER, JCLOUDS_KEY_USERNAME);
-    }
-
-    public boolean isWindows(Template template, ConfigBag config) {
-        return isWindows(template.getImage(), config);
-    }
-    
-    /**
-     * Whether VMs provisioned from this image will be Windows. Assume windows if the image
-     * explicitly says so, or if image does not tell us then fall back to whether the config 
-     * explicitly says windows in {@link JcloudsLocationConfig#OS_FAMILY}.
-     * 
-     * Will first look at {@link JcloudsLocationConfig#OS_FAMILY_OVERRIDE}, to check if that 
-     * is set. If so, no further checks are done: the value is compared against {@link OsFamily#WINDOWS}.
-     * 
-     * We believe the config (e.g. from brooklyn.properties) because for some clouds there is 
-     * insufficient meta-data so the Image might not tell us. Thus a user can work around it
-     * by explicitly supplying configuration. 
-     */
-    public boolean isWindows(Image image, ConfigBag config) {
-        OsFamily override = config.get(OS_FAMILY_OVERRIDE);
-        if (override != null) return override == OsFamily.WINDOWS;
-        
-        OsFamily confFamily = config.get(OS_FAMILY);
-        OperatingSystem os = (image != null) ? image.getOperatingSystem() : null;
-        return (os != null && os.getFamily() != OsFamily.UNRECOGNIZED) 
-                ? (OsFamily.WINDOWS == os.getFamily()) 
-                : (OsFamily.WINDOWS == confFamily);
-    }
-
-    /**
-     * Whether the given VM is Windows.
-     * 
-     * @see {@link #isWindows(Image, ConfigBag)}
-     */
-    public boolean isWindows(NodeMetadata node, ConfigBag config) {
-        OsFamily override = config.get(OS_FAMILY_OVERRIDE);
-        if (override != null) return override == OsFamily.WINDOWS;
-        
-        OsFamily confFamily = config.get(OS_FAMILY);
-        OperatingSystem os = (node != null) ? node.getOperatingSystem() : null;
-        return (os != null && os.getFamily() != OsFamily.UNRECOGNIZED) 
-                ? (OsFamily.WINDOWS == os.getFamily()) 
-                : (OsFamily.WINDOWS == confFamily);
-    }
-
-    public boolean isLocationFirewalldEnabled(SshMachineLocation location) {
-        int result = location.execCommands("checking if firewalld is active", 
-                ImmutableList.of(IptablesCommands.firewalldServiceIsActive()));
-        if (result == 0) {
-            return true;
-        }
-        
-        return false;
-    }
-    
-    protected Semaphore getMachineCreationSemaphore() {
-        return checkNotNull(getConfig(MACHINE_CREATION_SEMAPHORE), MACHINE_CREATION_SEMAPHORE.getName());
-    }
-
-    protected CloudMachineNamer getCloudMachineNamer(ConfigBag config) {
-        String namerClass = config.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS);
-        if (Strings.isNonBlank(namerClass)) {
-            Optional<CloudMachineNamer> cloudNamer = Reflections.invokeConstructorWithArgs(getManagementContext().getCatalogClassLoader(), namerClass);
-            if (cloudNamer.isPresent()) {
-                return cloudNamer.get();
-            } else {
-                throw new IllegalStateException("Failed to create CloudMachineNamer "+namerClass+" for location "+this);
-            }
-        } else {
-            return new JcloudsMachineNamer();
-        }
-    }
-
-    protected Collection<JcloudsLocationCustomizer> getCustomizers(ConfigBag setup) {
-        @SuppressWarnings("deprecation")
-        JcloudsLocationCustomizer customizer = setup.get(JCLOUDS_LOCATION_CUSTOMIZER);
-        Collection<JcloudsLocationCustomizer> customizers = setup.get(JCLOUDS_LOCATION_CUSTOMIZERS);
-        @SuppressWarnings("deprecation")
-        String customizerType = setup.get(JCLOUDS_LOCATION_CUSTOMIZER_TYPE);
-        @SuppressWarnings("deprecation")
-        String customizersSupplierType = setup.get(JCLOUDS_LOCATION_CUSTOMIZERS_SUPPLIER_TYPE);
-
-        ClassLoader catalogClassLoader = getManagementContext().getCatalogClassLoader();
-        List<JcloudsLocationCustomizer> result = new ArrayList<JcloudsLocationCustomizer>();
-        if (customizer != null) result.add(customizer);
-        if (customizers != null) result.addAll(customizers);
-        if (Strings.isNonBlank(customizerType)) {
-            Optional<JcloudsLocationCustomizer> customizerByType = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizerType, setup);
-            if (customizerByType.isPresent()) {
-                result.add(customizerByType.get());
-            } else {
-                customizerByType = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizerType);
-                if (customizerByType.isPresent()) {
-                    result.add(customizerByType.get());
-                } else {
-                    throw new IllegalStateException("Failed to create JcloudsLocationCustomizer "+customizersSupplierType+" for location "+this);
-                }
-            }
-        }
-        if (Strings.isNonBlank(customizersSupplierType)) {
-            Optional<Supplier<Collection<JcloudsLocationCustomizer>>> supplier = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizersSupplierType, setup);
-            if (supplier.isPresent()) {
-                result.addAll(supplier.get().get());
-            } else {
-                supplier = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizersSupplierType);
-                if (supplier.isPresent()) {
-                    result.addAll(supplier.get().get());
-                } else {
-                    throw new IllegalStateException("Failed to create JcloudsLocationCustomizer supplier "+customizersSupplierType+" for location "+this);
-                }
-            }
-        }
-        return result;
-    }
-
-    protected Collection<MachineLocationCustomizer> getMachineCustomizers(ConfigBag setup) {
-        Collection<MachineLocationCustomizer> customizers = setup.get(MACHINE_LOCATION_CUSTOMIZERS);
-        return (customizers == null ? ImmutableList.<MachineLocationCustomizer>of() : customizers);
-    }
-
-    public void setDefaultImageId(String val) {
-        config().set(DEFAULT_IMAGE_ID, val);
-    }
-
-    // TODO remove tagMapping, or promote it
-    // (i think i favour removing it, letting the config come in from the entity)
-
-    public void setTagMapping(Map<String,Map<String, ? extends Object>> val) {
-        tagMapping.clear();
-        tagMapping.putAll(val);
-    }
-
-    // TODO Decide on semantics. If I give "TomcatServer" and "Ubuntu", then must I get back an image that matches both?
-    // Currently, just takes first match that it finds...
-    @Override
-    public Map<String,Object> getProvisioningFlags(Collection<String> tags) {
-        Map<String,Object> result = Maps.newLinkedHashMap();
-        Collection<String> unmatchedTags = Lists.newArrayList();
-        for (String it : tags) {
-            if (groovyTruth(tagMapping.get(it)) && !groovyTruth(result)) {
-                result.putAll(tagMapping.get(it));
-            } else {
-                unmatchedTags.add(it);
-            }
-        }
-        if (unmatchedTags.size() > 0) {
-            LOG.debug("Location {}, failed to match provisioning tags {}", this, unmatchedTags);
-        }
-        return result;
-    }
-
-    public static final Set<ConfigKey<?>> getAllSupportedProperties() {
-        Set<String> configsOnClass = Sets.newLinkedHashSet(
-            Iterables.transform(ConfigUtils.getStaticKeysOnClass(JcloudsLocation.class),
-                new Function<HasConfigKey<?>,String>() {
-                    @Override @Nullable
-                    public String apply(@Nullable HasConfigKey<?> input) {
-                        return input.getConfigKey().getName();
-                    }
-                }));
-        Set<ConfigKey<?>> configKeysInList = ImmutableSet.<ConfigKey<?>>builder()
-                .addAll(SUPPORTED_TEMPLATE_BUILDER_PROPERTIES.keySet())
-                .addAll(SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.keySet())
-                .build();
-        Set<String> configsInList = Sets.newLinkedHashSet(
-            Iterables.transform(configKeysInList,
-            new Function<ConfigKey<?>,String>() {
-                @Override @Nullable
-                public String apply(@Nullable ConfigKey<?> input) {
-                    return input.getName();
-                }
-            }));
-
-        SetView<String> extrasInList = Sets.difference(configsInList, configsOnClass);
-        // notInList is normal
-        if (!extrasInList.isEmpty())
-            LOG.warn("JcloudsLocation supported properties differs from config defined on class: " + extrasInList);
-        return Collections.unmodifiableSet(configKeysInList);
-    }
-
-    public ComputeService getComputeService() {
-        return getComputeService(MutableMap.of());
-    }
-    public ComputeService getComputeService(Map<?,?> flags) {
-        ConfigBag conf = (flags==null || flags.isEmpty())
-                ? config().getBag()
-                : ConfigBag.newInstanceExtending(config().getBag(), flags);
-        return getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(conf, true);
-    }
-
-    /** @deprecated since 0.7.0 use {@link #listMachines()} */ @Deprecated
-    public Set<? extends ComputeMetadata> listNodes() {
-        return listNodes(MutableMap.of());
-    }
-    /** @deprecated since 0.7.0 use {@link #listMachines()}.
-     * (no support for custom compute service flags; if that is needed, we'll have to introduce a new method,
-     * but it seems there are no usages) */ @Deprecated
-    public Set<? extends ComputeMetadata> listNodes(Map<?,?> flags) {
-        return getComputeService(flags).listNodes();
-    }
-
-    @Override
-    public Map<String, MachineMetadata> listMachines() {
-        Set<? extends ComputeMetadata> nodes =
-            getRegion()!=null ? getComputeService().listNodesDetailsMatching(new NodeInLocation(getRegion(), true))
-                : getComputeService().listNodes();
-        Map<String,MachineMetadata> result = new LinkedHashMap<String, MachineMetadata>();
-
-        for (ComputeMetadata node: nodes)
-            result.put(node.getId(), getMachineMetadata(node));
-
-        return result;
-    }
-
-    protected MachineMetadata getMachineMetadata(ComputeMetadata node) {
-        if (node==null)
-            return null;
-        return new BasicMachineMetadata(node.getId(), node.getName(),
-            ((node instanceof NodeMetadata) ? Iterators.tryFind( ((NodeMetadata)node).getPublicAddresses().iterator(), Predicates.alwaysTrue() ).orNull() : null),
-            ((node instanceof NodeMetadata) ? ((NodeMetadata)node).getStatus()==Status.RUNNING : null),
-            node);
-    }
-
-    @Override
-    public MachineMetadata getMachineMetadata(MachineLocation l) {
-        if (l instanceof JcloudsSshMachineLocation) {
-            return getMachineMetadata( ((JcloudsSshMachineLocation)l).node );
-        }
-        return null;
-    }
-
-    @Override
-    public void killMachine(String cloudServiceId) {
-        getComputeService().destroyNode(cloudServiceId);
-    }
-
-    @Override
-    public void killMachine(MachineLocation l) {
-        MachineMetadata m = getMachineMetadata(l);
-        if (m==null) throw new NoSuchElementException("Machine "+l+" is not known at "+this);
-        killMachine(m.getId());
-    }
-
-    /** attaches a string describing where something is being created
-     * (provider, region/location and/or endpoint, callerContext) */
-    protected void setCreationString(ConfigBag config) {
-        config.setDescription(elvis(config.get(CLOUD_PROVIDER), "unknown")+
-                (config.containsKey(CLOUD_REGION_ID) ? ":"+config.get(CLOUD_REGION_ID) : "")+
-                (config.containsKey(CLOUD_ENDPOINT) ? ":"+config.get(CLOUD_ENDPOINT) : "")+
-                (config.containsKey(CALLER_CONTEXT) ? "@"+config.get(CALLER_CONTEXT) : ""));
-    }
-
-    // ----------------- obtaining a new machine ------------------------
-    public MachineLocation obtain() throws NoMachinesAvailableException {
-        return obtain(MutableMap.of());
-    }
-    public MachineLocation obtain(TemplateBuilder tb) throws NoMachinesAvailableException {
-        return obtain(MutableMap.of(), tb);
-    }
-    public MachineLocation obtain(Map<?,?> flags, TemplateBuilder tb) throws NoMachinesAvailableException {
-        return obtain(MutableMap.builder().putAll(flags).put(TEMPLATE_BUILDER, tb).build());
-    }
-
-    /** core method for obtaining a VM using jclouds;
-     * Map should contain CLOUD_PROVIDER and CLOUD_ENDPOINT or CLOUD_REGION, depending on the cloud,
-     * as well as ACCESS_IDENTITY and ACCESS_CREDENTIAL,
-     * plus any further properties to specify e.g. images, hardware profiles, accessing user
-     * (for initial login, and a user potentially to create for subsequent ie normal access) */
-    @Override
-    public MachineLocation obtain(Map<?,?> flags) throws NoMachinesAvailableException {
-        ConfigBag setup = ConfigBag.newInstanceExtending(config().getBag(), flags);
-        Integer attempts = setup.get(MACHINE_CREATE_ATTEMPTS);
-        List<Exception> exceptions = Lists.newArrayList();
-        if (attempts == null || attempts < 1) attempts = 1;
-        for (int i = 1; i <= attempts; i++) {
-            try {
-                return obtainOnce(setup);
-            } catch (RuntimeException e) {
-                LOG.warn("Attempt #{}/{} to obtain machine threw error: {}", new Object[]{i, attempts, e});
-                exceptions.add(e);
-            }
-        }
-        String msg = String.format("Failed to get VM after %d attempt%s.", attempts, attempts == 1 ? "" : "s");
-
-        Exception cause = (exceptions.size() == 1)
-                ? exceptions.get(0)
-                : new CompoundRuntimeException(msg + " - "
-                    + "First cause is "+exceptions.get(0)+" (listed in primary trace); "
-                    + "plus " + (exceptions.size()-1) + " more (e.g. the last is "+exceptions.get(exceptions.size()-1)+")",
-                    exceptions.get(0), exceptions);
-
-        if (exceptions.get(exceptions.size()-1) instanceof NoMachinesAvailableException) {
-            throw new NoMachinesAvailableException(msg, cause);
-        } else {
-            throw Exceptions.propagate(cause);
-        }
-    }
-
-    protected MachineLocation obtainOnce(ConfigBag setup) throws NoMachinesAvailableException {
-        AccessController.Response access = getManagementContext().getAccessController().canProvisionLocation(this);
-        if (!access.isAllowed()) {
-            throw new IllegalStateException("Access controller forbids provisioning in "+this+": "+access.getMsg());
-        }
-
-        setCreationString(setup);
-        boolean waitForSshable = !"false".equalsIgnoreCase(setup.get(WAIT_FOR_SSHABLE));
-        boolean waitForWinRmable = !"false".equalsIgnoreCase(setup.get(WAIT_FOR_WINRM_AVAILABLE));
-        boolean usePortForwarding = setup.get(USE_PORT_FORWARDING);
-        boolean skipJcloudsSshing = Boolean.FALSE.equals(setup.get(USE_JCLOUDS_SSH_INIT)) || usePortForwarding;
-        JcloudsPortForwarderExtension portForwarder = setup.get(PORT_FORWARDER);
-        if (usePortForwarding) checkNotNull(portForwarder, "portForwarder, when use-port-forwarding enabled");
-
-        final ComputeService computeService = getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(setup, true);
-        CloudMachineNamer cloudMachineNamer = getCloudMachineNamer(setup);
-        String groupId = elvis(setup.get(GROUP_ID), cloudMachineNamer.generateNewGroupId(setup));
-        NodeMetadata node = null;
-        JcloudsMachineLocation machineLocation = null;
-        
-        try {
-            LOG.info("Creating VM "+setup.getDescription()+" in "+this);
-
-            Semaphore machineCreationSemaphore = getMachineCreationSemaphore();
-            boolean acquired = machineCreationSemaphore.tryAcquire(0, TimeUnit.SECONDS);
-            if (!acquired) {
-                LOG.info("Waiting in {} for machine-creation permit ({} other queuing requests already)", new Object[] {this, machineCreationSemaphore.getQueueLength()});
-                Stopwatch blockStopwatch = Stopwatch.createStarted();
-                machineCreationSemaphore.acquire();
-                LOG.info("Acquired in {} machine-creation permit, after waiting {}", this, Time.makeTimeStringRounded(blockStopwatch));
-            } else {
-                LOG.debug("Acquired in {} machine-creation permit immediately", this);
-            }
-
-            Stopwatch provisioningStopwatch = Stopwatch.createStarted();
-            Duration templateTimestamp, provisionTimestamp, usableTimestamp, customizedTimestamp;
-
-            LoginCredentials userCredentials = null;
-            Set<? extends NodeMetadata> nodes;
-            Template template;
-            try {
-                // Setup the template
-                template = buildTemplate(computeService, setup);
-                boolean expectWindows = isWindows(template, setup);
-                if (!skipJcloudsSshing) {
-                    if (expectWindows) {
-                        // TODO Was this too early to look at template.getImage? e.g. customizeTemplate could subsequently modify it.
-                        LOG.warn("Ignoring invalid configuration for Windows provisioning of "+template.getImage()+": "+USE_JCLOUDS_SSH_INIT.getName()+" should be false");
-                        skipJcloudsSshing = true;
-                    } else if (waitForSshable) {
-                        userCredentials = initTemplateForCreateUser(template, setup);
-                    }
-                }
-
-                templateTimestamp = Duration.of(provisioningStopwatch);
-                // "Name" metadata seems to set the display name; at least in AWS
-                // TODO it would be nice if this salt comes from the location's ID (but we don't know that yet as the ssh machine location isn't created yet)
-                // TODO in softlayer we want to control the suffix of the hostname which is 3 random hex digits
-                template.getOptions().getUserMetadata().put("Name", cloudMachineNamer.generateNewMachineUniqueNameFromGroupId(setup, groupId));
-                
-                if (setup.get(JcloudsLocationConfig.INCLUDE_BROOKLYN_USER_METADATA)) {
-                    template.getOptions().getUserMetadata().put("brooklyn-user", System.getProperty("user.name"));
-                    
-                    Object context = setup.get(CALLER_CONTEXT);
-                    if (context instanceof Entity) {
-                        Entity entity = (Entity)context;
-                        template.getOptions().getUserMetadata().put("brooklyn-app-id", entity.getApplicationId());
-                        template.getOptions().getUserMetadata().put("brooklyn-app-name", entity.getApplication().getDisplayName());
-                        template.getOptions().getUserMetadata().put("brooklyn-entity-id", entity.getId());
-                        template.getOptions().getUserMetadata().put("brooklyn-entity-name", entity.getDisplayName());
-                        template.getOptions().getUserMetadata().put("brooklyn-server-creation-date", Time.makeDateSimpleStampString());
-                    }
-                }
-                
-                customizeTemplate(setup, computeService, template);
-                
-                LOG.debug("jclouds using template {} / options {} to provision machine in {}",
-                        new Object[] {template, template.getOptions(), setup.getDescription()});
-
-                if (!setup.getUnusedConfig().isEmpty())
-                    LOG.debug("NOTE: unused flags passed to obtain VM in "+setup.getDescription()+": "+
-                            setup.getUnusedConfig());
-                
-                nodes = computeService.createNodesInGroup(groupId, 1, template);
-                provisionTimestamp = Duration.of(provisioningStopwatch);
-            } finally {
-                machineCreationSemaphore.release();
-            }
-
-            node = Iterables.getOnlyElement(nodes, null);
-            LOG.debug("jclouds created {} for {}", node, setup.getDescription());
-            if (node == null)
-                throw new IllegalStateException("No nodes returned by jclouds create-nodes in " + setup.getDescription());
-
-            boolean windows = isWindows(node, setup);
-            if (windows) {
-                int newLoginPort = node.getLoginPort() == 22 ? 5985 : node.getLoginPort();
-                String newLoginUser = "root".equals(node.getCredentials().getUser()) ? "Administrator" : node.getCredentials().getUser();
-                LOG.debug("jclouds created Windows VM {}; transforming connection details: loginPort from {} to {}; loginUser from {} to {}", 
-                        new Object[] {node, node.getLoginPort(), newLoginPort, node.getCredentials().getUser(), newLoginUser});
-                
-                node = NodeMetadataBuilder.fromNodeMetadata(node)
-                        .loginPort(newLoginPort)
-                        .credentials(LoginCredentials.builder(node.getCredentials()).user(newLoginUser).build())
-                        .build();
-            }
-            // FIXME How do we influence the node.getLoginPort, so it is set correctly for Windows?
-            // Setup port-forwarding, if required
-            Optional<HostAndPort> sshHostAndPortOverride;
-            if (usePortForwarding) {
-                sshHostAndPortOverride = Optional.of(portForwarder.openPortForwarding(
-                        node,
-                        node.getLoginPort(),
-                        Optional.<Integer>absent(),
-                        Protocol.TCP,
-                        Cidr.UNIVERSAL));
-            } else {
-                sshHostAndPortOverride = Optional.absent();
-            }
-
-            if (skipJcloudsSshing) {
-                boolean waitForConnectable = (windows) ? waitForWinRmable : waitForSshable;
-                if (waitForConnectable) {
-                    if (windows) {
-                        // TODO Does jclouds support any windows user setup?
-                        waitForWinRmAvailable(computeService, node, sshHostAndPortOverride, node.getCredentials(), setup);
-                    } else {
-                        waitForSshable(computeService, node, sshHostAndPortOverride, node.getCredentials(), setup);
-                    }
-                    userCredentials = createUser(computeService, node, sshHostAndPortOverride, setup);
-                }
-            }
-
-            // Figure out which login-credentials to use
-            LoginCredentials customCredentials = setup.get(CUSTOM_CREDENTIALS);
-            if (customCredentials != null) {
-                userCredentials = customCredentials;
-                //set userName and other data, from these credentials
-                Object oldUsername = setup.put(USER, customCredentials.getUser());
-                LOG.debug("node {} username {} / {} (customCredentials)", new Object[] { node, customCredentials.getUser(), oldUsername });
-                if (customCredentials.getOptionalPassword().isPresent()) setup.put(PASSWORD, customCredentials.getOptionalPassword().get());
-                if (customCredentials.getOptionalPrivateKey().isPresent()) setup.put(PRIVATE_KEY_DATA, customCredentials.getOptionalPrivateKey().get());
-            }
-            if (userCredentials == null) {
-                userCredentials = extractVmCredentials(setup, node);
-            }
-            if (userCredentials != null) {
-                node = NodeMetadataBuilder.fromNodeMetadata(node).credentials(userCredentials).build();
-            } else {
-                // only happens if something broke above...
-                userCredentials = LoginCredentials.fromCredentials(node.getCredentials());
-            }
-            // store the credentials, in case they have changed
-            setup.putIfNotNull(JcloudsLocationConfig.PASSWORD, userCredentials.getOptionalPassword().orNull());
-            setup.putIfNotNull(JcloudsLocationConfig.PRIVATE_KEY_DATA, userCredentials.getOptionalPrivateKey().orNull());
-
-            // Wait for the VM to be reachable over SSH
-            if (waitForSshable && !windows) {
-                waitForSshable(computeService, node, sshHostAndPortOverride, userCredentials, setup);
-            } else {
-                LOG.debug("Skipping ssh check for {} ({}) due to config waitForSshable=false", node, setup.getDescription());
-            }
-            usableTimestamp = Duration.of(provisioningStopwatch);
-
-//            JcloudsSshMachineLocation jcloudsSshMachineLocation = null;
-//            WinRmMachineLocation winRmMachineLocation = null;
-            // Create a JcloudsSshMachineLocation, and register it
-            if (windows) {
-                machineLocation = registerWinRmMachineLocation(computeService, node, userCredentials, sshHostAndPortOverride, setup);
-            } else {
-                machineLocation = registerJcloudsSshMachineLocation(computeService, node, userCredentials, sshHostAndPortOverride, setup);
-                if (template!=null && machineLocation.getTemplate()==null) {
-                    ((JcloudsSshMachineLocation)machineLocation).template = template;
-                }
-            }
-
-            if (usePortForwarding && sshHostAndPortOverride.isPresent()) {
-                // Now that we have the sshMachineLocation, we can associate the port-forwarding address with it.
-                PortForwardManager portForwardManager = setup.get(PORT_FORWARDING_MANAGER);
-                if (portForwardManager != null) {
-                    portForwardManager.associate(node.getId(), sshHostAndPortOverride.get(), machineLocation, node.getLoginPort());
-                } else {
-                    LOG.warn("No port-forward manager for {} so could not associate {} -> {} for {}",
-                            new Object[] {this, node.getLoginPort(), sshHostAndPortOverride, machineLocation});
-                }
-            }
-
-            if ("docker".equals(this.getProvider())) {
-                if (windows) {
-                    throw new UnsupportedOperationException("Docker not supported on Windows");
-                }
-                Map<Integer, Integer> portMappings = JcloudsUtil.dockerPortMappingsFor(this, node.getId());
-                PortForwardManager portForwardManager = setup.get(PORT_FORWARDING_MANAGER);
-                if (portForwardManager != null) {
-                    for(Integer containerPort : portMappings.keySet()) {
-                        Integer hostPort = portMappings.get(containerPort);
-                        String dockerHost = ((JcloudsSshMachineLocation)machineLocation).getSshHostAndPort().getHostText();
-                        portForwardManager.associate(node.getId(), HostAndPort.fromParts(dockerHost, hostPort), machineLocation, containerPort);
-                    }
-                } else {
-                    LOG.warn("No port-forward manager for {} so could not associate docker port-mappings for {}",
-                            this, machineLocation);
-                }
-            }
-
-            List<String> customisationForLogging = new ArrayList<String>();
-            // Apply same securityGroups rules to iptables, if iptables is running on the node
-            if (waitForSshable) {
-
-                String setupScript = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_URL);
-                List<String> setupScripts = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_URL_LIST);
-                Collection<String> allScripts = new MutableList<String>().appendIfNotNull(setupScript).appendAll(setupScripts);
-                for (String setupScriptItem : allScripts) {
-                    if (Strings.isNonBlank(setupScriptItem)) {
-                        customisationForLogging.add("custom setup script " + setupScriptItem);
-
-                        String setupVarsString = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_VARS);
-                        Map<String, String> substitutions = (setupVarsString != null)
-                                ? Splitter.on(",").withKeyValueSeparator(":").split(setupVarsString)
-                                : ImmutableMap.<String, String>of();
-                        String scriptContent = ResourceUtils.create(this).getResourceAsString(setupScriptItem);
-                        String script = TemplateProcessor.processTemplateContents(scriptContent, getManagementContext(), substitutions);
-                        if (windows) {
-                            ((WinRmMachineLocation)machineLocation).executeScript(ImmutableList.copyOf((script.replace("\r", "").split("\n"))));
-                        } else {
-                            ((SshMachineLocation)machineLocation).execCommands("Customizing node " + this, ImmutableList.of(script));
-                        }
-                    }
-                }
-
-                if (setup.get(JcloudsLocationConfig.MAP_DEV_RANDOM_TO_DEV_URANDOM)) {
-                    if (windows) {
-                        LOG.warn("Ignoring flag MAP_DEV_RANDOM_TO_DEV_URANDOM on Windows location {}", machineLocation);
-                    } else {
-                        customisationForLogging.add("point /dev/random to urandom");
-
-                        ((SshMachineLocation)machineLocation).execCommands("using urandom instead of random",
-                                Arrays.asList("sudo mv /dev/random /dev/random-real", "sudo ln -s /dev/urandom /dev/random"));
-                    }
-                }
-
-
-                if (setup.get(GENERATE_HOSTNAME)) {
-                    if (windows) {
-                        // TODO: Generate Windows Hostname
-                        LOG.warn("Ignoring flag GENERATE_HOSTNAME on Windows location {}", machineLocation);
-                    } else {
-                        customisationForLogging.add("configure hostname");
-
-                        ((SshMachineLocation)machineLocation).execCommands("Generate hostname " + node.getName(),
-                                Arrays.asList("sudo hostname " + node.getName(),
-                                        "sudo sed -i \"s/HOSTNAME=.*/HOSTNAME=" + node.getName() + "/g\" /etc/sysconfig/network",
-                                        "sudo bash -c \"echo 127.0.0.1   `hostname` >> /etc/hosts\"")
-                        );
-                    }
-                }
-
-                if (setup.get(OPEN_IPTABLES)) {
-                    if (windows) {
-                        LOG.warn("Ignoring DEPRECATED flag OPEN_IPTABLES on Windows location {}", machineLocation);
-                    } else {
-                        LOG.warn("Using DEPRECATED flag OPEN_IPTABLES (will not be supported in future versions) for {} at {}", machineLocation, this);
-                        
-                        @SuppressWarnings("unchecked")
-                        Iterable<Integer> inboundPorts = (Iterable<Integer>) setup.get(INBOUND_PORTS);
-
-                        if (inboundPorts == null || Iterables.isEmpty(inboundPorts)) {
-                            LOG.info("No ports to open in iptables (no inbound ports) for {} at {}", machineLocation, this);
-                        } else {
-                            customisationForLogging.add("open iptables");
-
-                            List<String> iptablesRules = Lists.newArrayList();
-
-                            if (isLocationFirewalldEnabled((SshMachineLocation)machineLocation)) {
-                                for (Integer port : inboundPorts) {
-                                    iptablesRules.add(IptablesCommands.addFirewalldRule(Chain.INPUT, Protocol.TCP, port, Policy.ACCEPT));
-                                 }
-                            } else {
-                                iptablesRules = createIptablesRulesForNetworkInterface(inboundPorts);
-                                iptablesRules.add(IptablesCommands.saveIptablesRules());
-                            }
-                            List<String> batch = Lists.newArrayList();
-                            // Some entities, such as Riak (erlang based) have a huge range of ports, which leads to a script that
-                            // is too large to run (fails with a broken pipe). Batch the rules into batches of 50
-                            for (String rule : iptablesRules) {
-                                batch.add(rule);
-                                if (batch.size() == 50) {
-                                    ((SshMachineLocation)machineLocation).execCommands("Inserting iptables rules, 50 command batch", batch);
-                                    batch.clear();
-                                }
-                            }
-                            if (batch.size() > 0) {
-                                ((SshMachineLocation)machineLocation).execCommands("Inserting iptables rules", batch);
-                            }
-                            ((SshMachineLocation)machineLocation).execCommands("List iptables rules", ImmutableList.of(IptablesCommands.listIptablesRule()));
-                        }
-                    }
-                }
-
-                if (setup.get(STOP_IPTABLES)) {
-                    if (windows) {
-                        LOG.warn("Ignoring DEPRECATED flag OPEN_IPTABLES on Windows location {}", machineLocation);
-                    } else {
-                        LOG.warn("Using DEPRECATED flag STOP_IPTABLES (will not be supported in future versions) for {} at {}", machineLocation, this);
-                        
-                        customisationForLogging.add("stop iptables");
-
-                        List<String> cmds = ImmutableList.<String>of();
-                        if (isLocationFirewalldEnabled((SshMachineLocation)machineLocation)) {
-                            cmds = ImmutableList.of(IptablesCommands.firewalldServiceStop(), IptablesCommands.firewalldServiceStatus());
-                        } else {
-                            cmds = ImmutableList.of(IptablesCommands.iptablesServiceStop(), IptablesCommands.iptablesServiceStatus());
-                        }
-                        ((SshMachineLocation)machineLocation).execCommands("Stopping iptables", cmds);
-                    }
-                }
-
-                List<String> extraKeyUrlsToAuth = setup.get(EXTRA_PUBLIC_KEY_URLS_TO_AUTH);
-                if (extraKeyUrlsToAuth!=null && !extraKeyUrlsToAuth.isEmpty()) {
-                    if (windows) {
-                        LOG.warn("Ignoring flag EXTRA_PUBLIC_KEY_URLS_TO_AUTH on Windows location", machineLocation);
-                    } else {
-                        List<String> extraKeyDataToAuth = MutableList.of();
-                        for (String keyUrl : extraKeyUrlsToAuth) {
-                            extraKeyDataToAuth.add(ResourceUtils.create().getResourceAsString(keyUrl));
-                        }
-                        ((SshMachineLocation)machineLocation).execCommands("Authorizing ssh keys",
-                                ImmutableList.of(new AuthorizeRSAPublicKeys(extraKeyDataToAuth).render(org.jclouds.scriptbuilder.domain.OsFamily.UNIX)));
-                    }
-                }
-
-            } else {
-                // Otherwise we have deliberately not waited to be ssh'able, so don't try now to
-                // ssh to exec these commands!
-            }
-
-            // Apply any optional app-specific customization.
-            for (JcloudsLocationCustomizer customizer : getCustomizers(setup)) {
-                customizer.customize(this, computeService, machineLocation);
-            }
-            for (MachineLocationCustomizer customizer : getMachineCustomizers(setup)) {
-                customizer.customize(machineLocation);
-            }
-
-            customizedTimestamp = Duration.of(provisioningStopwatch);
-
-            try {
-                String logMessage = "Finished VM "+setup.getDescription()+" creation:"
-                        + " "+machineLocation.getUser()+"@"+machineLocation.getAddress()+":"+machineLocation.getPort()
-                        + (Boolean.TRUE.equals(setup.get(LOG_CREDENTIALS))
-                                ? "password=" + userCredentials.getOptionalPassword().or("<absent>")
-                                + " && key=" + userCredentials.getOptionalPrivateKey().or("<absent>")
-                                : "")
-                        + " ready after "+Duration.of(provisioningStopwatch).toStringRounded()
-                        + " ("+template+" template built in "+Duration.of(templateTimestamp).toStringRounded()+";"
-                        + " "+node+" provisioned in "+Duration.of(provisionTimestamp).subtract(templateTimestamp).toStringRounded()+";"
-                        + " "+machineLocation+" connection usable in "+Duration.of(usableTimestamp).subtract(provisionTimestamp).toStringRounded()+";"
-                        + " and os customized in "+Duration.of(customizedTimestamp).subtract(usableTimestamp).toStringRounded()+" - "+Joiner.on(", ").join(customisationForLogging)+")";
-                LOG.info(logMessage);
-            } catch (Exception e){
-                // TODO Remove try-catch! @Nakomis: why did you add it? What exception happened during logging?
-                Exceptions.propagateIfFatal(e);
-                LOG.warn("Problem generating log message summarising completion of jclouds machine provisioning "+machineLocation+" by "+this, e);
-            }
-
-            return machineLocation;
-            
-        } catch (Exception e) {
-            if (e instanceof RunNodesException && ((RunNodesException)e).getNodeErrors().size() > 0) {
-                node = Iterables.get(((RunNodesException)e).getNodeErrors().keySet(), 0);
-            }
-            // sometimes AWS nodes come up busted (eg ssh not allowed); just throw it back (and maybe try for another one)
-            boolean destroyNode = (node != null) && Boolean.TRUE.equals(setup.get(DESTROY_ON_FAILURE));
-
-            if (e.toString().contains("VPCResourceNotSpecified")) {
-                LOG.error("Detected that your EC2 account is a legacy 'classic' account, but the recommended instance type requires VPC. "
-                    + "You can specify the 'eu-central-1' region to avoid this problem, or you can specify a classic-compatible instance type, "
-                    + "or you can specify a subnet to use with 'networkName' "
-                    + "(taking care that the subnet auto-assigns public IP's and allows ingress on all ports, "
-                    + "as Brooklyn does not currently configure security groups for non-default VPC's; "
-                    + "or setting up Brooklyn to be in the subnet or have a jump host or other subnet access configuration). "
-                    + "For more information on VPC vs classic see http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-vpc.html.");
-            }
-            
-            LOG.error("Failed to start VM for {}{}: {}",
-                    new Object[] {setup.getDescription(), (destroyNode ? " (destroying "+node+")" : ""), e.getMessage()});
-            LOG.debug(Throwables.getStackTraceAsString(e));
-            
-            if (destroyNode) {
-                if (machineLocation != null) {
-                    releaseSafely(machineLocation);
-                } else {
-                    releaseNodeSafely(node);
-                }
-            }
-
-            throw Exceptions.propagate(e);
-        }
-    }
-
-    // ------------- suspend and resume ------------------------------------
-
-    /**
-     * Suspends the given location.
-     * <p>
-     * Note that this method does <b>not</b> call the lifecycle methods of any
-     * {@link #getCustomizers(ConfigBag) customizers} attached to this location.
-     */
-    @Override
-    public void suspendMachine(MachineLocation rawLocation) {
-        String instanceId = vmInstanceIds.remove(rawLocation);
-        if (instanceId == null) {
-            LOG.info("Attempt to suspend unknown machine " + rawLocation + " in " + this);
-            throw new IllegalArgumentException("Unknown machine " + rawLocation);
-        }
-        LOG.info("Suspending machine {} in {}, instance id {}", new Object[]{rawLocation, this, instanceId});
-        Exception toThrow = null;
-        try {
-            getComputeService().suspendNode(instanceId);
-        } catch (Exception e) {
-            toThrow = e;
-            LOG.error("Problem suspending machine " + rawLocation + " in " + this + ", instance id " + instanceId, e);
-        }
-        removeChild(rawLocation);
-        if (toThrow != null) {
-            throw Exceptions.propagate(toThrow);
-        }
-    }
-
-    // ------------- constructing the template, etc ------------------------
-
-    private static interface CustomizeTemplateBuilder {
-        void apply(TemplateBuilder tb, ConfigBag props, Object v);
-    }
-
-    public static interface CustomizeTemplateOptions {
-        void apply(TemplateOptions tb, ConfigBag props, Object v);
-    }
-
-    /** properties which cause customization of the TemplateBuilder */
-    public static final Map<ConfigKey<?>,CustomizeTemplateBuilder> SUPPORTED_TEMPLATE_BUILDER_PROPERTIES = ImmutableMap.<ConfigKey<?>,CustomizeTemplateBuilder>builder()
-            .put(OS_64_BIT, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        Boolean os64Bit = TypeCoercions.coerce(v, Boolean.class);
-                        if (os64Bit!=null)
-                            tb.os64Bit(os64Bit);
-                    }})
-            .put(MIN_RAM, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.minRam( (int)(ByteSizeStrings.parse(Strings.toString(v), "mb")/1000/1000) );
-                    }})
-            .put(MIN_CORES, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.minCores(TypeCoercions.coerce(v, Double.class));
-                    }})
-            .put(MIN_DISK, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.minDisk( (int)(ByteSizeStrings.parse(Strings.toString(v), "gb")/1000/1000/1000) );
-                    }})
-            .put(HARDWARE_ID, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.hardwareId(((CharSequence)v).toString());
-                    }})
-            .put(IMAGE_ID, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.imageId(((CharSequence)v).toString());
-                    }})
-            .put(IMAGE_DESCRIPTION_REGEX, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.imageDescriptionMatches(((CharSequence)v).toString());
-                    }})
-            .put(IMAGE_NAME_REGEX, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.imageNameMatches(((CharSequence)v).toString());
-                    }})
-            .put(OS_FAMILY, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        Maybe<OsFamily> osFamily = Enums.valueOfIgnoreCase(OsFamily.class, v.toString());
-                        if (osFamily.isAbsent())
-                            throw new IllegalArgumentException("Invalid "+OS_FAMILY+" value "+v);
-                        tb.osFamily(osFamily.get());
-                    }})
-            .put(OS_VERSION_REGEX, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.osVersionMatches( ((CharSequence)v).toString() );
-                    }})
-            .put(TEMPLATE_SPEC, new CustomizeTemplateBuilder() {
-                public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        tb.from(TemplateBuilderSpec.parse(((CharSequence)v).toString()));
-                    }})
-            .put(DEFAULT_IMAGE_ID, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        /* done in the code, but included here so that it is in the map */
-                    }})
-            .put(TEMPLATE_BUILDER, new CustomizeTemplateBuilder() {
-                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
-                        /* done in the code, but included here so that it is in the map */
-                    }})
-            .build();
-
-    /** properties which cause customization of the TemplateOptions */
-    public static final Map<ConfigKey<?>,CustomizeTemplateOptions> SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES = ImmutableMap.<ConfigKey<?>,CustomizeTemplateOptions>builder()
-            .put(SECURITY_GROUPS, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof EC2TemplateOptions) {
-                            String[] securityGroups = toStringArray(v);
-                            ((EC2TemplateOptions)t).securityGroups(securityGroups);
-                        } else if (t instanceof NovaTemplateOptions) {
-                            String[] securityGroups = toStringArray(v);
-                            ((NovaTemplateOptions)t).securityGroups(securityGroups);
-                        } else if (t instanceof SoftLayerTemplateOptions) {
-                            String[] securityGroups = toStringArray(v);
-                            ((SoftLayerTemplateOptions)t).securityGroups(securityGroups);
-                        } else if (t instanceof GoogleComputeEngineTemplateOptions) {
-                            String[] securityGroups = toStringArray(v);
-                            ((GoogleComputeEngineTemplateOptions)t).securityGroups(securityGroups);
-                        } else {
-                            LOG.info("ignoring securityGroups({}) in VM creation because not supported for cloud/type ({})", v, t.getClass());
-                        }
-                    }})
-            .put(INBOUND_PORTS, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        int[] inboundPorts = toIntArray(v);
-                        if (LOG.isDebugEnabled()) LOG.debug("opening inbound ports {} for cloud/type {}", Arrays.toString(inboundPorts), t.getClass());
-                        t.inboundPorts(inboundPorts);
-                    }})
-            .put(USER_METADATA_STRING, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof EC2TemplateOptions) {
-                            // See AWS docs: http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html#user-data-execution
-                            if (v==null) return;
-                            String data = v.toString();
-                            if (!(data.startsWith("<script>") || data.startsWith("<powershell>"))) {
-                                data = "<script> " + data + " </script>";
-                            }
-                            ((EC2TemplateOptions)t).userData(data.getBytes());
-                        } else if (t instanceof SoftLayerTemplateOptions) {
-                            ((SoftLayerTemplateOptions)t).userData(Strings.toString(v));
-                        } else {
-                            // Try reflection: userData(String), or guestCustomizationScript(String);
-                            // the latter is used by vCloud Director.
-                            Class<? extends TemplateOptions> clazz = t.getClass();
-                            Method userDataMethod = null;
-                            try {
-                                userDataMethod = clazz.getMethod("userData", String.class);
-                            } catch (SecurityException e) {
-                                LOG.info("Problem reflectively inspecting methods of "+t.getClass()+" for setting userData", e);
-                            } catch (NoSuchMethodException e) {
-                                try {
-                                    // For vCloud Director
-                                    userDataMethod = clazz.getMethod("guestCustomizationScript", String.class);
-                                } catch (NoSuchMethodException e2) {
-                                    // expected on various other clouds
-                                }
-                            }
-                            if (userDataMethod != null) {
-                                try {
-                                    userDataMethod.invoke(t, Strings.toString(v));
-                                } catch (InvocationTargetException e) {
-                                    LOG.info("Problem invoking "+userDataMethod.getName()+" of "+t.getClass()+", for setting userData (rethrowing)", e);
-                                    throw Exceptions.propagate(e);
-                                } catch (IllegalAccessException e) {
-                                    LOG.debug("Unable to reflectively invoke "+userDataMethod.getName()+" of "+t.getClass()+", for setting userData (rethrowing)", e);
-                                    throw Exceptions.propagate(e);
-                                }
-                            } else {
-                                LOG.info("ignoring userDataString({}) in VM creation because not supported for cloud/type ({})", v, t.getClass());
-                            }
-                        }
-                    }})
-            .put(USER_DATA_UUENCODED, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof EC2TemplateOptions) {
-                            byte[] bytes = toByteArray(v);
-                            ((EC2TemplateOptions)t).userData(bytes);
-                        } else if (t instanceof SoftLayerTemplateOptions) {
-                            ((SoftLayerTemplateOptions)t).userData(Strings.toString(v));
-                        } else {
-                            LOG.info("ignoring userData({}) in VM creation because not supported for cloud/type ({})", v, t.getClass());
-                        }
-                    }})
-            .put(STRING_TAGS, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        List<String> tags = toListOfStrings(v);
-                        if (LOG.isDebugEnabled()) LOG.debug("setting VM tags {} for {}", tags, t);
-                        t.tags(tags);
-                    }})
-            .put(USER_METADATA_MAP, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (v != null) {
-                            t.userMetadata(toMapStringString(v));
-                        }
-                    }})
-            .put(EXTRA_PUBLIC_KEY_DATA_TO_AUTH, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        t.authorizePublicKey(((CharSequence)v).toString());
-                    }})
-            .put(RUN_AS_ROOT, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        t.runAsRoot((Boolean)v);
-                    }})
-            .put(LOGIN_USER, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (v != null) {
-                            t.overrideLoginUser(((CharSequence)v).toString());
-                        }
-                    }})
-            .put(LOGIN_USER_PASSWORD, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (v != null) {
-                            t.overrideLoginPassword(((CharSequence)v).toString());
-                        }
-                    }})
-            .put(LOGIN_USER_PRIVATE_KEY_FILE, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (v != null) {
-                            String privateKeyFileName = ((CharSequence)v).toString();
-                            String privateKey;
-                            try {
-                                privateKey = Files.toString(new File(Os.tidyPath(privateKeyFileName)), Charsets.UTF_8);
-                            } catch (IOException e) {
-                                LOG.error(privateKeyFileName + "not found", e);
-                                throw Exceptions.propagate(e);
-                            }
-                            t.overrideLoginPrivateKey(privateKey);
-                        }
-                    }})
-            .put(LOGIN_USER_PRIVATE_KEY_DATA, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (v != null) {
-                            t.overrideLoginPrivateKey(((CharSequence)v).toString());
-                        }
-                    }})
-            .put(KEY_PAIR, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof EC2TemplateOptions) {
-                            ((EC2TemplateOptions)t).keyPair(((CharSequence)v).toString());
-                        } else if (t instanceof NovaTemplateOptions) {
-                            ((NovaTemplateOptions)t).keyPairName(((CharSequence)v).toString());
-                        } else if (t instanceof CloudStackTemplateOptions) {
-                            ((CloudStackTemplateOptions) t).keyPair(((CharSequence) v).toString());
-                        } else {
-                            LOG.info("ignoring keyPair({}) in VM creation because not supported for cloud/type ({})", v, t);
-                        }
-                    }})
-            .put(AUTO_GENERATE_KEYPAIRS, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof NovaTemplateOptions) {
-                            ((NovaTemplateOptions)t).generateKeyPair((Boolean)v);
-                        } else if (t instanceof CloudStackTemplateOptions) {
-                            ((CloudStackTemplateOptions) t).generateKeyPair((Boolean) v);
-                        } else {
-                            LOG.info("ignoring auto-generate-keypairs({}) in VM creation because not supported for cloud/type ({})", v, t);
-                        }
-                    }})
-            .put(AUTO_CREATE_FLOATING_IPS, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof NovaTemplateOptions) {
-                            ((NovaTemplateOptions)t).autoAssignFloatingIp((Boolean)v);
-                        } else {
-                            LOG.info("ignoring auto-generate-floating-ips({}) in VM creation because not supported for cloud/type ({})", v, t);
-                        }
-                    }})
-            .put(AUTO_ASSIGN_FLOATING_IP, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof NovaTemplateOptions) {
-                            ((NovaTemplateOptions)t).autoAssignFloatingIp((Boolean)v);
-                        } else if (t instanceof CloudStackTemplateOptions) {
-                            ((CloudStackTemplateOptions)t).setupStaticNat((Boolean)v);
-                        } else {
-                            LOG.info("ignoring auto-assign-floating-ip({}) in VM creation because not supported for cloud/type ({})", v, t);
-                        }
-                    }})
-            .put(NETWORK_NAME, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof AWSEC2TemplateOptions) {
-                            // subnet ID is the sensible interpretation of network name in EC2
-                            ((AWSEC2TemplateOptions)t).subnetId((String)v);
-                            
-                        } else {
-                            if (t instanceof GoogleComputeEngineTemplateOptions) {
-                                // no warning needed
-                                // we think this is the only jclouds endpoint which supports this option
-                                
-                            } else if (t instanceof SoftLayerTemplateOptions) {
-                                LOG.warn("networkName is not be supported in SoftLayer; use `templateOptions` with `primaryNetworkComponentNetworkVlanId` or `primaryNetworkBackendComponentNetworkVlanId`");
-                            } else if (!(t instanceof CloudStackTemplateOptions) && !(t instanceof NovaTemplateOptions)) {
-                                LOG.warn("networkName is experimental in many jclouds endpoints may not be supported in this cloud");
-                                // NB, from @andreaturli
-//                                Cloudstack uses custom securityGroupIds and networkIds not the generic networks
-//                                Openstack Nova uses securityGroupNames which is marked as @deprecated (suggests to use groups which is maybe even more confusing)
-//                                Azure supports the custom networkSecurityGroupName
-                            }
-                            
-                            t.networks((String)v);
-                        }
-                    }})
-            .put(DOMAIN_NAME, new CustomizeTemplateOptions() {
-                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
-                        if (t instanceof SoftLayerTemplateOptions) {
-                            ((SoftLayerTemplateOptions)t).domainName(TypeCoercions.coerce(v, String.class));
-                        } else {
-                            LOG.info("ignoring domain-name({}) in VM creation because not supported for cloud/type ({})", v, t);                            
-                        }
-                    }})
-            .put(TEMPLATE_OPTIONS, new CustomizeTemplateOptions() {
-                @Override
-                public void apply(TemplateOptions options, ConfigBag config, Object v) {
-                    if (v == null) return;
-                    @SuppressWarnings("unchecked") Map<String, Object> optionsMap = (Map<String, Object>) v;
-                    if (optionsMap.isEmpty()) return;
-
-                    Class<? extends TemplateOptions> clazz = options.getClass();
-                    for(final Map.Entry<String, Object> option : optionsMap.entrySet()) {
-                        Maybe<?> result = MethodCoercions.tryFindAndInvokeBestMatchingMethod(options, option.getKey(), option.getValue());
-                        if(result.isAbsent()) {
-                            LOG.warn("Ignoring request to set template option {} because this is not supported by {}", new Object[] { option.getKey(), clazz.getCanonicalName() });
-                        }
-                    }
-                }})
-            .build();
-
-    /** hook whereby template customizations can be made for various clouds */
-    protected void customizeTemplate(ConfigBag setup, ComputeService computeService, Template template) {
-        for (JcloudsLocationCustomizer customizer : getCustomizers(setup)) {
-            customizer.customize(this, computeService, template);
-            customizer.customize(this, computeService, template.getOptions());
-        }
-
-        // these things are nice on softlayer
-        if (template.getOptions() instanceof SoftLayerTemplateOptions) {
-            SoftLayerTemplateOptions slT = ((SoftLayerTemplateOptions)template.getOptions());
-            if (Strings.isBlank(slT.getDomainName()) || "jclouds.org".equals(slT.getDomainName())) {
-                // set a quasi-sensible domain name if none was provided (better than the default, jclouds.org)
-                // NB: things like brooklyn.local are disallowed
-                slT.domainName("local.brooklyncentral.org");
-            }
-            // convert user metadata to tags and notes because user metadata is otherwise ignored
-            Map<String, String> md = slT.getUserMetadata();
-            if (md!=null && !md.isEmpty()) {
-                Set<String> tags = MutableSet.copyOf(slT.getTags());
-                for (Map.Entry<String,String> entry: md.entrySet()) {
-                    tags.add(AbstractCloudMachineNamer.sanitize(entry.getKey())+":"+AbstractCloudMachineNamer.sanitize(entry.getValue()));
-                }
-                slT.tags(tags);
-
-                if (!md.containsKey("notes")) {
-                    String notes = "User Metadata\n=============\n\n  * " + Joiner.on("\n  * ").withKeyValueSeparator(": ").join(md);
-                    if (notes.length() > NOTES_MAX_LENGTH) {
-                        String truncatedMsg = "...\n<truncated - notes total length is " + notes.length() + " characters>";
-                        notes = notes.substring(0, NOTES_MAX_LENGTH - truncatedMsg.length()) + truncatedMsg;
-                    }
-                    md.put("notes", notes);
-                }
-            }
-        }
-    }
-
-    /** returns the jclouds Template which describes the image to be built, for the given config and compute service */
-    public Template buildTemplate(ComputeService computeService, ConfigBag config) {
-        TemplateBuilder templateBuilder = (TemplateBuilder) config.get(TEMPLATE_BUILDER);
-        if (templateBuilder==null) {
-            templateBuilder = new PortableTemplateBuilder<PortableTemplateBuilder<?>>();
-        } else {
-            LOG.debug("jclouds using templateBuilder {} as custom base for provisioning in {} for {}", new Object[] {
-                    templateBuilder, this, config.getDescription()});
-        }
-        if (templateBuilder instanceof PortableTemplateBuilder<?>) {
-            if (((PortableTemplateBuilder<?>)templateBuilder).imageChooser()==null) {
-                Function<Iterable<? extends Image>, Image> chooser = config.get(JcloudsLocationConfig.IMAGE_CHOOSER);
-                chooser = BrooklynImageChooser.cloneFor(chooser, computeService);
-                templateBuilder.imageChooser(chooser);
-            } else {
-                // an image chooser is already set, so do nothing
-            }
-        } else {
-            // template builder supplied, and we cannot check image chooser status; warn, for now
-            LOG.warn("Cannot check imageChooser status for {} due to manually supplied black-box TemplateBuilder; "
-                + "it is recommended to use a PortableTemplateBuilder if you supply a TemplateBuilder", config.getDescription());
-        }
-
-        if (!Strings.isEmpty(config.get(CLOUD_REGION_ID))) {
-            templateBuilder.locationId(config.get(CLOUD_REGION_ID));
-        }
-
-        // Apply the template builder and options properties
-        for (Map.Entry<ConfigKey<?>, CustomizeTemplateBuilder> entry : SUPPORTED_TEMPLATE_BUILDER_PROPERTIES.entrySet()) {
-            ConfigKey<?> name = entry.getKey();
-            CustomizeTemplateBuilder code = entry.getValue();
-            if (config.containsKey(name))
-                code.apply(templateBuilder, config, config.get(name));
-        }
-
-        if (templateBuilder instanceof PortableTemplateBuilder) {
-            ((PortableTemplateBuilder<?>)templateBuilder).attachComputeService(computeService);
-            // do the default last, and only if nothing else specified (guaranteed to be a PTB if nothing else specified)
-            if (groovyTruth(config.get(DEFAULT_IMAGE_ID))) {
-                if (((PortableTemplateBuilder<?>)templateBuilder).isBlank()) {
-                    templateBuilder.imageId(config.get(DEFAULT_IMAGE_ID).toString());
-                }
-            }
-        }
-
-        // Then apply any optional app-specific customization.
-        for (JcloudsLocationCustomizer customizer : getCustomizers(config)) {
-            customizer.customize(this, computeService, templateBuilder);
-        }
-
-        LOG.debug("jclouds using templateBuilder {} for provisioning in {} for {}", new Object[] {
-            templateBuilder, this, config.getDescription()});
-
-        // Finally try to build the template
-        Template template;
-        Image image;
-        try {
-            template = templateBuilder.build();
-            if (template==null) throw new NullPointerException("No template found (templateBuilder.build returned null)");
-            image = template.getImage();
-            LOG.debug("jclouds found template "+template+" (image "+image+") for provisioning in "+this+" for "+config.getDescription());
-            if (image==null) throw new NullPointerException("Template does not contain an image (templateBuilder.build returned invalid template)");
-        } catch (AuthorizationException e) {
-            LOG.warn("Error resolving template: not authorized (rethrowing: "+e+")");
-            throw new IllegalStateException("Not authorized to access cloud "+this+" to resolve "+templateBuilder, e);
-        } catch (Exception e) {
-            try {
-                IOException ioe = Exceptions.getFirstThrowableOfType(e, IOException.class);
-                if (ioe != null) {
-                    LOG.warn("IOException found...", ioe);
-                    throw ioe;
-                }
-                if (listedAvailableTemplatesOnNoSuchTemplate.compareAndSet(false, true)) {
-                    // delay subsequent log.warns (put in synch block) so the "Loading..." message is obvious
-                    LOG.warn("Unable to match required VM template constraints "+templateBuilder+" when trying to provision VM in "+this+" (rethrowing): "+e);
-                    logAvailableTemplates(config);
-                }
-            } catch (Exception e2) {
-                LOG.warn("Error loading available images to report (following original error matching template which will be rethrown): "+e2, e2);
-                throw new IllegalStateException("Unable to access cloud "+this+" to resolve "+templateBuilder+": "+e, e);
-            }
-            throw new IllegalStateException("Unable to match required VM template constraints "+templateBuilder+" when trying to provision VM in "+this+"; "
-                + "see list of images in log. Root cause: "+e, e);
-        }
-        TemplateOptions options = template.getOptions();
-
-        boolean windows = isWindows(template, config);
-        if (windows) {
-            if (!(config.containsKey(JcloudsLocationConfig.USER_METADATA_STRING) || config.containsKey(JcloudsLocationConfig.USER_METADATA_MAP))) {
-                config.put(JcloudsLocationConfig.USER_METADATA_STRING, WinRmMachineLocation.getDefaultUserMetadataString());
-            }
-        }
-               
-        for (Map.Entry<ConfigKey<?>, CustomizeTemplateOptions> entry : SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.entrySet()) {
-            ConfigKey<?> key = entry.getKey();
-            CustomizeTemplateOptions code = entry.getValue();
-            if (config.containsKey(key))
-                code.apply(options, config, config.get(key));
-        }
-
-        return template;
-    }
-
-    protected void logAvailableTemplates(ConfigBag config) {
-        LOG.info("Loading available images at "+this+" for reference...");
-        ConfigBag m1 = ConfigBag.newInstanceCopying(config);
-        if (m1.containsKey(IMAGE_ID)) {
-            // if caller specified an image ID, remove that, but don't apply default filters
-            m1.remove(IMAGE_ID);
-            // TODO use key
-            m1.putStringKey("anyOwner", true);
-        }
-        ComputeService computeServiceLessRestrictive = getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(m1, true);
-        Set<? extends Image> imgs = computeServiceLessRestrictive.listImages();
-        LOG.info(""+imgs.size()+" available images at "+this);
-        for (Image img: imgs) {
-            LOG.info(" Image: "+img);
-        }
-
-        Set<? extends Hardware> profiles = computeServiceLessRestrictive.listHardwareProfiles();
-        LOG.info(""+profiles.size()+" available profiles at "+this);
-        for (Hardware profile: profiles) {
-            LOG.info(" Profile: "+profile);
-        }
-
-        Set<? extends org.jclouds.domain.Location> assignableLocations = computeServiceLessRestrictive.listAssignableLocations();
-        LOG.info(""+assignableLocations.size()+" available locations at "+this);
-        for (org.jclouds.domain.Location assignableLocation: assignableLocations) {
-            LOG.info(" Location: "+assignableLocation);
-        }
-    }
-
-    protected SshMachineLocation createTemporarySshMachineLocation(HostAndPort hostAndPort, LoginCredentials creds, ConfigBag config) {
-        Optional<String> initialPassword = creds.getOptionalPassword();
-        Optional<String> initialPrivateKey = creds.getOptionalPrivateKey();
-        String initialUser = creds.getUser();
-
-        Map<String,Object> sshProps = Maps.newLinkedHashMap(config.getAllConfig());
-        sshProps.put("user", initialUser);
-        sshProps.put("address", hostAndPort.getHostText());
-        sshProps.put("port", hostAndPort.getPort());
-        sshProps.put(AbstractLocation.TEMPORARY_LOCATION.getName(), true);
-        if (initialPassword.isPresent()) sshProps.put("password", initialPassword.get());
-        if (initialPrivateKey.isPresent()) sshProps.put("privateKeyData", initialPrivateKey.get());
-        if (initialPrivateKey.isPresent()) sshProps.put("privateKeyData", initialPrivateKey.get());
-
-        if (isManaged()) {
-            return getManagementContext().getLocationManager().createLocation(sshProps, SshMachineLocation.class);
-        } else {
-            return new SshMachineLocation(sshProps);
-        }
-    }
-
-    /**
-     * Create the user immediately - executing ssh commands as required.
-     */
-    protected LoginCredentials createUser(ComputeService computeService, NodeMetadata node, Optional<HostAndPort> hostAndPortOverride, ConfigBag config) {
-        Image image = (node.getImageId() != null) ? computeService.getImage(node.getImageId()) : null;
-        UserCreation userCreation = createUserStatements(image, config);
-
-        if (!userCreation.statements.isEmpty()) {
-            // If unsure of OS family, default to unix for rendering statements.
-            org.jclouds.scriptbuilder.domain.OsFamily scriptOsFamily;
-            if (isWindows(node, config)) {
-                scriptOsFamily = org.jclouds.scriptbuilder.domain.OsFamily.WINDOWS;
-            } else {
-                scriptOsFamily = org.jclouds.scriptbuilder.domain.OsFamily.UNIX;
-            }
-
-            boolean windows = isWindows(node, config);
-
-            if (windows) {
-                LOG.warn("Unable to execute statements on WinRM in JcloudsLocation; skipping for "+node+": "+userCreation.statements);
-                
-            } else {
-                List<String> commands = Lists.newArrayList();
-                for (Statement statement : userCreation.statements) {
-                    InitAdminAccess initAdminAccess = new InitAdminAccess(new AdminAccessConfiguration.Default());
-                    initAdminAccess.visit(statement);
-                    commands.add(statement.render(scriptOsFamily));
-                }
-
-                LoginCredentials initialCredentials = node.getCredentials();
-                Optional<String> initialPassword = initialCredentials.getOptionalPassword();
-                Optional<String> initialPrivateKey = initialCredentials.getOptionalPrivateKey();
-                String initialUser = initialCredentials.getUser();
-                String address = hostAndPortOverride.isPresent() ? hostAndPortOverride.get().getHostText() : JcloudsUtil.getFirstReachableAddress(computeService.getContext(), node);
-                int port = hostAndPortOverride.isPresent() ? hostAndPortOverri

<TRUNCATED>


[50/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java b/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
index a1d0851..aa16b8c 100644
--- a/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
+++ b/core/src/test/java/brooklyn/event/feed/http/HttpFeedTest.java
@@ -28,6 +28,7 @@ import java.util.concurrent.Callable;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,7 +45,6 @@ import brooklyn.entity.basic.EntityInternal.FeedSupport;
 import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.FeedConfig;
 import brooklyn.event.feed.PollConfig;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
index 7ecba77..4aa55d7 100644
--- a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
+++ b/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
@@ -23,6 +23,9 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
@@ -30,9 +33,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java b/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java
index 33b8934..18a7f40 100644
--- a/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java
+++ b/core/src/test/java/brooklyn/event/feed/windows/WindowsPerformanceCounterFeedTest.java
@@ -29,6 +29,7 @@ import java.util.Iterator;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.slf4j.Logger;
@@ -39,8 +40,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.util.text.Strings;
 import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
index 018641e..63ee8a0 100644
--- a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
+++ b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
@@ -23,6 +23,7 @@ import java.net.URI;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.Assert;
@@ -36,7 +37,6 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
 import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java b/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
index c4c8956..b6bf5c1 100644
--- a/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
+++ b/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
@@ -20,6 +20,7 @@ package brooklyn.management.entitlement;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.slf4j.Logger;
@@ -34,7 +35,6 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
 import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.management.internal.LocalManagementContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
index 1062229..ff86733 100644
--- a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
+++ b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerInMemoryTest.java
@@ -23,6 +23,8 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -34,10 +36,10 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.persister.InMemoryObjectStore;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
index ea99621..e747a82 100644
--- a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
+++ b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
@@ -28,6 +28,7 @@ import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.api.management.ha.ManagementNodeState;
 import org.apache.brooklyn.api.management.ha.ManagementNodeSyncRecord;
@@ -50,7 +51,6 @@ import brooklyn.entity.rebind.persister.ListeningObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.ha.TestEntityFailingRebind.RebindException;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.test.Asserts;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java b/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java
index ae9e3b4..f061289 100644
--- a/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java
+++ b/core/src/test/java/brooklyn/management/ha/HotStandbyTest.java
@@ -33,6 +33,8 @@ import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.api.management.ha.ManagementNodeState;
 import org.apache.brooklyn.api.management.ha.ManagementPlaneSyncRecordPersister;
@@ -58,9 +60,9 @@ import brooklyn.entity.rebind.persister.InMemoryObjectStore;
 import brooklyn.entity.rebind.persister.ListeningObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+
 import brooklyn.management.internal.AbstractManagementContext;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java b/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java
index 4afc78c..54f4b8b 100644
--- a/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java
+++ b/core/src/test/java/brooklyn/management/ha/WarmStandbyTest.java
@@ -24,6 +24,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.api.management.ha.ManagementNodeState;
 import org.apache.brooklyn.api.management.ha.ManagementPlaneSyncRecordPersister;
@@ -42,7 +43,6 @@ import brooklyn.entity.rebind.persister.InMemoryObjectStore;
 import brooklyn.entity.rebind.persister.ListeningObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java b/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java
index 59d92c7..34f733c 100644
--- a/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java
+++ b/core/src/test/java/brooklyn/management/internal/AccessManagerTest.java
@@ -24,6 +24,8 @@ import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -33,9 +35,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.ImmutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java b/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java
index a648c74..d225cd7 100644
--- a/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java
+++ b/core/src/test/java/brooklyn/management/internal/LocalManagementContextTest.java
@@ -25,6 +25,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext.PropertiesReloadListener;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.annotations.AfterMethod;
@@ -33,7 +34,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.config.BrooklynProperties.Factory.Builder;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.os.Os;
 
 import com.google.common.base.Charsets;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java
index 6b8f87c..fc15ff3 100644
--- a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java
+++ b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTest.java
@@ -19,9 +19,9 @@
 package brooklyn.qa.longevity;
 
 import org.testng.annotations.Test;
-
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.javalang.JavaClassNames;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
index 225dc08..f419101 100644
--- a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
+++ b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupLongevityTestFixture.java
@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -39,8 +40,9 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.internal.storage.DataGrid;
 import brooklyn.internal.storage.impl.BrooklynStorageImpl;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.management.internal.AbstractManagementContext;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java
index 2313e08..70c1e1b 100644
--- a/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java
+++ b/core/src/test/java/brooklyn/qa/longevity/EntityCleanupTest.java
@@ -19,9 +19,9 @@
 package brooklyn.qa.longevity;
 
 import org.testng.annotations.Test;
-
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.javalang.JavaClassNames;
 
 public class EntityCleanupTest extends EntityCleanupLongevityTestFixture {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java b/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java
index 1f8b669..8303062 100644
--- a/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java
+++ b/core/src/test/java/brooklyn/qa/performance/EntityPersistencePerformanceTest.java
@@ -23,6 +23,7 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.policy.Policy;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.apache.brooklyn.test.PerformanceTestUtils;
@@ -30,8 +31,9 @@ import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.policy.TestPolicy;
 import brooklyn.util.repeat.Repeater;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/test/HttpService.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/test/HttpService.java b/core/src/test/java/brooklyn/test/HttpService.java
index 8a73541..2710211 100644
--- a/core/src/test/java/brooklyn/test/HttpService.java
+++ b/core/src/test/java/brooklyn/test/HttpService.java
@@ -19,6 +19,7 @@
 package brooklyn.test;
 
 import org.apache.brooklyn.test.TestResourceUnavailableException;
+
 import java.io.File;
 import java.io.InputStream;
 import java.net.InetAddress;
@@ -38,9 +39,9 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.eclipse.jetty.webapp.WebAppContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.crypto.SecureKeys;
 import brooklyn.util.javalang.Threads;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java b/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
index 6fd7560..f5e0052 100644
--- a/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
+++ b/core/src/test/java/brooklyn/util/task/ssh/SshTasksTest.java
@@ -21,6 +21,7 @@ package brooklyn.util.task.ssh;
 import java.io.File;
 import java.io.IOException;
 
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
@@ -32,9 +33,10 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
index da69b24..541585f 100644
--- a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerLocationResolverTest.java
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.location.access;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java
index 6645217..d36dec0 100644
--- a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerRebindTest.java
@@ -25,8 +25,9 @@ import java.io.File;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ha.MementoCopyMode;
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.apache.brooklyn.test.entity.TestEntityImpl;
 import org.slf4j.Logger;
@@ -43,8 +44,9 @@ import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils;
 import brooklyn.entity.rebind.persister.FileBasedObjectStore;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;
 import brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java
index 904e9dc..ef5cf93 100644
--- a/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/access/PortForwardManagerTest.java
@@ -34,8 +34,10 @@ import org.testng.annotations.Test;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
+
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.net.Networking;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java
index 4977195..089b719 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/AbstractLocationTest.java
@@ -26,9 +26,9 @@ import static org.testng.Assert.assertTrue;
 import java.util.Collections;
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
index 05b53b2..3cb5ab9 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
@@ -23,17 +23,19 @@ import static org.testng.Assert.fail;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java
index 141ab5d..09eb142 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/ByonLocationResolverTest.java
@@ -30,9 +30,9 @@ import java.util.Set;
 
 import javax.annotation.Nullable;
 
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
index c4df75f..84cc898 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationRebindTest.java
@@ -25,8 +25,8 @@ import java.util.Set;
 
 import javax.annotation.Nullable;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
index d689512..73ca57a 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
@@ -28,9 +28,9 @@ import java.util.List;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java
index 2d66cb5..2ef938d 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/HostLocationResolverTest.java
@@ -25,7 +25,7 @@ import java.net.InetAddress;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java
index fd6f29c..704f5ac 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostLocationResolverTest.java
@@ -26,7 +26,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -35,7 +36,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.text.StringEscapes.JavaStringEscapes;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
index d948eaf..2bd0d28 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
@@ -34,11 +34,13 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
-import org.apache.brooklyn.location.PortRange;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.location.geo.HostGeoInfo;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
index fad4567..e1dff5e 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
@@ -23,7 +23,7 @@ import static org.testng.Assert.assertTrue;
 
 import java.util.Arrays;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java
index b3e4f04..1f265fd 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationConfigTest.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.location.basic;
 
 import static org.testng.Assert.assertEquals;
 
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.LocationSpec;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java
index 1b5b743..4cbe0c4 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationExtensionsTest.java
@@ -23,9 +23,9 @@ import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java
index be68557..5f6fa03 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationManagementTest.java
@@ -24,8 +24,8 @@ import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.LocationManager;
-import org.apache.brooklyn.location.LocationSpec;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java
index 3324477..219acd2 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationPredicatesTest.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.location.basic;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java
index ed8a96d..b1e01ca 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/LocationRegistryTest.java
@@ -18,7 +18,8 @@
  */
 package org.apache.brooklyn.location.basic;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,7 +29,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationDefinition;
 import brooklyn.management.internal.LocalManagementContext;
 
 public class LocationRegistryTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java
index 7b36172..a3ce1d6 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsTest.java
@@ -23,11 +23,11 @@ import static org.testng.Assert.assertNotNull;
 
 import java.util.Arrays;
 
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineDetails;
-import org.apache.brooklyn.location.OsDetails;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java
index 25c2e9e..6d2e841 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationRebindTest.java
@@ -22,9 +22,9 @@ import java.io.File;
 import java.util.List;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
 import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java
index 6fbf54e..8953397 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationResolverTest.java
@@ -31,9 +31,10 @@ import java.util.NoSuchElementException;
 
 import javax.annotation.Nullable;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.Assert;
@@ -43,7 +44,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java
index 57d6c79..26423f5 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/MultiLocationTest.java
@@ -29,9 +29,11 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java
index 3e4812f..2b7ab69 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/PortRangesTest.java
@@ -24,8 +24,8 @@ import java.util.Iterator;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
+import org.apache.brooklyn.api.location.PortRange;
 
-import org.apache.brooklyn.location.PortRange;
 import brooklyn.util.flags.TypeCoercions;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.java b/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
index a30d6e1..53e261f 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
@@ -26,8 +26,8 @@ import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineLocationCustomizer;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineLocationCustomizer;
 
 public class RecordingMachineLocationCustomizer implements MachineLocationCustomizer {
     public static class Call {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java b/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java
index c904619..fdbcf1c 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SimulatedLocation.java
@@ -23,14 +23,15 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.brooklyn.location.HardwareDetails;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineDetails;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.OsDetails;
-import org.apache.brooklyn.location.PortRange;
-import org.apache.brooklyn.location.PortSupplier;
+import org.apache.brooklyn.api.location.HardwareDetails;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.api.location.PortRange;
+import org.apache.brooklyn.api.location.PortSupplier;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
index 27731e5..1fef80b 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationReuseIntegrationTest.java
@@ -32,7 +32,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java
index 37f3b32..b4ee5ef 100644
--- a/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/basic/SshMachineLocationTest.java
@@ -37,12 +37,12 @@ import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntityInitializer;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineDetails;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.PortRange;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java b/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java
index f288bee..173acf8 100644
--- a/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/geo/HostGeoInfoTest.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.location.geo;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNotNull;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java b/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java
index 8dbb21d..3e1ad87 100644
--- a/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java
+++ b/core/src/test/java/org/apache/brooklyn/test/entity/BlockingEntityImpl.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.test.entity;
 import java.util.Collection;
 import java.util.concurrent.CountDownLatch;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.base.Throwables;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java b/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java
index 33c52ed..697577a 100644
--- a/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java
+++ b/core/src/test/java/org/apache/brooklyn/test/entity/TestApplicationImpl.java
@@ -25,14 +25,16 @@ import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.Sensor;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.SubscriptionHandle;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractApplication;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.logging.LoggingSetup;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java b/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java
index c444b51..44bc11a 100644
--- a/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java
+++ b/core/src/test/java/org/apache/brooklyn/test/entity/TestEntityImpl.java
@@ -28,13 +28,13 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.Lists;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
index 9c3edad..6f9bdea 100644
--- a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
@@ -31,6 +31,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
 import org.apache.brooklyn.entity.nosql.cassandra.CassandraFabric;
 import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode;
@@ -56,9 +57,8 @@ import brooklyn.event.basic.DependentConfiguration;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 import org.apache.brooklyn.policy.EnricherSpec;
 import org.apache.brooklyn.policy.PolicySpec;
-
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.policy.ha.ServiceFailureDetector;
 import brooklyn.policy.ha.ServiceReplacer;
 import brooklyn.policy.ha.ServiceRestarter;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java b/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
index 900ba4a..1755cf7 100644
--- a/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
+++ b/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.demo;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
 import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
@@ -55,7 +56,6 @@ import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.java.JavaEntityMethods;
 import brooklyn.entity.rebind.RebindOptions;
 import brooklyn.entity.rebind.RebindTestFixture;
-import org.apache.brooklyn.location.Location;
 import brooklyn.policy.autoscaling.AutoScalerPolicy;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java b/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java
index bd02f60..266f738 100644
--- a/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java
+++ b/locations/jclouds/src/main/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicy.java
@@ -23,13 +23,15 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.WinRmMachineLocation;
+
 import brooklyn.policy.basic.AbstractPolicy;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java b/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java
index 4e2f68c..bc8eab1 100644
--- a/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java
+++ b/locations/jclouds/src/main/java/brooklyn/policy/os/CreateUserPolicy.java
@@ -25,6 +25,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.jclouds.compute.config.AdminAccessConfiguration;
 import org.jclouds.scriptbuilder.functions.InitAdminAccess;
 import org.jclouds.scriptbuilder.statements.login.AdminAccess;
@@ -37,8 +38,9 @@ import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.internal.ssh.SshTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java
index e857e93..fa71a3a 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/BrooklynMachinePool.java
@@ -26,17 +26,19 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.management.Task;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.jclouds.pool.MachinePool;
 import org.apache.brooklyn.location.jclouds.pool.MachineSet;
 import org.apache.brooklyn.location.jclouds.pool.ReusableMachineTemplate;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.task.BasicExecutionContext;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
index 5aa026d..e8f63b3 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsByonLocationResolver.java
@@ -25,21 +25,21 @@ import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.LocationRegistry;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.location.LocationResolver;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.basic.LocationConfigUtils;
 import org.apache.brooklyn.location.basic.LocationInternal;
 import org.apache.brooklyn.location.basic.LocationPropertiesFromBrooklynProperties;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
index d355721..2583234 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -51,10 +51,12 @@ import java.util.regex.Pattern;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineLocationCustomizer;
+import org.apache.brooklyn.api.location.MachineManagementMixins;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.AccessController;
-import org.apache.brooklyn.location.MachineLocationCustomizer;
-import org.apache.brooklyn.location.MachineManagementMixins;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.access.PortMapping;
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation;
@@ -131,8 +133,7 @@ import brooklyn.entity.basic.Sanitizer;
 import brooklyn.entity.rebind.persister.LocationWithObjectStore;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
 import brooklyn.entity.rebind.persister.jclouds.JcloudsBlobStoreBasedObjectStore;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.access.PortForwardManager;
 import org.apache.brooklyn.location.basic.BasicMachineMetadata;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
@@ -144,6 +145,7 @@ import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
 import org.apache.brooklyn.location.cloud.names.CloudMachineNamer;
 import org.apache.brooklyn.location.jclouds.JcloudsPredicates.NodeInLocation;
 import org.apache.brooklyn.location.jclouds.templates.PortableTemplateBuilder;
+
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
index 1ca33c2..cf5335f 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolver.java
@@ -25,10 +25,10 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
-import org.apache.brooklyn.location.LocationSpec;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.basic.LocationConfigUtils;
 import org.apache.brooklyn.location.basic.LocationInternal;
@@ -38,8 +38,8 @@ import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.Providers;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
+
 import brooklyn.util.text.Strings;
 
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
index 2619206..11d20ef 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
@@ -18,12 +18,11 @@
  */
 package org.apache.brooklyn.location.jclouds;
 
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.location.basic.HasSubnetHostname;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Template;
 
-import org.apache.brooklyn.location.MachineLocation;
-
 public interface JcloudsMachineLocation extends MachineLocation, HasSubnetHostname {
     
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
index 08fd3b0..a2a5735 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
@@ -31,9 +31,9 @@ import java.util.concurrent.TimeoutException;
 
 import javax.annotation.Nullable;
 
-import org.apache.brooklyn.location.HardwareDetails;
-import org.apache.brooklyn.location.MachineDetails;
-import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.api.location.HardwareDetails;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.location.basic.BasicHardwareDetails;
 import org.apache.brooklyn.location.basic.BasicMachineDetails;
 import org.apache.brooklyn.location.basic.BasicOsDetails;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
index dcb6b4c..f62e6e4 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtension.java
@@ -24,12 +24,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
 import org.jclouds.aws.ec2.AWSEC2Api;
 import org.jclouds.ec2.domain.AvailabilityZoneInfo;
-
 import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
 import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver b/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
new file mode 100644
index 0000000..cef522c
--- /dev/null
+++ b/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
@@ -0,0 +1,20 @@
+#
+# 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.
+#
+org.apache.brooklyn.location.jclouds.JcloudsLocationResolver
+org.apache.brooklyn.location.jclouds.JcloudsByonLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver b/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
deleted file mode 100644
index e29b717..0000000
--- a/locations/jclouds/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
+++ /dev/null
@@ -1,2 +0,0 @@
-org.apache.brooklyn.location.jclouds.JcloudsLocationResolver
-org.apache.brooklyn.location.jclouds.JcloudsByonLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java b/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java
index 3973ade..37f46c9 100644
--- a/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/policy/os/AdvertiseWinrmLoginPolicyTest.java
@@ -19,13 +19,14 @@
 package brooklyn.policy.os;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java b/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java
index fe77f5e..78817df 100644
--- a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyLiveTest.java
@@ -25,6 +25,9 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -33,11 +36,10 @@ import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.text.Identifiers;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java b/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java
index 4184163..42fafd8 100644
--- a/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java
+++ b/locations/jclouds/src/test/java/brooklyn/policy/os/CreateUserPolicyTest.java
@@ -27,6 +27,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -37,8 +38,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.internal.ssh.SshTool;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java
index acf838e..7892c8e 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/BailOutJcloudsLocation.java
@@ -24,8 +24,8 @@ import java.util.Map;
 
 import javax.annotation.Nullable;
 
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.LocationSpec;
 import org.jclouds.compute.ComputeService;
 import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.Template;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
index 2694ed5..e24d070 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsAddressesLiveTest.java
@@ -28,7 +28,7 @@ import java.net.InetAddress;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.Locations;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
index 7bce1ab..3c3d4a5 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationMetadataTest.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.location.jclouds;
 
 import static org.testng.Assert.assertEquals;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
@@ -28,7 +28,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
+
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
+
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java
index 4c5788f..100f98a 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationTest.java
@@ -27,7 +27,10 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.annotation.Nullable;
 
-import org.apache.brooklyn.location.MachineLocationCustomizer;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineLocationCustomizer;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.cloud.names.CustomMachineNamer;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.jclouds.scriptbuilder.domain.OsFamily;
@@ -50,12 +53,11 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.geo.HostGeoInfo;
 import org.apache.brooklyn.location.jclouds.JcloudsLocation.UserCreation;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;



[41/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/AbstractLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/AbstractLocationResolver.java b/core/src/main/java/brooklyn/location/basic/AbstractLocationResolver.java
deleted file mode 100644
index f2799df..0000000
--- a/core/src/main/java/brooklyn/location/basic/AbstractLocationResolver.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.AbstractLocationResolver.SpecParser.ParsedSpec;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.text.KeyValueParser;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * Examples of valid specs:
- *   <ul>
- *     <li>byon(hosts=myhost)
- *     <li>byon(hosts=myhost,myhost2)
- *     <li>byon(hosts="myhost, myhost2")
- *     <li>byon(hosts=myhost,myhost2, name=abc)
- *     <li>byon(hosts="myhost, myhost2", name="my location name")
- *   </ul>
- * 
- * @author aled
- */
-@SuppressWarnings({"unchecked","rawtypes"})
-public abstract class AbstractLocationResolver implements LocationResolver {
-
-    public static final Logger log = LoggerFactory.getLogger(AbstractLocationResolver.class);
-    
-    protected volatile ManagementContext managementContext;
-
-    protected volatile SpecParser specParser;
-
-    protected abstract Class<? extends Location> getLocationType();
-    
-    protected abstract SpecParser getSpecParser();
-    
-    @Override
-    public void init(ManagementContext managementContext) {
-        this.managementContext = checkNotNull(managementContext, "managementContext");
-        this.specParser = getSpecParser();
-    }
-    
-    @Override
-    public boolean accepts(String spec, LocationRegistry registry) {
-        return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true);
-    }
-
-    @Override
-    public Location newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        ConfigBag config = extractConfig(locationFlags, spec, registry);
-        Map globalProperties = registry.getProperties();
-        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
-        
-        if (registry != null) {
-            LocationPropertiesFromBrooklynProperties.setLocalTempDir(globalProperties, config);
-        }
-
-        return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationType())
-            .configure(config.getAllConfig())
-            .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
-    }
-
-    protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        Map globalProperties = registry.getProperties();
-        ParsedSpec parsedSpec = specParser.parse(spec);
-        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());
-        
-        // prefer args map over location flags
-        Map<String, Object> filteredProperties = getFilteredLocationProperties(getPrefix(), namedLocation, globalProperties);
-        ConfigBag flags = ConfigBag.newInstance(parsedSpec.argsMap).putIfAbsent(locationFlags).putIfAbsent(filteredProperties);
-
-        return flags;
-    }
-    
-    protected Map<String, Object> getFilteredLocationProperties(String provider, String namedLocation, Map<String, ?> globalProperties) {
-        return new LocationPropertiesFromBrooklynProperties().getLocationProperties(getPrefix(), namedLocation, globalProperties);
-    }
-    
-    /**
-     * Parses a spec, by default of the general form "prefix:parts1:part2(arg1=val1,arg2=val2)"
-     */
-    protected static class SpecParser {
-        
-        protected static class ParsedSpec {
-            public final String spec;
-            public final List<String> partsList;
-            public final Map<String,String> argsMap;
-            
-            ParsedSpec(String spec, List<String> partsList, Map<String,String> argsMap) {
-                this.spec = spec;
-                this.partsList = ImmutableList.copyOf(partsList);
-                this.argsMap = Collections.unmodifiableMap(MutableMap.copyOf(argsMap));
-            }
-        }
-        
-        protected final String prefix;
-        protected final Pattern pattern;
-        private String exampleUsage;
-        
-        public SpecParser(String prefix) {
-            this.prefix = prefix;
-            pattern = Pattern.compile("("+prefix+"|"+prefix.toLowerCase()+"|"+prefix.toUpperCase()+")" + "(:)?" + "(\\((.*)\\))?$");
-        }
-        
-        public SpecParser(String prefix, Pattern pattern) {
-            this.prefix = prefix;
-            this.pattern = pattern;
-        }
-        
-        public SpecParser setExampleUsage(String exampleUsage) {
-            this.exampleUsage = exampleUsage;
-            return this;
-        }
-
-        protected String getUsage(String spec) {
-            if (exampleUsage == null) {
-                return "Spec should be in the form "+pattern;
-            } else {
-                return "for example, "+exampleUsage;
-            }
-        }
-        
-        protected void checkParsedSpec(ParsedSpec parsedSpec) {
-            // If someone tries "byon:(),byon:()" as a single spec, we get weird key-values!
-            for (String key : parsedSpec.argsMap.keySet()) {
-                if (key.contains(":") || key.contains("{") || key.contains("}") || key.contains("(") || key.contains(")")) {
-                    throw new IllegalArgumentException("Invalid byon spec: "+parsedSpec.spec+" (key="+key+")");
-                }
-            }
-            String name = parsedSpec.argsMap.get("name");
-            if (parsedSpec.argsMap.containsKey("name") && (name == null || name.isEmpty())) {
-                throw new IllegalArgumentException("Invalid location '"+parsedSpec.spec+"'; if name supplied then value must be non-empty");
-            }
-            String displayName = parsedSpec.argsMap.get("displayName");
-            if (parsedSpec.argsMap.containsKey("displayName") && (displayName == null || displayName.isEmpty())) {
-                throw new IllegalArgumentException("Invalid location '"+parsedSpec.spec+"'; if displayName supplied then value must be non-empty");
-            }
-        }
-        
-        public ParsedSpec parse(String spec) {
-            Matcher matcher = pattern.matcher(spec);
-            if (!matcher.matches()) {
-                throw new IllegalArgumentException("Invalid location '"+spec+"'; "+getUsage(spec));
-            }
-            
-            String argsPart = matcher.group(3);
-            if (argsPart != null && argsPart.startsWith("(") && argsPart.endsWith(")")) {
-                // TODO Hacky; hosts("1.1.1.1") returns argsPart=("1.1.1.1")
-                argsPart = argsPart.substring(1, argsPart.length()-1);
-            }
-            Map<String, String> argsMap = KeyValueParser.parseMap(argsPart);
-            ParsedSpec result = new ParsedSpec(spec, ImmutableList.<String>of(), argsMap);
-            checkParsedSpec(result);
-            return result;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java b/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
deleted file mode 100644
index a644459..0000000
--- a/core/src/main/java/brooklyn/location/basic/AggregatingMachineProvisioningLocation.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import java.io.Closeable;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.stream.Streams;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-/**
- * Takes a list of other provisioners, and round-robins across them when obtaining a machine.
- */
-public class AggregatingMachineProvisioningLocation<T extends MachineLocation> extends AbstractLocation 
-        implements MachineProvisioningLocation<T>, Closeable {
-
-    private Object lock;
-    
-    @SetFromFlag
-    protected List<MachineProvisioningLocation<T>> provisioners;
-    
-    @SetFromFlag
-    protected Map<T, MachineProvisioningLocation<T>> inUse;
-
-    protected final AtomicInteger obtainCounter = new AtomicInteger();
-    
-    public AggregatingMachineProvisioningLocation() {
-        this(Maps.newLinkedHashMap());
-    }
-    
-    public AggregatingMachineProvisioningLocation(Map properties) {
-        super(properties);
-
-        if (isLegacyConstruction()) {
-            init();
-        }
-    }
-
-    @Override
-    public void init() {
-        super.init();
-    }
-    
-    @Override
-    public String toVerboseString() {
-        return Objects.toStringHelper(this).omitNullValues()
-                .add("id", getId()).add("name", getDisplayName())
-                .add("provisioners", provisioners)
-                .toString();
-    }
-
-    @Override
-    public AbstractLocation configure(Map<?,?> properties) {
-        if (lock == null) {
-            lock = new Object();
-            provisioners = Lists.<MachineProvisioningLocation<T>>newArrayList();
-            inUse = Maps.<T, MachineProvisioningLocation<T>>newLinkedHashMap();
-        }
-        return super.configure(properties);
-    }
-    
-    @Override
-    public AggregatingMachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void close() {
-        for (MachineProvisioningLocation<?> provisioner : provisioners) {
-            if (provisioner instanceof Closeable) {
-                Streams.closeQuietly((Closeable)provisioner);
-            }
-        }
-    }
-    
-    public T obtain() throws NoMachinesAvailableException {
-        return obtain(Maps.<String,Object>newLinkedHashMap());
-    }
-    
-    @Override
-    public T obtain(Map<?,?> flags) throws NoMachinesAvailableException {
-        checkState(provisioners.size() > 0, "no provisioners!");
-        int index = obtainCounter.getAndIncrement();
-        for (int i = 0; i < provisioners.size(); i++) {
-            MachineProvisioningLocation<T> provisioner = provisioners.get(index++ % provisioners.size());
-            try {
-                T machine = provisioner.obtain(flags);
-                inUse.put(machine, provisioner);
-                return machine;
-            } catch (NoMachinesAvailableException e) {
-                // move on; try next
-            }
-        }
-        throw new NoMachinesAvailableException("No machines available in "+toString());
-    }
-
-    @Override
-    public void release(T machine) {
-        MachineProvisioningLocation<T> provisioner = inUse.remove(machine);
-        if (provisioner != null) {
-            provisioner.release(machine);
-        } else {
-            throw new IllegalStateException("Request to release machine "+machine+", but this machine is not currently allocated");
-        }
-    }
-
-    @Override
-    public Map<String,Object> getProvisioningFlags(Collection<String> tags) {
-        return Maps.<String,Object>newLinkedHashMap();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/BasicHardwareDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicHardwareDetails.java b/core/src/main/java/brooklyn/location/basic/BasicHardwareDetails.java
deleted file mode 100644
index eac4a2b..0000000
--- a/core/src/main/java/brooklyn/location/basic/BasicHardwareDetails.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import javax.annotation.concurrent.Immutable;
-
-import com.google.common.base.Objects;
-
-import brooklyn.location.HardwareDetails;
-
-@Immutable
-public class BasicHardwareDetails implements HardwareDetails {
-
-    private final Integer cpuCount;
-    private final Integer ram;
-
-    public BasicHardwareDetails(Integer cpuCount, Integer ram) {
-        this.cpuCount = cpuCount;
-        this.ram = ram;
-    }
-
-    @Override
-    public Integer getCpuCount() {
-        return cpuCount;
-    }
-
-    @Override
-    public Integer getRam() {
-        return ram;
-    }
-
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(HardwareDetails.class)
-                .omitNullValues()
-                .add("cpuCount", cpuCount)
-                .add("ram", ram)
-                .toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/BasicLocationDefinition.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicLocationDefinition.java b/core/src/main/java/brooklyn/location/basic/BasicLocationDefinition.java
deleted file mode 100644
index 2604c18..0000000
--- a/core/src/main/java/brooklyn/location/basic/BasicLocationDefinition.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import brooklyn.location.LocationDefinition;
-import brooklyn.util.text.Identifiers;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-
-public class BasicLocationDefinition implements LocationDefinition {
-
-    private final String id;
-    private final String name;
-    private final String spec;
-    private final Map<String,Object> config;
-
-    public BasicLocationDefinition(String name, String spec, Map<String,? extends Object> config) {
-        this(Identifiers.makeRandomId(8), name, spec, config);
-    }
-    
-    public BasicLocationDefinition(String id, String name, String spec, Map<String,? extends Object> config) {      
-        this.id = Preconditions.checkNotNull(id);
-        this.name = name;
-        this.spec = Preconditions.checkNotNull(spec);
-        this.config = config==null ? ImmutableMap.<String, Object>of() : ImmutableMap.<String, Object>copyOf(config);
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public String getName() {
-        return name;
-    }
-    
-    public String getSpec() {
-        return spec;
-    }
-    
-    @Override
-    public Map<String, Object> getConfig() {
-        return config;
-    }
-    
-    @Override
-    public boolean equals(Object o) {
-        if (this==o) return true;
-        if ((o instanceof LocationDefinition) && id.equals(((LocationDefinition)o).getId())) return true;
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return id.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return "LocationDefinition{" +
-                "id='" + getId() + '\'' +
-                ", name='" + getName() + '\'' +
-                ", spec='" + getSpec() + '\'' +
-                ", config=" + getConfig() +
-                '}';
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java b/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
deleted file mode 100644
index c0169d6..0000000
--- a/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.ServiceLoader;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.api.catalog.BrooklynCatalog;
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.management.ManagementContext;
-
-import brooklyn.catalog.CatalogPredicates;
-import brooklyn.config.ConfigMap;
-import brooklyn.config.ConfigPredicates;
-import brooklyn.config.ConfigUtils;
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-import brooklyn.location.LocationResolver.EnableableLocationResolver;
-import brooklyn.location.LocationSpec;
-import brooklyn.management.internal.LocalLocationManager;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.guava.Maybe.Absent;
-import brooklyn.util.javalang.JavaClassNames;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-import brooklyn.util.text.WildcardGlobs;
-import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
-
-/**
- * See {@link LocationRegistry} for general description.
- * <p>
- * TODO The relationship between the catalog and the location registry is a bit messy.
- * For all existing code, the location registry is the definitive way to resolve
- * locations. 
- * <p>
- * Any location item added to the catalog must therefore be registered here.
- * Whenever an item is added to the catalog, it will automatically call 
- * {@link #updateDefinedLocation(CatalogItem)}. Similarly, when a location
- * is deleted from the catalog it will call {@link #removeDefinedLocation(CatalogItem)}.
- * <p>
- * However, the location item in the catalog has an unparsed blob of YAML, which contains
- * important things like the type and the config of the location. This is only parsed when 
- * {@link BrooklynCatalog#createSpec(CatalogItem)} is called. We therefore jump through 
- * some hoops to wire together the catalog and the registry.
- * <p>
- * To add a location to the catalog, and then to resolve a location that is in the catalog, 
- * it goes through the following steps:
- * 
- * <ol>
- *   <li>Call {@link BrooklynCatalog#addItems(String)}
- *     <ol>
- *       <li>This automatically calls {@link #updateDefinedLocation(CatalogItem)}
- *       <li>A LocationDefinition is creating, using as its id the {@link CatalogItem#getSymbolicName()}.
- *           The definition's spec is {@code brooklyn.catalog:<symbolicName>:<version>},
- *     </ol>
- *   <li>A blueprint can reference the catalog item using its symbolic name, 
- *       such as the YAML {@code location: my-new-location}.
- *       (this feels similar to the "named locations").
- *     <ol>
- *       <li>This automatically calls {@link #resolve(String)}.
- *       <li>The LocationDefinition is found by lookig up this name.
- *       <li>The {@link LocationDefiniton.getSpec()} is retrieved; the right {@link LocationResolver} is 
- *           found for it.
- *       <li>This uses the {@link CatalogLocationResolver}, because the spec starts with {@code brooklyn.catalog:}.
- *       <li>This resolver extracts from the spec the <symobolicName>:<version>, and looks up the 
- *           catalog item using {@link BrooklynCatalog#getCatalogItem(String, String)}.
- *       <li>It then creates a {@link LocationSpec} by calling {@link BrooklynCatalog#createSpec(CatalogItem)}.
- *         <ol>
- *           <li>This first tries to use the type (that is in the YAML) as a simple Java class.
- *           <li>If that fails, it will resolve the type using {@link #resolve(String, Boolean, Map)}, which
- *               returns an actual location object.
- *           <li>It extracts from that location object the appropriate metadata to create a {@link LocationSpec},
- *               returns the spec and discards the location object.
- *         </ol>
- *       <li>The resolver creates the {@link Location} from the {@link LocationSpec}
- *     </ol>
- * </ol>
- * 
- * There is no concept of a location version in this registry. The version
- * in the catalog is generally ignored.
- */
-@SuppressWarnings({"rawtypes","unchecked"})
-public class BasicLocationRegistry implements LocationRegistry {
-
-    // TODO save / serialize
-    // (we persist live locations, ie those in the LocationManager, but not "catalog" locations, ie those in this Registry)
-    
-    public static final Logger log = LoggerFactory.getLogger(BasicLocationRegistry.class);
-
-    /**
-     * Splits a comma-separated list of locations (names or specs) into an explicit list.
-     * The splitting is very careful to handle commas embedded within specs, to split correctly.
-     */
-    public static List<String> expandCommaSeparateLocations(String locations) {
-        return WildcardGlobs.getGlobsAfterBraceExpansion("{"+locations+"}", false, PhraseTreatment.INTERIOR_NOT_EXPANDABLE, PhraseTreatment.INTERIOR_NOT_EXPANDABLE);
-        // don't do this, it tries to expand commas inside parentheses which is not good!
-//        QuotedStringTokenizer.builder().addDelimiterChars(",").buildList((String)id);
-    }
-
-    private final ManagementContext mgmt;
-    /** map of defined locations by their ID */
-    private final Map<String,LocationDefinition> definedLocations = new LinkedHashMap<String, LocationDefinition>();
-
-    protected final Map<String,LocationResolver> resolvers = new LinkedHashMap<String, LocationResolver>();
-
-    private final Set<String> specsWarnedOnException = Sets.newConcurrentHashSet();
-
-    public BasicLocationRegistry(ManagementContext mgmt) {
-        this.mgmt = checkNotNull(mgmt, "mgmt");
-        findServices();
-        updateDefinedLocations();
-    }
-
-    protected void findServices() {
-        ServiceLoader<LocationResolver> loader = ServiceLoader.load(LocationResolver.class, mgmt.getCatalogClassLoader());
-        for (LocationResolver r: loader) {
-            registerResolver(r);
-        }
-        if (log.isDebugEnabled()) log.debug("Location resolvers are: "+resolvers);
-        if (resolvers.isEmpty()) log.warn("No location resolvers detected: is src/main/resources correctly included?");
-    }
-
-    /** Registers the given resolver, invoking {@link LocationResolver#init(ManagementContext)} on the argument
-     * and returning true, unless the argument indicates false for {@link EnableableLocationResolver#isEnabled()} */
-    public boolean registerResolver(LocationResolver r) {
-        r.init(mgmt);
-        if (r instanceof EnableableLocationResolver) {
-            if (!((EnableableLocationResolver)r).isEnabled()) {
-                return false;
-            }
-        }
-        resolvers.put(r.getPrefix(), r);
-        return true;
-    }
-    
-    @Override
-    public Map<String,LocationDefinition> getDefinedLocations() {
-        synchronized (definedLocations) {
-            return ImmutableMap.<String,LocationDefinition>copyOf(definedLocations);
-        }
-    }
-    
-    @Override
-    public LocationDefinition getDefinedLocationById(String id) {
-        return definedLocations.get(id);
-    }
-
-    @Override
-    public LocationDefinition getDefinedLocationByName(String name) {
-        synchronized (definedLocations) {
-            for (LocationDefinition l: definedLocations.values()) {
-                if (l.getName().equals(name)) return l;
-            }
-            return null;
-        }
-    }
-
-    @Override
-    public void updateDefinedLocation(LocationDefinition l) {
-        synchronized (definedLocations) { 
-            definedLocations.put(l.getId(), l); 
-        }
-    }
-
-    /**
-     * Converts the given item from the catalog into a LocationDefinition, and adds it
-     * to the registry (overwriting anything already registered with the id
-     * {@link CatalogItem#getCatalogItemId()}.
-     */
-    public void updateDefinedLocation(CatalogItem<Location, LocationSpec<?>> item) {
-        String id = item.getCatalogItemId();
-        String symbolicName = item.getSymbolicName();
-        String spec = CatalogLocationResolver.NAME + ":" + id;
-        Map<String, Object> config = ImmutableMap.<String, Object>of();
-        BasicLocationDefinition locDefinition = new BasicLocationDefinition(symbolicName, symbolicName, spec, config);
-        
-        updateDefinedLocation(locDefinition);
-    }
-
-    public void removeDefinedLocation(CatalogItem<Location, LocationSpec<?>> item) {
-        removeDefinedLocation(item.getSymbolicName());
-    }
-    
-    @Override
-    public void removeDefinedLocation(String id) {
-        LocationDefinition removed;
-        synchronized (definedLocations) { 
-            removed = definedLocations.remove(id);
-        }
-        if (removed == null && log.isDebugEnabled()) {
-            log.debug("{} was asked to remove location with id {} but no such location was registered", this, id);
-        }
-    }
-    
-    public void updateDefinedLocations() {
-        synchronized (definedLocations) {
-            // first read all properties starting  brooklyn.location.named.xxx
-            // (would be nice to move to a better way, e.g. yaml, then deprecate this approach, but first
-            // we need ability/format for persisting named locations, and better support for adding+saving via REST/GUI)
-            int count = 0; 
-            String NAMED_LOCATION_PREFIX = "brooklyn.location.named.";
-            ConfigMap namedLocationProps = mgmt.getConfig().submap(ConfigPredicates.startingWith(NAMED_LOCATION_PREFIX));
-            for (String k: namedLocationProps.asMapWithStringKeys().keySet()) {
-                String name = k.substring(NAMED_LOCATION_PREFIX.length());
-                // If has a dot, then is a sub-property of a named location (e.g. brooklyn.location.named.prod1.user=bob)
-                if (!name.contains(".")) {
-                    // this is a new named location
-                    String spec = (String) namedLocationProps.asMapWithStringKeys().get(k);
-                    // make up an ID
-                    String id = Identifiers.makeRandomId(8);
-                    Map<String, Object> config = ConfigUtils.filterForPrefixAndStrip(namedLocationProps.asMapWithStringKeys(), k+".");
-                    definedLocations.put(id, new BasicLocationDefinition(id, name, spec, config));
-                    count++;
-                }
-            }
-            if (log.isDebugEnabled())
-                log.debug("Found "+count+" defined locations from properties (*.named.* syntax): "+definedLocations.values());
-            if (getDefinedLocationByName("localhost")==null && !BasicOsDetails.Factory.newLocalhostInstance().isWindows()
-                    && LocationConfigUtils.isEnabled(mgmt, "brooklyn.location.localhost")) {
-                log.debug("Adding a defined location for localhost");
-                // add 'localhost' *first*
-                ImmutableMap<String, LocationDefinition> oldDefined = ImmutableMap.copyOf(definedLocations);
-                definedLocations.clear();
-                String id = Identifiers.makeRandomId(8);
-                definedLocations.put(id, localhost(id));
-                definedLocations.putAll(oldDefined);
-            }
-            
-            for (CatalogItem<Location, LocationSpec<?>> item : mgmt.getCatalog().getCatalogItems(CatalogPredicates.IS_LOCATION)) {
-                updateDefinedLocation(item);
-                count++;
-            }
-        }
-    }
-    
-    @VisibleForTesting
-    void disablePersistence() {
-        // persistence isn't enabled yet anyway (have to manually save things,
-        // defining the format and file etc)
-    }
-
-    protected static BasicLocationDefinition localhost(String id) {
-        return new BasicLocationDefinition(id, "localhost", "localhost", null);
-    }
-    
-    /** to catch circular references */
-    protected ThreadLocal<Set<String>> specsSeen = new ThreadLocal<Set<String>>();
-    
-    @Override @Deprecated
-    public boolean canMaybeResolve(String spec) {
-        return getSpecResolver(spec) != null;
-    }
-
-    @Override
-    public final Location resolve(String spec) {
-        return resolve(spec, true, null).get();
-    }
-    
-    @Override @Deprecated
-    public final Location resolveIfPossible(String spec) {
-        if (!canMaybeResolve(spec)) return null;
-        return resolve(spec, null, null).orNull();
-    }
-    
-    @Deprecated /** since 0.7.0 not used */
-    public final Maybe<Location> resolve(String spec, boolean manage) {
-        return resolve(spec, manage, null);
-    }
-    
-    public Maybe<Location> resolve(String spec, Boolean manage, Map locationFlags) {
-        try {
-            locationFlags = MutableMap.copyOf(locationFlags);
-            if (manage!=null) {
-                locationFlags.put(LocalLocationManager.CREATE_UNMANAGED, !manage);
-            }
-            
-            Set<String> seenSoFar = specsSeen.get();
-            if (seenSoFar==null) {
-                seenSoFar = new LinkedHashSet<String>();
-                specsSeen.set(seenSoFar);
-            }
-            if (seenSoFar.contains(spec))
-                return Maybe.absent(Suppliers.ofInstance(new IllegalStateException("Circular reference in definition of location '"+spec+"' ("+seenSoFar+")")));
-            seenSoFar.add(spec);
-            
-            LocationResolver resolver = getSpecResolver(spec);
-
-            if (resolver != null) {
-                try {
-                    return Maybe.of(resolver.newLocationFromString(locationFlags, spec, this));
-                } catch (RuntimeException e) {
-                    return Maybe.absent(Suppliers.ofInstance(e));
-                }
-            }
-
-            // problem: but let's ensure that classpath is sane to give better errors in common IDE bogus case;
-            // and avoid repeated logging
-            String errmsg;
-            if (spec == null || specsWarnedOnException.add(spec)) {
-                if (resolvers.get("id")==null || resolvers.get("named")==null) {
-                    log.error("Standard location resolvers not installed, location resolution will fail shortly. "
-                            + "This usually indicates a classpath problem, such as when running from an IDE which "
-                            + "has not properly copied META-INF/services from src/main/resources. "
-                            + "Known resolvers are: "+resolvers.keySet());
-                    errmsg = "Unresolvable location '"+spec+"': "
-                            + "Problem detected with location resolver configuration; "
-                            + resolvers.keySet()+" are the only available location resolvers. "
-                            + "More information can be found in the logs.";
-                } else {
-                    log.debug("Location resolution failed for '"+spec+"' (if this is being loaded it will fail shortly): known resolvers are: "+resolvers.keySet());
-                    errmsg = "Unknown location '"+spec+"': "
-                            + "either this location is not recognised or there is a problem with location resolver configuration.";
-                }
-            } else {
-                // For helpful log message construction: assumes classpath will not suddenly become wrong; might happen with OSGi though!
-                if (log.isDebugEnabled()) log.debug("Location resolution failed again for '"+spec+"' (throwing)");
-                errmsg = "Unknown location '"+spec+"': "
-                        + "either this location is not recognised or there is a problem with location resolver configuration.";
-            }
-
-            return Maybe.absent(Suppliers.ofInstance(new NoSuchElementException(errmsg)));
-
-        } finally {
-            specsSeen.remove();
-        }
-    }
-
-    @Override
-    public final Location resolve(String spec, Map locationFlags) {
-        return resolve(spec, null, locationFlags).get();
-    }
-
-    protected LocationResolver getSpecResolver(String spec) {
-        int colonIndex = spec.indexOf(':');
-        int bracketIndex = spec.indexOf("(");
-        int dividerIndex = (colonIndex < 0) ? bracketIndex : (bracketIndex < 0 ? colonIndex : Math.min(bracketIndex, colonIndex));
-        String prefix = dividerIndex >= 0 ? spec.substring(0, dividerIndex) : spec;
-        LocationResolver resolver = resolvers.get(prefix);
-       
-        if (resolver == null)
-            resolver = getSpecDefaultResolver(spec);
-        
-        return resolver;
-    }
-    
-    protected LocationResolver getSpecDefaultResolver(String spec) {
-        return getSpecFirstResolver(spec, "id", "named", "jclouds");
-    }
-    protected LocationResolver getSpecFirstResolver(String spec, String ...resolversToCheck) {
-        for (String resolverId: resolversToCheck) {
-            LocationResolver resolver = resolvers.get(resolverId);
-            if (resolver!=null && resolver.accepts(spec, this))
-                return resolver;
-        }
-        return null;
-    }
-
-    /** providers default impl for RegistryLocationResolver.accepts */
-    public static boolean isResolverPrefixForSpec(LocationResolver resolver, String spec, boolean argumentRequired) {
-        if (spec==null) return false;
-        if (spec.startsWith(resolver.getPrefix()+":")) return true;
-        if (!argumentRequired && spec.equals(resolver.getPrefix())) return true;
-        return false;
-    }
-
-    @Override
-    public List<Location> resolve(Iterable<?> spec) {
-        List<Location> result = new ArrayList<Location>();
-        for (Object id : spec) {
-            if (id instanceof String) {
-                result.add(resolve((String) id));
-            } else if (id instanceof Location) {
-                result.add((Location) id);
-            } else {
-                if (id instanceof Iterable)
-                    throw new IllegalArgumentException("Cannot resolve '"+id+"' to a location; collections of collections not allowed"); 
-                throw new IllegalArgumentException("Cannot resolve '"+id+"' to a location; unsupported type "+
-                        (id == null ? "null" : id.getClass().getName())); 
-            }
-        }
-        return result;
-    }
-    
-    public List<Location> resolveList(Object l) {
-        if (l==null) l = Collections.emptyList();
-        if (l instanceof String) l = JavaStringEscapes.unwrapJsonishListIfPossible((String)l);
-        if (l instanceof Iterable) return resolve((Iterable<?>)l);
-        throw new IllegalArgumentException("Location list must be supplied as a collection or a string, not "+
-            JavaClassNames.simpleClassName(l)+"/"+l);
-    }
-    
-    @Override
-    public Location resolve(LocationDefinition ld) {
-        return resolve(ld, null, null).get();
-    }
-
-    @Override @Deprecated
-    public Location resolveForPeeking(LocationDefinition ld) {
-        // TODO should clean up how locations are stored, figuring out whether they are shared or not;
-        // or maybe better, the API calls to this might just want to get the LocationSpec objects back
-        
-        // for now we use a 'CREATE_UNMANGED' flag to prevent management (leaks and logging)
-        return resolve(ld, ConfigBag.newInstance().configure(LocalLocationManager.CREATE_UNMANAGED, true).getAllConfig());
-    }
-
-    @Override @Deprecated
-    public Location resolve(LocationDefinition ld, Map<?,?> flags) {
-        return resolveLocationDefinition(ld, flags, null);
-    }
-    
-    /** @deprecated since 0.7.0 not used (and optionalName was ignored anyway) */
-    @Deprecated
-    public Location resolveLocationDefinition(LocationDefinition ld, Map locationFlags, String optionalName) {
-        return resolve(ld, null, locationFlags).get();
-    }
-    
-    public Maybe<Location> resolve(LocationDefinition ld, Boolean manage, Map locationFlags) {
-        ConfigBag newLocationFlags = ConfigBag.newInstance(ld.getConfig())
-            .putAll(locationFlags)
-            .putIfAbsentAndNotNull(LocationInternal.NAMED_SPEC_NAME, ld.getName())
-            .putIfAbsentAndNotNull(LocationInternal.ORIGINAL_SPEC, ld.getName());
-        Maybe<Location> result = resolve(ld.getSpec(), manage, newLocationFlags.getAllConfigRaw());
-        if (result.isPresent()) 
-            return result;
-        throw new IllegalStateException("Cannot instantiate location '"+ld+"' pointing at "+ld.getSpec()+": "+
-            Exceptions.collapseText( ((Absent<?>)result).getException() ));
-    }
-
-    @Override
-    public Map getProperties() {
-        return mgmt.getConfig().asMapWithStringKeys();
-    }
-
-    @VisibleForTesting
-    public static void setupLocationRegistryForTesting(ManagementContext mgmt) {
-        // ensure localhost is added (even on windows)
-        LocationDefinition l = mgmt.getLocationRegistry().getDefinedLocationByName("localhost");
-        if (l==null) mgmt.getLocationRegistry().updateDefinedLocation(
-                BasicLocationRegistry.localhost(Identifiers.makeRandomId(8)) );
-        
-        ((BasicLocationRegistry)mgmt.getLocationRegistry()).disablePersistence();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java b/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java
deleted file mode 100644
index 543db37..0000000
--- a/core/src/main/java/brooklyn/location/basic/BasicMachineDetails.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.Immutable;
-
-import org.apache.brooklyn.api.management.Task;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.HardwareDetails;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.OsDetails;
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.stream.Streams;
-import brooklyn.util.task.DynamicTasks;
-import brooklyn.util.task.TaskTags;
-import brooklyn.util.task.ssh.internal.PlainSshExecTaskFactory;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.base.Throwables;
-import com.google.common.collect.Maps;
-import com.google.common.io.CharStreams;
-
-@Immutable
-public class BasicMachineDetails implements MachineDetails {
-
-    public static final Logger LOG = LoggerFactory.getLogger(BasicMachineDetails.class);
-
-    private final HardwareDetails hardwareDetails;
-    private final OsDetails osDetails;
-
-    public BasicMachineDetails(HardwareDetails hardwareDetails, OsDetails osDetails) {
-        this.hardwareDetails = checkNotNull(hardwareDetails, "hardwareDetails");
-        this.osDetails = checkNotNull(osDetails, "osDetails");
-    }
-
-    @Nonnull
-    @Override
-    public HardwareDetails getHardwareDetails() {
-        return hardwareDetails;
-    }
-
-    @Nonnull
-    @Override
-    public OsDetails getOsDetails() {
-        return osDetails;
-    }
-
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(MachineDetails.class)
-                .add("os", osDetails)
-                .add("hardware", hardwareDetails)
-                .toString();
-    }
-
-    /**
-     * Creates a MachineDetails for the given location by SSHing to the machine and
-     * running a Bash script to gather data. Should only be called from within a
-     * task context. If this might not be the case then use {@link
-     * #taskForSshMachineLocation(SshMachineLocation)} instead.
-     */
-    static BasicMachineDetails forSshMachineLocation(SshMachineLocation location) {
-        return TaskTags.markInessential(DynamicTasks.queueIfPossible(taskForSshMachineLocation(location))
-                .orSubmitAsync()
-                .asTask())
-                .getUnchecked();
-    }
-
-    /**
-     * @return A task that gathers machine details by SSHing to the machine and running
-     *         a Bash script to gather data.
-     */
-    static Task<BasicMachineDetails> taskForSshMachineLocation(SshMachineLocation location) {
-        BufferedReader reader = new BufferedReader(Streams.reader(
-                new ResourceUtils(BasicMachineDetails.class).getResourceFromUrl(
-                        "classpath://brooklyn/location/basic/os-details.sh")));
-        List<String> script;
-        try {
-            script = CharStreams.readLines(reader);
-        } catch (IOException e) {
-            LOG.error("Error reading os-details script", e);
-            throw Throwables.propagate(e);
-        } finally {
-            try {
-                reader.close();
-            } catch (IOException e) {
-                // Not rethrowing e because it might obscure an exception caught by the first catch
-                LOG.error("Error closing os-details script reader", e);
-            }
-        }
-        Task<BasicMachineDetails> task = new PlainSshExecTaskFactory<String>(location, script)
-                .summary("Getting machine details for: " + location)
-                .requiringZeroAndReturningStdout()
-                .returning(taskToMachineDetailsFunction(location))
-                .newTask()
-                .asTask();
-
-        return task;
-    }
-
-    private static Function<ProcessTaskWrapper<?>, BasicMachineDetails> taskToMachineDetailsFunction(final SshMachineLocation location) {
-        return new Function<ProcessTaskWrapper<?>, BasicMachineDetails>() {
-            @Override
-            public BasicMachineDetails apply(ProcessTaskWrapper<?> input) {
-                if (input.getExitCode() != 0) {
-                    LOG.warn("Non-zero exit code when fetching machine details for {}; guessing anonymous linux", location);
-                    return new BasicMachineDetails(new BasicHardwareDetails(null, null),
-                            BasicOsDetails.Factory.ANONYMOUS_LINUX);
-                }
-
-                String stdout = input.getStdout();
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Found following details at {}: {}", location, stdout);
-                }
-
-                Map<String,String> details = Maps.newHashMap(Splitter.on(CharMatcher.anyOf("\r\n"))
-                        .omitEmptyStrings()
-                        .withKeyValueSeparator(":")
-                        .split(stdout));
-
-                String name = details.remove("name");
-                String version = details.remove("version");
-                String architecture = details.remove("architecture");
-                Integer ram = intOrNull(details, "ram");
-                Integer cpuCount = intOrNull(details, "cpus");
-                if (!details.isEmpty()) {
-                    LOG.debug("Unused keys from os-details script: " + Joiner.on(", ").join(details.keySet()));
-                }
-
-                OsDetails osDetails = new BasicOsDetails(name, architecture, version);
-                HardwareDetails hardwareDetails = new BasicHardwareDetails(cpuCount, ram);
-                BasicMachineDetails machineDetails = new BasicMachineDetails(hardwareDetails, osDetails);
-
-                if (LOG.isDebugEnabled())
-                    LOG.debug("Machine details for {}: {}", location, machineDetails);
-
-                return machineDetails;
-            }
-
-            private Integer intOrNull(Map<String, String> details, String key) {
-                try {
-                    return Integer.valueOf(details.remove(key));
-                } catch (NumberFormatException e) {
-                    return null;
-                }
-            }
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/BasicMachineMetadata.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicMachineMetadata.java b/core/src/main/java/brooklyn/location/basic/BasicMachineMetadata.java
deleted file mode 100644
index 6808312..0000000
--- a/core/src/main/java/brooklyn/location/basic/BasicMachineMetadata.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import brooklyn.location.MachineManagementMixins.MachineMetadata;
-
-import com.google.common.base.Objects;
-
-public class BasicMachineMetadata implements MachineMetadata {
-
-    final String id, name, primaryIp;
-    final Boolean isRunning;
-    final Object originalMetadata;
-    
-    public BasicMachineMetadata(String id, String name, String primaryIp, Boolean isRunning, Object originalMetadata) {
-        super();
-        this.id = id;
-        this.name = name;
-        this.primaryIp = primaryIp;
-        this.isRunning = isRunning;
-        this.originalMetadata = originalMetadata;
-    }
-
-    public String getId() {
-        return id;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getPrimaryIp() {
-        return primaryIp;
-    }
-
-    public Boolean isRunning() {
-        return isRunning;
-    }
-
-    public Object getOriginalMetadata() {
-        return originalMetadata;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(id, isRunning, name, originalMetadata, primaryIp);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        BasicMachineMetadata other = (BasicMachineMetadata) obj;
-        if (!Objects.equal(id, other.id)) return false;
-        if (!Objects.equal(name, other.name)) return false;
-        if (!Objects.equal(primaryIp, other.primaryIp)) return false;
-        if (!Objects.equal(isRunning, other.isRunning)) return false;
-        if (!Objects.equal(originalMetadata, other.originalMetadata)) return false;
-        return true;
-    }
-
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(this).add("id", id).add("name", name).add("originalMetadata", originalMetadata).toString();
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/BasicOsDetails.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicOsDetails.java b/core/src/main/java/brooklyn/location/basic/BasicOsDetails.java
deleted file mode 100644
index a9eba56..0000000
--- a/core/src/main/java/brooklyn/location/basic/BasicOsDetails.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.regex.Pattern;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-import com.google.common.base.Objects;
-
-import brooklyn.location.OsDetails;
-
-@Immutable
-public class BasicOsDetails implements OsDetails {
-
-    final String name, arch, version;
-    final boolean is64bit;
-    // (?i) forces matches to be case insensitive
-    public static final String UNIX_OS_NAME_PATTERNS = "(?i).*linux.*|centos|debian|fedora|gentoo|rhel|slackware|solaris|suse|ubuntu|coreos";
-
-    /** Sets is64Bit according to value of arch parameter. */
-    public BasicOsDetails(String name, String arch, String version) {
-       this(name, arch, version, arch != null && arch.contains("64"));
-    }
-
-    public BasicOsDetails(String name, String arch, String version, boolean is64Bit) {
-        this.name = name; this.arch = arch; this.version = version; this.is64bit = is64Bit;
-    }
-    
-    // TODO: Should be replaced with an enum like Jclouds' OsFamily and isX methods should
-    // switch against known cases
-    @Nullable
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Nullable
-    @Override
-    public String getArch() {
-        return arch;
-    }
-
-    @Nullable
-    @Override
-    public String getVersion() {
-        return version;
-    }
-
-    @Override
-    public boolean isWindows() {
-        //TODO confirm
-        return getName()!=null && getName().toLowerCase().contains("microsoft");
-    }
-
-    @Override
-    public boolean isLinux() {
-        return getName() != null && Pattern.matches(UNIX_OS_NAME_PATTERNS, getName());
-    }
-
-    @Override
-    public boolean isMac() {
-        return getName()!=null && getName().equals(OsNames.MAC_OS_X);
-    }
-
-    @Override
-    public boolean is64bit() {
-        return is64bit;
-    }
-
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(OsDetails.class)
-                .omitNullValues()
-                .add("name", name)
-                .add("version", version)
-                .add("arch", arch)
-                .toString();
-    }
-
-    public static class OsNames {
-        public static final String MAC_OS_X = "Mac OS X";
-    }
-    
-    public static class OsArchs {
-        public static final String X_86_64 = "x86_64";
-//        public static final String X_86 = "x86";
-//        // is this standard?  or do we ever need the above?
-        public static final String I386 = "i386";
-    }
-
-    public static class OsVersions {
-        public static final String MAC_10_8 = "10.8";
-        public static final String MAC_10_9 = "10.9";
-    }
-    
-    public static class Factory {
-        public static OsDetails newLocalhostInstance() {
-            return new BasicOsDetails(System.getProperty("os.name"), System.getProperty("os.arch"), System.getProperty("os.version"));
-        }
-        
-        public static final OsDetails ANONYMOUS_LINUX = new BasicOsDetails("linux", OsArchs.I386, "unknown");
-        public static final OsDetails ANONYMOUS_LINUX_64 = new BasicOsDetails("linux", OsArchs.X_86_64, "unknown");
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java b/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java
deleted file mode 100644
index 7838e24..0000000
--- a/core/src/main/java/brooklyn/location/basic/ByonLocationResolver.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.net.InetAddress;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.net.HostAndPort;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Sanitizer;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.management.internal.LocalLocationManager;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.net.UserAndHostAndPort;
-import brooklyn.util.text.WildcardGlobs;
-import brooklyn.util.text.WildcardGlobs.PhraseTreatment;
-
-/**
- * Examples of valid specs:
- *   <ul>
- *     <li>byon:(hosts=myhost)
- *     <li>byon:(hosts=myhost,myhost2)
- *     <li>byon:(hosts="myhost, myhost2")
- *     <li>byon:(hosts=myhost,myhost2, name=abc)
- *     <li>byon:(hosts="myhost, myhost2", name="my location name")
- *   </ul>
- * 
- * @author aled
- */
-@SuppressWarnings({"rawtypes"})
-public class ByonLocationResolver extends AbstractLocationResolver {
-
-    public static final Logger log = LoggerFactory.getLogger(ByonLocationResolver.class);
-    
-    public static final String BYON = "byon";
-
-    public static final ConfigKey<String> OS_FAMILY = ConfigKeys.newStringConfigKey("osfamily", "OS Family of the machine, either windows or linux", "linux");
-
-    public static final Map<String, Class<? extends MachineLocation>> OS_TO_MACHINE_LOCATION_TYPE = ImmutableMap.<String, Class<? extends MachineLocation>>of(
-            "windows", WinRmMachineLocation.class,
-            "linux", SshMachineLocation.class);
-
-    @Override
-    public String getPrefix() {
-        return BYON;
-    }
-
-    @Override
-    protected Class<? extends Location> getLocationType() {
-        return FixedListMachineProvisioningLocation.class;
-    }
-
-    @Override
-    protected SpecParser getSpecParser() {
-        return new AbstractLocationResolver.SpecParser(getPrefix()).setExampleUsage("\"byon(hosts='addr1,addr2')\"");
-    }
-
-    @Override
-    protected ConfigBag extractConfig(Map<?,?> locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        ConfigBag config = super.extractConfig(locationFlags, spec, registry);
-
-        Object hosts = config.getStringKey("hosts");
-        config.remove("hosts");
-        String user = (String) config.getStringKey("user");
-        Integer port = (Integer) TypeCoercions.coerce(config.getStringKey("port"), Integer.class);
-        Class<? extends MachineLocation> locationClass = OS_TO_MACHINE_LOCATION_TYPE.get(config.get(OS_FAMILY));
-
-        MutableMap<String, Object> defaultProps = MutableMap.of();
-        defaultProps.addIfNotNull("user", user);
-        defaultProps.addIfNotNull("port", port);
-
-        List<String> hostAddresses;
-        
-        if (hosts instanceof String) {
-            if (((String) hosts).isEmpty()) {
-                hostAddresses = ImmutableList.of();
-            } else {
-                hostAddresses = WildcardGlobs.getGlobsAfterBraceExpansion("{"+hosts+"}",
-                        true /* numeric */, /* no quote support though */ PhraseTreatment.NOT_A_SPECIAL_CHAR, PhraseTreatment.NOT_A_SPECIAL_CHAR);
-            }
-        } else if (hosts instanceof Iterable) {
-            hostAddresses = ImmutableList.copyOf((Iterable<String>)hosts);
-        } else {
-            throw new IllegalArgumentException("Invalid location '"+spec+"'; at least one host must be defined");
-        }
-        if (hostAddresses.isEmpty()) {
-            throw new IllegalArgumentException("Invalid location '"+spec+"'; at least one host must be defined");
-        }
-        
-        List<MachineLocation> machines = Lists.newArrayList();
-        for (Object host : hostAddresses) {
-            LocationSpec<? extends MachineLocation> machineSpec;
-            if (host instanceof String) {
-                machineSpec = parseMachine((String)host, locationClass, defaultProps, spec);
-            } else if (host instanceof Map) {
-                machineSpec = parseMachine((Map<String, ?>)host, locationClass, defaultProps, spec);
-            } else {
-                throw new IllegalArgumentException("Expected machine to be String or Map, but was "+host.getClass().getName()+" ("+host+")");
-            }
-            machineSpec.configureIfNotNull(LocalLocationManager.CREATE_UNMANAGED, config.get(LocalLocationManager.CREATE_UNMANAGED));
-            MachineLocation machine = managementContext.getLocationManager().createLocation(machineSpec);
-            machines.add(machine);
-        }
-        
-        config.putStringKey("machines", machines);
-
-        return config;
-    }
-    
-    protected LocationSpec<? extends MachineLocation> parseMachine(Map<String, ?> vals, Class<? extends MachineLocation> locationClass, Map<String, ?> defaults, String specForErrMsg) {
-        Map<String, Object> valSanitized = Sanitizer.sanitize(vals);
-        Map<String, Object> machineConfig = MutableMap.copyOf(vals);
-        
-        String osfamily = (String) machineConfig.remove(OS_FAMILY.getName());
-        String ssh = (String) machineConfig.remove("ssh");
-        String winrm = (String) machineConfig.remove("winrm");
-        Map<Integer, String> tcpPortMappings = (Map<Integer, String>) machineConfig.get("tcpPortMappings");
-        
-        checkArgument(ssh != null ^ winrm != null, "Must specify exactly one of 'ssh' or 'winrm' for machine: %s", valSanitized);
-        
-        UserAndHostAndPort userAndHostAndPort;
-        String host;
-        int port;
-        if (ssh != null) {
-            userAndHostAndPort = parseUserAndHostAndPort((String)ssh, 22);
-        } else {
-            userAndHostAndPort = parseUserAndHostAndPort((String)winrm, 5985);
-        }
-        
-        // If there is a tcpPortMapping defined for the connection-port, then use that for ssh/winrm machine
-        port = userAndHostAndPort.getHostAndPort().getPort();
-        if (tcpPortMappings != null && tcpPortMappings.containsKey(port)) {
-            String override = tcpPortMappings.get(port);
-            HostAndPort hostAndPortOverride = HostAndPort.fromString(override);
-            if (!hostAndPortOverride.hasPort()) {
-                throw new IllegalArgumentException("Invalid portMapping ('"+override+"') for port "+port+" in "+specForErrMsg);
-            }
-            port = hostAndPortOverride.getPort();
-            host = hostAndPortOverride.getHostText().trim();
-        } else {
-            host = userAndHostAndPort.getHostAndPort().getHostText().trim();
-        }
-        
-        machineConfig.put("address", host);
-        try {
-            InetAddress.getByName(host);
-        } catch (Exception e) {
-            throw new IllegalArgumentException("Invalid host '"+host+"' specified in '"+specForErrMsg+"': "+e);
-        }
-
-        if (userAndHostAndPort.getUser() != null) {
-            checkArgument(!vals.containsKey("user"), "Must not specify user twice for machine: %s", valSanitized);
-            machineConfig.put("user", userAndHostAndPort.getUser());
-        }
-        if (userAndHostAndPort.getHostAndPort().hasPort()) {
-            checkArgument(!vals.containsKey("port"), "Must not specify port twice for machine: %s", valSanitized);
-            machineConfig.put("port", port);
-        }
-        for (Map.Entry<String, ?> entry : defaults.entrySet()) {
-            if (!machineConfig.containsKey(entry.getKey())) {
-                machineConfig.put(entry.getKey(), entry.getValue());
-            }
-        }
-        
-        Class<? extends MachineLocation> locationClassHere = locationClass;
-        if (osfamily != null) {
-            locationClassHere = OS_TO_MACHINE_LOCATION_TYPE.get(osfamily);
-        }
-
-        return LocationSpec.create(locationClassHere).configure(machineConfig);
-    }
-
-    protected LocationSpec<? extends MachineLocation> parseMachine(String val, Class<? extends MachineLocation> locationClass, Map<String, ?> defaults, String specForErrMsg) {
-        Map<String, Object> machineConfig = Maps.newLinkedHashMap();
-        
-        UserAndHostAndPort userAndHostAndPort = parseUserAndHostAndPort(val);
-        
-        String host = userAndHostAndPort.getHostAndPort().getHostText().trim();
-        machineConfig.put("address", host);
-        try {
-            InetAddress.getByName(host.trim());
-        } catch (Exception e) {
-            throw new IllegalArgumentException("Invalid host '"+host+"' specified in '"+specForErrMsg+"': "+e);
-        }
-        
-        if (userAndHostAndPort.getUser() != null) {
-            machineConfig.put("user", userAndHostAndPort.getUser());
-        }
-        if (userAndHostAndPort.getHostAndPort().hasPort()) {
-            machineConfig.put("port", userAndHostAndPort.getHostAndPort().getPort());
-        }
-        for (Map.Entry<String, ?> entry : defaults.entrySet()) {
-            if (!machineConfig.containsKey(entry.getKey())) {
-                machineConfig.put(entry.getKey(), entry.getValue());
-            }
-        }
-
-        return LocationSpec.create(locationClass).configure(machineConfig);
-    }
-    
-    private UserAndHostAndPort parseUserAndHostAndPort(String val) {
-        String userPart = null;
-        String hostPart = val;
-        if (val.contains("@")) {
-            userPart = val.substring(0, val.indexOf("@"));
-            hostPart = val.substring(val.indexOf("@")+1);
-        }
-        return UserAndHostAndPort.fromParts(userPart, HostAndPort.fromString(hostPart));
-    }
-    
-    private UserAndHostAndPort parseUserAndHostAndPort(String val, int defaultPort) {
-        UserAndHostAndPort result = parseUserAndHostAndPort(val);
-        if (!result.getHostAndPort().hasPort()) {
-            result = UserAndHostAndPort.fromParts(result.getUser(), result.getHostAndPort().getHostText(), defaultPort);
-        }
-        return result;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/CatalogLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/CatalogLocationResolver.java b/core/src/main/java/brooklyn/location/basic/CatalogLocationResolver.java
deleted file mode 100644
index a036c85..0000000
--- a/core/src/main/java/brooklyn/location/basic/CatalogLocationResolver.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.management.ManagementContext;
-
-import brooklyn.catalog.internal.CatalogUtils;
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-import brooklyn.location.LocationSpec;
-
-/**
- * Given a location spec in the form {@code brooklyn.catalog:<symbolicName>:<version>}, 
- * looks up the catalog to get its definition and creates such a location.
- */
-public class CatalogLocationResolver implements LocationResolver {
-
-    @SuppressWarnings("unused")
-    private static final Logger log = LoggerFactory.getLogger(CatalogLocationResolver.class);
-
-    public static final String NAME = "brooklyn.catalog";
-
-    private ManagementContext managementContext;
-
-    @Override
-    public void init(ManagementContext managementContext) {
-        this.managementContext = checkNotNull(managementContext, "managementContext");
-    }
-    
-    @Override
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    public Location newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        String id = spec.substring(NAME.length()+1);
-        CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(managementContext, id);
-        LocationSpec<?> origLocSpec = managementContext.getCatalog().createSpec((CatalogItem<Location, LocationSpec<?>>)item);
-        LocationSpec<?> locSpec = LocationSpec.create(origLocSpec)
-                .configure(locationFlags);
-        return managementContext.getLocationManager().createLocation(locSpec);
-    }
-
-    @Override
-    public String getPrefix() {
-        return NAME;
-    }
-    
-    /**
-     * accepts anything that looks like it will be a YAML catalog item (e.g. starting "brooklyn.locations")
-     */
-    @Override
-    public boolean accepts(String spec, LocationRegistry registry) {
-        if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true;
-        if (registry.getDefinedLocationByName(spec)!=null) return true;
-        return false;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/DefinedLocationByIdResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/DefinedLocationByIdResolver.java b/core/src/main/java/brooklyn/location/basic/DefinedLocationByIdResolver.java
deleted file mode 100644
index 62aaf66..0000000
--- a/core/src/main/java/brooklyn/location/basic/DefinedLocationByIdResolver.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver;
-
-/**
- * looks up based on ID in DefinedLocations map
- */
-public class DefinedLocationByIdResolver implements LocationResolver {
-
-    public static final Logger log = LoggerFactory.getLogger(DefinedLocationByIdResolver.class);
-
-    public static final String ID = "id";
-    
-    private volatile ManagementContext managementContext;
-
-    @Override
-    public void init(ManagementContext managementContext) {
-        this.managementContext = checkNotNull(managementContext, "managementContext");
-    }
-    
-    @SuppressWarnings({ "rawtypes" })
-    @Override
-    public Location newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) {
-        String id = spec;
-        if (spec.toLowerCase().startsWith(ID+":")) {
-            id = spec.substring( (ID+":").length() );
-        }
-        LocationDefinition ld = registry.getDefinedLocationById(id);
-        ld.getSpec();
-        return ((BasicLocationRegistry)registry).resolveLocationDefinition(ld, locationFlags, null);
-    }
-
-    @Override
-    public String getPrefix() {
-        return ID;
-    }
-    
-    /** accepts anything starting  id:xxx  or just   xxx where xxx is a defined location ID */
-    @Override
-    public boolean accepts(String spec, LocationRegistry registry) {
-        if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true;
-        if (registry.getDefinedLocationById(spec)!=null) return true;
-        return false;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/basic/DeprecatedKeysMappingBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/DeprecatedKeysMappingBuilder.java b/core/src/main/java/brooklyn/location/basic/DeprecatedKeysMappingBuilder.java
deleted file mode 100644
index a426b6e..0000000
--- a/core/src/main/java/brooklyn/location/basic/DeprecatedKeysMappingBuilder.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-
-import brooklyn.config.ConfigKey;
-
-import com.google.common.base.CaseFormat;
-import com.google.common.collect.ImmutableMap;
-
-/**
-* @deprecated since 0.6; for use only in converting deprecated flags; will be deleted in future version.
-*/
-public class DeprecatedKeysMappingBuilder {
-    private final ImmutableMap.Builder<String,String> builder = new ImmutableMap.Builder<String,String>();
-    private final Logger logger;
-    
-    public DeprecatedKeysMappingBuilder(Logger logger) {
-        this.logger = logger;
-    }
-
-    public DeprecatedKeysMappingBuilder camelToHyphen(ConfigKey<?> key) {
-        return camelToHyphen(key.getName());
-    }
-    
-    public DeprecatedKeysMappingBuilder camelToHyphen(String key) {
-        String hyphen = toHyphen(key);
-        if (key.equals(hyphen)) {
-            logger.warn("Invalid attempt to convert camel-case key {} to deprecated hyphen-case: both the same", hyphen);
-        } else {
-            builder.put(hyphen, key);
-        }
-        return this;
-    }
-    
-    public DeprecatedKeysMappingBuilder putAll(Map<String,String> vals) {
-        builder.putAll(vals);
-        return this;
-    }
-
-    public Map<String,String> build() {
-        return builder.build();
-    }
-    
-    private String toHyphen(String word) {
-        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, word);
-    }
-}


[18/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsWinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsWinRmMachineLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsWinRmMachineLocation.java
deleted file mode 100644
index d555cd9..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsWinRmMachineLocation.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.basic.WinRmMachineLocation;
-import brooklyn.util.flags.SetFromFlag;
-import brooklyn.util.net.Networking;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.net.HostAndPort;
-
-public class JcloudsWinRmMachineLocation extends WinRmMachineLocation implements JcloudsMachineLocation {
-
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsWinRmMachineLocation.class);
-
-    @SetFromFlag
-    JcloudsLocation jcloudsParent;
-    
-    @SetFromFlag
-    NodeMetadata node;
-    
-    @SetFromFlag
-    Template template;
-
-    public JcloudsWinRmMachineLocation() {
-    }
-
-    @Override
-    public String toVerboseString() {
-        return Objects.toStringHelper(this).omitNullValues()
-                .add("id", getId()).add("name", getDisplayName())
-                .add("user", getUser())
-                .add("address", getAddress())
-                .add("port", getPort())
-                .add("node", getNode())
-                .add("jcloudsId", getJcloudsId())
-                .add("privateAddresses", node.getPrivateAddresses())
-                .add("publicAddresses", node.getPublicAddresses())
-                .add("parentLocation", getParent())
-                .add("osDetails", getOsDetails())
-                .toString();
-    }
-
-    @Override
-    public int getPort() {
-        return getConfig(WINRM_PORT);
-    }
-    
-    @Override
-    public NodeMetadata getNode() {
-        return node;
-    }
-    
-    @Override
-    public Template getTemplate() {
-        return template;
-    }
-    
-    @Override
-    public JcloudsLocation getParent() {
-        return jcloudsParent;
-    }
-    
-    @Override
-    public String getHostname() {
-        InetAddress address = getAddress();
-        return (address != null) ? address.getHostAddress() : null;
-    }
-    
-    @Override
-    public Set<String> getPublicAddresses() {
-        return node.getPublicAddresses();
-    }
-    
-    @Override
-    public Set<String> getPrivateAddresses() {
-        return node.getPrivateAddresses();
-    }
-
-    @Override
-    public String getSubnetHostname() {
-        // TODO: TEMP FIX: WAS:
-        // String publicHostname = jcloudsParent.getPublicHostname(node, Optional.<HostAndPort>absent(), config().getBag());
-        // but this causes a call to JcloudsUtil.getFirstReachableAddress, which searches for accessible SSH service.
-        // This workaround is good for public nodes but not private-subnet ones.
-        return getHostname();
-    }
-
-    @Override
-    public String getSubnetIp() {
-        Optional<String> privateAddress = getPrivateAddress();
-        if (privateAddress.isPresent()) {
-            return privateAddress.get();
-        }
-
-        String hostname = jcloudsParent.getPublicHostname(node, Optional.<HostAndPort>absent(), config().getBag());
-        if (hostname != null && !Networking.isValidIp4(hostname)) {
-            try {
-                return InetAddress.getByName(hostname).getHostAddress();
-            } catch (UnknownHostException e) {
-                LOG.debug("Cannot resolve IP for hostname {} of machine {} (so returning hostname): {}", new Object[] {hostname, this, e});
-            }
-        }
-        return hostname;
-    }
-
-    protected Optional<String> getPrivateAddress() {
-        if (groovyTruth(node.getPrivateAddresses())) {
-            Iterator<String> pi = node.getPrivateAddresses().iterator();
-            while (pi.hasNext()) {
-                String p = pi.next();
-                // disallow local only addresses
-                if (Networking.isLocalOnly(p)) continue;
-                // other things may be public or private, but either way, return it
-                return Optional.of(p);
-            }
-        }
-        return Optional.absent();
-    }
-    
-    @Override
-    public String getJcloudsId() {
-        return node.getId();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/SudoTtyFixingCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/SudoTtyFixingCustomizer.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/SudoTtyFixingCustomizer.java
deleted file mode 100644
index 889c7e3..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/SudoTtyFixingCustomizer.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import org.jclouds.compute.ComputeService;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.task.DynamicTasks;
-import brooklyn.util.task.ssh.SshTasks;
-import brooklyn.util.task.ssh.SshTasks.OnFailingTask;
-
-/**
- * Wraps Brooklyn's sudo-tty mitigations in a {@link JcloudsLocationCustomizer} for easy(-ish) consumption
- * in YAML blueprints:
- *
- * <pre>
- *   name: My App
- *   brooklyn.config:
- *     provisioning.properties:
- *       customizerType: brooklyn.location.jclouds.SudoTtyFixingCustomizer
- *   services: ...
- * </pre>
- *
- * <p>This class should be seen as a temporary workaround and might disappear completely if/when Brooklyn takes care of this automatically.
- *
- * <p>See
- * <a href='http://unix.stackexchange.com/questions/122616/why-do-i-need-a-tty-to-run-sudo-if-i-can-sudo-without-a-password'>http://unix.stackexchange.com/questions/122616/why-do-i-need-a-tty-to-run-sudo-if-i-can-sudo-without-a-password</a>
- * for background.
- */
-@Beta
-public class SudoTtyFixingCustomizer extends BasicJcloudsLocationCustomizer {
-
-    @Override
-    public void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine) {
-        Preconditions.checkArgument(machine instanceof SshMachineLocation, "machine must be SshMachineLocation, but is %s", machine.getClass());
-        DynamicTasks.queueIfPossible(SshTasks.dontRequireTtyForSudo((SshMachineLocation)machine, OnFailingTask.FAIL)).orSubmitAndBlock();
-        DynamicTasks.waitForLast();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
deleted file mode 100644
index 3944912..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsLocationSecurityGroupCustomizer.java
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.networking;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Iterator;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.jclouds.aws.AWSResponseException;
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.domain.SecurityGroup;
-import org.jclouds.compute.domain.Template;
-import org.jclouds.compute.extensions.SecurityGroupExtension;
-import org.jclouds.domain.Location;
-import org.jclouds.net.domain.IpPermission;
-import org.jclouds.net.domain.IpProtocol;
-import org.jclouds.providers.ProviderMetadata;
-import org.jclouds.providers.Providers;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.geo.LocalhostExternalIpLoader;
-import brooklyn.location.jclouds.BasicJcloudsLocationCustomizer;
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsMachineLocation;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.net.Cidr;
-import brooklyn.util.task.Tasks;
-import brooklyn.util.time.Duration;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.base.Throwables;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-/**
- * Configures custom security groups on Jclouds locations.
- *
- * @see SecurityGroupExtension is an optional extension to jclouds compute service. It allows the manipulation of
- * {@link SecurityGroup}s.
- *
- * This customizer can be injected into {@link JcloudsLocation#obtainOnce} using
- * It will be executed after the provisiioning of the {@link JcloudsMachineLocation} to apply app-specific
- * customization related to the security groups.
- *
- * @since 0.7.0
- */
-@Beta
-public class JcloudsLocationSecurityGroupCustomizer extends BasicJcloudsLocationCustomizer {
-
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsLocationSecurityGroupCustomizer.class);
-
-    // Caches instances of JcloudsLocationSecurityGroupCustomizer by application IDs.
-    private static final LoadingCache<String, JcloudsLocationSecurityGroupCustomizer> CUSTOMISERS = CacheBuilder.newBuilder()
-            .build(new CacheLoader<String, JcloudsLocationSecurityGroupCustomizer>() {
-                @Override
-                public JcloudsLocationSecurityGroupCustomizer load(final String appContext) throws Exception {
-                    return new JcloudsLocationSecurityGroupCustomizer(appContext);
-                }
-            });
-
-    /** Caches the base security group that should be shared between all instances in the same Jclouds location */
-    private final Cache<Location, SecurityGroup> sharedGroupCache = CacheBuilder.newBuilder().build();
-
-    /** Caches security groups unique to instances */
-    private final Cache<String, SecurityGroup> uniqueGroupCache = CacheBuilder.newBuilder().build();
-
-    /** The context for this location customizer. */
-    private final String applicationId;
-
-    /** The CIDR for addresses that may SSH to machines. */
-    private Supplier<Cidr> sshCidrSupplier;
-
-    /**
-     * A predicate indicating whether the customiser can retry a request to add a security group
-     * or a rule after an throwable is thrown.
-     */
-    private Predicate<Exception> isExceptionRetryable = Predicates.alwaysFalse();
-
-    protected JcloudsLocationSecurityGroupCustomizer(String applicationId) {
-        // Would be better to restrict with something like LocalhostExternalIpCidrSupplier, but
-        // we risk making machines inaccessible from Brooklyn when HA fails over.
-        this(applicationId, Suppliers.ofInstance(new Cidr("0.0.0.0/0")));
-    }
-
-    protected JcloudsLocationSecurityGroupCustomizer(String applicationId, Supplier<Cidr> sshCidrSupplier) {
-        this.applicationId = applicationId;
-        this.sshCidrSupplier = sshCidrSupplier;
-    }
-
-    /**
-     * Gets the customizer for the given applicationId. Multiple calls to this method with the
-     * same application context will return the same JcloudsLocationSecurityGroupCustomizer instance.
-     * @param applicationId An identifier for the application the customizer is to be used for
-     * @return the unique customizer for the given context
-     */
-    public static JcloudsLocationSecurityGroupCustomizer getInstance(String applicationId) {
-        return CUSTOMISERS.getUnchecked(applicationId);
-    }
-
-    /**
-     * Gets a customizer for the given entity's application. Multiple calls to this method with entities
-     * in the same application will return the same JcloudsLocationSecurityGroupCustomizer instance.
-     * @param entity The entity the customizer is to be used for
-     * @return the unique customizer for the entity's owning application
-     */
-    public static JcloudsLocationSecurityGroupCustomizer getInstance(Entity entity) {
-        return getInstance(entity.getApplicationId());
-    }
-
-    /**
-     * @param predicate
-     *          A predicate whose return value indicates whether a request to add a security group
-     *          or permission may be retried after its input {@link Exception} was thrown.
-     * @return this
-     */
-    public JcloudsLocationSecurityGroupCustomizer setRetryExceptionPredicate(Predicate<Exception> predicate) {
-        this.isExceptionRetryable = checkNotNull(predicate, "predicate");
-        return this;
-    }
-
-    /**
-     * @param cidrSupplier A supplier returning a CIDR for hosts that are allowed to SSH to locations.
-     */
-    public JcloudsLocationSecurityGroupCustomizer setSshCidrSupplier(Supplier<Cidr> cidrSupplier) {
-        this.sshCidrSupplier = checkNotNull(cidrSupplier, "cidrSupplier");
-        return this;
-    }
-
-    /** @see #addPermissionsToLocation(brooklyn.location.jclouds.JcloudsSshMachineLocation, java.lang.Iterable) */
-    public JcloudsLocationSecurityGroupCustomizer addPermissionsToLocation(final JcloudsMachineLocation location, IpPermission... permissions) {
-        addPermissionsToLocation(location, ImmutableList.copyOf(permissions));
-        return this;
-    }
-
-    /** @see #addPermissionsToLocation(brooklyn.location.jclouds.JcloudsSshMachineLocation, java.lang.Iterable) */
-    public JcloudsLocationSecurityGroupCustomizer addPermissionsToLocation(final JcloudsMachineLocation location, SecurityGroupDefinition securityGroupDefinition) {
-        addPermissionsToLocation(location, securityGroupDefinition.getPermissions());
-        return this;
-    }
-
-    /**
-     * Applies the given security group permissions to the given location.
-     * <p>
-     * Takes no action if the location's compute service does not have a security group extension.
-     * @param permissions The set of permissions to be applied to the location
-     * @param location Location to gain permissions
-     */
-    public JcloudsLocationSecurityGroupCustomizer addPermissionsToLocation(final JcloudsMachineLocation location, final Iterable<IpPermission> permissions) {
-        ComputeService computeService = location.getParent().getComputeService();
-        String nodeId = location.getNode().getId();
-        addPermissionsToLocation(permissions, nodeId, computeService);
-        return this;
-    }
-
-    /**
-     * Applies the given security group permissions to the given node with the given compute service.
-     * <p>
-     * Takes no action if the compute service does not have a security group extension.
-     * @param permissions The set of permissions to be applied to the node
-     * @param nodeId The id of the node to update
-     * @param computeService The compute service to use to apply the changes
-     */
-    @VisibleForTesting
-    void addPermissionsToLocation(Iterable<IpPermission> permissions, final String nodeId, ComputeService computeService) {
-        if (!computeService.getSecurityGroupExtension().isPresent()) {
-            LOG.warn("Security group extension for {} absent; cannot update node {} with {}",
-                    new Object[] {computeService, nodeId, permissions});
-            return;
-        }
-        final SecurityGroupExtension securityApi = computeService.getSecurityGroupExtension().get();
-        final String locationId = computeService.getContext().unwrap().getId();
-
-        // Expect to have two security groups on the node: one shared between all nodes in the location,
-        // that is cached in sharedGroupCache, and one created by Jclouds that is unique to the node.
-        // Relies on customize having been called before. This should be safe because the arguments
-        // needed to call this method are not available until post-instance creation.
-        SecurityGroup machineUniqueSecurityGroup;
-        Tasks.setBlockingDetails("Loading unique security group for node: " + nodeId);
-        try {
-            machineUniqueSecurityGroup = uniqueGroupCache.get(nodeId, new Callable<SecurityGroup>() {
-                @Override public SecurityGroup call() throws Exception {
-                    SecurityGroup sg = getUniqueSecurityGroupForNodeCachingSharedGroupIfPreviouslyUnknown(nodeId, locationId, securityApi);
-                    if (sg == null) {
-                        throw new IllegalStateException("Failed to find machine-unique group on node: " + nodeId);
-                    }
-                    return sg;
-                }
-            });
-        } catch (ExecutionException e) {
-            throw Throwables.propagate(new Exception(e.getCause()));
-        } finally {
-            Tasks.resetBlockingDetails();
-        }
-        for (IpPermission permission : permissions) {
-            addPermission(permission, machineUniqueSecurityGroup, securityApi);
-        }
-    }
-
-    /**
-     * Loads the security groups attached to the node with the given ID and returns the group
-     * that is unique to the node, per the application context. This method will also update
-     * {@link #sharedGroupCache} if no mapping for the shared group's location previously
-     * existed (e.g. Brooklyn was restarted and rebound to an existing application).
-     *
-     * Notice that jclouds will attach 2 securityGroups to the node if the locationId is `aws-ec2` so it needs to
-     * look for the uniqueSecurityGroup rather than the shared securityGroup.
-     *
-     * @param nodeId The id of the node in question
-     * @param locationId The id of the location in question
-     * @param securityApi The API to use to list security groups
-     * @return the security group unique to the given node, or null if one could not be determined.
-     */
-    private SecurityGroup getUniqueSecurityGroupForNodeCachingSharedGroupIfPreviouslyUnknown(String nodeId, String locationId, SecurityGroupExtension securityApi) {
-        Set<SecurityGroup> groupsOnNode = securityApi.listSecurityGroupsForNode(nodeId);
-        SecurityGroup unique;
-        if (locationId.equals("aws-ec2")) {
-            if (groupsOnNode.size() != 2) {
-                LOG.warn("Expected to find two security groups on node {} in app {} (one shared, one unique). Found {}: {}",
-                        new Object[]{nodeId, applicationId, groupsOnNode.size(), groupsOnNode});
-                return null;
-            }
-            String expectedSharedName = getNameForSharedSecurityGroup();
-            Iterator<SecurityGroup> it = groupsOnNode.iterator();
-            SecurityGroup shared = it.next();
-            if (shared.getName().endsWith(expectedSharedName)) {
-                unique = it.next();
-            } else {
-                unique = shared;
-                shared = it.next();
-            }
-            if (!shared.getName().endsWith(expectedSharedName)) {
-                LOG.warn("Couldn't determine which security group is shared between instances in app {}. Expected={}, found={}",
-                        new Object[]{applicationId, expectedSharedName, groupsOnNode});
-                return null;
-            }
-            // Shared entry might be missing if Brooklyn has rebound to an application
-            SecurityGroup old = sharedGroupCache.asMap().putIfAbsent(shared.getLocation(), shared);
-            LOG.info("Loaded unique security group for node {} (in {}): {}",
-                    new Object[]{nodeId, applicationId, unique});
-            if (old == null) {
-                LOG.info("Proactively set shared group for app {} to: {}", applicationId, shared);
-            }
-            return unique;
-        }
-        return Iterables.getOnlyElement(groupsOnNode);
-    }
-
-    /**
-     * Replaces security groups configured on the given template with one that allows
-     * SSH access on port 22 and allows communication on all ports between machines in
-     * the same group. Security groups are reused when templates have equal
-     * {@link org.jclouds.compute.domain.Template#getLocation locations}.
-     * <p>
-     * This method is called by Brooklyn when obtaining machines, as part of the
-     * {@link brooklyn.location.jclouds.JcloudsLocationCustomizer} contract. It
-     * should not be called from anywhere else.
-     *
-     * @param location The Brooklyn location that has called this method while obtaining a machine
-     * @param computeService The compute service being used by the location argument to provision a machine
-     * @param template The machine template created by the location argument
-     */
-    @Override
-    public void customize(JcloudsLocation location, ComputeService computeService, Template template) {
-        if (!computeService.getSecurityGroupExtension().isPresent()) {
-            LOG.warn("Security group extension for {} absent; cannot configure security groups in context: {}", computeService, applicationId);
-        } else if (template.getLocation() == null) {
-            LOG.warn("No location has been set on {}; cannot configure security groups in context: {}", template, applicationId);
-        } else {
-            LOG.info("Configuring security groups on location {} in context {}", location, applicationId);
-            setSecurityGroupOnTemplate(location, template, computeService.getSecurityGroupExtension().get());
-        }
-    }
-
-    private void setSecurityGroupOnTemplate(final JcloudsLocation location, final Template template, final SecurityGroupExtension securityApi) {
-        SecurityGroup shared;
-        Tasks.setBlockingDetails("Loading security group shared by instances in " + template.getLocation() +
-                " in app " + applicationId);
-        try {
-            shared = sharedGroupCache.get(template.getLocation(), new Callable<SecurityGroup>() {
-                @Override public SecurityGroup call() throws Exception {
-                    return getOrCreateSharedSecurityGroup(template.getLocation(), securityApi);
-                }
-            });
-        } catch (ExecutionException e) {
-            throw Throwables.propagate(new Exception(e.getCause()));
-        } finally {
-            Tasks.resetBlockingDetails();
-        }
-
-        Set<String> originalGroups = template.getOptions().getGroups();
-        template.getOptions().securityGroups(shared.getName());
-        if (!originalGroups.isEmpty()) {
-            LOG.info("Replaced configured security groups: configured={}, replaced with={}", originalGroups, template.getOptions().getGroups());
-        } else {
-            LOG.debug("Configured security groups at {} to: {}", location, template.getOptions().getGroups());
-        }
-    }
-
-    /**
-     * Loads the security group to be shared between nodes in the same application in the
-     * given Location. If no such security group exists it is created.
-     *
-     * @param location The location in which the security group will be found
-     * @param securityApi The API to use to list and create security groups
-     * @return the security group to share between instances in the given location in this application
-     */
-    private SecurityGroup getOrCreateSharedSecurityGroup(Location location, SecurityGroupExtension securityApi) {
-        final String groupName = getNameForSharedSecurityGroup();
-        // Could sort-and-search if straight search is too expensive
-        Optional<SecurityGroup> shared = Iterables.tryFind(securityApi.listSecurityGroupsInLocation(location), new Predicate<SecurityGroup>() {
-            @Override
-            public boolean apply(final SecurityGroup input) {
-                // endsWith because Jclouds prepends 'jclouds#' to security group names.
-                return input.getName().endsWith(groupName);
-            }
-        });
-        if (shared.isPresent()) {
-            LOG.info("Found existing shared security group in {} for app {}: {}",
-                    new Object[]{location, applicationId, groupName});
-            return shared.get();
-        } else {
-            LOG.info("Creating new shared security group in {} for app {}: {}",
-                    new Object[]{location, applicationId, groupName});
-            return createBaseSecurityGroupInLocation(groupName, location, securityApi);
-        }
-    }
-
-    /**
-     * Creates a security group with rules to:
-     * <ul>
-     *     <li>Allow SSH access on port 22 from the world</li>
-     *     <li>Allow TCP, UDP and ICMP communication between machines in the same group</li>
-     * </ul>
-     *
-     * It needs to consider locationId as port ranges and groupId are cloud provider-dependent e.g openstack nova
-     * wants from 1-65535 while aws-ec2 accepts from 0-65535.
-     *
-     *
-     * @param groupName The name of the security group to create
-     * @param location The location in which the security group will be created
-     * @param securityApi The API to use to create the security group
-     *
-     * @return the created security group
-     */
-    private SecurityGroup createBaseSecurityGroupInLocation(String groupName, Location location, SecurityGroupExtension securityApi) {
-        SecurityGroup group = addSecurityGroupInLocation(groupName, location, securityApi);
-
-        Set<String> openstackNovaIds = getJcloudsLocationIds("openstack-nova");
-
-        String groupId = group.getProviderId();
-        int fromPort = 0;
-        if (location.getParent() != null && Iterables.contains(openstackNovaIds, location.getParent().getId())) {
-            groupId = group.getId();
-            fromPort = 1;
-        }
-        // Note: For groupName to work with GCE we also need to tag the machines with the same ID.
-        // See sourceTags section at https://developers.google.com/compute/docs/networking#firewalls
-        IpPermission.Builder allWithinGroup = IpPermission.builder()
-                .groupId(groupId)
-                .fromPort(fromPort)
-                .toPort(65535);
-        addPermission(allWithinGroup.ipProtocol(IpProtocol.TCP).build(), group, securityApi);
-        addPermission(allWithinGroup.ipProtocol(IpProtocol.UDP).build(), group, securityApi);
-        addPermission(allWithinGroup.ipProtocol(IpProtocol.ICMP).fromPort(-1).toPort(-1).build(), group, securityApi);
-
-        IpPermission sshPermission = IpPermission.builder()
-                .fromPort(22)
-                .toPort(22)
-                .ipProtocol(IpProtocol.TCP)
-                .cidrBlock(getBrooklynCidrBlock())
-                .build();
-        addPermission(sshPermission, group, securityApi);
-
-        return group;
-    }
-
-    private Set<String> getJcloudsLocationIds(final String jcloudsApiId) {
-        Set<String> openstackNovaProviders = FluentIterable.from(Providers.all())
-                .filter(new Predicate<ProviderMetadata>() {
-            @Override
-            public boolean apply(ProviderMetadata providerMetadata) {
-                return providerMetadata.getApiMetadata().getId().equals(jcloudsApiId);
-            }
-        }).transform(new Function<ProviderMetadata, String>() {
-            @Nullable
-            @Override
-            public String apply(ProviderMetadata input) {
-                return input.getId();
-            }
-        }).toSet();
-
-        return new ImmutableSet.Builder<String>()
-                .addAll(openstackNovaProviders)
-                .add(jcloudsApiId)
-                .build();
-    }
-
-    protected SecurityGroup addSecurityGroupInLocation(final String groupName, final Location location, final SecurityGroupExtension securityApi) {
-        LOG.debug("Creating security group {} in {}", groupName, location);
-        Callable<SecurityGroup> callable = new Callable<SecurityGroup>() {
-            @Override
-            public SecurityGroup call() throws Exception {
-                return securityApi.createSecurityGroup(groupName, location);
-            }
-        };
-        return runOperationWithRetry(callable);
-    }
-
-    protected SecurityGroup addPermission(final IpPermission permission, final SecurityGroup group, final SecurityGroupExtension securityApi) {
-        LOG.debug("Adding permission to security group {}: {}", group.getName(), permission);
-        Callable<SecurityGroup> callable = new Callable<SecurityGroup>() {
-            @Override
-            public SecurityGroup call() throws Exception {
-                return securityApi.addIpPermission(permission, group);
-            }
-        };
-        return runOperationWithRetry(callable);
-    }
-
-    /** @return the CIDR block used to configure Brooklyn's in security groups */
-    public String getBrooklynCidrBlock() {
-        return sshCidrSupplier.get().toString();
-    }
-
-    /**
-     * @return The name to be used by security groups that will be shared between machines
-     *         in the same location for this instance's application context.
-     */
-    @VisibleForTesting
-    String getNameForSharedSecurityGroup() {
-        return "brooklyn-" + applicationId.toLowerCase() + "-shared";
-    }
-
-    /**
-     * Invalidates all entries in {@link #sharedGroupCache} and {@link #uniqueGroupCache}.
-     * Use to simulate the effects of rebinding Brooklyn to a deployment.
-     */
-    @VisibleForTesting
-    void clearSecurityGroupCaches() {
-        LOG.info("Clearing security group caches");
-        sharedGroupCache.invalidateAll();
-        uniqueGroupCache.invalidateAll();
-    }
-
-    /**
-     * Runs the given callable. Repeats until the operation succeeds or {@link #isExceptionRetryable} indicates
-     * that the request cannot be retried.
-     */
-    protected <T> T runOperationWithRetry(Callable<T> operation) {
-        int backoff = 64;
-        Exception lastException = null;
-        for (int retries = 0; retries < 100; retries++) {
-            try {
-                return operation.call();
-            } catch (Exception e) {
-                lastException = e;
-                if (isExceptionRetryable.apply(e)) {
-                    LOG.debug("Attempt #{} failed to add security group: {}", retries + 1, e.getMessage());
-                    try {
-                        Thread.sleep(backoff);
-                    } catch (InterruptedException e1) {
-                        throw Exceptions.propagate(e1);
-                    }
-                    backoff = backoff << 1;
-                } else {
-                    break;
-                }
-            }
-        }
-
-        throw new RuntimeException("Unable to add security group rule; repeated errors from provider", lastException);
-    }
-
-    /**
-     * @return
-     *      A predicate that is true if an exception contains an {@link org.jclouds.aws.AWSResponseException}
-     *      whose error code is either <code>InvalidGroup.InUse</code>, <code>DependencyViolation</code> or
-     *      <code>RequestLimitExceeded</code>.
-     */
-    public static Predicate<Exception> newAwsExceptionRetryPredicate() {
-        return new AwsExceptionRetryPredicate();
-    }
-
-    private static class AwsExceptionRetryPredicate implements Predicate<Exception> {
-        // Error reference: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html
-        private static final Set<String> AWS_ERRORS_TO_RETRY = ImmutableSet.of(
-                "InvalidGroup.InUse", "DependencyViolation", "RequestLimitExceeded");
-
-        @Override
-        public boolean apply(Exception input) {
-            @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
-            AWSResponseException exception = Exceptions.getFirstThrowableOfType(input, AWSResponseException.class);
-            if (exception != null) {
-                String code = exception.getError().getCode();
-                return AWS_ERRORS_TO_RETRY.contains(code);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * A supplier of CIDRs that loads the external IP address of the localhost machine.
-     */
-    private static class LocalhostExternalIpCidrSupplier implements Supplier<Cidr> {
-
-        private volatile Cidr cidr;
-
-        @Override
-        public Cidr get() {
-            Cidr local = cidr;
-            if (local == null) {
-                synchronized (this) {
-                    local = cidr;
-                    if (local == null) {
-                        String externalIp = LocalhostExternalIpLoader.getLocalhostIpWithin(Duration.seconds(5));
-                        cidr = local = new Cidr(externalIp + "/32");
-                    }
-                }
-            }
-            return local;
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsPortForwarderExtension.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsPortForwarderExtension.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsPortForwarderExtension.java
deleted file mode 100644
index adfdde3..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/JcloudsPortForwarderExtension.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.networking;
-
-import org.jclouds.compute.domain.NodeMetadata;
-
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.access.PortForwardManager;
-import brooklyn.util.net.Cidr;
-import brooklyn.util.net.Protocol;
-
-import com.google.common.base.Optional;
-import com.google.common.net.HostAndPort;
-
-public interface JcloudsPortForwarderExtension {
-
-    /**
-     * Opens port forwarding (e.g. DNAT or iptables port-forwarding) to reach the given given 
-     * target port on this node (from the given cidr).
-     * 
-     * This should also register the port with the {@link PortForwardManager}, via 
-     * {@code portForwardManager.associate(node.getId(), result, targetPort)} so that
-     * subsequent calls to {@link BrooklynAccessUtils#getBrooklynAccessibleAddress(brooklyn.entity.Entity, int)}
-     * will know about the mapped port.
-     */
-    public HostAndPort openPortForwarding(NodeMetadata node, int targetPort, Optional<Integer> optionalPublicPort, Protocol protocol, Cidr accessingCidr);
-
-    public void closePortForwarding(NodeMetadata node, int targetPort, HostAndPort publicHostAndPort, Protocol protocol);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/SecurityGroupDefinition.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/SecurityGroupDefinition.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/SecurityGroupDefinition.java
deleted file mode 100644
index 7ced79f..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/SecurityGroupDefinition.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.networking;
-
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import org.jclouds.aws.ec2.AWSEC2Api;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.net.domain.IpPermission;
-import org.jclouds.net.domain.IpProtocol;
-import org.jclouds.net.util.IpPermissions;
-
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.net.Cidr;
-import brooklyn.util.text.Identifiers;
-
-import com.google.common.annotations.Beta;
-
-/** WIP to define a security group in an up-front way, where subsequently it can be applied to a jclouds location */
-@Beta
-public class SecurityGroupDefinition {
-
-    private Callable<String> groupNameFactory = new Callable<String>() { public String call() { return "br-sg-"+Identifiers.makeRandomId(8); } };
-    private List<IpPermission> ipPerms = MutableList.of();
-    
-    public void createGroupInAwsRegion(ComputeServiceContext computeServiceContext, String region) {
-        AWSEC2Api ec2Client = computeServiceContext.unwrapApi(AWSEC2Api.class);
-        String sgId = ec2Client.getSecurityGroupApi().get().createSecurityGroupInRegionAndReturnId(region, getName(), "Brooklyn-managed security group "+getName());
-        ec2Client.getSecurityGroupApi().get().authorizeSecurityGroupIngressInRegion(region, sgId, ipPerms);
-    }
-
-    /** allows access to the given port on TCP from within the subnet */
-    public SecurityGroupDefinition allowingInternalPort(int port) {
-        return allowing(IpPermissions.permit(IpProtocol.TCP).port(port));
-    }
-    public SecurityGroupDefinition allowingInternalPorts(int port1, int port2, int ...ports) {
-        allowing(IpPermissions.permit(IpProtocol.TCP).port(port1));
-        allowing(IpPermissions.permit(IpProtocol.TCP).port(port2));
-        for (int port: ports)
-            allowing(IpPermissions.permit(IpProtocol.TCP).port(port));
-        return this;
-    }
-    public SecurityGroupDefinition allowingInternalPortRange(int portRangeStart, int portRangeEnd) {
-        return allowing(IpPermissions.permit(IpProtocol.TCP).fromPort(portRangeStart).to(portRangeEnd));
-    }
-    public SecurityGroupDefinition allowingInternalPing() {
-        return allowing(IpPermissions.permit(IpProtocol.ICMP));
-    }
-    
-    public SecurityGroupDefinition allowingPublicPort(int port) {
-        return allowing(IpPermissions.permit(IpProtocol.TCP).port(port).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
-    }
-    public SecurityGroupDefinition allowingPublicPorts(int port1, int port2, int ...ports) {
-        allowing(IpPermissions.permit(IpProtocol.TCP).port(port1).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
-        allowing(IpPermissions.permit(IpProtocol.TCP).port(port2).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
-        for (int port: ports)
-            allowing(IpPermissions.permit(IpProtocol.TCP).port(port).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
-        return this;
-    }
-    public SecurityGroupDefinition allowingPublicPortRange(int portRangeStart, int portRangeEnd) {
-        return allowing(IpPermissions.permit(IpProtocol.TCP).fromPort(portRangeStart).to(portRangeEnd).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
-    }
-    public SecurityGroupDefinition allowingPublicPing() {
-        return allowing(IpPermissions.permit(IpProtocol.ICMP).originatingFromCidrBlock(Cidr.UNIVERSAL.toString()));
-    }
-    
-    public SecurityGroupDefinition allowing(IpPermission permission) {
-        ipPerms.add(permission);
-        return this;
-    }
-    
-    // TODO use cloud machine namer
-    public SecurityGroupDefinition named(final String name) {
-        groupNameFactory = new Callable<String>() { public String call() { return name; } };
-        return this;
-    }
-    public String getName() { 
-        try { return groupNameFactory.call(); } 
-        catch (Exception e) { throw Exceptions.propagate(e); } 
-    }
-
-    public Iterable<IpPermission> getPermissions() {
-        return ipPerms;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/SecurityGroupTool.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/SecurityGroupTool.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/SecurityGroupTool.java
deleted file mode 100644
index 31b06a0..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/networking/SecurityGroupTool.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.networking;
-
-import java.util.Set;
-
-import org.jclouds.aws.ec2.AWSEC2Api;
-import org.jclouds.aws.util.AWSUtils;
-import org.jclouds.compute.domain.SecurityGroup;
-import org.jclouds.compute.extensions.SecurityGroupExtension;
-import org.jclouds.net.domain.IpPermission;
-import org.jclouds.rest.ApiContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.jclouds.JcloudsLocation;
-import brooklyn.location.jclouds.JcloudsLocationConfig;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.text.Strings;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
-/** WIP to apply a security group to a jclouds endpoint.
- * <p>
- * sections of this code have been used but overall it is not yet in a working state,
- * but merged May 2014 to make it easier to pick up if and when needed.
- * (if not needed after several months this may simply be removed.) */
-@Beta
-public class SecurityGroupTool {
-
-    private static final Logger log = LoggerFactory.getLogger(SecurityGroupTool.class);
-    
-    protected final JcloudsLocation location;
-    protected final SecurityGroupDefinition sgDef;
-
-    public SecurityGroupTool(JcloudsLocation location, SecurityGroupDefinition sgDef) {
-        this.location = Preconditions.checkNotNull(location);
-        this.sgDef = Preconditions.checkNotNull(sgDef);
-    }
-    
-    public String getName() {
-        return sgDef.getName();
-    }
-    
-    public void apply() {
-        Optional<SecurityGroupExtension> sgExtO = location.getComputeService().getSecurityGroupExtension();
-        if (!sgExtO.isPresent()) {
-            throw new IllegalStateException("Advanced networking not supported in this location ("+location+")");
-        }
-        SecurityGroupExtension sgExt = sgExtO.get();
-        
-        SecurityGroup sg = findSecurityGroupWithName(sgExt, getName());
-        if (sg==null) {
-            // TODO initialize the location
-            org.jclouds.domain.Location sgLoc = null;
-
-            // TODO record that we created it
-            // create it
-            try {
-                // FIXME this will always fail for providers which need a location, until we set it above
-                // https://github.com/brooklyncentral/brooklyn/pull/1343#discussion_r12275188
-                sg = sgExt.createSecurityGroup(getName(), sgLoc);
-            } catch (Exception e) {
-                Exceptions.propagateIfFatal(e);
-                // check if someone else already created it
-                sg = findSecurityGroupWithName(sgExt, getName());
-                if (sg==null) {
-                    // no - so propagate error
-                    throw Exceptions.propagate(e);
-                } else {
-                    log.debug("Looks like parallel thread created security group "+getName()+"; ignoring error in our thread ("+e+") as we now have an SG");
-                }
-            }
-        }
-        
-        if (sg==null)
-            throw new IllegalStateException("Unable to find or create security group ID for "+getName());
-
-        addPermissions(sgExt, sg);
-    }
-    
-    protected SecurityGroup findSecurityGroupWithName(SecurityGroupExtension sgExt, String name) {
-        Set<SecurityGroup> groups = sgExt.listSecurityGroups();
-        // jclouds appends this sometimes so for portability let's add this
-        String nameAlt = name.startsWith("jclouds#") ? Strings.removeFromStart(name, "jclouds#") : "jclouds#"+name;
-        for (SecurityGroup g: groups) {
-            if (name.equals(g.getName())) return g;
-            if (nameAlt.equals(g.getName())) return g;
-        }
-        return null;
-    }
-
-    protected void addPermissions(SecurityGroupExtension sgExt, SecurityGroup sg) {
-
-        Object api = ((ApiContext<?>)location.getComputeService().getContext().unwrap()).getApi();
-        if (api instanceof AWSEC2Api) {
-            // optimization for AWS where rules can be added all at once, and it cuts down Req Limit Exceeded problems!
-            String region = AWSUtils.getRegionFromLocationOrNull(sg.getLocation());
-            String id = sg.getProviderId();
-            
-            ((AWSEC2Api)api).getSecurityGroupApi().get().authorizeSecurityGroupIngressInRegion(region, id, sgDef.getPermissions());
-            
-        } else {
-            for (IpPermission p: sgDef.getPermissions()) {
-                sgExt.addIpPermission(p, sg);
-            }
-        }
-    }
-    
-    
-    // TODO remove this method once we've confirmed the above works nicely (this is an early attempt)
-    protected void applyOldEc2(AWSEC2Api client) {
-        String region = location.getConfig(JcloudsLocationConfig.CLOUD_REGION_ID);
-        if (region==null) {
-            // TODO where does the default come from?
-            log.warn("No region set for "+location+"; assuming EC2");
-            region = "us-east-1"; 
-        }
-        
-        Set<org.jclouds.ec2.domain.SecurityGroup> groups = client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, getName());
-        String id = null;
-        if (groups.isEmpty()) {
-            // create it
-            try {
-                id = client.getSecurityGroupApi().get().createSecurityGroupInRegionAndReturnId(region , getName(), "Brooklyn-managed security group "+getName());
-            } catch (Exception e) {
-                Exceptions.propagateIfFatal(e);
-                // check if someone else already created it!
-                groups = client.getSecurityGroupApi().get().describeSecurityGroupsInRegion(region, getName());
-                if (groups.isEmpty()) {
-                    // no - so propagate error
-                    throw Exceptions.propagate(e);
-                } else {
-                    log.debug("Looks like parallel thread created security group "+getName()+"; ignoring error in our thread ("+e+") as we now have an SG");
-                }
-            }
-        }
-        if (!groups.isEmpty()) {
-            if (groups.size()>1)
-                log.warn("Multiple security groups matching '"+getName()+"' (using the first): "+groups);
-            id = groups.iterator().next().getId();
-        }
-        if (id==null)
-            throw new IllegalStateException("Unable to find or create security group ID for "+getName());
-
-        client.getSecurityGroupApi().get().authorizeSecurityGroupIngressInRegion(region, id, sgDef.getPermissions());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachinePool.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachinePool.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachinePool.java
deleted file mode 100644
index d2dcf80..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachinePool.java
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.pool;
-
-import static brooklyn.location.jclouds.pool.MachinePoolPredicates.compose;
-import static brooklyn.location.jclouds.pool.MachinePoolPredicates.matching;
-
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.RunNodesException;
-import org.jclouds.compute.domain.ComputeMetadata;
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Template;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-/**
- * Contains details of machines detected at a given cloud (ComputeService),
- * and records claims made against those machines via this pool.
- * <p>
- * Machine instances themselves are persisted and rescanned as new instances of this class are created.
- * Claims however are specific to this instance of the class, i.e. <b>not</b> persisted.
- * <p>
- * This class is believed to be thread-safe.
- * Refreshes to the remote detected machines are synchronized on the pool instance.
- * Details of detected and claimed machines are also synchronized on the pool instance.
- * (If it is necessary to claim machines whilst the pool is being rescanned,
- * we can investigate a more sophisticated threading model.
- * Access to some fields is clearly independent and uses a tighter synchonization
- * strategy, e.g. templates.  
- * Synchronization of fields within a synch block on the class instance
- * is permitted, but not the other way round,
- * and synching on multiple fields is also not permitted.)
- * <p>
- * Callers wishing to guarantee results of e.g. ensureUnclaimed remaining available
- * can synchronize on this class for the duration that they wish to have that guarantee
- * (at the cost, of course, of any other threads being able to access this pool).
- * <p>
- * If underlying provisioning/destroying operations fail, the pool
- * currently may be in an unknown state, currently.
- * If more robustness is needed this can be added.
- * 
- * @deprecated since 0.6.0; never used in production setting, and thus of dubious value; best avoided as unlikely to be supported in future versions
- */
-@Deprecated
-public class MachinePool {
-    
-    private static final Logger log = LoggerFactory.getLogger(MachinePool.class);
-    
-    protected final ComputeService computeService;
-    final AtomicBoolean refreshNeeded = new AtomicBoolean(true);
-    final List<ReusableMachineTemplate> templates = new ArrayList<ReusableMachineTemplate>();
-    String poolName = null;
-    
-    /** all machines detected, less those in the black list */
-    volatile MachineSet detectedMachines = new MachineSet();
-    volatile MachineSet matchedMachines = new MachineSet();
-    volatile MachineSet claimedMachines = new MachineSet();
-    volatile MachineSet blacklistedMachines = new MachineSet();
-    
-    public MachinePool(ComputeService computeService) {
-        this.computeService = computeService;
-    }
-    
-    protected synchronized void init() {
-        if (!refreshNeeded.get()) return;
-        refresh();
-    }
-    
-    public void setPoolName(String poolName) {
-        if (poolName!=null)
-            log.warn("Changing pool name of "+this+" (from "+this.poolName+" to "+poolName+") is discouraged.");
-        this.poolName = poolName;
-    }
-    /** pool name is used as a group/label by jclouds, for convenience only; 
-     * it has no special properties for detecting matching instances
-     * (use explicit tags on the templates, for that). 
-     * defaults to name of pool class and user name.
-     * callers should set pool name before getting, if using a custom name. */
-    public synchronized String getPoolName() {
-        if (poolName==null)
-            poolName = getClass().getSimpleName()+"-"+System.getProperty("user.name");
-        return poolName;
-    }
-    
-    /** refreshes the pool of machines from the server (finding all instances matching the registered templates) */
-    public synchronized void refresh() {
-        refreshNeeded.set(false);
-        Set<? extends ComputeMetadata> computes = computeService.listNodes();
-        Set<NodeMetadata> nodes = new LinkedHashSet<NodeMetadata>();
-        for (ComputeMetadata c: computes) {
-            if (c instanceof NodeMetadata) {
-                nodes.add((NodeMetadata)c);
-            } else {
-                // TODO should we try to fetch more info?
-                log.warn("MachinePool "+this+" ignoring non-Node record for remote machine: "+c);
-            }
-        }
-
-        MachineSet allNewDetectedMachines = new MachineSet(nodes);
-        MachineSet newDetectedMachines = filterForAllowedMachines(allNewDetectedMachines);
-        MachineSet oldDetectedMachines = detectedMachines;
-        MachineSet newMatchedMachines = new MachineSet();
-        detectedMachines = newDetectedMachines;
-
-        MachineSet appearedMachinesIncludingBlacklist = allNewDetectedMachines.removed(oldDetectedMachines);
-        MachineSet appearedMachines = filterForAllowedMachines(appearedMachinesIncludingBlacklist);
-        if (appearedMachinesIncludingBlacklist.size()>appearedMachines.size())
-            if (log.isDebugEnabled()) log.debug("Pool "+this+", ignoring "+(appearedMachinesIncludingBlacklist.size()-appearedMachines.size())+" disallowed");
-        int matchedAppeared = 0;
-        for (NodeMetadata m: appearedMachines) {
-            if (m.getStatus() != NodeMetadata.Status.RUNNING) {
-                if (log.isDebugEnabled()) 
-                    log.debug("Pool "+this+", newly detected machine "+m+", not running ("+m.getStatus()+")");
-            } else {
-                Set<ReusableMachineTemplate> ts = getTemplatesMatchingInstance(m);
-                if (!ts.isEmpty()) {
-                    matchedAppeared++;
-                    newMatchedMachines = newMatchedMachines.added(new MachineSet(m));
-                    if (log.isDebugEnabled()) 
-                        log.debug("Pool "+this+", newly detected machine "+m+", matches pool templates "+ts);
-                } else {
-                    if (log.isDebugEnabled()) 
-                        log.debug("Pool "+this+", newly detected machine "+m+", does not match any pool templates");
-                }
-            }
-        }
-        if (matchedAppeared>0) {
-            log.info("Pool "+this+" discovered "+matchedAppeared+" matching machines (of "+appearedMachines.size()+" total new; "+newDetectedMachines.size()+" total including claimed and unmatched)");
-        } else {
-            if (log.isDebugEnabled()) 
-                log.debug("Pool "+this+" discovered "+matchedAppeared+" matching machines (of "+appearedMachines.size()+" total new; "+newDetectedMachines.size()+" total including claimed and unmatched)");
-        }
-        matchedMachines = newMatchedMachines;
-    }
-
-    protected MachineSet filterForAllowedMachines(MachineSet input) {
-        return input.removed(blacklistedMachines);
-    }
-
-    // TODO template registry and claiming from a template could be a separate responsibility
-    
-    protected ReusableMachineTemplate registerTemplate(ReusableMachineTemplate template) {
-        registerTemplates(template);
-        return template;
-    }
-    protected void registerTemplates(ReusableMachineTemplate ...templatesToReg) {
-        synchronized (templates) { 
-            for (ReusableMachineTemplate template: templatesToReg)
-                templates.add(template); 
-        }
-    }
-    
-    protected ReusableMachineTemplate newTemplate(String name) {
-        return registerTemplate(new ReusableMachineTemplate(name));
-    }
-
-    
-    public List<ReusableMachineTemplate> getTemplates() {
-        List<ReusableMachineTemplate> result;
-        synchronized (templates) { result = ImmutableList.copyOf(templates); }
-        return result;
-    }
-    
-    /** all machines matching any templates */
-    public MachineSet all() {
-        init();
-        return matchedMachines;
-    }
-
-    /** machines matching any templates which have not been claimed */
-    public MachineSet unclaimed() {
-        init();
-        synchronized (this) {
-            return matchedMachines.removed(claimedMachines);
-        }
-    }
-    
-    /** returns all machines matching the given criteria (may be claimed) */
-    @SuppressWarnings("unchecked")
-    public MachineSet all(Predicate<NodeMetadata> criterion) {
-        // To avoid generics complaints in callers caused by varargs, overload here
-        return all(new Predicate[] {criterion});
-    }
-    
-    /** returns all machines matching the given criteria (may be claimed) */
-    public MachineSet all(Predicate<NodeMetadata> ...ops) {
-        return new MachineSet(Iterables.filter(all(), compose(ops)));
-    }
-
-    /** returns unclaimed machines matching the given criteria */
-    @SuppressWarnings("unchecked")
-    public MachineSet unclaimed(Predicate<NodeMetadata> criterion) {
-        // To avoid generics complaints in callers caused by varargs, overload here
-        return unclaimed(new Predicate[] {criterion});
-    }
-    
-    /** returns unclaimed machines matching the given criteria */
-    public MachineSet unclaimed(Predicate<NodeMetadata> ...criteria) {
-        return new MachineSet(Iterables.filter(unclaimed(), compose(criteria)));
-    }
-
-    /** creates machines if necessary so that this spec exists (may already be claimed however) 
-     * returns a set of all matching machines, guaranteed non-empty 
-     * (but possibly some are already claimed) */
-    public MachineSet ensureExists(ReusableMachineTemplate template) {
-        return ensureExists(1, template);
-    }
-
-    public synchronized void addToBlacklist(MachineSet newToBlacklist) {
-        setBlacklist(blacklistedMachines.added(newToBlacklist));
-    }
-    
-    /** replaces the blacklist set; callers should generally perform a refresh()
-     * afterwards, to trigger re-detection of blacklisted machines
-     */
-    public synchronized void setBlacklist(MachineSet newBlacklist) {
-        blacklistedMachines = newBlacklist;
-        detectedMachines = detectedMachines.removed(blacklistedMachines);
-        matchedMachines = matchedMachines.removed(blacklistedMachines);
-    }
-    
-    /** creates machines if necessary so that this spec exists (may already be claimed however);
-     * returns a set of all matching machines, of size at least count (but possibly some are already claimed).
-     * (the pool can change at any point, so this set is a best-effort but may be out of date.
-     * see javadoc comments on this class.) */
-    public MachineSet ensureExists(int count, ReusableMachineTemplate template) {
-        MachineSet current;
-        current = all(matching(template));
-        if (current.size() >= count)
-            return current;
-        //have to create more
-        MachineSet moreNeeded = create(count-current.size(), template);
-        return current.added(moreNeeded);
-    }
-    
-    /** creates machines if necessary so that this spec can subsequently be claimed;
-     * returns all such unclaimed machines, guaranteed to be non-empty.
-    * (the pool can change at any point, so this set is a best-effort but may be out of date.
-    * see javadoc comments on this class.) */
-    public MachineSet ensureUnclaimed(ReusableMachineTemplate template) {
-        return ensureUnclaimed(1, template);
-    }
-
-    /** creates machines if necessary so that this spec can subsequently be claimed;
-     * returns a set of at least count unclaimed machines */
-    public MachineSet ensureUnclaimed(int count, ReusableMachineTemplate template) {
-        MachineSet current;
-        current = unclaimed(matching(template));
-        if (current.size() >= count)
-            return current;
-        //have to create more
-        MachineSet moreNeeded = create(count-current.size(), template);
-        return current.added(moreNeeded);
-    }
-
-    public Set<ReusableMachineTemplate> getTemplatesMatchingInstance(NodeMetadata nm) {
-        Set<ReusableMachineTemplate> result = new LinkedHashSet<ReusableMachineTemplate>(); 
-        for (ReusableMachineTemplate t: getTemplates()) {
-            if (matching(t).apply(nm)) {
-               result.add(t); 
-            }
-        }        
-        return result;
-    }
-    
-    /** creates the given number of machines of the indicated template */
-    public MachineSet create(int count, ReusableMachineTemplate template) {
-        Set<? extends NodeMetadata> nodes;
-        try {
-            Template t = template.newJcloudsTemplate(computeService);
-            if (log.isDebugEnabled()) log.debug("Creating "+count+" new instances of "+t);
-            nodes = computeService.createNodesInGroup(getPoolName(), count, t);
-        } catch (RunNodesException e) {
-            throw Throwables.propagate(e);
-        }
-        MachineSet result = new MachineSet(nodes);
-        registerNewNodes(result, template);
-        return result;
-    }
-    protected void registerNewNodes(MachineSet result, ReusableMachineTemplate template) {
-        for (NodeMetadata m: result) {
-            Set<ReusableMachineTemplate> ts = getTemplatesMatchingInstance(m);
-            if (ts.isEmpty()) {
-                log.error("Pool "+this+", created machine "+m+" from template "+template+", but no pool templates match!");
-            } else {
-                if (log.isDebugEnabled())
-                    log.debug("Pool "+this+", created machine "+m+" from template "+template+", matching templates "+ts);
-            }
-        }
-        synchronized (this) {
-            detectedMachines = detectedMachines.added(result);
-            matchedMachines = matchedMachines.added(result);
-        }
-    }
-
-    /** claims the indicated number of machines with the indicated spec, creating if necessary */
-    public MachineSet claim(int count, ReusableMachineTemplate t) {
-        init();
-        Set<NodeMetadata> claiming = new LinkedHashSet<NodeMetadata>();
-        while (claiming.size() < count) {
-            MachineSet mm = ensureUnclaimed(count - claiming.size(), t);
-            for (NodeMetadata m : mm) {
-                synchronized (this) {
-                    if (claiming.size() < count && !claimedMachines.contains(m)) {
-                        claiming.add(m);
-                        claimedMachines = claimedMachines.added(new MachineSet(m));
-                    }
-                }
-            }
-        }
-        MachineSet result = new MachineSet(claiming);
-        return result;
-    }
-
-
-    /** claims the indicated set of machines;
-     * throws exception if cannot all be claimed;
-     * returns the set passed in if successful */
-    public MachineSet claim(MachineSet set) {
-        init();
-        synchronized (this) {
-            MachineSet originalClaimed = claimedMachines;
-            claimedMachines = claimedMachines.added(set);
-            MachineSet newlyClaimed = claimedMachines.removed(originalClaimed);
-            if (newlyClaimed.size() != set.size()) {
-                //did not claim all; unclaim and fail
-                claimedMachines = originalClaimed;
-                MachineSet unavailable = set.removed(newlyClaimed); 
-                throw new IllegalArgumentException("Could not claim all requested machines; failed to claim "+unavailable);
-            }
-            return newlyClaimed;
-        }
-    }
-    
-    public int unclaim(MachineSet set) {
-        init();
-        synchronized (this) {
-            MachineSet originalClaimed = claimedMachines;
-            claimedMachines = claimedMachines.removed(set);
-            return originalClaimed.size() - claimedMachines.size();
-        }
-    }
-
-    
-    public int destroy(final MachineSet set) {
-        init();
-        synchronized (this) {
-            detectedMachines = detectedMachines.removed(set);
-            matchedMachines = matchedMachines.removed(set);
-            claimedMachines = claimedMachines.removed(set);
-        }
-        Set<? extends NodeMetadata> destroyed = computeService.destroyNodesMatching(new Predicate<NodeMetadata>() {
-            @Override
-            public boolean apply(NodeMetadata input) {
-                return set.contains(input);
-            }
-        });
-        synchronized (this) {
-            //in case a rescan happened while we were destroying
-            detectedMachines = detectedMachines.removed(set);
-            matchedMachines = matchedMachines.removed(set);
-            claimedMachines = claimedMachines.removed(set);
-        }
-        return destroyed.size();        
-    }
-        
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachinePoolPredicates.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachinePoolPredicates.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachinePoolPredicates.java
deleted file mode 100644
index e2158c1..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachinePoolPredicates.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.pool;
-
-import java.util.Map;
-
-import org.jclouds.compute.domain.NodeMetadata;
-import org.jclouds.compute.domain.Processor;
-import org.jclouds.domain.Location;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Throwables;
-
-public class MachinePoolPredicates {
-
-    private static final Logger log = LoggerFactory.getLogger(MachinePoolPredicates.class);
-    
-    public static Predicate<NodeMetadata> except(final MachineSet removedItems) {
-        return new Predicate<NodeMetadata>() {
-            @Override
-            public boolean apply(NodeMetadata input) {
-                return !removedItems.contains(input);
-            }
-        };
-    }
-
-    public static Predicate<NodeMetadata> except(final Predicate<NodeMetadata> predicateToExclude) {
-        return Predicates.not(predicateToExclude);
-    }
-
-    public static Predicate<NodeMetadata> matching(final ReusableMachineTemplate template) {
-        return new Predicate<NodeMetadata>() {
-            @Override
-            public boolean apply(NodeMetadata input) {
-                return matches(template, input);
-            }
-        };
-    }
-
-    public static Predicate<NodeMetadata> withTag(final String tag) {
-        return new Predicate<NodeMetadata>() {
-            @Override
-            public boolean apply(NodeMetadata input) {
-                return input.getTags().contains(tag);
-            }
-        };
-    }
-
-    public static Predicate<NodeMetadata> compose(final Predicate<NodeMetadata> ...predicates) {
-        return Predicates.and(predicates);
-    }
-
-    /** True iff the node matches the criteria specified in this template. 
-     * <p>
-     * NB: This only checks some of the most common fields, 
-     * plus a hashcode (in strict mode).  
-     * In strict mode you're practically guaranteed to match only machines created by this template.
-     * (Add a tag(uid) and you _will_ be guaranteed, strict mode or not.)
-     * <p> 
-     * Outside strict mode, some things (OS and hypervisor) can fall through the gaps.  
-     * But if that is a problem we can easily add them in.
-     * <p>
-     * (Caveat: If explicit Hardware, Image, and/or Template were specified in the template,
-     * then the hash code probably will not detect it.)   
-     **/
-    public static boolean matches(ReusableMachineTemplate template, NodeMetadata m) {
-        try {
-            // tags and user metadata
-
-            if (! m.getTags().containsAll( template.getTags(false) )) return false;
-
-            if (! isSubMapOf(template.getUserMetadata(false), m.getUserMetadata())) return false;
-
-
-            // common hardware parameters
-
-            if (template.getMinRam()!=null && m.getHardware().getRam() < template.getMinRam()) return false;
-
-            if (template.getMinCores()!=null) {
-                double numCores = 0;
-                for (Processor p: m.getHardware().getProcessors()) numCores += p.getCores();
-                if (numCores+0.001 < template.getMinCores()) return false;
-            }
-
-            if (template.getIs64bit()!=null) {
-                if (m.getOperatingSystem().is64Bit() != template.getIs64bit()) return false;
-            }
-
-            if (template.getOsFamily()!=null) {
-                if (m.getOperatingSystem() == null || 
-                        !template.getOsFamily().equals(m.getOperatingSystem().getFamily())) return false;
-            }
-            if (template.getOsNameMatchesRegex()!=null) {
-                if (m.getOperatingSystem() == null || m.getOperatingSystem().getName()==null ||
-                        !m.getOperatingSystem().getName().matches(template.getOsNameMatchesRegex())) return false;
-            }
-
-            if (template.getLocationId()!=null) {
-                if (!isLocationContainedIn(m.getLocation(), template.getLocationId())) return false;
-            }
-
-            // TODO other TemplateBuilder fields and TemplateOptions
-
-            return true;
-            
-        } catch (Exception e) {
-            log.warn("Error (rethrowing) trying to match "+m+" against "+template+": "+e, e);
-            throw Throwables.propagate(e);
-        }
-    }
-
-    private static boolean isLocationContainedIn(Location location, String locationId) {
-        if (location==null) return false;
-        if (locationId.equals(location.getId())) return true;
-        return isLocationContainedIn(location.getParent(), locationId);
-    }
-
-    public static boolean isSubMapOf(Map<String, String> sub, Map<String, String> bigger) {
-        for (Map.Entry<String, String> e: sub.entrySet()) {
-            if (e.getValue()==null) {
-                if (!bigger.containsKey(e.getKey())) return false;
-                if (bigger.get(e.getKey())!=null) return false;
-            } else {
-                if (!e.getValue().equals(bigger.get(e.getKey()))) return false;
-            }
-        }
-        return true;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachineSet.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachineSet.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachineSet.java
deleted file mode 100644
index fe21e2a..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/MachineSet.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.pool;
-
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import javax.annotation.concurrent.Immutable;
-
-import org.jclouds.compute.domain.NodeMetadata;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-@Immutable
-public class MachineSet implements Iterable<NodeMetadata> {
-
-    final Set<NodeMetadata> members;
-    
-    public MachineSet(Iterable<? extends NodeMetadata> m) { 
-        members = ImmutableSet.copyOf(m); 
-    }
-    public MachineSet(NodeMetadata ...nodes) {
-        members = ImmutableSet.copyOf(nodes); 
-    }
-
-    @Override
-    public Iterator<NodeMetadata> iterator() {
-        return members.iterator();
-    }
-
-    public MachineSet removed(MachineSet toRemove) {
-        Set<NodeMetadata> s = new LinkedHashSet<NodeMetadata>(members);
-        for (NodeMetadata m: toRemove) s.remove(m);
-        return new MachineSet(s);
-    }
-    public MachineSet added(MachineSet toAdd) {
-        Set<NodeMetadata> s = new LinkedHashSet<NodeMetadata>(members);
-        for (NodeMetadata m: toAdd) s.add(m);
-        return new MachineSet(s);
-    }
-
-    @SuppressWarnings("unchecked")
-    public MachineSet filtered(Predicate<NodeMetadata> criterion) {
-        // To avoid generics complaints in callers caused by varargs, overload here
-        return filtered(new Predicate[] {criterion});
-    }
-
-    public MachineSet filtered(Predicate<NodeMetadata> ...criteria) {
-        return new MachineSet(Iterables.filter(members, MachinePoolPredicates.compose(criteria)));
-    }
-
-    public int size() {
-        return members.size();
-    }
-    
-    public boolean isEmpty() {
-        return members.isEmpty();
-    }
-    
-    public boolean contains(NodeMetadata input) {
-        return members.contains(input);
-    }
-    
-    @Override
-    public String toString() {
-        return members.toString();
-    }
-    
-    @Override
-    public int hashCode() {
-        return members.hashCode();
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        return (obj instanceof MachineSet) && (members.equals( ((MachineSet)obj).members ));
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java
deleted file mode 100644
index d1f3331..0000000
--- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds.pool;
-
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.jclouds.compute.options.TemplateOptions;
-
-import brooklyn.location.jclouds.templates.PortableTemplateBuilder;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-/**
- * A facility for having a template we can declare without knowing the provider,
- * then find matching instances, create instances, and generally manipulate them.
- * <p>
- * NB: to be sure of matching a specific template, you should provide a unique id in the constructor.
- * (this will force 'strict' mode.)
- */
-// TODO tags/metadata semantics are not quite right, as they could apply to the server _image_ or _instance_
-
-// TODO we could use a hashcode over the values of template-builder and template-options fields, as a tag/usermetadata, 
-// to guarantee (virtually) matching only machines created from this template (instead of asking for unique id)
-public class ReusableMachineTemplate extends PortableTemplateBuilder<ReusableMachineTemplate> {
-
-    public static final String PREFIX = "brooklyn:template.";
-    public static final String NAME_METADATA_KEY = PREFIX+"name";
-    public static final String DESCRIPTION_METADATA_KEY = PREFIX+"name";
-    public static final String HASH_METADATA_KEY = PREFIX+"hash";
-    public static final String TEMPLATE_OWNER_METADATA_KEY = PREFIX+"owner";
-    
-    private String name = null;
-    private String templateOwner = null;
-    private String description = null;
-    private boolean strict;
-    
-    public ReusableMachineTemplate() { strict = false; }
-    public ReusableMachineTemplate(String name) { name(name); }
-    
-    /** see #getName() */
-    public ReusableMachineTemplate name(String name) {
-        this.name = name;
-        strict = true;
-        return this;
-    }
-    
-    /** see #getDescription() */
-    public ReusableMachineTemplate description(String description) {
-        this.description = description;
-        return this;
-    }
-
-    /** whether this template only matches machines instances created from this template; 
-     * defaults true if a name is set, otherwise false.
-     * if false, it will ignore name, owner, and hashcode */
-    public ReusableMachineTemplate strict(boolean strict) {
-        this.strict = strict;
-        return this;
-    }
-
-    /** no owner, means anyone can pick this up (default) */
-    public ReusableMachineTemplate templateUnowned() {
-        return templateOwner(null);
-    }
-    /** adds user.name as owner of this template */
-    public ReusableMachineTemplate templateOwnedByMe() {
-        return templateOwner(System.getProperty("user.name"));
-    }
-    /** adds an owner tag to this template */
-    public ReusableMachineTemplate templateOwner(String owner) {
-        this.templateOwner = owner;
-        return this;
-    }
-    
-    /** human-friendly name for this template. should normally be unique, it is the primary differentiator for strict matching. */
-    public String getName() {
-        return name;
-    }
-    
-    /** a description for this template; this is set on created machines but _not_ used to filter them 
-     * (so you can change description freely).  */
-    public String getDescription() {
-        return description;
-    }
-    
-    public String getOwner() {
-        return templateOwner;
-    }
-    
-    public boolean isStrict() {
-        return strict;
-    }
-
-    @Override
-    public List<TemplateOptions> getAdditionalOptions() {
-        List<TemplateOptions> result = new ArrayList<TemplateOptions>();
-        result.addAll(super.getAdditionalOptions());
-        if (isStrict()) addStrictOptions(result);
-        return result;
-    }
-
-    @Override
-    public List<TemplateOptions> getAdditionalOptionalOptions() {
-        List<TemplateOptions> result = new ArrayList<TemplateOptions>();
-        result.addAll(super.getAdditionalOptions());
-        addStrictOptions(result);
-        return result;
-    }
-    
-    protected void addStrictOptions(List<TemplateOptions> result) {
-        if (name!=null) result.add(TemplateOptions.Builder.userMetadata(NAME_METADATA_KEY, name));
-        if (templateOwner!=null) result.add(TemplateOptions.Builder.userMetadata(TEMPLATE_OWNER_METADATA_KEY, templateOwner));
-        // this is too strict -- the hash code seems to change from run to run (would be nice to fix that)
-//        result.add(TemplateOptions.Builder.userMetadata(HASH_METADATA_KEY, ""+hashCode()));
-    }
-    
-    /** computes the user metadata that this template will set (argument true) or required to match (argument false) */
-    public Map<String,String> getUserMetadata(boolean includeOptional) {
-        return ImmutableMap.copyOf(computeAggregatedOptions(includeOptional).getUserMetadata());
-    }
-
-    /** computes the tags that this template will set (argument true) or require to match (argument false) */
-    public Set<String> getTags(boolean includeOptional) {
-        return ImmutableSet.copyOf(computeAggregatedOptions(includeOptional).getTags());
-    }
-    
-    public ReusableMachineTemplate tag(String tag) {
-        return tags(tag);
-    }
-    public ReusableMachineTemplate tags(String ...tags) {
-        return addOptions(TemplateOptions.Builder.tags(Arrays.asList(tags)));
-    }
-
-    public ReusableMachineTemplate metadata(String key, String value) {
-        return addOptions(TemplateOptions.Builder.userMetadata(key, value));
-    }
-    public ReusableMachineTemplate metadata(Map<String,String> m) {
-        return addOptions(TemplateOptions.Builder.userMetadata(m));
-    }
-
-    public ReusableMachineTemplate tagOptional(String tag) {
-        return tagsOptional(tag);
-    }
-    public ReusableMachineTemplate tagsOptional(String ...tags) {
-        return addOptionalOptions(TemplateOptions.Builder.tags(Arrays.asList(tags)));
-    }
-
-    public ReusableMachineTemplate metadataOptional(String key, String value) {
-        return addOptionalOptions(TemplateOptions.Builder.userMetadata(key, value));
-    }
-    public ReusableMachineTemplate metadataOptional(Map<String,String> m) {
-        return addOptionalOptions(TemplateOptions.Builder.userMetadata(m));
-    }
-
-    @Override
-    public String toString() {
-        String s = makeNonTrivialArgumentsString();
-        return (name!=null ? name : "Template") + " [ " + s + " ]";
-    }
-    
-}



[46/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java
index 29081bb..a5d5f53 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppEc2LiveTest.java
@@ -23,11 +23,11 @@ import static org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppFixtureIntegr
 import static org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppFixtureIntegrationTest.GIT_REPO_URL;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
index 0f82d5d..4cc1522 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppFixtureIntegrationTest.java
@@ -21,8 +21,9 @@ package org.apache.brooklyn.entity.webapp.nodejs;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcessDriver;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Urls;
@@ -33,6 +34,7 @@ import com.google.common.collect.ImmutableList;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppService;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java
index 610b990..e1b10e2 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSimpleIntegrationTest.java
@@ -25,14 +25,16 @@ import java.net.ServerSocket;
 import java.util.Iterator;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.PortRange;
 import org.jclouds.util.Throwables2;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.location.PortRange;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.util.net.Networking;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java
index 7717d81..0c6df06 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppSoftlayerLiveTest.java
@@ -23,11 +23,11 @@ import static org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppFixtureIntegr
 import static org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppFixtureIntegrationTest.GIT_REPO_URL;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java
index eb46abe..8d58710 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerEc2LiveTest.java
@@ -23,10 +23,10 @@ import static org.testng.Assert.assertNotNull;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java
index 8215e7b..595ace4 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8ServerSoftlayerLiveTest.java
@@ -23,10 +23,10 @@ import static org.testng.Assert.assertNotNull;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java
index 0b591a0..51a4546 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerEc2LiveTest.java
@@ -22,12 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java
index ad9939f..2ff6866 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerSoftlayerLiveTest.java
@@ -22,12 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java b/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java
index 09cafd2..c5967d0 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/test/entity/TestJavaWebAppEntity.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.test.entity;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,7 +33,6 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.SoftwareProcessDriverLifecycleEffectorTasks;
 import brooklyn.entity.java.VanillaJavaApp;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.config.ConfigBag;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index 53c8eeb..d17740d 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
@@ -53,7 +54,6 @@ import brooklyn.entity.basic.BrooklynTags;
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.proxying.InternalEntityFactory;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.ManagementContextInjectable;
 import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
index 298b093..04a7ac0 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynYamlLocationResolver.java
@@ -22,10 +22,10 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
 import org.apache.brooklyn.api.management.ManagementContext;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
index 6fb5816..2828846 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
@@ -41,7 +42,7 @@ import com.google.common.net.HostAndPort;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.DoNothingSoftwareProcess;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.access.PortForwardManager;
 import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.LocationPredicates;
@@ -49,6 +50,7 @@ import org.apache.brooklyn.location.basic.Machines;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.net.UserAndHostAndPort;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
index fc942da..e7bb7db 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EmptySoftwareProcessYamlTest.java
@@ -22,6 +22,7 @@ import java.util.Iterator;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
@@ -29,8 +30,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.Jsonya;
 
 @Test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
index db185da..6c803e1 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
@@ -34,6 +34,7 @@ import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon;
 import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent;
@@ -59,7 +60,6 @@ import brooklyn.entity.basic.SameServerEntity;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.EntityManagerInternal;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
index 0f8c839..524ea17 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/LocationsYamlTest.java
@@ -26,17 +26,17 @@ import java.io.StringReader;
 import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
-
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineLocation;
 import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.MultiLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.text.Strings;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
index 82181d5..995a94d 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestEntityWithInitConfigImpl.java
@@ -21,11 +21,11 @@ package org.apache.brooklyn.camp.brooklyn;
 import java.util.Collection;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractEntity;
-import org.apache.brooklyn.location.Location;
 
 public class TestEntityWithInitConfigImpl extends AbstractEntity implements TestEntityWithInitConfig {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
index 19849b3..6b220fd 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
@@ -32,11 +32,11 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
 import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityMatcher;
 
 import brooklyn.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.location.LocationSpec;
 import brooklyn.management.osgi.OsgiVersionMoreEntityTest;
 
 import org.apache.brooklyn.policy.Policy;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
index 8788d5b..7160657 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlLocationTest.java
@@ -29,14 +29,16 @@ import org.testng.annotations.Test;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest;
 
 import brooklyn.catalog.CatalogPredicates;
 import brooklyn.event.basic.BasicConfigKey;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.management.osgi.OsgiStandaloneTest;
 
 import org.apache.brooklyn.test.TestResourceUnavailableException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
index ba0a25b..32d2cec 100644
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/CloudExplorer.java
@@ -38,13 +38,13 @@ import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.options.TemplateOptions;
-
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import org.apache.brooklyn.location.jclouds.JcloudsUtil;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
 import brooklyn.util.stream.Streams;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
index 61cc6de..bb12732 100644
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/ItemLister.java
@@ -36,13 +36,13 @@ import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.catalog.Catalog;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationResolver;
 import org.apache.brooklyn.cli.lister.ClassFinder;
 import org.apache.brooklyn.cli.lister.ItemDescriptors;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationResolver;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.net.Urls;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
index 11a636d..9cef866 100644
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ItemDescriptors.java
@@ -36,10 +36,10 @@ import org.apache.brooklyn.api.catalog.Catalog;
 import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.EntityType;
 import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.location.LocationResolver;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynConfigKeys;
-import org.apache.brooklyn.location.LocationResolver;
 
 import org.apache.brooklyn.rest.domain.EffectorSummary;
 import org.apache.brooklyn.rest.domain.EntityConfigSummary;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java b/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
index 123acd3..ff6a5d3 100644
--- a/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
+++ b/usage/cli/src/test/java/org/apache/brooklyn/cli/CliTest.java
@@ -44,6 +44,7 @@ import java.util.regex.Pattern;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.cli.AbstractMain.BrooklynCommand;
 import org.apache.brooklyn.cli.AbstractMain.BrooklynCommandCollectingArgs;
 import org.apache.brooklyn.cli.AbstractMain.HelpCommand;
@@ -65,8 +66,9 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.StartableApplication;
 import brooklyn.entity.proxying.EntityProxy;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
index f5a6b2c..a044735 100644
--- a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
+++ b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynLauncher.java
@@ -37,6 +37,9 @@ import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.rebind.PersistenceExceptionHandler;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityManager;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
@@ -80,12 +83,9 @@ import brooklyn.entity.trait.Startable;
 
 import org.apache.brooklyn.launcher.config.StopWhichAppsOnShutdown;
 import org.apache.brooklyn.mementos.BrooklynMementoRawData;
-
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.PortRange;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.management.ha.HighAvailabilityManagerImpl;
 import brooklyn.management.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import brooklyn.management.internal.LocalManagementContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
index d63bb68..2b6c831 100644
--- a/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
+++ b/usage/launcher/src/main/java/org/apache/brooklyn/launcher/BrooklynWebServer.java
@@ -65,12 +65,12 @@ import brooklyn.config.BrooklynServiceAttributes;
 import brooklyn.config.ConfigKey;
 import brooklyn.internal.BrooklynInitialization;
 
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.launcher.config.CustomResourceLocator;
-
-import org.apache.brooklyn.location.PortRange;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.management.internal.ManagementContextInternal;
 
 import org.apache.brooklyn.rest.BrooklynRestApi;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java b/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
index 9489ad4..a8d301e 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
@@ -42,11 +42,11 @@ import brooklyn.event.basic.BasicConfigKey;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.launcher.SimpleYamlLauncherForTests;
 import org.apache.brooklyn.launcher.camp.SimpleYamlLauncher;
 
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.Jsonya;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
index 13931e4..bfbe81e 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindTestFixture.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.launcher;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
@@ -45,7 +46,6 @@ import brooklyn.entity.basic.StartableApplication;
 import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.exceptions.FatalConfigurationRuntimeException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
index 822a0ed..9f11563 100644
--- a/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
+++ b/usage/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherTest.java
@@ -20,6 +20,7 @@ package org.apache.brooklyn.launcher;
 
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
@@ -51,8 +52,9 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.config.BrooklynServerConfig;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.rebind.RebindTestUtils;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.util.exceptions.FatalRuntimeException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
index 2748179..59c5b0b 100644
--- a/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
@@ -42,11 +42,11 @@ import brooklyn.entity.brooklynnode.BrooklynNode;
 import brooklyn.entity.brooklynnode.BrooklynNode.DeployBlueprintEffector;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
-
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig;
+
 import brooklyn.util.BrooklynMavenArtifacts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
index e7dc4d4..d692790 100644
--- a/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/load/LoadTest.java
@@ -42,11 +42,11 @@ import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.trait.Startable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.launcher.BrooklynLauncher;
 
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.os.Os;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
index ef9d8e6..c691efa 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
@@ -22,7 +22,8 @@ import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigMap;
 import brooklyn.config.ConfigPredicates;
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.PortRange;
+
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.rest.security.provider.DelegatingSecurityProvider;
 import org.apache.brooklyn.rest.security.provider.ExplicitUsersSecurityProvider;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index 96b098f..9849ed2 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -52,7 +52,6 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.EntitlementPredicates;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
@@ -65,6 +64,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.rest.api.ApplicationApi;
 import org.apache.brooklyn.rest.domain.ApplicationSpec;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
index 31ee26c..b475ce3 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java
@@ -40,14 +40,14 @@ import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 
 import brooklyn.catalog.CatalogPredicates;
 import brooklyn.catalog.internal.BasicBrooklynCatalog;
 import brooklyn.catalog.internal.CatalogDto;
 import brooklyn.catalog.internal.CatalogItemComparator;
 import brooklyn.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
index bbe921c..ec730a9 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/EntityResource.java
@@ -41,7 +41,6 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.BrooklynTags;
 import brooklyn.entity.basic.BrooklynTags.NamedStringTag;
 import brooklyn.entity.basic.BrooklynTaskTags;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.EntitlementPredicates;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.internal.EntityManagementUtils;
@@ -49,6 +48,7 @@ import brooklyn.management.internal.EntityManagementUtils.CreationResult;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.rest.api.EntityApi;
 import org.apache.brooklyn.rest.domain.EntitySummary;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java
index 9694747..83fa84d 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/LocationResource.java
@@ -30,12 +30,12 @@ import javax.ws.rs.core.Response;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
 
 import brooklyn.catalog.internal.CatalogUtils;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
-import org.apache.brooklyn.location.basic.LocationConfigKeys;
 
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.rest.api.LocationApi;
 import org.apache.brooklyn.rest.domain.LocationSpec;
 import org.apache.brooklyn.rest.domain.LocationSummary;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java
index 18cb2ad..f56f67b 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/ApplicationTransformer.java
@@ -37,9 +37,9 @@ import javax.annotation.Nullable;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.rest.domain.ApplicationSpec;
 import org.apache.brooklyn.rest.domain.ApplicationSummary;
 import org.apache.brooklyn.rest.domain.Status;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
index 53a0f85..9c7f64c 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/CatalogTransformer.java
@@ -33,11 +33,11 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntityType;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.EntityDynamicType;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
 
 import org.apache.brooklyn.policy.Policy;
 import org.apache.brooklyn.policy.PolicySpec;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
index 1e2e8d4..72d17db 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/transform/LocationTransformer.java
@@ -25,12 +25,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Sanitizer;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
+
 import org.apache.brooklyn.location.basic.BasicLocationDefinition;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.basic.LocationInternal;
-
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.rest.domain.LocationSummary;
 import org.apache.brooklyn.rest.util.WebResourceUtils;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
index f0de6d9..5218c99 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
@@ -45,6 +45,8 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Application;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
 
@@ -58,8 +60,6 @@ import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.policy.basic.AbstractPolicy;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java
index 20f5eb0..88eb899 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/EntityLocationUtils.java
@@ -22,9 +22,8 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
-
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 
 public class EntityLocationUtils {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java
index f4fe4e9..52124b0 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/json/BidiSerialization.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.codehaus.jackson.JsonGenerationException;
 import org.codehaus.jackson.JsonGenerator;
@@ -34,8 +35,6 @@ import org.codehaus.jackson.map.JsonSerializer;
 import org.codehaus.jackson.map.SerializerProvider;
 import org.codehaus.jackson.map.module.SimpleModule;
 
-import org.apache.brooklyn.location.Location;
-
 public class BidiSerialization {
 
     protected final static ThreadLocal<Boolean> STRICT_SERIALIZATION = new ThreadLocal<Boolean>(); 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java
index 25351fe..d4c0089 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/LocationResourceTest.java
@@ -42,12 +42,13 @@ import com.google.common.collect.Iterables;
 import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.GenericType;
 
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import org.apache.brooklyn.rest.domain.CatalogLocationSummary;
 import org.apache.brooklyn.rest.domain.LocationSummary;
 import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
+
 import brooklyn.test.Asserts;
 
 @Test(singleThreaded = true)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java
index dae1a6b..521c01e 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/ScriptResourceTest.java
@@ -24,8 +24,8 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.rest.domain.ScriptExecutionSummary;
 import org.apache.brooklyn.rest.testing.mocks.RestMockApp;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java
index 4e1fd22..42d1717 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/UsageResourceTest.java
@@ -38,13 +38,16 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.SoftwareProcessEntityTest;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.management.internal.LocalUsageManager;
 import brooklyn.management.internal.ManagementContextInternal;
+
 import org.apache.brooklyn.rest.domain.ApplicationSpec;
 import org.apache.brooklyn.rest.domain.EntitySpec;
 import org.apache.brooklyn.rest.domain.Status;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
index 8194547..9d1e9bd 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/BrooklynRestApiTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.brooklyn.rest.testing;
 
+import org.apache.brooklyn.api.location.LocationRegistry;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
 import org.codehaus.jackson.map.ObjectMapper;
@@ -32,8 +33,9 @@ import com.sun.jersey.test.framework.JerseyTest;
 import com.sun.jersey.test.framework.LowLevelAppDescriptor;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationRegistry;
+
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
+
 import brooklyn.management.ManagementContextInjectable;
 import brooklyn.management.internal.LocalManagementContext;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java
index 4647c13..c91568f 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/util/EntityLocationUtilsTest.java
@@ -31,12 +31,12 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcess;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationInternal;
 import org.apache.brooklyn.location.geo.HostGeoInfo;
-
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.rest.testing.mocks.RestMockSimpleEntity;
 
 import com.google.common.collect.ImmutableList;


[04/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
new file mode 100644
index 0000000..bcee1a3
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+
+import brooklyn.entity.AbstractGoogleComputeLiveTest;
+import brooklyn.entity.basic.EmptySoftwareProcess;
+import brooklyn.entity.trait.Startable;
+
+// This test really belongs in brooklyn-location but depends on AbstractGoogleComputeLiveTest in brooklyn-software-base
+public class MachineDetailsGoogleComputeLiveTest extends AbstractGoogleComputeLiveTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MachineDetailsGoogleComputeLiveTest.class);
+
+    @Override
+    protected void doTest(Location loc) throws Exception {
+        Entity testEntity = app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
+        app.start(ImmutableList.of(loc));
+        EntityTestUtils.assertAttributeEqualsEventually(testEntity, Startable.SERVICE_UP, true);
+
+        SshMachineLocation sshLoc = Locations.findUniqueSshMachineLocation(testEntity.getLocations()).get();
+        MachineDetails machine = app.getExecutionContext()
+                .submit(BasicMachineDetails.taskForSshMachineLocation(sshLoc))
+                .getUnchecked();
+        LOG.info("Found the following at {}: {}", loc, machine);
+        assertNotNull(machine);
+        OsDetails details = machine.getOsDetails();
+        assertNotNull(details);
+        assertNotNull(details.getArch());
+        assertNotNull(details.getName());
+        assertNotNull(details.getVersion());
+        assertFalse(details.getArch().startsWith("architecture:"));
+        assertFalse(details.getName().startsWith("name:"));
+        assertFalse(details.getVersion().startsWith("version:"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
new file mode 100644
index 0000000..c089531
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationLiveTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.test.entity.TestApplication;
+
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.BrooklynAppLiveTestSupport;
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.jclouds.JcloudsWinRmMachineLocation;
+import brooklyn.management.internal.ManagementContextInternal;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class WinRmMachineLocationLiveTest {
+    
+    // FIXME failing locally with:
+    //   Caused by: Traceback (most recent call last):
+    //     File "__pyclasspath__/winrm/__init__.py", line 40, in run_cmd
+    //     File "__pyclasspath__/winrm/protocol.py", line 118, in open_shell
+    //     File "__pyclasspath__/winrm/protocol.py", line 190, in send_message
+    //     File "__pyclasspath__/winrm/transport.py", line 112, in send_message
+    //     winrm.exceptions.WinRMTransportError: 500 WinRMTransport. [Errno 20001] getaddrinfo failed
+    //     at org.python.core.PyException.doRaise(PyException.java:226)
+
+    private static final Logger LOG = LoggerFactory.getLogger(BrooklynAppLiveTestSupport.class);
+
+    protected JcloudsLocation loc;
+    protected TestApplication app;
+    protected ManagementContextInternal mgmt;
+
+    private JcloudsWinRmMachineLocation machine;
+    
+    @BeforeClass(alwaysRun=true)
+    public void setUpClass() throws Exception {
+        mgmt = new LocalManagementContextForTests(BrooklynProperties.Factory.newDefault());
+        JcloudsLocation loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve("jclouds:aws-ec2:us-west-2", ImmutableMap.of(
+                "inboundPorts", ImmutableList.of(5985, 3389),
+                "displayName", "AWS Oregon (Windows)",
+                "imageId", "us-west-2/ami-8fd3f9bf",
+                "hardwareId", "m3.medium",
+                "useJcloudsSshInit", false));
+        machine = (JcloudsWinRmMachineLocation) loc.obtain();
+    }
+
+    @AfterClass(alwaysRun=true)
+    public void tearDownClass() throws Exception {
+        try {
+            if (machine != null) loc.release(machine);
+            if (mgmt != null) Entities.destroyAll(mgmt);
+        } catch (Throwable t) {
+            LOG.error("Caught exception in tearDown method", t);
+        } finally {
+            mgmt = null;
+        }
+    }
+
+    @Test(groups="Live")
+    public void testExecScript() throws Exception {
+        WinRmToolResponse response = machine.executeScript("echo true");
+        assertEquals(response.getStatusCode(), 0);
+        assertEquals(response.getStdErr(), "");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
new file mode 100644
index 0000000..97b9358
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
@@ -0,0 +1,44 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.location.LocationSpec;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.BrooklynAppUnitTestSupport;
+import brooklyn.entity.basic.BrooklynConfigKeys;
+import brooklyn.util.net.Networking;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class WinRmMachineLocationTest extends BrooklynAppUnitTestSupport {
+
+    @Test
+    public void testConfigurePrivateAddresses() throws Exception {
+        WinRmMachineLocation host = mgmt.getLocationManager().createLocation(LocationSpec.create(WinRmMachineLocation.class)
+                .configure("address", Networking.getLocalHost())
+                .configure(WinRmMachineLocation.PRIVATE_ADDRESSES, ImmutableList.of("1.2.3.4"))
+                .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
+
+        assertEquals(host.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/crate/CrateNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/crate/CrateNode.java b/software/database/src/main/java/brooklyn/entity/database/crate/CrateNode.java
index 3300fd5..8d5fae3 100644
--- a/software/database/src/main/java/brooklyn/entity/database/crate/CrateNode.java
+++ b/software/database/src/main/java/brooklyn/entity/database/crate/CrateNode.java
@@ -33,7 +33,7 @@ import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 
 @ImplementedBy(CrateNodeImpl.class)

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/crate/CrateNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/crate/CrateNodeSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/crate/CrateNodeSshDriver.java
index 1fc8db2..55610da 100644
--- a/software/database/src/main/java/brooklyn/entity/database/crate/CrateNodeSshDriver.java
+++ b/software/database/src/main/java/brooklyn/entity/database/crate/CrateNodeSshDriver.java
@@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableList;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java
index e270251..d067625 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNode.java
@@ -34,7 +34,7 @@ import brooklyn.event.basic.BasicAttributeSensorAndConfigKey.StringAttributeSens
 import brooklyn.event.basic.MapConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 
 @Catalog(name="MariaDB Node", description="MariaDB is an open source relational database management system (RDBMS)", iconUrl="classpath:///mariadb-logo-180x119.png")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
index aedca17..0212749 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
@@ -26,8 +26,8 @@ import brooklyn.entity.effector.EffectorBody;
 import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshPollValue;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
index 1ecd18e..1833024 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
@@ -39,8 +39,8 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.database.DatastoreMixins;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java
index 79e2b5a..c0cfb46 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java
@@ -52,7 +52,7 @@ import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.guava.Functionals;
 import brooklyn.util.guava.IfFunctions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNode.java b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNode.java
index c1b16ae..0ab51d0 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNode.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNode.java
@@ -36,7 +36,7 @@ import brooklyn.event.basic.BasicAttributeSensorAndConfigKey.StringAttributeSens
 import brooklyn.event.basic.MapConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 
 @Catalog(name="MySql Node", description="MySql is an open source relational database management system (RDBMS)", iconUrl="classpath:///mysql-logo-110x57.png")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
index 569cdb3..00a591b 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlNodeImpl.java
@@ -29,8 +29,8 @@ import brooklyn.entity.effector.EffectorBody;
 import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshPollValue;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java
index d4fd396..e600e5b 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java
@@ -41,9 +41,9 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.database.DatastoreMixins;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.BasicOsDetails.OsVersions;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.BasicOsDetails.OsVersions;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.io.FileUtil;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNode.java b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNode.java
index f464e67..793debf 100644
--- a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNode.java
+++ b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNode.java
@@ -31,7 +31,7 @@ import brooklyn.entity.database.DatastoreMixins;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
index 311fa8b..7572845 100644
--- a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
+++ b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
@@ -34,8 +34,8 @@ import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.software.SshEffectorTasks;
 import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.Jsonya;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
index 5f112af..29f9c10 100644
--- a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
+++ b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
@@ -46,8 +46,8 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.database.DatastoreMixins;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/main/java/brooklyn/entity/database/rubyrep/RubyRepSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/rubyrep/RubyRepSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/rubyrep/RubyRepSshDriver.java
index e41c7f6..8415dd6 100644
--- a/software/database/src/main/java/brooklyn/entity/database/rubyrep/RubyRepSshDriver.java
+++ b/software/database/src/main/java/brooklyn/entity/database/rubyrep/RubyRepSshDriver.java
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;
 import brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/crate/CrateNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/crate/CrateNodeIntegrationTest.java b/software/database/src/test/java/brooklyn/entity/database/crate/CrateNodeIntegrationTest.java
index 7bbd063..3439217 100644
--- a/software/database/src/test/java/brooklyn/entity/database/crate/CrateNodeIntegrationTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/crate/CrateNodeIntegrationTest.java
@@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableList;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 public class CrateNodeIntegrationTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.java b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.java
index f5ef0a6..67c8a51 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbIntegrationTest.java
@@ -36,7 +36,7 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java
index e97da1d..f1e7886 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java
@@ -24,8 +24,8 @@ import org.testng.annotations.Test;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.Location;
-import brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java
index 867c12a..e3c617c 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveRackspaceTest.java
@@ -25,8 +25,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import brooklyn.util.net.Protocol;
 import brooklyn.util.ssh.IptablesCommands;
 import brooklyn.util.ssh.IptablesCommands.Chain;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java
index b2adfbd..807b462 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java
@@ -21,7 +21,7 @@ package brooklyn.entity.database.mysql;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 @Test(groups = { "Live" })
 public class MySqlClusterLiveEc2Test extends AbstractEc2LiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java
index cb26f1e..06bd0bc 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java
@@ -21,7 +21,7 @@ package brooklyn.entity.database.mysql;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 @Test(groups = { "Live" })
 public class MySqlClusterLiveSoftlayerTest extends AbstractSoftlayerLiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
index b2dc9c3..7fac59a 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
@@ -33,7 +33,7 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlIntegrationTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlIntegrationTest.java
index 61af5fb..523cbda 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlIntegrationTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlIntegrationTest.java
@@ -28,7 +28,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
index 1d07a6a..e874ce6 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
@@ -24,7 +24,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
index 1474b79..b5e4543 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
@@ -24,7 +24,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java
index b6ddd6a..4175a7e 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveRackspaceTest.java
@@ -26,8 +26,8 @@ import org.testng.annotations.Test;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import brooklyn.util.net.Protocol;
 import brooklyn.util.ssh.IptablesCommands;
 import brooklyn.util.ssh.IptablesCommands.Chain;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
index 08d1202..aa7ae45 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
@@ -20,10 +20,8 @@ package brooklyn.entity.database.mysql;
 
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
-import brooklyn.entity.database.postgresql.PostgreSqlNode;
 import brooklyn.entity.software.AbstractDockerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java
index a8353cd..8a4805c 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java
@@ -21,7 +21,7 @@ package brooklyn.entity.database.postgresql;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
 import brooklyn.entity.software.AbstractDockerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
index eee87aa..6f650ec 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
@@ -31,9 +31,9 @@ import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
 import brooklyn.entity.effector.EffectorTasks;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.task.system.ProcessTaskWrapper;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java
index 605ad58..f90f6fa 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java
@@ -24,7 +24,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java
index 6721d4a..4ae3600 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java
@@ -24,7 +24,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlIntegrationTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlIntegrationTest.java
index c9db677..3d6ed4c 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlIntegrationTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlIntegrationTest.java
@@ -32,7 +32,7 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRackspaceLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRackspaceLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRackspaceLiveTest.java
index 267b87d..bd6abbf 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRackspaceLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRackspaceLiveTest.java
@@ -25,9 +25,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import brooklyn.util.net.Protocol;
 import brooklyn.util.ssh.IptablesCommands;
 import brooklyn.util.ssh.IptablesCommands.Chain;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRebindIntegrationTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRebindIntegrationTest.java
index 54b5740..8a00587 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRebindIntegrationTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlRebindIntegrationTest.java
@@ -24,7 +24,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java
index 2601727..02a00fc 100644
--- a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java
@@ -25,8 +25,8 @@ import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
 import brooklyn.entity.database.postgresql.PostgreSqlNode;
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.PortRanges;
 
 public class RubyRepEc2LiveTest extends AbstractEc2LiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
index 6d56060..0ef7081 100644
--- a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
@@ -41,9 +41,9 @@ import brooklyn.entity.database.mysql.MySqlIntegrationTest;
 import brooklyn.entity.database.mysql.MySqlNode;
 import brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
 import brooklyn.entity.database.postgresql.PostgreSqlNode;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.management.internal.LocalManagementContext;
 
 public class RubyRepIntegrationTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java
index 2362819..da28512 100644
--- a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java
@@ -26,9 +26,9 @@ import org.testng.annotations.Test;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
 import brooklyn.entity.database.postgresql.PostgreSqlNode;
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.net.Protocol;
 import brooklyn.util.ssh.IptablesCommands;
 import brooklyn.util.ssh.IptablesCommands.Chain;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQSshDriver.java
index 39e6e0b..43096ed 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQSshDriver.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/activemq/ActiveMQSshDriver.java
@@ -26,7 +26,7 @@ import java.util.Map;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/AbstractfKafkaSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/AbstractfKafkaSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/AbstractfKafkaSshDriver.java
index 3b4a4c9..b797f7e 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/AbstractfKafkaSshDriver.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/AbstractfKafkaSshDriver.java
@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBroker.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBroker.java b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBroker.java
index cabfd47..28b51c9 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBroker.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBroker.java
@@ -30,7 +30,7 @@ import brooklyn.entity.zookeeper.ZooKeeperNode;
 import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerSshDriver.java
index 43950fe..7892ac5 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerSshDriver.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaBrokerSshDriver.java
@@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.java.UsesJmx;
 import brooklyn.entity.java.UsesJmx.JmxAgentModes;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 
 public class KafkaBrokerSshDriver extends AbstractfKafkaSshDriver implements KafkaBrokerDriver {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
index 0f5720f..99020bc 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
@@ -33,7 +33,7 @@ import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperNode;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.exceptions.CompoundRuntimeException;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaZooKeeperSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaZooKeeperSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaZooKeeperSshDriver.java
index d5b47e3..dc7688f 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaZooKeeperSshDriver.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaZooKeeperSshDriver.java
@@ -22,7 +22,7 @@ import java.util.Map;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.Attributes;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 
 import static brooklyn.util.text.StringEscapes.BashStringEscapes.escapeLiteralForDoubleQuotedBash;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidSshDriver.java
index 25d34df..2b1a8ec 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidSshDriver.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/qpid/QpidSshDriver.java
@@ -29,7 +29,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitDestination.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitDestination.java b/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitDestination.java
index bb97d08..14e0e47 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitDestination.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitDestination.java
@@ -25,7 +25,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.messaging.amqp.AmqpExchange;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.base.Objects.ToStringHelper;
 import com.google.common.base.Predicates;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java
index c2f4a7f..470221e 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java
@@ -35,7 +35,7 @@ import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
 import brooklyn.entity.messaging.amqp.AmqpServer;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormSshDriver.java
index 7c7ce24..76d5bfd 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormSshDriver.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/storm/StormSshDriver.java
@@ -34,8 +34,8 @@ import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
 import brooklyn.entity.zookeeper.ZooKeeperEnsemble;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java
index 3a6011b..4c0a73a 100644
--- a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java
+++ b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java
@@ -32,8 +32,7 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
-import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.Lists;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperSshDriver.java
index 445386b..2683682 100644
--- a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperSshDriver.java
+++ b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperSshDriver.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.api.entity.Entity;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java
index 3a1a6d0..fc58d6f 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java
@@ -34,7 +34,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java
index 59ae310..698bc5e 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java
@@ -20,7 +20,7 @@ package brooklyn.entity.messaging.activemq;
 
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java
index a879810..d156b4d 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java
@@ -46,7 +46,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.UsesJmx;
 import brooklyn.entity.java.UsesJmx.JmxAgentModes;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java
index a08cd1d..d568bd2 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java
@@ -35,9 +35,9 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.messaging.activemq.ActiveMQBroker;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java
index 96183b8..0656bc6 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java
index c584148..d3a860c 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java
@@ -23,7 +23,7 @@ import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java
index 74c07c1..7c5d262 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java
@@ -50,7 +50,7 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java
index 09820f1..7db574b 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java
@@ -30,7 +30,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.messaging.MessageBroker;
 import brooklyn.entity.messaging.amqp.AmqpExchange;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java
index f358c1e..d08eb97 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java
@@ -37,8 +37,8 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.messaging.MessageBroker;
 import brooklyn.entity.messaging.amqp.AmqpExchange;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
index 536e482..f18af02 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
@@ -50,7 +50,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.messaging.storm.topologies.ExclamationBolt;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperEnsemble;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java
index b587e00..35a83f4 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java
@@ -26,7 +26,7 @@ import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperNode;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java
index 1b08112..ccb8f5d 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java
@@ -26,7 +26,7 @@ import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperNode;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java
index a2ad585..42091fd 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java
@@ -24,7 +24,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperEnsemble;
 import brooklyn.entity.zookeeper.ZooKeeperNode;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
index 1cb3948..dd712c4 100644
--- a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
+++ b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
@@ -28,8 +28,8 @@ import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshPollValue;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.text.Strings;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java
index 0c22b67..28b8548 100644
--- a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java
+++ b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java
@@ -26,8 +26,8 @@ import java.util.Map;
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;
 import brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java b/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
index c72343c..4cb8e39 100644
--- a/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
+++ b/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
@@ -42,8 +42,8 @@ import brooklyn.entity.basic.SameServerEntity;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.database.mysql.MySqlNode;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.MachineDetails;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
index df12707..032a471 100644
--- a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
@@ -37,7 +37,7 @@ import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.net.Cidr;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
index f3013b1..94bcdda 100644
--- a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
@@ -57,8 +57,8 @@ import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.net.Cidr;
 import brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
index 09451c6..e4e3ea5 100644
--- a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSshDriver.java
@@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.net.Protocol;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java
index 8ea9ce6..a766dd1 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java
@@ -25,7 +25,7 @@ import org.testng.annotations.Parameters;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.text.Strings;
 
 public class BindDnsServerByonLiveTest extends BrooklynAppLiveTestSupport {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java
index b6f5b76..e9cbaff 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java
@@ -22,7 +22,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class BindDnsServerEc2LiveTest extends AbstractEc2LiveTest {
     private static final Logger LOG = LoggerFactory.getLogger(BindDnsServerEc2LiveTest.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java
index d62e25e..d73eb0c 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java
@@ -37,7 +37,7 @@ import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SameServerEntity;
 import brooklyn.entity.group.DynamicCluster;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.repeat.Repeater;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java
index 9cf7d8d..ffe391d 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.network.bind;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class BindDnsServerSoftlayerLiveTest extends AbstractSoftlayerLiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/DoNothingSoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/DoNothingSoftwareProcessDriver.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/DoNothingSoftwareProcessDriver.java
index 9603de7..c6c7fcc 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/DoNothingSoftwareProcessDriver.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/DoNothingSoftwareProcessDriver.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.network.bind;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 /**
  * Implements methods in {@link brooklyn.entity.basic.AbstractSoftwareProcessSshDriver}.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/TestBindDnsServerImpl.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/TestBindDnsServerImpl.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/TestBindDnsServerImpl.java
index faa806e..346b0aa 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/TestBindDnsServerImpl.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/TestBindDnsServerImpl.java
@@ -23,7 +23,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 public class TestBindDnsServerImpl extends BindDnsServerImpl {
 



[54/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
[BROOKLYN-162] Move ./api/location to the right package


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/d32d672a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/d32d672a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/d32d672a

Branch: refs/heads/master
Commit: d32d672ad66cda00adc92053e262595e6d00ace3
Parents: e2c5705
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Thu Aug 13 23:18:00 2015 -0400
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Thu Aug 13 23:18:00 2015 -0400

----------------------------------------------------------------------
 .../org/apache/brooklyn/api/entity/Entity.java  |   2 +-
 .../api/entity/drivers/EntityDriver.java        |   3 +-
 .../api/entity/drivers/EntityDriverManager.java |   2 +-
 .../api/entity/proxying/EntitySpec.java         |   2 +-
 .../api/entity/proxying/EntityTypeRegistry.java |   3 +-
 .../api/entity/rebind/BrooklynObjectType.java   |   3 +-
 .../entity/rebind/RebindExceptionHandler.java   |   3 +-
 .../api/location/AddressableLocation.java       |  43 ++++
 .../BasicMachineLocationCustomizer.java         |  41 ++++
 .../brooklyn/api/location/HardwareDetails.java  |  40 ++++
 .../apache/brooklyn/api/location/Location.java  | 146 ++++++++++++
 .../api/location/LocationDefinition.java        |  42 ++++
 .../location/LocationNotAvailableException.java |  35 +++
 .../brooklyn/api/location/LocationRegistry.java | 128 +++++++++++
 .../brooklyn/api/location/LocationResolver.java |  57 +++++
 .../brooklyn/api/location/LocationSpec.java     | 229 +++++++++++++++++++
 .../brooklyn/api/location/LocationType.java     |  32 +++
 .../brooklyn/api/location/MachineDetails.java   |  34 +++
 .../brooklyn/api/location/MachineLocation.java  |  46 ++++
 .../api/location/MachineLocationCustomizer.java |  42 ++++
 .../api/location/MachineManagementMixins.java   |  92 ++++++++
 .../location/MachineProvisioningLocation.java   |  72 ++++++
 .../location/NoMachinesAvailableException.java  |  35 +++
 .../apache/brooklyn/api/location/OsDetails.java |  46 ++++
 .../apache/brooklyn/api/location/PortRange.java |  48 ++++
 .../brooklyn/api/location/PortSupplier.java     |  50 ++++
 .../api/location/ProvisioningLocation.java      |  44 ++++
 .../api/management/AccessController.java        |   3 +-
 .../api/management/LocationManager.java         |   4 +-
 .../api/management/ManagementContext.java       |   2 +-
 .../brooklyn/location/AddressableLocation.java  |  43 ----
 .../BasicMachineLocationCustomizer.java         |  41 ----
 .../brooklyn/location/HardwareDetails.java      |  40 ----
 .../org/apache/brooklyn/location/Location.java  | 146 ------------
 .../brooklyn/location/LocationDefinition.java   |  42 ----
 .../location/LocationNotAvailableException.java |  35 ---
 .../brooklyn/location/LocationRegistry.java     | 128 -----------
 .../brooklyn/location/LocationResolver.java     |  57 -----
 .../apache/brooklyn/location/LocationSpec.java  | 229 -------------------
 .../apache/brooklyn/location/LocationType.java  |  32 ---
 .../brooklyn/location/MachineDetails.java       |  34 ---
 .../brooklyn/location/MachineLocation.java      |  46 ----
 .../location/MachineLocationCustomizer.java     |  42 ----
 .../location/MachineManagementMixins.java       |  92 --------
 .../location/MachineProvisioningLocation.java   |  72 ------
 .../location/NoMachinesAvailableException.java  |  35 ---
 .../org/apache/brooklyn/location/OsDetails.java |  46 ----
 .../org/apache/brooklyn/location/PortRange.java |  48 ----
 .../apache/brooklyn/location/PortSupplier.java  |  50 ----
 .../brooklyn/location/ProvisioningLocation.java |  44 ----
 .../mementos/BrooklynMementoPersister.java      |   2 +-
 .../main/java/brooklyn/basic/BrooklynTypes.java |   2 +-
 .../brooklyn/catalog/CatalogPredicates.java     |   4 +-
 .../catalog/internal/BasicBrooklynCatalog.java  |   6 +-
 .../catalog/internal/CatalogClasspathDo.java    |   2 +-
 .../internal/CatalogLocationItemDto.java        |   4 +-
 .../entity/basic/AbstractApplication.java       |   2 +-
 .../brooklyn/entity/basic/AbstractEntity.java   |   4 +-
 .../brooklyn/entity/basic/BasicStartable.java   |   3 +-
 .../entity/basic/BasicStartableImpl.java        |   2 +-
 .../entity/basic/BrooklynConfigKeys.java        |   4 +-
 .../brooklyn/entity/basic/DataEntityImpl.java   |   2 +-
 .../entity/basic/EffectorStartableImpl.java     |   4 +-
 .../java/brooklyn/entity/basic/Entities.java    |   6 +-
 .../entity/basic/EntityFactoryForLocation.java  |   3 +-
 .../brooklyn/entity/basic/EntityFunctions.java  |   2 +-
 .../brooklyn/entity/basic/EntityInternal.java   |   2 +-
 .../brooklyn/entity/basic/EntityPredicates.java |   2 +-
 .../basic/EntityTransientCopyInternal.java      |   2 +-
 .../java/brooklyn/entity/basic/Lifecycle.java   |   3 +-
 .../drivers/BasicEntityDriverManager.java       |   3 +-
 .../drivers/ReflectiveEntityDriverFactory.java  |   4 +-
 .../drivers/RegistryEntityDriverFactory.java    |   3 +-
 .../brooklyn/entity/group/DynamicCluster.java   |   2 +-
 .../entity/group/DynamicClusterImpl.java        |   6 +-
 .../entity/group/DynamicFabricImpl.java         |   2 +-
 .../entity/group/DynamicRegionsFabricImpl.java  |   2 +-
 .../zoneaware/AbstractZoneFailureDetector.java  |   2 +-
 .../BalancingNodePlacementStrategy.java         |   2 +-
 .../zoneaware/CombiningZoneFailureDetector.java |   2 +-
 .../CriticalCauseZoneFailureDetector.java       |   3 +-
 .../ProportionalZoneFailureDetector.java        |   3 +-
 .../proxying/InternalLocationFactory.java       |   6 +-
 .../entity/rebind/BasicEntityRebindSupport.java |   2 +-
 .../rebind/BasicLocationRebindSupport.java      |   4 +-
 .../rebind/ImmediateDeltaChangeListener.java    |   3 +-
 .../rebind/PeriodicDeltaChangeListener.java     |   2 +-
 .../entity/rebind/RebindContextImpl.java        |   2 +-
 .../rebind/RebindContextLookupContext.java      |   2 +-
 .../rebind/RebindExceptionHandlerImpl.java      |   2 +-
 .../brooklyn/entity/rebind/RebindIteration.java |   4 +-
 .../java/brooklyn/entity/rebind/TreeUtils.java  |   2 +-
 .../entity/rebind/dto/MementosGenerators.java   |   4 +-
 .../persister/BrooklynPersistenceUtils.java     |   6 +-
 .../rebind/persister/XmlMementoSerializer.java  |   2 +-
 .../java/brooklyn/entity/trait/Startable.java   |   2 +-
 .../brooklyn/entity/trait/StartableMethods.java |   2 +-
 .../basic/PortAttributeSensorAndConfigKey.java  |  10 +-
 .../ha/HighAvailabilityManagerImpl.java         |   2 +-
 .../internal/AbstractManagementContext.java     |   4 +-
 .../internal/BrooklynGarbageCollector.java      |   2 +-
 .../management/internal/LocalAccessManager.java |   3 +-
 .../internal/LocalLocationManager.java          |   8 +-
 .../internal/LocalManagementContext.java        |   2 +-
 .../management/internal/LocalUsageManager.java  |   4 +-
 .../internal/LocationManagerInternal.java       |   3 +-
 .../internal/ManagementContextInternal.java     |   2 +-
 .../internal/NonDeploymentLocationManager.java  |   5 +-
 .../NonDeploymentManagementContext.java         |   4 +-
 .../internal/NonDeploymentUsageManager.java     |   2 +-
 .../management/internal/UsageListener.java      |   2 +-
 .../management/internal/UsageManager.java       |   2 +-
 .../java/brooklyn/util/task/ssh/SshTasks.java   |   4 +-
 .../brooklyn/util/text/TemplateProcessor.java   |   2 +-
 .../location/access/BrooklynAccessUtils.java    |   6 +-
 .../location/access/PortForwardManager.java     |   4 +-
 .../access/PortForwardManagerClient.java        |   2 +-
 .../location/access/PortForwardManagerImpl.java |   2 +-
 .../PortForwardManagerLocationResolver.java     |   8 +-
 .../brooklyn/location/access/PortMapping.java   |   2 +-
 .../location/basic/AbstractLocation.java        |   6 +-
 .../basic/AbstractLocationResolver.java         |  10 +-
 .../AggregatingMachineProvisioningLocation.java |   7 +-
 .../location/basic/BasicHardwareDetails.java    |   2 +-
 .../location/basic/BasicLocationDefinition.java |   3 +-
 .../location/basic/BasicLocationRegistry.java   |  10 +-
 .../location/basic/BasicMachineDetails.java     |   6 +-
 .../location/basic/BasicMachineMetadata.java    |   3 +-
 .../brooklyn/location/basic/BasicOsDetails.java |   3 +-
 .../location/basic/ByonLocationResolver.java    |   8 +-
 .../location/basic/CatalogLocationResolver.java |   8 +-
 .../basic/DefinedLocationByIdResolver.java      |   8 +-
 .../FixedListMachineProvisioningLocation.java   |  14 +-
 .../location/basic/HostLocationResolver.java    |   7 +-
 .../basic/LocalhostLocationResolver.java        |   7 +-
 .../LocalhostMachineProvisioningLocation.java   |  10 +-
 .../location/basic/LocationDynamicType.java     |   5 +-
 .../location/basic/LocationInternal.java        |   2 +-
 .../location/basic/LocationPredicates.java      |   3 +-
 .../brooklyn/location/basic/Locations.java      |   6 +-
 .../brooklyn/location/basic/Machines.java       |   6 +-
 .../brooklyn/location/basic/MultiLocation.java  |  10 +-
 .../location/basic/MultiLocationResolver.java   |   8 +-
 .../location/basic/NamedLocationResolver.java   |   8 +-
 .../brooklyn/location/basic/PortRanges.java     |   3 +-
 .../basic/RegistryLocationResolver.java         |   6 +-
 .../basic/SingleMachineLocationResolver.java    |   7 +-
 .../SingleMachineProvisioningLocation.java      |   6 +-
 .../location/basic/SshMachineLocation.java      |  12 +-
 .../location/basic/WinRmMachineLocation.java    |   8 +-
 .../AbstractAvailabilityZoneExtension.java      |   3 +-
 ...bstractCloudMachineProvisioningLocation.java |   7 +-
 .../cloud/AvailabilityZoneExtension.java        |   3 +-
 .../location/cloud/CloudLocationConfig.java     |   4 +-
 .../location/cloud/names/CloudMachineNamer.java |   4 +-
 .../location/dynamic/DynamicLocation.java       |   2 +-
 .../location/dynamic/LocationOwner.java         |   4 +-
 .../brooklyn/location/geo/HostGeoInfo.java      |   4 +-
 .../brooklyn/location/paas/PaasLocation.java    |   2 +-
 ...pache.brooklyn.api.location.LocationResolver |  27 +++
 ...rg.apache.brooklyn.location.LocationResolver |   9 -
 .../enricher/CustomAggregatingEnricherTest.java |   4 +-
 .../brooklyn/entity/EffectorMetadataTest.java   |   2 +-
 .../java/brooklyn/entity/SetFromFlagTest.java   |   4 +-
 .../basic/AbstractApplicationLegacyTest.java    |   3 +-
 .../entity/basic/BasicStartableTest.java        |   5 +-
 .../brooklyn/entity/basic/DataEntityTest.java   |   4 +-
 .../brooklyn/entity/basic/EntitiesTest.java     |   4 +-
 .../entity/basic/EntityFunctionsTest.java       |   2 +-
 .../entity/basic/EntityLocationsTest.java       |   2 +-
 .../entity/basic/EntityPredicatesTest.java      |   2 +-
 .../entity/basic/EntitySuppliersTest.java       |   5 +-
 .../entity/basic/ServiceStateLogicTest.java     |   2 +-
 .../ReflectiveEntityDriverFactoryTest.java      |   4 +-
 .../RegistryEntityDriverFactoryTest.java        |   4 +-
 .../downloads/BasicDownloadsRegistryTest.java   |   4 +-
 .../DownloadProducerFromLocalRepoTest.java      |   4 +-
 .../DownloadProducerFromPropertiesTest.java     |   4 +-
 .../downloads/DownloadSubstitutersTest.java     |   3 +-
 .../drivers/downloads/MyEntityDriver.java       |   3 +-
 .../entity/group/DynamicClusterTest.java        |   4 +-
 ...DynamicClusterWithAvailabilityZonesTest.java |   6 +-
 .../entity/group/DynamicFabricTest.java         |   4 +-
 .../entity/group/DynamicRegionsFabricTest.java  |   4 +-
 .../java/brooklyn/entity/group/GroupTest.java   |   4 +-
 .../group/MembershipTrackingPolicyTest.java     |   4 +-
 .../entity/group/QuarantineGroupTest.java       |   3 +-
 .../BalancingNodePlacementStrategyTest.java     |   6 +-
 .../ProportionalZoneFailureDetectorTest.java    |   4 +-
 .../entity/rebind/RebindEnricherTest.java       |   4 +-
 .../entity/rebind/RebindEntityTest.java         |   6 +-
 .../brooklyn/entity/rebind/RebindFeedTest.java  |   4 +-
 .../rebind/RebindLocalhostLocationTest.java     |   3 +-
 .../entity/rebind/RebindLocationTest.java       |   6 +-
 .../entity/rebind/RebindPolicyTest.java         |   4 +-
 .../rebind/RebindSshMachineLocationTest.java    |   3 +-
 .../brooklyn/entity/rebind/RebindTestUtils.java |   2 +-
 .../rebind/RecordingRebindExceptionHandler.java |   3 +-
 .../BrooklynMementoPersisterTestFixture.java    |   6 +-
 .../persister/XmlMementoSerializerTest.java     |   4 +-
 .../entity/trait/FailingEntityImpl.java         |   2 +-
 .../event/feed/function/FunctionFeedTest.java   |   4 +-
 .../feed/http/HttpFeedIntegrationTest.java      |   4 +-
 .../brooklyn/event/feed/http/HttpFeedTest.java  |   2 +-
 .../WindowsPerformanceCounterFeedLiveTest.java  |   6 +-
 .../WindowsPerformanceCounterFeedTest.java      |   4 +-
 .../AcmeEntitlementManagerTestFixture.java      |   2 +-
 .../entitlement/EntityEntitlementTest.java      |   2 +-
 .../ha/HighAvailabilityManagerInMemoryTest.java |   6 +-
 .../HighAvailabilityManagerSplitBrainTest.java  |   2 +-
 .../brooklyn/management/ha/HotStandbyTest.java  |   6 +-
 .../brooklyn/management/ha/WarmStandbyTest.java |   2 +-
 .../management/internal/AccessManagerTest.java  |   6 +-
 .../internal/LocalManagementContextTest.java    |   2 +-
 .../longevity/EntityCleanupLongevityTest.java   |   4 +-
 .../EntityCleanupLongevityTestFixture.java      |   4 +-
 .../qa/longevity/EntityCleanupTest.java         |   4 +-
 .../EntityPersistencePerformanceTest.java       |   4 +-
 .../test/java/brooklyn/test/HttpService.java    |   5 +-
 .../brooklyn/util/task/ssh/SshTasksTest.java    |   4 +-
 .../PortForwardManagerLocationResolverTest.java |   2 +-
 .../access/PortForwardManagerRebindTest.java    |   6 +-
 .../location/access/PortForwardManagerTest.java |   4 +-
 .../location/basic/AbstractLocationTest.java    |   4 +-
 ...regatingMachineProvisioningLocationTest.java |  10 +-
 .../basic/ByonLocationResolverTest.java         |   6 +-
 ...stMachineProvisioningLocationRebindTest.java |   2 +-
 ...ixedListMachineProvisioningLocationTest.java |   6 +-
 .../basic/HostLocationResolverTest.java         |   2 +-
 .../basic/LocalhostLocationResolverTest.java    |   4 +-
 ...ocalhostMachineProvisioningLocationTest.java |  10 +-
 .../LocalhostProvisioningAndAccessTest.java     |   2 +-
 .../location/basic/LocationConfigTest.java      |   2 +-
 .../location/basic/LocationExtensionsTest.java  |   4 +-
 .../location/basic/LocationManagementTest.java  |   2 +-
 .../location/basic/LocationPredicatesTest.java  |   4 +-
 .../location/basic/LocationRegistryTest.java    |   4 +-
 .../location/basic/MachineDetailsTest.java      |   6 +-
 .../location/basic/MultiLocationRebindTest.java |   4 +-
 .../basic/MultiLocationResolverTest.java        |   8 +-
 .../location/basic/MultiLocationTest.java       |   6 +-
 .../brooklyn/location/basic/PortRangesTest.java |   2 +-
 .../RecordingMachineLocationCustomizer.java     |   4 +-
 .../location/basic/SimulatedLocation.java       |  17 +-
 .../SshMachineLocationReuseIntegrationTest.java |   4 +-
 .../location/basic/SshMachineLocationTest.java  |  10 +-
 .../brooklyn/location/geo/HostGeoInfoTest.java  |   2 +-
 .../test/entity/BlockingEntityImpl.java         |   2 +-
 .../test/entity/TestApplicationImpl.java        |   4 +-
 .../brooklyn/test/entity/TestEntityImpl.java    |   2 +-
 .../brooklyn/demo/CumulusRDFApplication.java    |   4 +-
 ...lusterDatabaseExampleAppIntegrationTest.java |   2 +-
 .../policy/os/AdvertiseWinrmLoginPolicy.java    |   4 +-
 .../brooklyn/policy/os/CreateUserPolicy.java    |   4 +-
 .../location/jclouds/BrooklynMachinePool.java   |   4 +-
 .../jclouds/JcloudsByonLocationResolver.java    |  10 +-
 .../location/jclouds/JcloudsLocation.java       |  12 +-
 .../jclouds/JcloudsLocationResolver.java        |   8 +-
 .../jclouds/JcloudsMachineLocation.java         |   3 +-
 .../jclouds/JcloudsSshMachineLocation.java      |   6 +-
 .../zone/AwsAvailabilityZoneExtension.java      |   3 +-
 ...pache.brooklyn.api.location.LocationResolver |  20 ++
 ...rg.apache.brooklyn.location.LocationResolver |   2 -
 .../os/AdvertiseWinrmLoginPolicyTest.java       |   3 +-
 .../policy/os/CreateUserPolicyLiveTest.java     |   8 +-
 .../policy/os/CreateUserPolicyTest.java         |   4 +-
 .../jclouds/BailOutJcloudsLocation.java         |   2 +-
 .../jclouds/JcloudsAddressesLiveTest.java       |   2 +-
 .../jclouds/JcloudsLocationMetadataTest.java    |   4 +-
 .../location/jclouds/JcloudsLocationTest.java   |  10 +-
 .../location/jclouds/JcloudsLoginLiveTest.java  |   4 +-
 .../location/jclouds/LiveTestEntity.java        |   7 +-
 .../jclouds/RebindJcloudsLocationLiveTest.java  |   2 +-
 ...loudsLocationUserLoginAndConfigLiveTest.java |   2 +-
 ...hineProvisioningLocationJcloudsLiveTest.java |   3 +-
 .../provider/AbstractJcloudsLocationTest.java   |   4 +-
 .../zone/AwsAvailabilityZoneExtensionTest.java  |   4 +-
 parent/pom.xml                                  |   1 -
 .../followthesun/DefaultFollowTheSunModel.java  |   3 +-
 .../policy/followthesun/FollowTheSunModel.java  |   2 +-
 .../followthesun/FollowTheSunParameters.java    |   3 +-
 .../policy/followthesun/FollowTheSunPolicy.java |   4 +-
 .../followthesun/FollowTheSunStrategy.java      |   2 +-
 .../loadbalancing/BalanceablePoolModel.java     |   2 +-
 .../policy/loadbalancing/BalancingStrategy.java |   3 +-
 .../DefaultBalanceablePoolModel.java            |   3 +-
 .../loadbalancing/LocationConstraint.java       |   2 +-
 .../autoscaling/AutoScalerPolicyRebindTest.java |   4 +-
 .../AbstractFollowTheSunPolicyTest.java         |   6 +-
 .../followthesun/FollowTheSunModelTest.java     |   4 +-
 .../FollowTheSunPolicySoakTest.java             |   4 +-
 .../followthesun/FollowTheSunPolicyTest.java    |   4 +-
 .../brooklyn/policy/ha/HaPolicyRebindTest.java  |   6 +-
 .../brooklyn/policy/ha/ServiceReplacerTest.java |   6 +-
 .../loadbalancing/MockContainerEntityImpl.java  |   2 +-
 .../basic/AbstractSoftwareProcessDriver.java    |   2 +-
 .../SameServerDriverLifecycleEffectorTasks.java |   8 +-
 .../brooklyn/entity/basic/SameServerEntity.java |   2 +-
 .../entity/basic/SameServerEntityImpl.java      |   2 +-
 .../brooklyn/entity/basic/SoftwareProcess.java  |   2 +-
 ...wareProcessDriverLifecycleEffectorTasks.java |   4 +-
 .../entity/basic/SoftwareProcessImpl.java       |  10 +-
 .../entity/chef/ChefLifecycleEffectorTasks.java |   4 +-
 .../main/java/brooklyn/entity/java/UsesJmx.java |   4 +-
 .../java/brooklyn/entity/pool/ServerPool.java   |   5 +-
 .../brooklyn/entity/pool/ServerPoolImpl.java    |  10 +-
 .../entity/pool/ServerPoolLocation.java         |   8 +-
 .../entity/pool/ServerPoolLocationResolver.java |   9 +-
 .../software/MachineLifecycleEffectorTasks.java |  14 +-
 .../software/ProvidesProvisioningFlags.java     |   3 +-
 .../entity/software/SshEffectorTasks.java       |   4 +-
 ...pache.brooklyn.api.location.LocationResolver |  19 ++
 ...rg.apache.brooklyn.location.LocationResolver |   1 -
 .../brooklyn/entity/AbstractEc2LiveTest.java    |   4 +-
 .../entity/AbstractGoogleComputeLiveTest.java   |   2 +-
 .../entity/AbstractSoftlayerLiveTest.java       |   2 +-
 .../entity/basic/SameServerEntityTest.java      |   3 +-
 .../basic/SoftwareProcessEntityLatchTest.java   |   4 +-
 .../basic/SoftwareProcessEntityRebindTest.java  |   8 +-
 .../entity/basic/SoftwareProcessEntityTest.java |   8 +-
 ...SoftwareProcessSshDriverIntegrationTest.java |   4 +-
 .../basic/SoftwareProcessSubclassTest.java      |   2 +-
 ...ftwareProcessAndChildrenIntegrationTest.java |   2 +-
 .../basic/lifecycle/NaiveScriptRunnerTest.java  |   4 +-
 .../basic/lifecycle/ScriptHelperTest.java       |   4 +-
 .../entity/brooklynnode/BrooklynNodeTest.java   |   4 +-
 .../entity/brooklynnode/MockBrooklynNode.java   |   2 +-
 .../brooklynnode/SameBrooklynNodeImpl.java      |   3 +-
 .../entity/chef/ChefLiveTestSupport.java        |   6 +-
 .../AbstractChefToyMySqlEntityLiveTest.java     |   3 +-
 .../brooklyn/entity/driver/MockSshDriver.java   |   3 +-
 ...rWithAvailabilityZonesMultiLocationTest.java |  10 +-
 .../brooklyn/entity/java/EntityPollingTest.java |   4 +-
 .../java/brooklyn/entity/java/JavaOptsTest.java |   6 +-
 ...SoftwareProcessSshDriverIntegrationTest.java |   6 +-
 .../machine/MachineEntityEc2LiveTest.java       |   2 +-
 .../entity/pool/AbstractServerPoolTest.java     |   8 +-
 .../entity/pool/ServerPoolLiveTest.java         |   2 +-
 .../pool/ServerPoolLocationResolverTest.java    |   6 +-
 .../brooklyn/entity/pool/ServerPoolTest.java    |   3 +-
 .../entity/software/AbstractDockerLiveTest.java |   2 +-
 .../entity/software/SoftwareEffectorTest.java   |   4 +-
 .../entity/software/SshEffectorTasksTest.java   |   4 +-
 .../software/http/HttpRequestSensorTest.java    |   2 +-
 .../mysql/AbstractToyMySqlEntityTest.java       |   6 +-
 .../mysql/DynamicToyMySqlEntityBuilder.java     |   6 +-
 .../software/ssh/SshCommandIntegrationTest.java |   4 +-
 .../PortAttributeSensorAndConfigKeyTest.java    |   3 +-
 .../event/feed/jmx/RebindJmxFeedTest.java       |   4 +-
 .../usage/ApplicationUsageTrackingTest.java     |   2 +-
 .../usage/LocationUsageTrackingTest.java        |   8 +-
 .../management/usage/UsageListenerTest.java     |   4 +-
 .../basic/MachineDetailsEc2LiveTest.java        |   6 +-
 .../MachineDetailsGoogleComputeLiveTest.java    |   6 +-
 .../basic/WinRmMachineLocationTest.java         |   2 +-
 .../database/mariadb/MariaDbSshDriver.java      |   4 +-
 .../entity/database/mysql/MySqlClusterImpl.java |   2 +-
 .../entity/database/mysql/MySqlSshDriver.java   |   4 +-
 .../postgresql/PostgreSqlSshDriver.java         |   4 +-
 .../database/mariadb/MariaDbLiveEc2Test.java    |   3 +-
 .../database/mysql/MySqlClusterLiveEc2Test.java |   3 +-
 .../mysql/MySqlClusterLiveSoftlayerTest.java    |   3 +-
 .../database/mysql/MySqlClusterTestHelper.java  |   2 +-
 .../entity/database/mysql/MySqlLiveEc2Test.java |   2 +-
 .../entity/database/mysql/MySqlLiveGceTest.java |   2 +-
 .../database/mysql/MysqlDockerLiveTest.java     |   2 +-
 .../postgresql/PostgreSqDockerLiveTest.java     |   2 +-
 .../database/postgresql/PostgreSqlChefTest.java |   4 +-
 .../postgresql/PostgreSqlEc2LiveTest.java       |   2 +-
 .../postgresql/PostgreSqlGceLiveTest.java       |   2 +-
 .../database/rubyrep/RubyRepEc2LiveTest.java    |   3 +-
 .../rubyrep/RubyRepIntegrationTest.java         |   4 +-
 .../rubyrep/RubyRepRackspaceLiveTest.java       |   4 +-
 .../messaging/kafka/KafkaClusterImpl.java       |   2 +-
 .../entity/zookeeper/ZooKeeperEnsembleImpl.java |   2 +-
 .../messaging/activemq/ActiveMQEc2LiveTest.java |   2 +-
 .../activemq/ActiveMQGoogleComputeLiveTest.java |   2 +-
 .../activemq/ActiveMQIntegrationTest.java       |   2 +-
 .../messaging/kafka/KafkaIntegrationTest.java   |   6 +-
 .../entity/messaging/kafka/KafkaLiveTest.java   |   2 +-
 .../entity/messaging/qpid/QpidEc2LiveTest.java  |   2 +-
 .../messaging/qpid/QpidIntegrationTest.java     |   2 +-
 .../messaging/rabbit/RabbitEc2LiveTest.java     |   2 +-
 .../messaging/rabbit/RabbitIntegrationTest.java |   3 +-
 .../storm/StormAbstractCloudLiveTest.java       |   2 +-
 .../messaging/storm/StormEc2LiveTest.java       |   2 +-
 .../zookeeper/ZooKeeperEc2LiveTest.java         |   2 +-
 .../zookeeper/ZooKeeperEnsembleLiveTest.java    |   2 +-
 .../entity/monitoring/monit/MonitNodeImpl.java  |   4 +-
 .../entity/monitoring/monit/MonitSshDriver.java |   4 +-
 .../monitoring/monit/MonitIntegrationTest.java  |   4 +-
 .../network/bind/BindDnsServerByonLiveTest.java |   4 +-
 .../network/bind/BindDnsServerEc2LiveTest.java  |   3 +-
 .../network/bind/BindDnsServerLiveTest.java     |   2 +-
 .../bind/BindDnsServerSoftlayerLiveTest.java    |   3 +-
 .../cassandra/CassandraDatacenterImpl.java      |   4 +-
 .../entity/nosql/cassandra/CassandraFabric.java |   2 +-
 .../nosql/cassandra/CassandraFabricImpl.java    |   2 +-
 .../nosql/cassandra/CassandraNodeImpl.java      |   6 +-
 .../nosql/cassandra/CassandraNodeSshDriver.java |   4 +-
 .../nosql/couchbase/CouchbaseNodeImpl.java      |   4 +-
 .../nosql/couchbase/CouchbaseNodeSshDriver.java |   4 +-
 .../CouchbaseSyncGatewaySshDriver.java          |   4 +-
 .../nosql/couchdb/CouchDBNodeSshDriver.java     |   4 +-
 .../nosql/mongodb/AbstractMongoDBSshDriver.java |   4 +-
 .../nosql/mongodb/MongoDBReplicaSetImpl.java    |   2 +-
 .../sharding/CoLocatedMongoDBRouterImpl.java    |   2 +-
 .../MongoDBConfigServerClusterImpl.java         |   2 +-
 .../sharding/MongoDBRouterClusterImpl.java      |   2 +-
 .../sharding/MongoDBShardClusterImpl.java       |   2 +-
 .../sharding/MongoDBShardedDeploymentImpl.java  |   2 +-
 .../entity/nosql/redis/RedisClusterImpl.java    |   2 +-
 .../entity/nosql/redis/RedisStoreImpl.java      |   5 +-
 .../entity/nosql/redis/RedisStoreSshDriver.java |   4 +-
 .../entity/nosql/riak/RiakNodeImpl.java         |   4 +-
 .../entity/nosql/riak/RiakNodeSshDriver.java    |   5 +-
 .../entity/nosql/solr/SolrServerSshDriver.java  |   5 +-
 .../cassandra/AbstractCassandraNodeTest.java    |   3 +-
 .../CassandraDatacenterIntegrationTest.java     |   2 +-
 .../cassandra/CassandraDatacenterLiveTest.java  |   2 +-
 .../cassandra/CassandraDatacenterTest.java      |   4 +-
 .../nosql/cassandra/CassandraFabricTest.java    |   6 +-
 .../cassandra/CassandraNodeEc2LiveTest.java     |   2 +-
 .../CouchbaseSyncGatewayEc2LiveTest.java        |   2 +-
 .../nosql/couchdb/AbstractCouchDBNodeTest.java  |   4 +-
 .../nosql/couchdb/CouchDBClusterLiveTest.java   |   2 +-
 .../nosql/couchdb/CouchDBNodeEc2LiveTest.java   |   2 +-
 .../ElasticSearchClusterIntegrationTest.java    |   2 +-
 .../ElasticSearchNodeIntegrationTest.java       |   4 +-
 .../nosql/mongodb/MongoDBEc2LiveTest.java       |   2 +-
 .../mongodb/MongoDBReplicaSetEc2LiveTest.java   |   2 +-
 .../nosql/mongodb/MongoDBSoftLayerLiveTest.java |   2 +-
 .../MongoDBShardedDeploymentEc2LiveTest.java    |   2 +-
 .../redis/RedisClusterIntegrationTest.java      |   4 +-
 .../entity/nosql/redis/RedisEc2LiveTest.java    |   2 +-
 .../nosql/redis/RedisIntegrationTest.java       |   4 +-
 .../nosql/riak/RiakClusterEc2LiveTest.java      |   2 +-
 .../entity/nosql/riak/RiakNodeEc2LiveTest.java  |   2 +-
 .../riak/RiakNodeGoogleComputeLiveTest.java     |   2 +-
 .../nosql/riak/RiakNodeSoftlayerLiveTest.java   |   2 +-
 .../nosql/solr/AbstractSolrServerTest.java      |   3 +-
 .../nosql/solr/SolrServerEc2LiveTest.java       |   2 +-
 .../osgi/karaf/KarafContainerEc2LiveTest.java   |   2 +-
 .../entity/osgi/karaf/KarafContainerTest.java   |   4 +-
 .../AbstractNonProvisionedControllerImpl.java   |   2 +-
 .../entity/proxy/nginx/NginxSshDriver.java      |   6 +-
 .../ControlledDynamicWebAppClusterImpl.java     |   2 +-
 .../entity/webapp/ElasticJavaWebAppService.java |   4 +-
 .../webapp/nodejs/NodeJsWebAppService.java      |   4 +-
 .../entity/dns/AbstractGeoDnsServiceTest.java   |  10 +-
 .../geoscaling/GeoscalingIntegrationTest.java   |   4 +-
 .../entity/proxy/AbstractControllerTest.java    |  12 +-
 .../brooklyn/entity/proxy/StubAppServer.java    |   8 +-
 .../brooklyn/entity/proxy/UrlMappingTest.java   |   4 +-
 .../nginx/NginxClusterIntegrationTest.java      |   4 +-
 .../entity/proxy/nginx/NginxEc2LiveTest.java    |   2 +-
 .../nginx/NginxHttpsSslIntegrationTest.java     |   4 +-
 .../proxy/nginx/NginxIntegrationTest.java       |   2 +-
 .../proxy/nginx/NginxRebindIntegrationTest.java |   4 +-
 .../nginx/NginxRebindWithHaIntegrationTest.java |   4 +-
 .../proxy/nginx/NginxWebClusterEc2LiveTest.java |   6 +-
 .../AbstractWebAppFixtureIntegrationTest.java   |   4 +-
 .../webapp/TomcatAutoScalerPolicyTest.java      |   4 +-
 .../webapp/WebAppConcurrentDeployTest.java      |   6 +-
 .../webapp/WebAppLiveIntegrationTest.groovy     |   2 +-
 .../jboss/JBoss6ServerAwsEc2LiveTest.java       |   2 +-
 .../jboss/JBoss7ServerAwsEc2LiveTest.java       |   2 +-
 .../jboss/JBoss7ServerDockerLiveTest.java       |   2 +-
 .../Jboss7ServerGoogleComputeLiveTest.java      |   2 +-
 .../webapp/nodejs/NodeJsWebAppEc2LiveTest.java  |   2 +-
 .../NodeJsWebAppFixtureIntegrationTest.java     |   4 +-
 .../NodeJsWebAppSimpleIntegrationTest.java      |   4 +-
 .../nodejs/NodeJsWebAppSoftlayerLiveTest.java   |   2 +-
 .../webapp/tomcat/Tomcat8ServerEc2LiveTest.java |   2 +-
 .../tomcat/Tomcat8ServerSoftlayerLiveTest.java  |   2 +-
 .../webapp/tomcat/TomcatServerEc2LiveTest.java  |   2 +-
 .../tomcat/TomcatServerSoftlayerLiveTest.java   |   2 +-
 .../test/entity/TestJavaWebAppEntity.java       |   2 +-
 .../BrooklynComponentTemplateResolver.java      |   2 +-
 .../creation/BrooklynYamlLocationResolver.java  |   4 +-
 .../camp/brooklyn/ByonLocationsYamlTest.java    |   4 +-
 .../brooklyn/EmptySoftwareProcessYamlTest.java  |   4 +-
 .../camp/brooklyn/EntitiesYamlTest.java         |   2 +-
 .../camp/brooklyn/LocationsYamlTest.java        |   6 +-
 .../brooklyn/TestEntityWithInitConfigImpl.java  |   2 +-
 .../CatalogOsgiVersionMoreEntityTest.java       |   2 +-
 .../catalog/CatalogYamlLocationTest.java        |   8 +-
 .../org/apache/brooklyn/cli/CloudExplorer.java  |   6 +-
 .../org/apache/brooklyn/cli/ItemLister.java     |   4 +-
 .../brooklyn/cli/lister/ItemDescriptors.java    |   2 +-
 .../java/org/apache/brooklyn/cli/CliTest.java   |   4 +-
 .../brooklyn/launcher/BrooklynLauncher.java     |   8 +-
 .../brooklyn/launcher/BrooklynWebServer.java    |   4 +-
 .../brooklynnode/BrooklynNodeRestTest.java      |   2 +-
 .../BrooklynLauncherRebindTestFixture.java      |   2 +-
 .../brooklyn/launcher/BrooklynLauncherTest.java |   4 +-
 .../SoftlayerObtainPrivateLiveTest.java         |   4 +-
 .../org/apache/brooklyn/qa/load/LoadTest.java   |   2 +-
 .../apache/brooklyn/rest/BrooklynWebConfig.java |   3 +-
 .../rest/resources/ApplicationResource.java     |   2 +-
 .../rest/resources/CatalogResource.java         |   4 +-
 .../brooklyn/rest/resources/EntityResource.java |   2 +-
 .../rest/resources/LocationResource.java        |   6 +-
 .../rest/transform/ApplicationTransformer.java  |   2 +-
 .../rest/transform/CatalogTransformer.java      |   4 +-
 .../rest/transform/LocationTransformer.java     |   6 +-
 .../rest/util/BrooklynRestResourceUtils.java    |   4 +-
 .../brooklyn/rest/util/EntityLocationUtils.java |   3 +-
 .../rest/util/json/BidiSerialization.java       |   3 +-
 .../rest/resources/LocationResourceTest.java    |   3 +-
 .../rest/resources/ScriptResourceTest.java      |   2 +-
 .../rest/resources/UsageResourceTest.java       |   9 +-
 .../rest/testing/BrooklynRestApiTest.java       |   4 +-
 .../rest/util/EntityLocationUtilsTest.java      |   4 +-
 514 files changed, 2456 insertions(+), 2054 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java b/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java
index 844996a..0918d14 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/Entity.java
@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.EnricherSpec;
@@ -34,7 +35,6 @@ import org.apache.brooklyn.policy.PolicySpec;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.guava.Maybe;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java
index 7ba0966..6a5ebd2 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriver.java
@@ -19,8 +19,7 @@
 package org.apache.brooklyn.api.entity.drivers;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.annotations.Beta;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java
index fe7134b..b2ad37e 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/drivers/EntityDriverManager.java
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.api.entity.drivers;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * Responsible for creating a driver for a given entity/location. Also used for customizing which 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java b/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java
index 5af103a..7a0d351 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntitySpec.java
@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
 import org.apache.brooklyn.api.basic.AbstractBrooklynObjectSpec;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.EnricherSpec;
@@ -40,7 +41,6 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 
 import com.google.common.base.Supplier;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java b/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java
index 5b55a54..76f5c54 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/proxying/EntityTypeRegistry.java
@@ -21,8 +21,7 @@ package org.apache.brooklyn.api.entity.proxying;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * A registry of the entity implementations to be used when creating an entity of a given type.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java b/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java
index 74f10ff..b4a120e 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/rebind/BrooklynObjectType.java
@@ -22,11 +22,10 @@ import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Feed;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import org.apache.brooklyn.location.Location;
-
 import com.google.common.annotations.Beta;
 import com.google.common.base.CaseFormat;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java b/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java
index 4b613c3..24e5997 100644
--- a/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java
+++ b/api/src/main/java/org/apache/brooklyn/api/entity/rebind/RebindExceptionHandler.java
@@ -25,11 +25,10 @@ import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.Policy;
 
-import org.apache.brooklyn.location.Location;
-
 import com.google.common.annotations.Beta;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/AddressableLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/AddressableLocation.java b/api/src/main/java/org/apache/brooklyn/api/location/AddressableLocation.java
new file mode 100644
index 0000000..31c3b29
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/AddressableLocation.java
@@ -0,0 +1,43 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import java.net.InetAddress;
+
+/** A location that has an IP address.
+ * <p>
+ * This IP address may be a machine (usually the MachineLocation sub-interface), 
+ * or often an entry point for a service.
+ */
+public interface AddressableLocation extends Location {
+
+    /**
+     * Return the single most appropriate address for this location.
+     * (An implementation or sub-interface definition may supply more information
+     * on the precise semantics of the address.)
+     * 
+     * Should not return null, but in some "special cases" (e.g. CloudFoundryLocation it
+     * may return null if the location is not configured correctly). Users should expect
+     * a non-null result and treat null as a programming error or misconfiguration. 
+     * Implementors of this interface should strive to not return null (and then we'll
+     * remove this caveat from the javadoc!).
+     */
+    InetAddress getAddress();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/BasicMachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/BasicMachineLocationCustomizer.java b/api/src/main/java/org/apache/brooklyn/api/location/BasicMachineLocationCustomizer.java
new file mode 100644
index 0000000..99d4fee
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/BasicMachineLocationCustomizer.java
@@ -0,0 +1,41 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * A default no-op implementation, which can be extended to override the appropriate methods.
+ * 
+ * Sub-classing will give the user some protection against future API changes - note that 
+ * {@link MachineLocationCustomizer} is marked {@link Beta}.
+ */
+@Beta
+public class BasicMachineLocationCustomizer implements MachineLocationCustomizer {
+
+    @Override
+    public void customize(MachineLocation machine) {
+        // no-op
+    }
+    
+    @Override
+    public void preRelease(MachineLocation machine) {
+        // no-op
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/HardwareDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/HardwareDetails.java b/api/src/main/java/org/apache/brooklyn/api/location/HardwareDetails.java
new file mode 100644
index 0000000..7e4cc49
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/HardwareDetails.java
@@ -0,0 +1,40 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import javax.annotation.Nullable;
+
+/**
+ * @since 0.7.0
+ */
+public interface HardwareDetails {
+
+    /**
+     * The number of CPUs on the machine
+     */
+    @Nullable
+    Integer getCpuCount();
+
+    /**
+     * Amount of RAM in megabytes
+     */
+    @Nullable
+    Integer getRam();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/Location.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/Location.java b/api/src/main/java/org/apache/brooklyn/api/location/Location.java
new file mode 100644
index 0000000..0d05556
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/Location.java
@@ -0,0 +1,146 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.brooklyn.api.basic.BrooklynObject;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+
+/**
+ * A location that an entity can be in. Examples of locations include a single machine
+ * or a pool of machines, or a region within a given cloud. 
+ * 
+ * See {@link brooklyn.entity.trait.Startable#start(Collection)}.
+ * 
+ * Locations may not be {@link Serializable} in subsequent releases!
+ */
+public interface Location extends Serializable, BrooklynObject {
+
+    /**
+     * A unique id for this location.
+     */
+    @Override
+    String getId();
+
+    /**
+     * Get the name assigned to this location.
+     *
+     * @return the name assigned to the location.
+     * @since 0.6 (previously getName())
+     */
+    @Override
+    String getDisplayName();
+
+    /**
+     * Get the 'parent' of this location. Locations are organized into a tree hierarchy, and this method will return a reference
+     * to the parent of this location, or {@code null} if this location is the tree root.
+     *
+     * @return a reference to the parent of this location, or {@code null} if this location is the tree root.
+     * @since 0.6 (previously getParentLocation())
+     */
+    Location getParent();
+
+    /**
+     * Get the 'children' of this location. Locations are organized into a tree hierarchy, and this method will return a
+     * collection containing the children of this location. This collection is an unmodifiable view of the data.
+     *
+     * @return a collection containing the children of this location.
+     * @since 0.6 (previously getChildLocations())
+     */
+    Collection<Location> getChildren();
+
+    /**
+     * Set the 'parent' of this location. If this location was previously a child of a different location, it is removed from
+     * the other location first. It is valid to pass in {@code null} to indicate that the location should be disconnected
+     * from its parent.
+     * 
+     * Adds this location as a child of the new parent (see {@code getChildLocations()}).
+     *
+     * @param newParent the new parent location object, or {@code null} to clear the parent reference.
+     * @since 0.6 (previously setParentLocation(Location))
+     */
+    void setParent(Location newParent);
+
+    /**
+     * @return meta-data about the location (usually a long line, or a small number of lines).
+     * 
+     * @since 0.6
+     */
+    String toVerboseString();
+    
+    /**
+     * Answers true if this location equals or is an ancestor of the given location.
+     */
+    boolean containsLocation(Location potentialDescendent);
+
+    /** 
+     * Returns configuration set at this location or inherited or default.
+     * 
+     * Convenience method for {@code config().get(key)}
+     */
+    <T> T getConfig(ConfigKey<T> key);
+
+    /**
+     * Convenience method for {@code config().get(key)}
+     * 
+     * @see {@link #getConfig(ConfigKey)}
+     */
+    <T> T getConfig(HasConfigKey<T> key);
+
+    /** 
+     * True iff the indication config key is set, either inherited (second argument true) or locally-only (second argument false).
+     * 
+     * @deprecated since 0.7.0; use {@link #config()}, such as {@code ((LocationInternal)location).config().getRaw(key).isPresent()}
+     */
+    @Deprecated
+    boolean hasConfig(ConfigKey<?> key, boolean includeInherited);
+
+    /** 
+     * Returns all config set, either inherited (argument true) or locally-only (argument false).
+     * 
+     * @deprecated since 0.7.0; use {@link #config()}, such as {@code policy.config().getBag()}
+     */
+    @Deprecated
+    public Map<String,Object> getAllConfig(boolean includeInherited);
+    
+    /**
+     * Whether this location has support for the given extension type.
+     * See additional comments in {@link #getExtension(Class)}.
+     * 
+     * @throws NullPointerException if extensionType is null
+     */
+    boolean hasExtension(Class<?> extensionType);
+
+    /**
+     * Returns an extension of the given type. Note that the type must be an exact match for
+     * how the extension was registered (e.g. {@code getExtension(Object.class)} will not match
+     * anything, even though registered extension extend {@link Object}.
+     * <p>
+     * This will not look at extensions of {@link #getParent()}.
+     * 
+     * @throws IllegalArgumentException if this location does not support the given extension type
+     * @throws NullPointerException if extensionType is null
+     */
+    <T> T getExtension(Class<T> extensionType);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java
new file mode 100644
index 0000000..000d883
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationDefinition.java
@@ -0,0 +1,42 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+
+/**
+ * Defines a location, where the {@link #getSpec()} is like a serialized representation
+ * of the location so that Brooklyn can create a corresponding location.
+ * 
+ * Examples include a complete description (e.g. giving a list of machines in a pool), or
+ * a name that matches a named location defined in the brooklyn poperties.
+ * 
+ * Users are not expected to implement this, or to use the interface directly. See
+ * {@link LocationRegistry#resolve(String)} and {@link ManagementContext#getLocationRegistry()}.
+ */
+public interface LocationDefinition {
+
+    public String getId();
+    public String getName();
+    public String getSpec();
+    public Map<String,Object> getConfig();
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/LocationNotAvailableException.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationNotAvailableException.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationNotAvailableException.java
new file mode 100644
index 0000000..de1c09d
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationNotAvailableException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+
+/**
+ * Indicates that a {@link ProvisioningLocation} is not able to provision a requested location
+ */
+public class LocationNotAvailableException extends Exception {
+    private static final long serialVersionUID = 1079817235289265761L;
+    
+    public LocationNotAvailableException(String s) {
+        super(s);
+    }
+
+    public LocationNotAvailableException(String s, Throwable throwable) {
+        super(s, throwable);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java
new file mode 100644
index 0000000..b3c3e5a
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationRegistry.java
@@ -0,0 +1,128 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.annotation.Nullable;
+
+import brooklyn.util.guava.Maybe;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * The registry of the sorts of locations that brooklyn knows about. Given a
+ * {@LocationDefinition} or a {@link String} representation of a spec, this can
+ * be used to create a {@link Location} instance.
+ */
+@SuppressWarnings("rawtypes")
+public interface LocationRegistry {
+
+    /** map of ID (possibly randomly generated) to the definition (spec, name, id, and props; 
+     * where spec is the spec as defined, for instance possibly another named:xxx location) */
+    public Map<String,LocationDefinition> getDefinedLocations();
+    
+    /** returns a LocationDefinition given its ID (usually a random string), or null if none */
+    public LocationDefinition getDefinedLocationById(String id);
+    
+    /** returns a LocationDefinition given its name (e.g. for named locations, supply the bit after the "named:" prefix), 
+     * or null if none */
+    public LocationDefinition getDefinedLocationByName(String name);
+
+    /** adds or updates the given defined location */
+    public void updateDefinedLocation(LocationDefinition l);
+
+    /** removes the defined location from the registry (applications running there are unaffected) */
+    public void removeDefinedLocation(String id);
+
+    /** Returns a fully populated (config etc) location from the given definition, with optional add'l flags.
+     * the location will be managed by default, unless the manage parameter is false, 
+     * or the manage parameter is null and the CREATE_UNMANAGED flag is set.
+     * <p>
+     * The manage parameter is {@link Boolean} so that null can be used to say rely on anything in the flags.
+     * 
+     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
+    @Beta
+    public Maybe<Location> resolve(LocationDefinition ld, Boolean manage, Map locationFlags);
+    
+    /** As {@link #resolve(LocationDefinition, Boolean, Map), with the location managed, and no additional flags,
+     * unwrapping the result (throwing if not resolvable) */
+    public Location resolve(LocationDefinition l);
+
+    /** Returns a location created from the given spec, which might correspond to a definition, or created on-the-fly.
+     * Optional flags can be passed through to underlying the location. 
+     * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
+    @Beta
+    public Maybe<Location> resolve(String spec, Boolean manage, Map locationFlags);
+    
+    /** efficiently returns for inspection only a fully populated (config etc) location from the given definition; 
+     * the value might be unmanaged so it is not meant for any use other than inspection,
+     * but callers should prefer this when they don't wish to create a new location which will be managed in perpetuity!
+     * 
+     * @deprecated since 0.7.0, use {@link #resolve(LocationDefinition, Boolean, Map)} */
+    @Deprecated
+    public Location resolveForPeeking(LocationDefinition l);
+
+    /** returns fully populated (config etc) location from the given definition, with overrides;
+     * @deprecated since 0.7.0, use {@link #resolve(LocationDefinition, Boolean, Map)} */
+    @Deprecated
+    public Location resolve(LocationDefinition l, Map<?,?> locationFlags);
+    
+    /** See {@link #resolve(String, Boolean, Map)}; asks for the location to be managed, and supplies no additional flags,
+     * and unwraps the result (throwing if the spec cannot be resolve) */
+    public Location resolve(String spec);
+    
+    /** Returns true/false depending whether spec seems like a valid location,
+     * that is it has a chance of being resolved (depending on the spec) but NOT guaranteed,
+     * as it is not passed to the spec;
+     * see {@link #resolve(String, Boolean, Map)} which has stronger guarantees 
+     * @deprecated since 0.7.0, not really needed, and semantics are weak; use {@link #resolve(String, Boolean, Map)} */
+    @Deprecated
+    public boolean canMaybeResolve(String spec);
+    
+    /** As {@link #resolve(String, Boolean, Map)}, but unwrapped
+     * @throws NoSuchElementException if the spec cannot be resolved */
+    public Location resolve(String spec, @Nullable Map locationFlags);
+    
+    /** as {@link #resolve(String)} but returning null (never throwing)
+     * @deprecated since 0.7.0 use {@link #resolve(String, Boolean, Map)} */
+    @Deprecated
+    public Location resolveIfPossible(String spec);
+
+    /**
+     * As {@link #resolve(String)} but takes collections (of strings or locations)
+     * <p>
+     * Expects a collection of elements being individual location spec strings or locations, 
+     * and returns a list of resolved (newly created and managed) locations.
+     * <p>
+     * From 0.7.0 this no longer flattens lists (nested lists are disallowed) 
+     * or parses comma-separated elements (they are resolved as-is)
+     */
+    public List<Location> resolve(Iterable<?> spec);
+    
+    /** Takes a string, interpreted as a comma-separated (or JSON style, when you need internal double quotes or commas) list;
+     * or a list, passed to {@link #resolve(Iterable)}; or null/empty (empty list),
+     * and returns a list of resolved (created and managed) locations */
+    public List<Location> resolveList(Object specList);
+    
+    public Map getProperties();
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java
new file mode 100644
index 0000000..0da6175
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationResolver.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.api.location;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Provides a way of creating location instances of a particular type.
+ */
+public interface LocationResolver {
+
+    void init(ManagementContext managementContext);
+    
+    /** the prefix that this resolver will attend to */
+    String getPrefix();
+    
+    /** whether the spec is something which should be passed to this resolver */
+    boolean accepts(String spec, LocationRegistry registry);
+
+    /**
+     * Similar to {@link #newLocationFromString(Map, String)} 
+     * but passing in a reference to the registry itself (from which the base properties are discovered)
+     * and including flags (e.g. user, key, cloud credential) which are known to be for this location.
+     * <p>
+     * introduced to support locations which refer to other locations, e.g. NamedLocationResolver  
+     **/ 
+    @SuppressWarnings("rawtypes")
+    Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry);
+
+    /** @since 0.7.0 exploring this as a mechanism to disable locations */
+    @Beta
+    public interface EnableableLocationResolver extends LocationResolver {
+        /** whether the location is enabled */
+        boolean isEnabled();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/LocationSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationSpec.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationSpec.java
new file mode 100644
index 0000000..8164ab0
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationSpec.java
@@ -0,0 +1,229 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.brooklyn.api.basic.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.management.Task;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+
+import com.google.common.collect.Maps;
+
+/**
+ * Gives details of a location to be created. It describes the location's configuration, and is
+ * reusable to create multiple locations with the same configuration.
+ * 
+ * To create a LocationSpec, it is strongly encouraged to use {@code create(...)} methods.
+ * 
+ * @param <T> The type of location to be created
+ * 
+ * @author aled
+ */
+public class LocationSpec<T extends Location> extends AbstractBrooklynObjectSpec<T,LocationSpec<T>> {
+
+    // TODO Would like to add `configure(ConfigBag)`, but `ConfigBag` is in core rather than api
+    
+    private static final Logger log = LoggerFactory.getLogger(LocationSpec.class);
+
+    private final static long serialVersionUID = 1L;
+
+    /**
+     * Creates a new {@link LocationSpec} instance for a location of the given type. The returned 
+     * {@link LocationSpec} can then be customized.
+     * 
+     * @param type A {@link Location} class
+     */
+    public static <T extends Location> LocationSpec<T> create(Class<T> type) {
+        return new LocationSpec<T>(type);
+    }
+    
+    /**
+     * Creates a new {@link LocationSpec} instance with the given config, for a location of the given type.
+     * 
+     * This is primarily for groovy code; equivalent to {@code LocationSpec.create(type).configure(config)}.
+     * 
+     * @param config The spec's configuration (see {@link LocationSpec#configure(Map)}).
+     * @param type   A {@link Location} class
+     */
+    public static <T extends Location> LocationSpec<T> create(Map<?,?> config, Class<T> type) {
+        return LocationSpec.create(type).configure(config);
+    }
+    
+    /**
+     * Copies entity spec so its configuration can be overridden without modifying the 
+     * original entity spec.
+     */
+    public static <T extends Location> LocationSpec<T> create(LocationSpec<T> spec) {
+        // need this to get LocationSpec<T> rather than LocationSpec<? extends T>
+        @SuppressWarnings("unchecked")
+        Class<T> exactType = (Class<T>)spec.getType();
+        
+        LocationSpec<T> result = create(exactType)
+                .displayName(spec.getDisplayName())
+                .tags(spec.getTags())
+                .configure(spec.getConfig())
+                .configure(spec.getFlags())
+                .catalogItemId(spec.getCatalogItemId())
+                .extensions(spec.getExtensions());
+        
+        if (spec.getParent() != null) result.parent(spec.getParent());
+        
+        return (LocationSpec<T>) result;
+    }
+
+    private String id;
+    private Location parent;
+    private final Map<String, Object> flags = Maps.newLinkedHashMap();
+    private final Map<ConfigKey<?>, Object> config = Maps.newLinkedHashMap();
+    private final Map<Class<?>, Object> extensions = Maps.newLinkedHashMap();
+
+    protected LocationSpec(Class<T> type) {
+        super(type);
+    }
+     
+    protected void checkValidType(Class<? extends T> type) {
+        checkIsImplementation(type, Location.class);
+        checkIsNewStyleImplementation(type);
+    }
+
+    /**
+     * @deprecated since 0.7.0; instead let the management context pick a random+unique id
+     */
+    @Deprecated
+    public LocationSpec<T> id(String val) {
+        id = val;
+        return this;
+    }
+
+    public LocationSpec<T> parent(Location val) {
+        parent = checkNotNull(val, "parent");
+        return this;
+    }
+
+    public LocationSpec<T> configure(Map<?,?> val) {
+        for (Map.Entry<?, ?> entry: val.entrySet()) {
+            if (entry.getKey()==null) throw new NullPointerException("Null key not permitted");
+            if (entry.getKey() instanceof CharSequence)
+                flags.put(entry.getKey().toString(), entry.getValue());
+            else if (entry.getKey() instanceof ConfigKey<?>)
+                config.put((ConfigKey<?>)entry.getKey(), entry.getValue());
+            else if (entry.getKey() instanceof HasConfigKey<?>)
+                config.put(((HasConfigKey<?>)entry.getKey()).getConfigKey(), entry.getValue());
+            else {
+                log.warn("Spec "+this+" ignoring unknown config key "+entry.getKey());
+            }
+        }
+        return this;
+    }
+    
+    public LocationSpec<T> configure(CharSequence key, Object val) {
+        flags.put(checkNotNull(key, "key").toString(), val);
+        return this;
+    }
+    
+    public <V> LocationSpec<T> configure(ConfigKey<V> key, V val) {
+        config.put(checkNotNull(key, "key"), val);
+        return this;
+    }
+
+    public <V> LocationSpec<T> configureIfNotNull(ConfigKey<V> key, V val) {
+        return (val != null) ? configure(key, val) : this;
+    }
+
+    public <V> LocationSpec<T> configure(ConfigKey<V> key, Task<? extends V> val) {
+        config.put(checkNotNull(key, "key"), val);
+        return this;
+    }
+
+    public <V> LocationSpec<T> configure(HasConfigKey<V> key, V val) {
+        config.put(checkNotNull(key, "key").getConfigKey(), val);
+        return this;
+    }
+
+    public <V> LocationSpec<T> configure(HasConfigKey<V> key, Task<? extends V> val) {
+        config.put(checkNotNull(key, "key").getConfigKey(), val);
+        return this;
+    }
+
+    public <V> LocationSpec<T> removeConfig(ConfigKey<V> key) {
+        config.remove( checkNotNull(key, "key") );
+        return this;
+    }
+
+    public <E> LocationSpec<T> extension(Class<E> extensionType, E extension) {
+        extensions.put(checkNotNull(extensionType, "extensionType"), checkNotNull(extension, "extension"));
+        return this;
+    }
+    
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public <E> LocationSpec<T> extensions(Map<Class<?>, ?> extensions) {
+        for (Map.Entry<Class<?>, ?> entry : extensions.entrySet()) {
+            extension((Class)entry.getKey(), entry.getValue());
+        }
+        return this;
+    }
+    
+    /**
+     * @return The id of the location to be created, or null if brooklyn can auto-generate an id
+     * 
+     * @deprecated since 0.7.0; instead let the management context pick a random+unique id
+     */
+    @Deprecated
+    public String getId() {
+        return id;
+    }
+    
+    /**
+     * @return The location's parent
+     */
+    public Location getParent() {
+        return parent;
+    }
+    
+    /**
+     * @return Read-only construction flags
+     * @see SetFromFlag declarations on the location type
+     */
+    public Map<String, ?> getFlags() {
+        return Collections.unmodifiableMap(flags);
+    }
+    
+    /**
+     * @return Read-only configuration values
+     */
+    public Map<ConfigKey<?>, Object> getConfig() {
+        return Collections.unmodifiableMap(config);
+    }
+        
+    /**
+     * @return Read-only extension values
+     */
+    public Map<Class<?>, Object> getExtensions() {
+        return Collections.unmodifiableMap(extensions);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/LocationType.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/LocationType.java b/api/src/main/java/org/apache/brooklyn/api/location/LocationType.java
new file mode 100644
index 0000000..dd895e3
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/LocationType.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.api.location;
+
+import org.apache.brooklyn.api.basic.BrooklynType;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Gives type information for a {@link Location}. It is immutable.
+ 
+ * @since 0.7.0
+ */
+@Beta
+public interface LocationType extends BrooklynType {
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/MachineDetails.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/MachineDetails.java b/api/src/main/java/org/apache/brooklyn/api/location/MachineDetails.java
new file mode 100644
index 0000000..ae8b1c2
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/MachineDetails.java
@@ -0,0 +1,34 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import javax.annotation.Nonnull;
+
+/**
+ * @since 0.7.0
+ */
+public interface MachineDetails {
+
+    @Nonnull
+    HardwareDetails getHardwareDetails();
+
+    @Nonnull
+    OsDetails getOsDetails();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/MachineLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/MachineLocation.java b/api/src/main/java/org/apache/brooklyn/api/location/MachineLocation.java
new file mode 100644
index 0000000..44c8e23
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/MachineLocation.java
@@ -0,0 +1,46 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import java.net.InetAddress;
+
+import brooklyn.util.net.HasNetworkAddresses;
+
+/**
+ * A location that is a machine.
+ *
+ * This interface marks a {@link Location} being a network node with an IP address, 
+ * and supports appropriate operations on the node.
+ */
+public interface MachineLocation extends AddressableLocation, HasNetworkAddresses {
+    /**
+     * @return the machine's network address.
+     */
+    InetAddress getAddress();
+
+    /** @deprecated since 0.7.0. Use getMachineDetails().getOsDetails() instead. */
+    @Deprecated
+    OsDetails getOsDetails();
+
+    /*
+     * @return hardware and operating system-specific details for the machine.
+     */
+    MachineDetails getMachineDetails();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/MachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/MachineLocationCustomizer.java b/api/src/main/java/org/apache/brooklyn/api/location/MachineLocationCustomizer.java
new file mode 100644
index 0000000..a9b4e2e
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/MachineLocationCustomizer.java
@@ -0,0 +1,42 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Customization hooks to allow apps to perform specific customisation of obtained machines.
+ * <p>
+ * Users are strongly encouraged to sub-class {@link BasicMachineLocationCustomizer}, to give
+ * some protection against this {@link Beta} API changing in future releases.
+ */
+@Beta
+public interface MachineLocationCustomizer {
+
+    /**
+     * Override to configure the given machine once it has been created (prior to any use).
+     */
+    void customize(MachineLocation machine);
+    
+    /**
+     * Override to handle machine-related cleanup prior to {@link MachineProvisioningLocation} 
+     * releasing the machine.
+     */
+    void preRelease(MachineLocation machine);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java b/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java
new file mode 100644
index 0000000..b91aeb8
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/MachineManagementMixins.java
@@ -0,0 +1,92 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import java.util.Map;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Defines mixins for interesting locations.
+ */
+public class MachineManagementMixins {
+    
+    public interface RichMachineProvisioningLocation<T extends MachineLocation> extends
+            MachineProvisioningLocation<T>, ListsMachines, GivesMachineMetadata, KillsMachines {}
+
+    public interface ListsMachines {
+        /**
+         * @return A map of machine ID to metadata record for all machines known in a given cloud location.
+         */
+        Map<String,MachineMetadata> listMachines();
+    }
+    
+    public interface GivesMachineMetadata {
+        /**
+         * @return the {@link MachineMetadata} for a given (brooklyn) machine location instance,
+         * or null if not matched.
+         */
+        MachineMetadata getMachineMetadata(MachineLocation location);
+    }
+    
+    public interface KillsMachines {
+        /** Kills the indicated machine; throws if not recognised or possible */
+        void killMachine(MachineLocation machine);
+        
+        /** Kills the machine indicated by the given (server-side) machine id;
+         *  note, the ID is the _cloud-service_ ID,
+         *  that is, pass in getMetadata(machineLocation).getId() not the machineLocation.getId() */
+        void killMachine(String cloudServiceId);
+    }
+    
+    /** very lightweight machine record */
+    public interface MachineMetadata {
+        /** The cloud service ID -- distinct from any Brooklyn {@link Location#getId()} */
+        String getId();
+        String getName();
+        String getPrimaryIp();
+        Boolean isRunning();
+        /** original metadata object, if available; e.g. ComputeMetadata when using jclouds */ 
+        Object getOriginalMetadata();
+    }
+
+    /**
+     * Implement to indicate that a location can suspend and resume machines.
+     */
+    @Beta
+    public interface SuspendResumeLocation extends SuspendsMachines, ResumesMachines {};
+
+
+    @Beta
+    public interface SuspendsMachines {
+        /**
+         * Suspend the indicated machine.
+         */
+        void suspendMachine(MachineLocation location);
+    }
+
+    @Beta
+    public interface ResumesMachines {
+        /**
+         * Resume the indicated machine.
+         */
+        void resumeMachine(MachineLocation location);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/api/src/main/java/org/apache/brooklyn/api/location/MachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/location/MachineProvisioningLocation.java b/api/src/main/java/org/apache/brooklyn/api/location/MachineProvisioningLocation.java
new file mode 100644
index 0000000..1fcf785
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/location/MachineProvisioningLocation.java
@@ -0,0 +1,72 @@
+/*
+ * 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.apache.brooklyn.api.location;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * A location that is able to provision new machines within its location.
+ *
+ * This interface extends {@link Location} to add the ability to provision {@link MachineLocation}s in this location.
+ */
+public interface MachineProvisioningLocation<T extends MachineLocation> extends ProvisioningLocation<T> {
+    /**
+     * Obtain a machine in this location.
+     * 
+     * @param flags Details of the desired machine (e.g. image, size, open ports, etc; some flag support is limited to selected providers).
+     * "callerContext" can be specified to have custom logging and error messages (useful if starting machines in parallel)
+     * @return a machine that is a child of this location.
+     * @throws NoMachinesAvailableException if there are no machines available in this location (or impls may return null, but that is discouraged)
+     */
+    @Override
+    T obtain(Map<?,?> flags) throws NoMachinesAvailableException;
+
+    /**
+     * Creates a new location of the same type, but with additional creation instructions in the form of flags,
+     * e.g. for specifying subnets, security groups, etc
+     * <p>
+     * Implementers who wish to subclass this provisioning location for additional functionality
+     * in a specific cloud can use the relevant implementation of this method as a guide. 
+     */
+    MachineProvisioningLocation<T> newSubLocation(Map<?,?> newFlags);
+    
+    /**
+     * Release a previously-obtained machine.
+     *
+     * @param machine a {@link MachineLocation} previously obtained from a call to {@link #obtain()}
+     * @throws IllegalStateException if the machine did not come from a call to {@link #obtain()} or it has already been released.
+     */
+    @Override
+    void release(T machine);
+    
+    /**
+     * Gets flags, suitable as an argument to {@link #obtain(Map)}. The tags provided give
+     * hints about the machine required. The provisioning-location could be configured to 
+     * understand those tags. 
+     * 
+     * For example, an AWS-location could be configured to understand that a particular entity
+     * type (e.g. "TomcatServer") requires a particular AMI in that region, so would return the 
+     * required image id.
+     *  
+     * @param tags
+     * @return
+     */
+    Map<String,Object> getProvisioningFlags(Collection<String> tags);
+}


[16/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
new file mode 100644
index 0000000..d355721
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -0,0 +1,2861 @@
+/*
+ * 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.apache.brooklyn.location.jclouds;
+
+import static brooklyn.util.JavaGroovyEquivalents.elvis;
+import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideLoginCredentials;
+import static org.jclouds.scriptbuilder.domain.Statements.exec;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.KeyPair;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.management.AccessController;
+import org.apache.brooklyn.location.MachineLocationCustomizer;
+import org.apache.brooklyn.location.MachineManagementMixins;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.access.PortMapping;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.cloud.AbstractCloudMachineProvisioningLocation;
+import org.apache.brooklyn.location.cloud.names.AbstractCloudMachineNamer;
+import org.apache.brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension;
+import org.apache.brooklyn.location.jclouds.zone.AwsAvailabilityZoneExtension;
+import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions;
+import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.RunNodesException;
+import org.jclouds.compute.config.AdminAccessConfiguration;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadata.Status;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.compute.domain.TemplateBuilderSpec;
+import org.jclouds.compute.functions.Sha512Crypt;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.ec2.compute.options.EC2TemplateOptions;
+import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
+import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
+import org.jclouds.rest.AuthorizationException;
+import org.jclouds.scriptbuilder.domain.LiteralStatement;
+import org.jclouds.scriptbuilder.domain.Statement;
+import org.jclouds.scriptbuilder.domain.StatementList;
+import org.jclouds.scriptbuilder.domain.Statements;
+import org.jclouds.scriptbuilder.functions.InitAdminAccess;
+import org.jclouds.scriptbuilder.statements.login.AdminAccess;
+import org.jclouds.scriptbuilder.statements.login.ReplaceShadowPasswordEntry;
+import org.jclouds.scriptbuilder.statements.ssh.AuthorizeRSAPublicKeys;
+import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Charsets;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Splitter;
+import com.google.common.base.Stopwatch;
+import com.google.common.base.Supplier;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Sets.SetView;
+import com.google.common.io.Files;
+import com.google.common.net.HostAndPort;
+import com.google.common.primitives.Ints;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import brooklyn.config.ConfigUtils;
+import brooklyn.entity.basic.Sanitizer;
+import brooklyn.entity.rebind.persister.LocationWithObjectStore;
+import brooklyn.entity.rebind.persister.PersistenceObjectStore;
+import brooklyn.entity.rebind.persister.jclouds.JcloudsBlobStoreBasedObjectStore;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.access.PortForwardManager;
+import org.apache.brooklyn.location.basic.BasicMachineMetadata;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.basic.LocationConfigUtils;
+import org.apache.brooklyn.location.basic.LocationConfigUtils.OsCredential;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+import org.apache.brooklyn.location.cloud.names.CloudMachineNamer;
+import org.apache.brooklyn.location.jclouds.JcloudsPredicates.NodeInLocation;
+import org.apache.brooklyn.location.jclouds.templates.PortableTemplateBuilder;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.crypto.SecureKeys;
+import brooklyn.util.exceptions.CompoundRuntimeException;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.exceptions.ReferenceWithError;
+import brooklyn.util.flags.MethodCoercions;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.internal.ssh.ShellTool;
+import brooklyn.util.internal.ssh.SshTool;
+import brooklyn.util.javalang.Enums;
+import brooklyn.util.javalang.Reflections;
+import brooklyn.util.net.Cidr;
+import brooklyn.util.net.Networking;
+import brooklyn.util.net.Protocol;
+import brooklyn.util.os.Os;
+import brooklyn.util.repeat.Repeater;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.ssh.IptablesCommands;
+import brooklyn.util.ssh.IptablesCommands.Chain;
+import brooklyn.util.ssh.IptablesCommands.Policy;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.text.ByteSizeStrings;
+import brooklyn.util.text.Identifiers;
+import brooklyn.util.text.KeyValueParser;
+import brooklyn.util.text.Strings;
+import brooklyn.util.text.TemplateProcessor;
+import brooklyn.util.time.Duration;
+import brooklyn.util.time.Time;
+import io.cloudsoft.winrm4j.pywinrm.Session;
+import io.cloudsoft.winrm4j.pywinrm.WinRMFactory;
+
+/**
+ * For provisioning and managing VMs in a particular provider/region, using jclouds.
+ * Configuration flags are defined in {@link JcloudsLocationConfig}.
+ */
+@SuppressWarnings("serial")
+public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation implements
+        JcloudsLocationConfig, MachineManagementMixins.RichMachineProvisioningLocation<MachineLocation>,
+        LocationWithObjectStore, MachineManagementMixins.SuspendsMachines {
+
+    // TODO After converting from Groovy to Java, this is now very bad code! It relies entirely on putting
+    // things into and taking them out of maps; it's not type-safe, and it's thus very error-prone.
+    // In Groovy, that's considered ok but not in Java.
+
+    // TODO test (and fix) ability to set config keys from flags
+
+    // TODO we say config is inherited, but it isn't the case for many "deep" / jclouds properties
+    // e.g. when we pass getRawLocalConfigBag() in and decorate it with additional flags
+    // (inheritance only works when we call getConfig in this class)
+
+    public static final Logger LOG = LoggerFactory.getLogger(JcloudsLocation.class);
+
+    public static final String ROOT_USERNAME = "root";
+    /** these userNames are known to be the preferred/required logins in some common/default images
+     *  where root@ is not allowed to log in */
+    public static final List<String> ROOT_ALIASES = ImmutableList.of("ubuntu", "ec2-user");
+    public static final List<String> COMMON_USER_NAMES_TO_TRY = ImmutableList.<String>builder().add(ROOT_USERNAME).addAll(ROOT_ALIASES).add("admin").build();
+
+    private static final Pattern LIST_PATTERN = Pattern.compile("^\\[(.*)\\]$");
+    private static final Pattern INTEGER_PATTERN = Pattern.compile("^\\d*$");
+
+    private static final int NOTES_MAX_LENGTH = 1000;
+
+    private final AtomicBoolean loggedSshKeysHint = new AtomicBoolean(false);
+    private final AtomicBoolean listedAvailableTemplatesOnNoSuchTemplate = new AtomicBoolean(false);
+
+    private final Map<String,Map<String, ? extends Object>> tagMapping = Maps.newLinkedHashMap();
+
+    @SetFromFlag // so it's persisted
+    private final Map<MachineLocation,String> vmInstanceIds = Maps.newLinkedHashMap();
+    
+    static { Networking.init(); }
+
+    public JcloudsLocation() {
+        super();
+    }
+
+    /** typically wants at least ACCESS_IDENTITY and ACCESS_CREDENTIAL */
+    public JcloudsLocation(Map<?,?> conf) {
+       super(conf);
+    }
+
+    @Override
+    @Deprecated
+    public JcloudsLocation configure(Map<?,?> properties) {
+        super.configure(properties);
+
+        if (config().getLocalBag().containsKey("providerLocationId")) {
+            LOG.warn("Using deprecated 'providerLocationId' key in "+this);
+            if (!config().getLocalBag().containsKey(CLOUD_REGION_ID))
+                config().addToLocalBag(MutableMap.of(CLOUD_REGION_ID.getName(), (String)config().getLocalBag().getStringKey("providerLocationId")));
+        }
+
+        if (isDisplayNameAutoGenerated() || !groovyTruth(getDisplayName())) {
+            setDisplayName(elvis(getProvider(), "unknown") +
+                   (groovyTruth(getRegion()) ? ":"+getRegion() : "") +
+                   (groovyTruth(getEndpoint()) ? ":"+getEndpoint() : ""));
+        }
+
+        setCreationString(config().getLocalBag());
+
+        if (getConfig(MACHINE_CREATION_SEMAPHORE) == null) {
+            Integer maxConcurrent = getConfig(MAX_CONCURRENT_MACHINE_CREATIONS);
+            if (maxConcurrent == null || maxConcurrent < 1) {
+                throw new IllegalStateException(MAX_CONCURRENT_MACHINE_CREATIONS.getName() + " must be >= 1, but was "+maxConcurrent);
+            }
+            config().set(MACHINE_CREATION_SEMAPHORE, new Semaphore(maxConcurrent, true));
+        }
+        return this;
+    }
+
+    @Override
+    public void init() {
+        super.init();
+        if ("aws-ec2".equals(getProvider())) {
+            addExtension(AvailabilityZoneExtension.class, new AwsAvailabilityZoneExtension(getManagementContext(), this));
+        }
+    }
+
+    @Override
+    public JcloudsLocation newSubLocation(Map<?,?> newFlags) {
+        return newSubLocation(getClass(), newFlags);
+    }
+
+    @Override
+    public JcloudsLocation newSubLocation(Class<? extends AbstractCloudMachineProvisioningLocation> type, Map<?,?> newFlags) {
+        // TODO should be able to use ConfigBag.newInstanceExtending; would require moving stuff around to api etc
+        return (JcloudsLocation) getManagementContext().getLocationManager().createLocation(LocationSpec.create(type)
+                .parent(this)
+                .configure(config().getLocalBag().getAllConfig())  // FIXME Should this just be inherited?
+                .configure(MACHINE_CREATION_SEMAPHORE, getMachineCreationSemaphore())
+                .configure(newFlags));
+    }
+
+    @Override
+    public String toString() {
+        Object identity = getIdentity();
+        String configDescription = config().getLocalBag().getDescription();
+        if (configDescription!=null && configDescription.startsWith(getClass().getSimpleName()))
+            return configDescription;
+        return getClass().getSimpleName()+"["+getDisplayName()+":"+(identity != null ? identity : null)+
+                (configDescription!=null ? "/"+configDescription : "") + "@" + getId() + "]";
+    }
+
+    @Override
+    public String toVerboseString() {
+        return Objects.toStringHelper(this).omitNullValues()
+                .add("id", getId()).add("name", getDisplayName()).add("identity", getIdentity())
+                .add("description", config().getLocalBag().getDescription()).add("provider", getProvider())
+                .add("region", getRegion()).add("endpoint", getEndpoint())
+                .toString();
+    }
+
+    public String getProvider() {
+        return getConfig(CLOUD_PROVIDER);
+    }
+
+    public String getIdentity() {
+        return getConfig(ACCESS_IDENTITY);
+    }
+
+    public String getCredential() {
+        return getConfig(ACCESS_CREDENTIAL);
+    }
+
+    /** returns the location ID used by the provider, if set, e.g. us-west-1 */
+    public String getRegion() {
+        return getConfig(CLOUD_REGION_ID);
+    }
+
+    public String getEndpoint() {
+        return (String) config().getBag().getWithDeprecation(CLOUD_ENDPOINT, JCLOUDS_KEY_ENDPOINT);
+    }
+
+    public String getUser(ConfigBag config) {
+        return (String) config.getWithDeprecation(USER, JCLOUDS_KEY_USERNAME);
+    }
+
+    public boolean isWindows(Template template, ConfigBag config) {
+        return isWindows(template.getImage(), config);
+    }
+    
+    /**
+     * Whether VMs provisioned from this image will be Windows. Assume windows if the image
+     * explicitly says so, or if image does not tell us then fall back to whether the config 
+     * explicitly says windows in {@link JcloudsLocationConfig#OS_FAMILY}.
+     * 
+     * Will first look at {@link JcloudsLocationConfig#OS_FAMILY_OVERRIDE}, to check if that 
+     * is set. If so, no further checks are done: the value is compared against {@link OsFamily#WINDOWS}.
+     * 
+     * We believe the config (e.g. from brooklyn.properties) because for some clouds there is 
+     * insufficient meta-data so the Image might not tell us. Thus a user can work around it
+     * by explicitly supplying configuration. 
+     */
+    public boolean isWindows(Image image, ConfigBag config) {
+        OsFamily override = config.get(OS_FAMILY_OVERRIDE);
+        if (override != null) return override == OsFamily.WINDOWS;
+        
+        OsFamily confFamily = config.get(OS_FAMILY);
+        OperatingSystem os = (image != null) ? image.getOperatingSystem() : null;
+        return (os != null && os.getFamily() != OsFamily.UNRECOGNIZED) 
+                ? (OsFamily.WINDOWS == os.getFamily()) 
+                : (OsFamily.WINDOWS == confFamily);
+    }
+
+    /**
+     * Whether the given VM is Windows.
+     * 
+     * @see {@link #isWindows(Image, ConfigBag)}
+     */
+    public boolean isWindows(NodeMetadata node, ConfigBag config) {
+        OsFamily override = config.get(OS_FAMILY_OVERRIDE);
+        if (override != null) return override == OsFamily.WINDOWS;
+        
+        OsFamily confFamily = config.get(OS_FAMILY);
+        OperatingSystem os = (node != null) ? node.getOperatingSystem() : null;
+        return (os != null && os.getFamily() != OsFamily.UNRECOGNIZED) 
+                ? (OsFamily.WINDOWS == os.getFamily()) 
+                : (OsFamily.WINDOWS == confFamily);
+    }
+
+    public boolean isLocationFirewalldEnabled(SshMachineLocation location) {
+        int result = location.execCommands("checking if firewalld is active", 
+                ImmutableList.of(IptablesCommands.firewalldServiceIsActive()));
+        if (result == 0) {
+            return true;
+        }
+        
+        return false;
+    }
+    
+    protected Semaphore getMachineCreationSemaphore() {
+        return checkNotNull(getConfig(MACHINE_CREATION_SEMAPHORE), MACHINE_CREATION_SEMAPHORE.getName());
+    }
+
+    protected CloudMachineNamer getCloudMachineNamer(ConfigBag config) {
+        String namerClass = config.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS);
+        if (Strings.isNonBlank(namerClass)) {
+            Optional<CloudMachineNamer> cloudNamer = Reflections.invokeConstructorWithArgs(getManagementContext().getCatalogClassLoader(), namerClass);
+            if (cloudNamer.isPresent()) {
+                return cloudNamer.get();
+            } else {
+                throw new IllegalStateException("Failed to create CloudMachineNamer "+namerClass+" for location "+this);
+            }
+        } else {
+            return new JcloudsMachineNamer();
+        }
+    }
+
+    protected Collection<JcloudsLocationCustomizer> getCustomizers(ConfigBag setup) {
+        @SuppressWarnings("deprecation")
+        JcloudsLocationCustomizer customizer = setup.get(JCLOUDS_LOCATION_CUSTOMIZER);
+        Collection<JcloudsLocationCustomizer> customizers = setup.get(JCLOUDS_LOCATION_CUSTOMIZERS);
+        @SuppressWarnings("deprecation")
+        String customizerType = setup.get(JCLOUDS_LOCATION_CUSTOMIZER_TYPE);
+        @SuppressWarnings("deprecation")
+        String customizersSupplierType = setup.get(JCLOUDS_LOCATION_CUSTOMIZERS_SUPPLIER_TYPE);
+
+        ClassLoader catalogClassLoader = getManagementContext().getCatalogClassLoader();
+        List<JcloudsLocationCustomizer> result = new ArrayList<JcloudsLocationCustomizer>();
+        if (customizer != null) result.add(customizer);
+        if (customizers != null) result.addAll(customizers);
+        if (Strings.isNonBlank(customizerType)) {
+            Optional<JcloudsLocationCustomizer> customizerByType = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizerType, setup);
+            if (customizerByType.isPresent()) {
+                result.add(customizerByType.get());
+            } else {
+                customizerByType = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizerType);
+                if (customizerByType.isPresent()) {
+                    result.add(customizerByType.get());
+                } else {
+                    throw new IllegalStateException("Failed to create JcloudsLocationCustomizer "+customizersSupplierType+" for location "+this);
+                }
+            }
+        }
+        if (Strings.isNonBlank(customizersSupplierType)) {
+            Optional<Supplier<Collection<JcloudsLocationCustomizer>>> supplier = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizersSupplierType, setup);
+            if (supplier.isPresent()) {
+                result.addAll(supplier.get().get());
+            } else {
+                supplier = Reflections.invokeConstructorWithArgs(catalogClassLoader, customizersSupplierType);
+                if (supplier.isPresent()) {
+                    result.addAll(supplier.get().get());
+                } else {
+                    throw new IllegalStateException("Failed to create JcloudsLocationCustomizer supplier "+customizersSupplierType+" for location "+this);
+                }
+            }
+        }
+        return result;
+    }
+
+    protected Collection<MachineLocationCustomizer> getMachineCustomizers(ConfigBag setup) {
+        Collection<MachineLocationCustomizer> customizers = setup.get(MACHINE_LOCATION_CUSTOMIZERS);
+        return (customizers == null ? ImmutableList.<MachineLocationCustomizer>of() : customizers);
+    }
+
+    public void setDefaultImageId(String val) {
+        config().set(DEFAULT_IMAGE_ID, val);
+    }
+
+    // TODO remove tagMapping, or promote it
+    // (i think i favour removing it, letting the config come in from the entity)
+
+    public void setTagMapping(Map<String,Map<String, ? extends Object>> val) {
+        tagMapping.clear();
+        tagMapping.putAll(val);
+    }
+
+    // TODO Decide on semantics. If I give "TomcatServer" and "Ubuntu", then must I get back an image that matches both?
+    // Currently, just takes first match that it finds...
+    @Override
+    public Map<String,Object> getProvisioningFlags(Collection<String> tags) {
+        Map<String,Object> result = Maps.newLinkedHashMap();
+        Collection<String> unmatchedTags = Lists.newArrayList();
+        for (String it : tags) {
+            if (groovyTruth(tagMapping.get(it)) && !groovyTruth(result)) {
+                result.putAll(tagMapping.get(it));
+            } else {
+                unmatchedTags.add(it);
+            }
+        }
+        if (unmatchedTags.size() > 0) {
+            LOG.debug("Location {}, failed to match provisioning tags {}", this, unmatchedTags);
+        }
+        return result;
+    }
+
+    public static final Set<ConfigKey<?>> getAllSupportedProperties() {
+        Set<String> configsOnClass = Sets.newLinkedHashSet(
+            Iterables.transform(ConfigUtils.getStaticKeysOnClass(JcloudsLocation.class),
+                new Function<HasConfigKey<?>,String>() {
+                    @Override @Nullable
+                    public String apply(@Nullable HasConfigKey<?> input) {
+                        return input.getConfigKey().getName();
+                    }
+                }));
+        Set<ConfigKey<?>> configKeysInList = ImmutableSet.<ConfigKey<?>>builder()
+                .addAll(SUPPORTED_TEMPLATE_BUILDER_PROPERTIES.keySet())
+                .addAll(SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.keySet())
+                .build();
+        Set<String> configsInList = Sets.newLinkedHashSet(
+            Iterables.transform(configKeysInList,
+            new Function<ConfigKey<?>,String>() {
+                @Override @Nullable
+                public String apply(@Nullable ConfigKey<?> input) {
+                    return input.getName();
+                }
+            }));
+
+        SetView<String> extrasInList = Sets.difference(configsInList, configsOnClass);
+        // notInList is normal
+        if (!extrasInList.isEmpty())
+            LOG.warn("JcloudsLocation supported properties differs from config defined on class: " + extrasInList);
+        return Collections.unmodifiableSet(configKeysInList);
+    }
+
+    public ComputeService getComputeService() {
+        return getComputeService(MutableMap.of());
+    }
+    public ComputeService getComputeService(Map<?,?> flags) {
+        ConfigBag conf = (flags==null || flags.isEmpty())
+                ? config().getBag()
+                : ConfigBag.newInstanceExtending(config().getBag(), flags);
+        return getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(conf, true);
+    }
+
+    /** @deprecated since 0.7.0 use {@link #listMachines()} */ @Deprecated
+    public Set<? extends ComputeMetadata> listNodes() {
+        return listNodes(MutableMap.of());
+    }
+    /** @deprecated since 0.7.0 use {@link #listMachines()}.
+     * (no support for custom compute service flags; if that is needed, we'll have to introduce a new method,
+     * but it seems there are no usages) */ @Deprecated
+    public Set<? extends ComputeMetadata> listNodes(Map<?,?> flags) {
+        return getComputeService(flags).listNodes();
+    }
+
+    @Override
+    public Map<String, MachineManagementMixins.MachineMetadata> listMachines() {
+        Set<? extends ComputeMetadata> nodes =
+            getRegion()!=null ? getComputeService().listNodesDetailsMatching(new NodeInLocation(getRegion(), true))
+                : getComputeService().listNodes();
+        Map<String,MachineManagementMixins.MachineMetadata> result = new LinkedHashMap<String, MachineManagementMixins.MachineMetadata>();
+
+        for (ComputeMetadata node: nodes)
+            result.put(node.getId(), getMachineMetadata(node));
+
+        return result;
+    }
+
+    protected MachineManagementMixins.MachineMetadata getMachineMetadata(ComputeMetadata node) {
+        if (node==null)
+            return null;
+        return new BasicMachineMetadata(node.getId(), node.getName(),
+            ((node instanceof NodeMetadata) ? Iterators.tryFind( ((NodeMetadata)node).getPublicAddresses().iterator(), Predicates.alwaysTrue() ).orNull() : null),
+            ((node instanceof NodeMetadata) ? ((NodeMetadata)node).getStatus()==Status.RUNNING : null),
+            node);
+    }
+
+    @Override
+    public MachineManagementMixins.MachineMetadata getMachineMetadata(MachineLocation l) {
+        if (l instanceof JcloudsSshMachineLocation) {
+            return getMachineMetadata( ((JcloudsSshMachineLocation)l).node );
+        }
+        return null;
+    }
+
+    @Override
+    public void killMachine(String cloudServiceId) {
+        getComputeService().destroyNode(cloudServiceId);
+    }
+
+    @Override
+    public void killMachine(MachineLocation l) {
+        MachineManagementMixins.MachineMetadata m = getMachineMetadata(l);
+        if (m==null) throw new NoSuchElementException("Machine "+l+" is not known at "+this);
+        killMachine(m.getId());
+    }
+
+    /** attaches a string describing where something is being created
+     * (provider, region/location and/or endpoint, callerContext) */
+    protected void setCreationString(ConfigBag config) {
+        config.setDescription(elvis(config.get(CLOUD_PROVIDER), "unknown")+
+                (config.containsKey(CLOUD_REGION_ID) ? ":"+config.get(CLOUD_REGION_ID) : "")+
+                (config.containsKey(CLOUD_ENDPOINT) ? ":"+config.get(CLOUD_ENDPOINT) : "")+
+                (config.containsKey(CALLER_CONTEXT) ? "@"+config.get(CALLER_CONTEXT) : ""));
+    }
+
+    // ----------------- obtaining a new machine ------------------------
+    public MachineLocation obtain() throws NoMachinesAvailableException {
+        return obtain(MutableMap.of());
+    }
+    public MachineLocation obtain(TemplateBuilder tb) throws NoMachinesAvailableException {
+        return obtain(MutableMap.of(), tb);
+    }
+    public MachineLocation obtain(Map<?,?> flags, TemplateBuilder tb) throws NoMachinesAvailableException {
+        return obtain(MutableMap.builder().putAll(flags).put(TEMPLATE_BUILDER, tb).build());
+    }
+
+    /** core method for obtaining a VM using jclouds;
+     * Map should contain CLOUD_PROVIDER and CLOUD_ENDPOINT or CLOUD_REGION, depending on the cloud,
+     * as well as ACCESS_IDENTITY and ACCESS_CREDENTIAL,
+     * plus any further properties to specify e.g. images, hardware profiles, accessing user
+     * (for initial login, and a user potentially to create for subsequent ie normal access) */
+    @Override
+    public MachineLocation obtain(Map<?,?> flags) throws NoMachinesAvailableException {
+        ConfigBag setup = ConfigBag.newInstanceExtending(config().getBag(), flags);
+        Integer attempts = setup.get(MACHINE_CREATE_ATTEMPTS);
+        List<Exception> exceptions = Lists.newArrayList();
+        if (attempts == null || attempts < 1) attempts = 1;
+        for (int i = 1; i <= attempts; i++) {
+            try {
+                return obtainOnce(setup);
+            } catch (RuntimeException e) {
+                LOG.warn("Attempt #{}/{} to obtain machine threw error: {}", new Object[]{i, attempts, e});
+                exceptions.add(e);
+            }
+        }
+        String msg = String.format("Failed to get VM after %d attempt%s.", attempts, attempts == 1 ? "" : "s");
+
+        Exception cause = (exceptions.size() == 1)
+                ? exceptions.get(0)
+                : new CompoundRuntimeException(msg + " - "
+                    + "First cause is "+exceptions.get(0)+" (listed in primary trace); "
+                    + "plus " + (exceptions.size()-1) + " more (e.g. the last is "+exceptions.get(exceptions.size()-1)+")",
+                    exceptions.get(0), exceptions);
+
+        if (exceptions.get(exceptions.size()-1) instanceof NoMachinesAvailableException) {
+            throw new NoMachinesAvailableException(msg, cause);
+        } else {
+            throw Exceptions.propagate(cause);
+        }
+    }
+
+    protected MachineLocation obtainOnce(ConfigBag setup) throws NoMachinesAvailableException {
+        AccessController.Response access = getManagementContext().getAccessController().canProvisionLocation(this);
+        if (!access.isAllowed()) {
+            throw new IllegalStateException("Access controller forbids provisioning in "+this+": "+access.getMsg());
+        }
+
+        setCreationString(setup);
+        boolean waitForSshable = !"false".equalsIgnoreCase(setup.get(WAIT_FOR_SSHABLE));
+        boolean waitForWinRmable = !"false".equalsIgnoreCase(setup.get(WAIT_FOR_WINRM_AVAILABLE));
+        boolean usePortForwarding = setup.get(USE_PORT_FORWARDING);
+        boolean skipJcloudsSshing = Boolean.FALSE.equals(setup.get(USE_JCLOUDS_SSH_INIT)) || usePortForwarding;
+        JcloudsPortForwarderExtension portForwarder = setup.get(PORT_FORWARDER);
+        if (usePortForwarding) checkNotNull(portForwarder, "portForwarder, when use-port-forwarding enabled");
+
+        final ComputeService computeService = getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(setup, true);
+        CloudMachineNamer cloudMachineNamer = getCloudMachineNamer(setup);
+        String groupId = elvis(setup.get(GROUP_ID), cloudMachineNamer.generateNewGroupId(setup));
+        NodeMetadata node = null;
+        JcloudsMachineLocation machineLocation = null;
+        
+        try {
+            LOG.info("Creating VM "+setup.getDescription()+" in "+this);
+
+            Semaphore machineCreationSemaphore = getMachineCreationSemaphore();
+            boolean acquired = machineCreationSemaphore.tryAcquire(0, TimeUnit.SECONDS);
+            if (!acquired) {
+                LOG.info("Waiting in {} for machine-creation permit ({} other queuing requests already)", new Object[] {this, machineCreationSemaphore.getQueueLength()});
+                Stopwatch blockStopwatch = Stopwatch.createStarted();
+                machineCreationSemaphore.acquire();
+                LOG.info("Acquired in {} machine-creation permit, after waiting {}", this, Time.makeTimeStringRounded(blockStopwatch));
+            } else {
+                LOG.debug("Acquired in {} machine-creation permit immediately", this);
+            }
+
+            Stopwatch provisioningStopwatch = Stopwatch.createStarted();
+            Duration templateTimestamp, provisionTimestamp, usableTimestamp, customizedTimestamp;
+
+            LoginCredentials userCredentials = null;
+            Set<? extends NodeMetadata> nodes;
+            Template template;
+            try {
+                // Setup the template
+                template = buildTemplate(computeService, setup);
+                boolean expectWindows = isWindows(template, setup);
+                if (!skipJcloudsSshing) {
+                    if (expectWindows) {
+                        // TODO Was this too early to look at template.getImage? e.g. customizeTemplate could subsequently modify it.
+                        LOG.warn("Ignoring invalid configuration for Windows provisioning of "+template.getImage()+": "+USE_JCLOUDS_SSH_INIT.getName()+" should be false");
+                        skipJcloudsSshing = true;
+                    } else if (waitForSshable) {
+                        userCredentials = initTemplateForCreateUser(template, setup);
+                    }
+                }
+
+                templateTimestamp = Duration.of(provisioningStopwatch);
+                // "Name" metadata seems to set the display name; at least in AWS
+                // TODO it would be nice if this salt comes from the location's ID (but we don't know that yet as the ssh machine location isn't created yet)
+                // TODO in softlayer we want to control the suffix of the hostname which is 3 random hex digits
+                template.getOptions().getUserMetadata().put("Name", cloudMachineNamer.generateNewMachineUniqueNameFromGroupId(setup, groupId));
+                
+                if (setup.get(JcloudsLocationConfig.INCLUDE_BROOKLYN_USER_METADATA)) {
+                    template.getOptions().getUserMetadata().put("brooklyn-user", System.getProperty("user.name"));
+                    
+                    Object context = setup.get(CALLER_CONTEXT);
+                    if (context instanceof Entity) {
+                        Entity entity = (Entity)context;
+                        template.getOptions().getUserMetadata().put("brooklyn-app-id", entity.getApplicationId());
+                        template.getOptions().getUserMetadata().put("brooklyn-app-name", entity.getApplication().getDisplayName());
+                        template.getOptions().getUserMetadata().put("brooklyn-entity-id", entity.getId());
+                        template.getOptions().getUserMetadata().put("brooklyn-entity-name", entity.getDisplayName());
+                        template.getOptions().getUserMetadata().put("brooklyn-server-creation-date", Time.makeDateSimpleStampString());
+                    }
+                }
+                
+                customizeTemplate(setup, computeService, template);
+                
+                LOG.debug("jclouds using template {} / options {} to provision machine in {}",
+                        new Object[] {template, template.getOptions(), setup.getDescription()});
+
+                if (!setup.getUnusedConfig().isEmpty())
+                    LOG.debug("NOTE: unused flags passed to obtain VM in "+setup.getDescription()+": "+
+                            setup.getUnusedConfig());
+                
+                nodes = computeService.createNodesInGroup(groupId, 1, template);
+                provisionTimestamp = Duration.of(provisioningStopwatch);
+            } finally {
+                machineCreationSemaphore.release();
+            }
+
+            node = Iterables.getOnlyElement(nodes, null);
+            LOG.debug("jclouds created {} for {}", node, setup.getDescription());
+            if (node == null)
+                throw new IllegalStateException("No nodes returned by jclouds create-nodes in " + setup.getDescription());
+
+            boolean windows = isWindows(node, setup);
+            if (windows) {
+                int newLoginPort = node.getLoginPort() == 22 ? 5985 : node.getLoginPort();
+                String newLoginUser = "root".equals(node.getCredentials().getUser()) ? "Administrator" : node.getCredentials().getUser();
+                LOG.debug("jclouds created Windows VM {}; transforming connection details: loginPort from {} to {}; loginUser from {} to {}", 
+                        new Object[] {node, node.getLoginPort(), newLoginPort, node.getCredentials().getUser(), newLoginUser});
+                
+                node = NodeMetadataBuilder.fromNodeMetadata(node)
+                        .loginPort(newLoginPort)
+                        .credentials(LoginCredentials.builder(node.getCredentials()).user(newLoginUser).build())
+                        .build();
+            }
+            // FIXME How do we influence the node.getLoginPort, so it is set correctly for Windows?
+            // Setup port-forwarding, if required
+            Optional<HostAndPort> sshHostAndPortOverride;
+            if (usePortForwarding) {
+                sshHostAndPortOverride = Optional.of(portForwarder.openPortForwarding(
+                        node,
+                        node.getLoginPort(),
+                        Optional.<Integer>absent(),
+                        Protocol.TCP,
+                        Cidr.UNIVERSAL));
+            } else {
+                sshHostAndPortOverride = Optional.absent();
+            }
+
+            if (skipJcloudsSshing) {
+                boolean waitForConnectable = (windows) ? waitForWinRmable : waitForSshable;
+                if (waitForConnectable) {
+                    if (windows) {
+                        // TODO Does jclouds support any windows user setup?
+                        waitForWinRmAvailable(computeService, node, sshHostAndPortOverride, node.getCredentials(), setup);
+                    } else {
+                        waitForSshable(computeService, node, sshHostAndPortOverride, node.getCredentials(), setup);
+                    }
+                    userCredentials = createUser(computeService, node, sshHostAndPortOverride, setup);
+                }
+            }
+
+            // Figure out which login-credentials to use
+            LoginCredentials customCredentials = setup.get(CUSTOM_CREDENTIALS);
+            if (customCredentials != null) {
+                userCredentials = customCredentials;
+                //set userName and other data, from these credentials
+                Object oldUsername = setup.put(USER, customCredentials.getUser());
+                LOG.debug("node {} username {} / {} (customCredentials)", new Object[] { node, customCredentials.getUser(), oldUsername });
+                if (customCredentials.getOptionalPassword().isPresent()) setup.put(PASSWORD, customCredentials.getOptionalPassword().get());
+                if (customCredentials.getOptionalPrivateKey().isPresent()) setup.put(PRIVATE_KEY_DATA, customCredentials.getOptionalPrivateKey().get());
+            }
+            if (userCredentials == null) {
+                userCredentials = extractVmCredentials(setup, node);
+            }
+            if (userCredentials != null) {
+                node = NodeMetadataBuilder.fromNodeMetadata(node).credentials(userCredentials).build();
+            } else {
+                // only happens if something broke above...
+                userCredentials = LoginCredentials.fromCredentials(node.getCredentials());
+            }
+            // store the credentials, in case they have changed
+            setup.putIfNotNull(JcloudsLocationConfig.PASSWORD, userCredentials.getOptionalPassword().orNull());
+            setup.putIfNotNull(JcloudsLocationConfig.PRIVATE_KEY_DATA, userCredentials.getOptionalPrivateKey().orNull());
+
+            // Wait for the VM to be reachable over SSH
+            if (waitForSshable && !windows) {
+                waitForSshable(computeService, node, sshHostAndPortOverride, userCredentials, setup);
+            } else {
+                LOG.debug("Skipping ssh check for {} ({}) due to config waitForSshable=false", node, setup.getDescription());
+            }
+            usableTimestamp = Duration.of(provisioningStopwatch);
+
+//            JcloudsSshMachineLocation jcloudsSshMachineLocation = null;
+//            WinRmMachineLocation winRmMachineLocation = null;
+            // Create a JcloudsSshMachineLocation, and register it
+            if (windows) {
+                machineLocation = registerWinRmMachineLocation(computeService, node, userCredentials, sshHostAndPortOverride, setup);
+            } else {
+                machineLocation = registerJcloudsSshMachineLocation(computeService, node, userCredentials, sshHostAndPortOverride, setup);
+                if (template!=null && machineLocation.getTemplate()==null) {
+                    ((JcloudsSshMachineLocation)machineLocation).template = template;
+                }
+            }
+
+            if (usePortForwarding && sshHostAndPortOverride.isPresent()) {
+                // Now that we have the sshMachineLocation, we can associate the port-forwarding address with it.
+                PortForwardManager portForwardManager = setup.get(PORT_FORWARDING_MANAGER);
+                if (portForwardManager != null) {
+                    portForwardManager.associate(node.getId(), sshHostAndPortOverride.get(), machineLocation, node.getLoginPort());
+                } else {
+                    LOG.warn("No port-forward manager for {} so could not associate {} -> {} for {}",
+                            new Object[] {this, node.getLoginPort(), sshHostAndPortOverride, machineLocation});
+                }
+            }
+
+            if ("docker".equals(this.getProvider())) {
+                if (windows) {
+                    throw new UnsupportedOperationException("Docker not supported on Windows");
+                }
+                Map<Integer, Integer> portMappings = JcloudsUtil.dockerPortMappingsFor(this, node.getId());
+                PortForwardManager portForwardManager = setup.get(PORT_FORWARDING_MANAGER);
+                if (portForwardManager != null) {
+                    for(Integer containerPort : portMappings.keySet()) {
+                        Integer hostPort = portMappings.get(containerPort);
+                        String dockerHost = ((JcloudsSshMachineLocation)machineLocation).getSshHostAndPort().getHostText();
+                        portForwardManager.associate(node.getId(), HostAndPort.fromParts(dockerHost, hostPort), machineLocation, containerPort);
+                    }
+                } else {
+                    LOG.warn("No port-forward manager for {} so could not associate docker port-mappings for {}",
+                            this, machineLocation);
+                }
+            }
+
+            List<String> customisationForLogging = new ArrayList<String>();
+            // Apply same securityGroups rules to iptables, if iptables is running on the node
+            if (waitForSshable) {
+
+                String setupScript = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_URL);
+                List<String> setupScripts = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_URL_LIST);
+                Collection<String> allScripts = new MutableList<String>().appendIfNotNull(setupScript).appendAll(setupScripts);
+                for (String setupScriptItem : allScripts) {
+                    if (Strings.isNonBlank(setupScriptItem)) {
+                        customisationForLogging.add("custom setup script " + setupScriptItem);
+
+                        String setupVarsString = setup.get(JcloudsLocationConfig.CUSTOM_MACHINE_SETUP_SCRIPT_VARS);
+                        Map<String, String> substitutions = (setupVarsString != null)
+                                ? Splitter.on(",").withKeyValueSeparator(":").split(setupVarsString)
+                                : ImmutableMap.<String, String>of();
+                        String scriptContent = ResourceUtils.create(this).getResourceAsString(setupScriptItem);
+                        String script = TemplateProcessor.processTemplateContents(scriptContent, getManagementContext(), substitutions);
+                        if (windows) {
+                            ((WinRmMachineLocation)machineLocation).executeScript(ImmutableList.copyOf((script.replace("\r", "").split("\n"))));
+                        } else {
+                            ((SshMachineLocation)machineLocation).execCommands("Customizing node " + this, ImmutableList.of(script));
+                        }
+                    }
+                }
+
+                if (setup.get(JcloudsLocationConfig.MAP_DEV_RANDOM_TO_DEV_URANDOM)) {
+                    if (windows) {
+                        LOG.warn("Ignoring flag MAP_DEV_RANDOM_TO_DEV_URANDOM on Windows location {}", machineLocation);
+                    } else {
+                        customisationForLogging.add("point /dev/random to urandom");
+
+                        ((SshMachineLocation)machineLocation).execCommands("using urandom instead of random",
+                                Arrays.asList("sudo mv /dev/random /dev/random-real", "sudo ln -s /dev/urandom /dev/random"));
+                    }
+                }
+
+
+                if (setup.get(GENERATE_HOSTNAME)) {
+                    if (windows) {
+                        // TODO: Generate Windows Hostname
+                        LOG.warn("Ignoring flag GENERATE_HOSTNAME on Windows location {}", machineLocation);
+                    } else {
+                        customisationForLogging.add("configure hostname");
+
+                        ((SshMachineLocation)machineLocation).execCommands("Generate hostname " + node.getName(),
+                                Arrays.asList("sudo hostname " + node.getName(),
+                                        "sudo sed -i \"s/HOSTNAME=.*/HOSTNAME=" + node.getName() + "/g\" /etc/sysconfig/network",
+                                        "sudo bash -c \"echo 127.0.0.1   `hostname` >> /etc/hosts\"")
+                        );
+                    }
+                }
+
+                if (setup.get(OPEN_IPTABLES)) {
+                    if (windows) {
+                        LOG.warn("Ignoring DEPRECATED flag OPEN_IPTABLES on Windows location {}", machineLocation);
+                    } else {
+                        LOG.warn("Using DEPRECATED flag OPEN_IPTABLES (will not be supported in future versions) for {} at {}", machineLocation, this);
+                        
+                        @SuppressWarnings("unchecked")
+                        Iterable<Integer> inboundPorts = (Iterable<Integer>) setup.get(INBOUND_PORTS);
+
+                        if (inboundPorts == null || Iterables.isEmpty(inboundPorts)) {
+                            LOG.info("No ports to open in iptables (no inbound ports) for {} at {}", machineLocation, this);
+                        } else {
+                            customisationForLogging.add("open iptables");
+
+                            List<String> iptablesRules = Lists.newArrayList();
+
+                            if (isLocationFirewalldEnabled((SshMachineLocation)machineLocation)) {
+                                for (Integer port : inboundPorts) {
+                                    iptablesRules.add(IptablesCommands.addFirewalldRule(Chain.INPUT, Protocol.TCP, port, Policy.ACCEPT));
+                                 }
+                            } else {
+                                iptablesRules = createIptablesRulesForNetworkInterface(inboundPorts);
+                                iptablesRules.add(IptablesCommands.saveIptablesRules());
+                            }
+                            List<String> batch = Lists.newArrayList();
+                            // Some entities, such as Riak (erlang based) have a huge range of ports, which leads to a script that
+                            // is too large to run (fails with a broken pipe). Batch the rules into batches of 50
+                            for (String rule : iptablesRules) {
+                                batch.add(rule);
+                                if (batch.size() == 50) {
+                                    ((SshMachineLocation)machineLocation).execCommands("Inserting iptables rules, 50 command batch", batch);
+                                    batch.clear();
+                                }
+                            }
+                            if (batch.size() > 0) {
+                                ((SshMachineLocation)machineLocation).execCommands("Inserting iptables rules", batch);
+                            }
+                            ((SshMachineLocation)machineLocation).execCommands("List iptables rules", ImmutableList.of(IptablesCommands.listIptablesRule()));
+                        }
+                    }
+                }
+
+                if (setup.get(STOP_IPTABLES)) {
+                    if (windows) {
+                        LOG.warn("Ignoring DEPRECATED flag OPEN_IPTABLES on Windows location {}", machineLocation);
+                    } else {
+                        LOG.warn("Using DEPRECATED flag STOP_IPTABLES (will not be supported in future versions) for {} at {}", machineLocation, this);
+                        
+                        customisationForLogging.add("stop iptables");
+
+                        List<String> cmds = ImmutableList.<String>of();
+                        if (isLocationFirewalldEnabled((SshMachineLocation)machineLocation)) {
+                            cmds = ImmutableList.of(IptablesCommands.firewalldServiceStop(), IptablesCommands.firewalldServiceStatus());
+                        } else {
+                            cmds = ImmutableList.of(IptablesCommands.iptablesServiceStop(), IptablesCommands.iptablesServiceStatus());
+                        }
+                        ((SshMachineLocation)machineLocation).execCommands("Stopping iptables", cmds);
+                    }
+                }
+
+                List<String> extraKeyUrlsToAuth = setup.get(EXTRA_PUBLIC_KEY_URLS_TO_AUTH);
+                if (extraKeyUrlsToAuth!=null && !extraKeyUrlsToAuth.isEmpty()) {
+                    if (windows) {
+                        LOG.warn("Ignoring flag EXTRA_PUBLIC_KEY_URLS_TO_AUTH on Windows location", machineLocation);
+                    } else {
+                        List<String> extraKeyDataToAuth = MutableList.of();
+                        for (String keyUrl : extraKeyUrlsToAuth) {
+                            extraKeyDataToAuth.add(ResourceUtils.create().getResourceAsString(keyUrl));
+                        }
+                        ((SshMachineLocation)machineLocation).execCommands("Authorizing ssh keys",
+                                ImmutableList.of(new AuthorizeRSAPublicKeys(extraKeyDataToAuth).render(org.jclouds.scriptbuilder.domain.OsFamily.UNIX)));
+                    }
+                }
+
+            } else {
+                // Otherwise we have deliberately not waited to be ssh'able, so don't try now to
+                // ssh to exec these commands!
+            }
+
+            // Apply any optional app-specific customization.
+            for (JcloudsLocationCustomizer customizer : getCustomizers(setup)) {
+                customizer.customize(this, computeService, machineLocation);
+            }
+            for (MachineLocationCustomizer customizer : getMachineCustomizers(setup)) {
+                customizer.customize(machineLocation);
+            }
+
+            customizedTimestamp = Duration.of(provisioningStopwatch);
+
+            try {
+                String logMessage = "Finished VM "+setup.getDescription()+" creation:"
+                        + " "+machineLocation.getUser()+"@"+machineLocation.getAddress()+":"+machineLocation.getPort()
+                        + (Boolean.TRUE.equals(setup.get(LOG_CREDENTIALS))
+                                ? "password=" + userCredentials.getOptionalPassword().or("<absent>")
+                                + " && key=" + userCredentials.getOptionalPrivateKey().or("<absent>")
+                                : "")
+                        + " ready after "+Duration.of(provisioningStopwatch).toStringRounded()
+                        + " ("+template+" template built in "+Duration.of(templateTimestamp).toStringRounded()+";"
+                        + " "+node+" provisioned in "+Duration.of(provisionTimestamp).subtract(templateTimestamp).toStringRounded()+";"
+                        + " "+machineLocation+" connection usable in "+Duration.of(usableTimestamp).subtract(provisionTimestamp).toStringRounded()+";"
+                        + " and os customized in "+Duration.of(customizedTimestamp).subtract(usableTimestamp).toStringRounded()+" - "+Joiner.on(", ").join(customisationForLogging)+")";
+                LOG.info(logMessage);
+            } catch (Exception e){
+                // TODO Remove try-catch! @Nakomis: why did you add it? What exception happened during logging?
+                Exceptions.propagateIfFatal(e);
+                LOG.warn("Problem generating log message summarising completion of jclouds machine provisioning "+machineLocation+" by "+this, e);
+            }
+
+            return machineLocation;
+            
+        } catch (Exception e) {
+            if (e instanceof RunNodesException && ((RunNodesException)e).getNodeErrors().size() > 0) {
+                node = Iterables.get(((RunNodesException)e).getNodeErrors().keySet(), 0);
+            }
+            // sometimes AWS nodes come up busted (eg ssh not allowed); just throw it back (and maybe try for another one)
+            boolean destroyNode = (node != null) && Boolean.TRUE.equals(setup.get(DESTROY_ON_FAILURE));
+
+            if (e.toString().contains("VPCResourceNotSpecified")) {
+                LOG.error("Detected that your EC2 account is a legacy 'classic' account, but the recommended instance type requires VPC. "
+                    + "You can specify the 'eu-central-1' region to avoid this problem, or you can specify a classic-compatible instance type, "
+                    + "or you can specify a subnet to use with 'networkName' "
+                    + "(taking care that the subnet auto-assigns public IP's and allows ingress on all ports, "
+                    + "as Brooklyn does not currently configure security groups for non-default VPC's; "
+                    + "or setting up Brooklyn to be in the subnet or have a jump host or other subnet access configuration). "
+                    + "For more information on VPC vs classic see http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-vpc.html.");
+            }
+            
+            LOG.error("Failed to start VM for {}{}: {}",
+                    new Object[] {setup.getDescription(), (destroyNode ? " (destroying "+node+")" : ""), e.getMessage()});
+            LOG.debug(Throwables.getStackTraceAsString(e));
+            
+            if (destroyNode) {
+                if (machineLocation != null) {
+                    releaseSafely(machineLocation);
+                } else {
+                    releaseNodeSafely(node);
+                }
+            }
+
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    // ------------- suspend and resume ------------------------------------
+
+    /**
+     * Suspends the given location.
+     * <p>
+     * Note that this method does <b>not</b> call the lifecycle methods of any
+     * {@link #getCustomizers(ConfigBag) customizers} attached to this location.
+     */
+    @Override
+    public void suspendMachine(MachineLocation rawLocation) {
+        String instanceId = vmInstanceIds.remove(rawLocation);
+        if (instanceId == null) {
+            LOG.info("Attempt to suspend unknown machine " + rawLocation + " in " + this);
+            throw new IllegalArgumentException("Unknown machine " + rawLocation);
+        }
+        LOG.info("Suspending machine {} in {}, instance id {}", new Object[]{rawLocation, this, instanceId});
+        Exception toThrow = null;
+        try {
+            getComputeService().suspendNode(instanceId);
+        } catch (Exception e) {
+            toThrow = e;
+            LOG.error("Problem suspending machine " + rawLocation + " in " + this + ", instance id " + instanceId, e);
+        }
+        removeChild(rawLocation);
+        if (toThrow != null) {
+            throw Exceptions.propagate(toThrow);
+        }
+    }
+
+    // ------------- constructing the template, etc ------------------------
+
+    private static interface CustomizeTemplateBuilder {
+        void apply(TemplateBuilder tb, ConfigBag props, Object v);
+    }
+
+    public static interface CustomizeTemplateOptions {
+        void apply(TemplateOptions tb, ConfigBag props, Object v);
+    }
+
+    /** properties which cause customization of the TemplateBuilder */
+    public static final Map<ConfigKey<?>,CustomizeTemplateBuilder> SUPPORTED_TEMPLATE_BUILDER_PROPERTIES = ImmutableMap.<ConfigKey<?>,CustomizeTemplateBuilder>builder()
+            .put(OS_64_BIT, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        Boolean os64Bit = TypeCoercions.coerce(v, Boolean.class);
+                        if (os64Bit!=null)
+                            tb.os64Bit(os64Bit);
+                    }})
+            .put(MIN_RAM, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.minRam( (int)(ByteSizeStrings.parse(Strings.toString(v), "mb")/1000/1000) );
+                    }})
+            .put(MIN_CORES, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.minCores(TypeCoercions.coerce(v, Double.class));
+                    }})
+            .put(MIN_DISK, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.minDisk( (int)(ByteSizeStrings.parse(Strings.toString(v), "gb")/1000/1000/1000) );
+                    }})
+            .put(HARDWARE_ID, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.hardwareId(((CharSequence)v).toString());
+                    }})
+            .put(IMAGE_ID, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.imageId(((CharSequence)v).toString());
+                    }})
+            .put(IMAGE_DESCRIPTION_REGEX, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.imageDescriptionMatches(((CharSequence)v).toString());
+                    }})
+            .put(IMAGE_NAME_REGEX, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.imageNameMatches(((CharSequence)v).toString());
+                    }})
+            .put(OS_FAMILY, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        Maybe<OsFamily> osFamily = Enums.valueOfIgnoreCase(OsFamily.class, v.toString());
+                        if (osFamily.isAbsent())
+                            throw new IllegalArgumentException("Invalid "+OS_FAMILY+" value "+v);
+                        tb.osFamily(osFamily.get());
+                    }})
+            .put(OS_VERSION_REGEX, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.osVersionMatches( ((CharSequence)v).toString() );
+                    }})
+            .put(TEMPLATE_SPEC, new CustomizeTemplateBuilder() {
+                public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        tb.from(TemplateBuilderSpec.parse(((CharSequence)v).toString()));
+                    }})
+            .put(DEFAULT_IMAGE_ID, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        /* done in the code, but included here so that it is in the map */
+                    }})
+            .put(TEMPLATE_BUILDER, new CustomizeTemplateBuilder() {
+                    public void apply(TemplateBuilder tb, ConfigBag props, Object v) {
+                        /* done in the code, but included here so that it is in the map */
+                    }})
+            .build();
+
+    /** properties which cause customization of the TemplateOptions */
+    public static final Map<ConfigKey<?>,CustomizeTemplateOptions> SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES = ImmutableMap.<ConfigKey<?>,CustomizeTemplateOptions>builder()
+            .put(SECURITY_GROUPS, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof EC2TemplateOptions) {
+                            String[] securityGroups = toStringArray(v);
+                            ((EC2TemplateOptions)t).securityGroups(securityGroups);
+                        } else if (t instanceof NovaTemplateOptions) {
+                            String[] securityGroups = toStringArray(v);
+                            ((NovaTemplateOptions)t).securityGroups(securityGroups);
+                        } else if (t instanceof SoftLayerTemplateOptions) {
+                            String[] securityGroups = toStringArray(v);
+                            ((SoftLayerTemplateOptions)t).securityGroups(securityGroups);
+                        } else if (t instanceof GoogleComputeEngineTemplateOptions) {
+                            String[] securityGroups = toStringArray(v);
+                            ((GoogleComputeEngineTemplateOptions)t).securityGroups(securityGroups);
+                        } else {
+                            LOG.info("ignoring securityGroups({}) in VM creation because not supported for cloud/type ({})", v, t.getClass());
+                        }
+                    }})
+            .put(INBOUND_PORTS, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        int[] inboundPorts = toIntArray(v);
+                        if (LOG.isDebugEnabled()) LOG.debug("opening inbound ports {} for cloud/type {}", Arrays.toString(inboundPorts), t.getClass());
+                        t.inboundPorts(inboundPorts);
+                    }})
+            .put(USER_METADATA_STRING, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof EC2TemplateOptions) {
+                            // See AWS docs: http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html#user-data-execution
+                            if (v==null) return;
+                            String data = v.toString();
+                            if (!(data.startsWith("<script>") || data.startsWith("<powershell>"))) {
+                                data = "<script> " + data + " </script>";
+                            }
+                            ((EC2TemplateOptions)t).userData(data.getBytes());
+                        } else if (t instanceof SoftLayerTemplateOptions) {
+                            ((SoftLayerTemplateOptions)t).userData(Strings.toString(v));
+                        } else {
+                            // Try reflection: userData(String), or guestCustomizationScript(String);
+                            // the latter is used by vCloud Director.
+                            Class<? extends TemplateOptions> clazz = t.getClass();
+                            Method userDataMethod = null;
+                            try {
+                                userDataMethod = clazz.getMethod("userData", String.class);
+                            } catch (SecurityException e) {
+                                LOG.info("Problem reflectively inspecting methods of "+t.getClass()+" for setting userData", e);
+                            } catch (NoSuchMethodException e) {
+                                try {
+                                    // For vCloud Director
+                                    userDataMethod = clazz.getMethod("guestCustomizationScript", String.class);
+                                } catch (NoSuchMethodException e2) {
+                                    // expected on various other clouds
+                                }
+                            }
+                            if (userDataMethod != null) {
+                                try {
+                                    userDataMethod.invoke(t, Strings.toString(v));
+                                } catch (InvocationTargetException e) {
+                                    LOG.info("Problem invoking "+userDataMethod.getName()+" of "+t.getClass()+", for setting userData (rethrowing)", e);
+                                    throw Exceptions.propagate(e);
+                                } catch (IllegalAccessException e) {
+                                    LOG.debug("Unable to reflectively invoke "+userDataMethod.getName()+" of "+t.getClass()+", for setting userData (rethrowing)", e);
+                                    throw Exceptions.propagate(e);
+                                }
+                            } else {
+                                LOG.info("ignoring userDataString({}) in VM creation because not supported for cloud/type ({})", v, t.getClass());
+                            }
+                        }
+                    }})
+            .put(USER_DATA_UUENCODED, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof EC2TemplateOptions) {
+                            byte[] bytes = toByteArray(v);
+                            ((EC2TemplateOptions)t).userData(bytes);
+                        } else if (t instanceof SoftLayerTemplateOptions) {
+                            ((SoftLayerTemplateOptions)t).userData(Strings.toString(v));
+                        } else {
+                            LOG.info("ignoring userData({}) in VM creation because not supported for cloud/type ({})", v, t.getClass());
+                        }
+                    }})
+            .put(STRING_TAGS, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        List<String> tags = toListOfStrings(v);
+                        if (LOG.isDebugEnabled()) LOG.debug("setting VM tags {} for {}", tags, t);
+                        t.tags(tags);
+                    }})
+            .put(USER_METADATA_MAP, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (v != null) {
+                            t.userMetadata(toMapStringString(v));
+                        }
+                    }})
+            .put(EXTRA_PUBLIC_KEY_DATA_TO_AUTH, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        t.authorizePublicKey(((CharSequence)v).toString());
+                    }})
+            .put(RUN_AS_ROOT, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        t.runAsRoot((Boolean)v);
+                    }})
+            .put(LOGIN_USER, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (v != null) {
+                            t.overrideLoginUser(((CharSequence)v).toString());
+                        }
+                    }})
+            .put(LOGIN_USER_PASSWORD, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (v != null) {
+                            t.overrideLoginPassword(((CharSequence)v).toString());
+                        }
+                    }})
+            .put(LOGIN_USER_PRIVATE_KEY_FILE, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (v != null) {
+                            String privateKeyFileName = ((CharSequence)v).toString();
+                            String privateKey;
+                            try {
+                                privateKey = Files.toString(new File(Os.tidyPath(privateKeyFileName)), Charsets.UTF_8);
+                            } catch (IOException e) {
+                                LOG.error(privateKeyFileName + "not found", e);
+                                throw Exceptions.propagate(e);
+                            }
+                            t.overrideLoginPrivateKey(privateKey);
+                        }
+                    }})
+            .put(LOGIN_USER_PRIVATE_KEY_DATA, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (v != null) {
+                            t.overrideLoginPrivateKey(((CharSequence)v).toString());
+                        }
+                    }})
+            .put(KEY_PAIR, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof EC2TemplateOptions) {
+                            ((EC2TemplateOptions)t).keyPair(((CharSequence)v).toString());
+                        } else if (t instanceof NovaTemplateOptions) {
+                            ((NovaTemplateOptions)t).keyPairName(((CharSequence)v).toString());
+                        } else if (t instanceof CloudStackTemplateOptions) {
+                            ((CloudStackTemplateOptions) t).keyPair(((CharSequence) v).toString());
+                        } else {
+                            LOG.info("ignoring keyPair({}) in VM creation because not supported for cloud/type ({})", v, t);
+                        }
+                    }})
+            .put(AUTO_GENERATE_KEYPAIRS, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof NovaTemplateOptions) {
+                            ((NovaTemplateOptions)t).generateKeyPair((Boolean)v);
+                        } else if (t instanceof CloudStackTemplateOptions) {
+                            ((CloudStackTemplateOptions) t).generateKeyPair((Boolean) v);
+                        } else {
+                            LOG.info("ignoring auto-generate-keypairs({}) in VM creation because not supported for cloud/type ({})", v, t);
+                        }
+                    }})
+            .put(AUTO_CREATE_FLOATING_IPS, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof NovaTemplateOptions) {
+                            ((NovaTemplateOptions)t).autoAssignFloatingIp((Boolean)v);
+                        } else {
+                            LOG.info("ignoring auto-generate-floating-ips({}) in VM creation because not supported for cloud/type ({})", v, t);
+                        }
+                    }})
+            .put(AUTO_ASSIGN_FLOATING_IP, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof NovaTemplateOptions) {
+                            ((NovaTemplateOptions)t).autoAssignFloatingIp((Boolean)v);
+                        } else if (t instanceof CloudStackTemplateOptions) {
+                            ((CloudStackTemplateOptions)t).setupStaticNat((Boolean)v);
+                        } else {
+                            LOG.info("ignoring auto-assign-floating-ip({}) in VM creation because not supported for cloud/type ({})", v, t);
+                        }
+                    }})
+            .put(NETWORK_NAME, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof AWSEC2TemplateOptions) {
+                            // subnet ID is the sensible interpretation of network name in EC2
+                            ((AWSEC2TemplateOptions)t).subnetId((String)v);
+                            
+                        } else {
+                            if (t instanceof GoogleComputeEngineTemplateOptions) {
+                                // no warning needed
+                                // we think this is the only jclouds endpoint which supports this option
+                                
+                            } else if (t instanceof SoftLayerTemplateOptions) {
+                                LOG.warn("networkName is not be supported in SoftLayer; use `templateOptions` with `primaryNetworkComponentNetworkVlanId` or `primaryNetworkBackendComponentNetworkVlanId`");
+                            } else if (!(t instanceof CloudStackTemplateOptions) && !(t instanceof NovaTemplateOptions)) {
+                                LOG.warn("networkName is experimental in many jclouds endpoints may not be supported in this cloud");
+                                // NB, from @andreaturli
+//                                Cloudstack uses custom securityGroupIds and networkIds not the generic networks
+//                                Openstack Nova uses securityGroupNames which is marked as @deprecated (suggests to use groups which is maybe even more confusing)
+//                                Azure supports the custom networkSecurityGroupName
+                            }
+                            
+                            t.networks((String)v);
+                        }
+                    }})
+            .put(DOMAIN_NAME, new CustomizeTemplateOptions() {
+                    public void apply(TemplateOptions t, ConfigBag props, Object v) {
+                        if (t instanceof SoftLayerTemplateOptions) {
+                            ((SoftLayerTemplateOptions)t).domainName(TypeCoercions.coerce(v, String.class));
+                        } else {
+                            LOG.info("ignoring domain-name({}) in VM creation because not supported for cloud/type ({})", v, t);                            
+                        }
+                    }})
+            .put(TEMPLATE_OPTIONS, new CustomizeTemplateOptions() {
+                @Override
+                public void apply(TemplateOptions options, ConfigBag config, Object v) {
+                    if (v == null) return;
+                    @SuppressWarnings("unchecked") Map<String, Object> optionsMap = (Map<String, Object>) v;
+                    if (optionsMap.isEmpty()) return;
+
+                    Class<? extends TemplateOptions> clazz = options.getClass();
+                    for(final Map.Entry<String, Object> option : optionsMap.entrySet()) {
+                        Maybe<?> result = MethodCoercions.tryFindAndInvokeBestMatchingMethod(options, option.getKey(), option.getValue());
+                        if(result.isAbsent()) {
+                            LOG.warn("Ignoring request to set template option {} because this is not supported by {}", new Object[] { option.getKey(), clazz.getCanonicalName() });
+                        }
+                    }
+                }})
+            .build();
+
+    /** hook whereby template customizations can be made for various clouds */
+    protected void customizeTemplate(ConfigBag setup, ComputeService computeService, Template template) {
+        for (JcloudsLocationCustomizer customizer : getCustomizers(setup)) {
+            customizer.customize(this, computeService, template);
+            customizer.customize(this, computeService, template.getOptions());
+        }
+
+        // these things are nice on softlayer
+        if (template.getOptions() instanceof SoftLayerTemplateOptions) {
+            SoftLayerTemplateOptions slT = ((SoftLayerTemplateOptions)template.getOptions());
+            if (Strings.isBlank(slT.getDomainName()) || "jclouds.org".equals(slT.getDomainName())) {
+                // set a quasi-sensible domain name if none was provided (better than the default, jclouds.org)
+                // NB: things like brooklyn.local are disallowed
+                slT.domainName("local.brooklyncentral.org");
+            }
+            // convert user metadata to tags and notes because user metadata is otherwise ignored
+            Map<String, String> md = slT.getUserMetadata();
+            if (md!=null && !md.isEmpty()) {
+                Set<String> tags = MutableSet.copyOf(slT.getTags());
+                for (Map.Entry<String,String> entry: md.entrySet()) {
+                    tags.add(AbstractCloudMachineNamer.sanitize(entry.getKey())+":"+AbstractCloudMachineNamer.sanitize(entry.getValue()));
+                }
+                slT.tags(tags);
+
+                if (!md.containsKey("notes")) {
+                    String notes = "User Metadata\n=============\n\n  * " + Joiner.on("\n  * ").withKeyValueSeparator(": ").join(md);
+                    if (notes.length() > NOTES_MAX_LENGTH) {
+                        String truncatedMsg = "...\n<truncated - notes total length is " + notes.length() + " characters>";
+                        notes = notes.substring(0, NOTES_MAX_LENGTH - truncatedMsg.length()) + truncatedMsg;
+                    }
+                    md.put("notes", notes);
+                }
+            }
+        }
+    }
+
+    /** returns the jclouds Template which describes the image to be built, for the given config and compute service */
+    public Template buildTemplate(ComputeService computeService, ConfigBag config) {
+        TemplateBuilder templateBuilder = (TemplateBuilder) config.get(TEMPLATE_BUILDER);
+        if (templateBuilder==null) {
+            templateBuilder = new PortableTemplateBuilder<PortableTemplateBuilder<?>>();
+        } else {
+            LOG.debug("jclouds using templateBuilder {} as custom base for provisioning in {} for {}", new Object[] {
+                    templateBuilder, this, config.getDescription()});
+        }
+        if (templateBuilder instanceof PortableTemplateBuilder<?>) {
+            if (((PortableTemplateBuilder<?>)templateBuilder).imageChooser()==null) {
+                Function<Iterable<? extends Image>, Image> chooser = config.get(JcloudsLocationConfig.IMAGE_CHOOSER);
+                chooser = BrooklynImageChooser.cloneFor(chooser, computeService);
+                templateBuilder.imageChooser(chooser);
+            } else {
+                // an image chooser is already set, so do nothing
+            }
+        } else {
+            // template builder supplied, and we cannot check image chooser status; warn, for now
+            LOG.warn("Cannot check imageChooser status for {} due to manually supplied black-box TemplateBuilder; "
+                + "it is recommended to use a PortableTemplateBuilder if you supply a TemplateBuilder", config.getDescription());
+        }
+
+        if (!Strings.isEmpty(config.get(CLOUD_REGION_ID))) {
+            templateBuilder.locationId(config.get(CLOUD_REGION_ID));
+        }
+
+        // Apply the template builder and options properties
+        for (Map.Entry<ConfigKey<?>, CustomizeTemplateBuilder> entry : SUPPORTED_TEMPLATE_BUILDER_PROPERTIES.entrySet()) {
+            ConfigKey<?> name = entry.getKey();
+            CustomizeTemplateBuilder code = entry.getValue();
+            if (config.containsKey(name))
+                code.apply(templateBuilder, config, config.get(name));
+        }
+
+        if (templateBuilder instanceof PortableTemplateBuilder) {
+            ((PortableTemplateBuilder<?>)templateBuilder).attachComputeService(computeService);
+            // do the default last, and only if nothing else specified (guaranteed to be a PTB if nothing else specified)
+            if (groovyTruth(config.get(DEFAULT_IMAGE_ID))) {
+                if (((PortableTemplateBuilder<?>)templateBuilder).isBlank()) {
+                    templateBuilder.imageId(config.get(DEFAULT_IMAGE_ID).toString());
+                }
+            }
+        }
+
+        // Then apply any optional app-specific customization.
+        for (JcloudsLocationCustomizer customizer : getCustomizers(config)) {
+            customizer.customize(this, computeService, templateBuilder);
+        }
+
+        LOG.debug("jclouds using templateBuilder {} for provisioning in {} for {}", new Object[] {
+            templateBuilder, this, config.getDescription()});
+
+        // Finally try to build the template
+        Template template;
+        Image image;
+        try {
+            template = templateBuilder.build();
+            if (template==null) throw new NullPointerException("No template found (templateBuilder.build returned null)");
+            image = template.getImage();
+            LOG.debug("jclouds found template "+template+" (image "+image+") for provisioning in "+this+" for "+config.getDescription());
+            if (image==null) throw new NullPointerException("Template does not contain an image (templateBuilder.build returned invalid template)");
+        } catch (AuthorizationException e) {
+            LOG.warn("Error resolving template: not authorized (rethrowing: "+e+")");
+            throw new IllegalStateException("Not authorized to access cloud "+this+" to resolve "+templateBuilder, e);
+        } catch (Exception e) {
+            try {
+                IOException ioe = Exceptions.getFirstThrowableOfType(e, IOException.class);
+                if (ioe != null) {
+                    LOG.warn("IOException found...", ioe);
+                    throw ioe;
+                }
+                if (listedAvailableTemplatesOnNoSuchTemplate.compareAndSet(false, true)) {
+                    // delay subsequent log.warns (put in synch block) so the "Loading..." message is obvious
+                    LOG.warn("Unable to match required VM template constraints "+templateBuilder+" when trying to provision VM in "+this+" (rethrowing): "+e);
+                    logAvailableTemplates(config);
+                }
+            } catch (Exception e2) {
+                LOG.warn("Error loading available images to report (following original error matching template which will be rethrown): "+e2, e2);
+                throw new IllegalStateException("Unable to access cloud "+this+" to resolve "+templateBuilder+": "+e, e);
+            }
+            throw new IllegalStateException("Unable to match required VM template constraints "+templateBuilder+" when trying to provision VM in "+this+"; "
+                + "see list of images in log. Root cause: "+e, e);
+        }
+        TemplateOptions options = template.getOptions();
+
+        boolean windows = isWindows(template, config);
+        if (windows) {
+            if (!(config.containsKey(JcloudsLocationConfig.USER_METADATA_STRING) || config.containsKey(JcloudsLocationConfig.USER_METADATA_MAP))) {
+                config.put(JcloudsLocationConfig.USER_METADATA_STRING, WinRmMachineLocation.getDefaultUserMetadataString());
+            }
+        }
+               
+        for (Map.Entry<ConfigKey<?>, CustomizeTemplateOptions> entry : SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.entrySet()) {
+            ConfigKey<?> key = entry.getKey();
+            CustomizeTemplateOptions code = entry.getValue();
+            if (config.containsKey(key))
+                code.apply(options, config, config.get(key));
+        }
+
+        return template;
+    }
+
+    protected void logAvailableTemplates(ConfigBag config) {
+        LOG.info("Loading available images at "+this+" for reference...");
+        ConfigBag m1 = ConfigBag.newInstanceCopying(config);
+        if (m1.containsKey(IMAGE_ID)) {
+            // if caller specified an image ID, remove that, but don't apply default filters
+            m1.remove(IMAGE_ID);
+            // TODO use key
+            m1.putStringKey("anyOwner", true);
+        }
+        ComputeService computeServiceLessRestrictive = getConfig(COMPUTE_SERVICE_REGISTRY).findComputeService(m1, true);
+        Set<? extends Image> imgs = computeServiceLessRestrictive.listImages();
+        LOG.info(""+imgs.size()+" available images at "+this);
+        for (Image img: imgs) {
+            LOG.info(" Image: "+img);
+        }
+
+        Set<? extends Hardware> profiles = computeServiceLessRestrictive.listHardwareProfiles();
+        LOG.info(""+profiles.size()+" available profiles at "+this);
+        for (Hardware profile: profiles) {
+            LOG.info(" Profile: "+profile);
+        }
+
+        Set<? extends org.jclouds.domain.Location> assignableLocations = computeServiceLessRestrictive.listAssignableLocations();
+        LOG.info(""+assignableLocations.size()+" available locations at "+this);
+        for (org.jclouds.domain.Location assignableLocation: assignableLocations) {
+            LOG.info(" Location: "+assignableLocation);
+        }
+    }
+
+    protected SshMachineLocation createTemporarySshMachineLocation(HostAndPort hostAndPort, LoginCredentials creds, ConfigBag config) {
+        Optional<String> initialPassword = creds.getOptionalPassword();
+        Optional<String> initialPrivateKey = creds.getOptionalPrivateKey();
+        String initialUser = creds.getUser();
+
+        Map<String,Object> sshProps = Maps.newLinkedHashMap(config.getAllConfig());
+        sshProps.put("user", initialUser);
+        sshProps.put("address", hostAndPort.getHostText());
+        sshProps.put("port", hostAndPort.getPort());
+        sshProps.put(AbstractLocation.TEMPORARY_LOCATION.getName(), true);
+        if (initialPassword.isPresent()) sshProps.put("password", initialPassword.get());
+        if (initialPrivateKey.isPresent()) sshProps.put("privateKeyData", initialPrivateKey.get());
+        if (initialPrivateKey.isPresent()) sshProps.put("privateKeyData", initialPrivateKey.get());
+
+        if (isManaged()) {
+            return getManagementContext().getLocationManager().createLocation(sshProps, SshMachineLocation.class);
+        } else {
+            return new SshMachineLocation(sshProps);
+        }
+    }
+
+    /**
+     * Create the user immediately - executing ssh commands as required.
+     */
+    protected LoginCredentials createUser(ComputeService computeService, NodeMetadata node, Optional<HostAndPort> hostAndPortOverride, ConfigBag config) {
+        Image image = (node.getImageId() != null) ? computeService.getImage(node.getImageId()) : null;
+        UserCreation userCreation = createUserStatements(image, config);
+
+        if (!userCreation.statements.isEmpty()) {
+            // If unsure of OS family, default to unix for rendering statements.
+            org.jclouds.scriptbuilder.domain.OsFamily scriptOsFamily;
+            if (isWindows(node, config)) {
+                scriptOsFamily = org.jclouds.scriptbuilder.domain.OsFamily.WINDOWS;
+            } else {
+                scriptOsFamily = org.jclouds.scriptbuilder.domain.OsFamily.UNIX;
+            }
+
+            boolean windows = isWindows(node, config);
+
+            if (windows) {
+                LOG.warn("Unable to execute statements on WinRM in JcloudsLocation; skipping for "+node+": "+userCreation.statements);
+                
+            } else {
+                List<String> commands = Lists.newArrayList();
+                for (Statement statement : userCreation.statements) {
+                    InitAdminAccess initAdminAccess = new InitAdminAccess(new AdminAccessConfiguration.Default());
+                    initAdminAccess.visit(statement);
+                    commands.add(statement.render(scriptOsFamily));
+                }
+
+                LoginCredentials initialCredentials = node.getCredentials();
+                Optional<String> initialPassword = initialCredentials.getOptionalPassword();
+                Optional<String> initialPrivateKey = initialCredentials.getOptionalPrivateKey();
+           

<TRUNCATED>


[48/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java
index 6a7e297..a7a8abe 100644
--- a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLiveTest.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertTrue;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -33,7 +34,6 @@ import com.google.common.collect.ImmutableList;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Attributes;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 
 public class ServerPoolLiveTest extends AbstractServerPoolTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java
index 6b6c045..e6c3ab6 100644
--- a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java
+++ b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolLocationResolverTest.java
@@ -24,6 +24,8 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.Assert;
@@ -37,10 +39,10 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.dynamic.DynamicLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java
index ef7c8c4..ba0e938 100644
--- a/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java
+++ b/software/base/src/test/java/brooklyn/entity/pool/ServerPoolTest.java
@@ -26,6 +26,7 @@ import java.util.Collection;
 import java.util.Iterator;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -34,7 +35,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Lifecycle;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
 
 import com.google.common.base.Joiner;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java b/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java
index e64ccdb..c0bf566 100644
--- a/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/AbstractDockerLiveTest.java
@@ -21,7 +21,6 @@ package brooklyn.entity.software;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 
@@ -29,6 +28,7 @@ import com.google.common.base.CaseFormat;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java b/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java
index ae5f436..599b7ac 100644
--- a/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/SoftwareEffectorTest.java
@@ -21,6 +21,7 @@ package brooklyn.entity.software;
 import java.util.Arrays;
 
 import org.apache.brooklyn.api.entity.Effector;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -34,9 +35,10 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.software.SshEffectorTasks.SshEffectorBody;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.system.ProcessTaskWrapper;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java b/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java
index dcea2bb..8494e36 100644
--- a/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/SshEffectorTasksTest.java
@@ -22,6 +22,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
 
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.TaskAdaptable;
 import org.apache.brooklyn.api.management.TaskFactory;
@@ -35,9 +36,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.exceptions.PropagatedRuntimeException;
 import brooklyn.util.net.Urls;
 import brooklyn.util.task.ssh.SshFetchTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java b/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
index 81a2a5b..eb53f3e 100644
--- a/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/http/HttpRequestSensorTest.java
@@ -21,6 +21,7 @@ package brooklyn.entity.software.http;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -31,7 +32,6 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.TestHttpRequestHandler;
 import brooklyn.test.TestHttpServer;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java b/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java
index 6521467..98bae62 100644
--- a/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/mysql/AbstractToyMySqlEntityTest.java
@@ -19,6 +19,8 @@
 package brooklyn.entity.software.mysql;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,10 +32,10 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.task.system.ProcessTaskWrapper;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java b/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java
index b7144dd..df3e436 100644
--- a/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java
+++ b/software/base/src/test/java/brooklyn/entity/software/mysql/DynamicToyMySqlEntityBuilder.java
@@ -24,6 +24,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntityInitializer;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,11 +34,11 @@ import brooklyn.entity.basic.BasicStartable;
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.OsDetails;
+
 import org.apache.brooklyn.location.basic.BasicOsDetails.OsVersions;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.ssh.BashCommands;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.task.Tasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java
index c69fb37..2d142e4 100644
--- a/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/ssh/SshCommandIntegrationTest.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -38,8 +39,9 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java b/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java
index 2db5108..3698a91 100644
--- a/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java
+++ b/software/base/src/test/java/brooklyn/event/basic/PortAttributeSensorAndConfigKeyTest.java
@@ -22,13 +22,14 @@ import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.EmptySoftwareProcessImpl;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java b/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java
index 6e444c1..433370a 100644
--- a/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java
+++ b/software/base/src/test/java/brooklyn/event/feed/jmx/RebindJmxFeedTest.java
@@ -25,6 +25,7 @@ import java.util.Collection;
 import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.apache.brooklyn.test.entity.TestEntityImpl;
@@ -42,9 +43,10 @@ import brooklyn.entity.java.UsesJmx.JmxAgentModes;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
 import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.ConfigToAttributes;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.test.GeneralisedDynamicMBean;
 import brooklyn.test.JmxService;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java b/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
index fac6ee4..4d032df 100644
--- a/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
+++ b/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -40,7 +41,6 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.proxying.EntityProxy;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.management.internal.UsageListener.ApplicationMetadata;
 import brooklyn.management.usage.ApplicationUsage.ApplicationEvent;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java b/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java
index fb047ef..61032c4 100644
--- a/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java
+++ b/software/base/src/test/java/brooklyn/management/usage/LocationUsageTrackingTest.java
@@ -28,17 +28,19 @@ import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.SoftwareProcessEntityTest;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.management.internal.UsageListener.LocationMetadata;
 import brooklyn.management.usage.LocationUsage.LocationEvent;
 import brooklyn.test.Asserts;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java b/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java
index ea3dedb..863f587 100644
--- a/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java
+++ b/software/base/src/test/java/brooklyn/management/usage/UsageListenerTest.java
@@ -32,7 +32,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
+
 import brooklyn.management.internal.ManagementContextInternal;
 import brooklyn.management.internal.UsageManager;
 import brooklyn.test.Asserts;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
index fce5c94..105479d 100644
--- a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsEc2LiveTest.java
@@ -23,6 +23,9 @@ import static org.testng.Assert.assertNotNull;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,9 +35,6 @@ import com.google.common.collect.ImmutableList;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineDetails;
-import org.apache.brooklyn.location.OsDetails;
 import brooklyn.util.collections.MutableMap;
 
 // This test really belongs in brooklyn-location but depends on AbstractEc2LiveTest in brooklyn-software-base

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
index bcee1a3..36db1f4 100644
--- a/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/location/basic/MachineDetailsGoogleComputeLiveTest.java
@@ -23,9 +23,9 @@ import static org.testng.Assert.assertNotNull;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineDetails;
-import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java b/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
index 97b9358..103c3f0 100644
--- a/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/location/basic/WinRmMachineLocationTest.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.location.basic;
 
 import static org.testng.Assert.assertEquals;
 
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
index 1833024..b35a1cd 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
@@ -39,8 +39,10 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.database.DatastoreMixins;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.OsDetails;
+
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java
index c0cfb46..6f752c2 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlClusterImpl.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.base.Function;
 import com.google.common.base.Functions;
@@ -52,7 +53,6 @@ import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.basic.Sensors;
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.guava.Functionals;
 import brooklyn.util.guava.IfFunctions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java
index e600e5b..2e748e8 100644
--- a/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java
+++ b/software/database/src/main/java/brooklyn/entity/database/mysql/MySqlSshDriver.java
@@ -41,9 +41,11 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.database.DatastoreMixins;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.OsDetails;
+
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.location.basic.BasicOsDetails.OsVersions;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.io.FileUtil;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
index 29f9c10..a23f2bc 100644
--- a/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
+++ b/software/database/src/main/java/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
@@ -46,8 +46,10 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.database.DatastoreMixins;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.OsDetails;
+
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java
index f1e7886..a860f1c 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mariadb/MariaDbLiveEc2Test.java
@@ -19,12 +19,13 @@
 package brooklyn.entity.database.mariadb;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java
index 807b462..477f81b 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveEc2Test.java
@@ -21,7 +21,8 @@ package brooklyn.entity.database.mysql;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 @Test(groups = { "Live" })
 public class MySqlClusterLiveEc2Test extends AbstractEc2LiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java
index 06bd0bc..6f1556c 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterLiveSoftlayerTest.java
@@ -21,7 +21,8 @@ package brooklyn.entity.database.mysql;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 @Test(groups = { "Live" })
 public class MySqlClusterLiveSoftlayerTest extends AbstractSoftlayerLiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
index 7fac59a..739d818 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlClusterTestHelper.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals;
 import java.util.List;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,7 +34,6 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 
 import brooklyn.entity.database.VogellaExampleAccess;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
index e874ce6..c9d5e97 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveEc2Test.java
@@ -19,12 +19,12 @@
 package brooklyn.entity.database.mysql;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
index b5e4543..f6322bd 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MySqlLiveGceTest.java
@@ -19,12 +19,12 @@
 package brooklyn.entity.database.mysql;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
index aa7ae45..0642dd6 100644
--- a/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/mysql/MysqlDockerLiveTest.java
@@ -21,11 +21,11 @@ package brooklyn.entity.database.mysql;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
 import brooklyn.entity.software.AbstractDockerLiveTest;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 public class MysqlDockerLiveTest extends AbstractDockerLiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java
index 8a4805c..8b23415 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqDockerLiveTest.java
@@ -21,11 +21,11 @@ package brooklyn.entity.database.postgresql;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
 import brooklyn.entity.software.AbstractDockerLiveTest;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 public class PostgreSqDockerLiveTest extends AbstractDockerLiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
index 6f650ec..5d8e984 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
@@ -31,9 +31,11 @@ import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
 import brooklyn.entity.effector.EffectorTasks;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.PortRange;
+
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.location.basic.PortRanges;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.task.system.ProcessTaskWrapper;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java
index f90f6fa..5eda573 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlEc2LiveTest.java
@@ -19,12 +19,12 @@
 package brooklyn.entity.database.postgresql;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java
index 4ae3600..70e44e0 100644
--- a/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlGceLiveTest.java
@@ -19,12 +19,12 @@
 package brooklyn.entity.database.postgresql;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.VogellaExampleAccess;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java
index 02a00fc..c53db06 100644
--- a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepEc2LiveTest.java
@@ -19,13 +19,14 @@
 package brooklyn.entity.database.rubyrep;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
 import brooklyn.entity.database.postgresql.PostgreSqlNode;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.PortRanges;
 
 public class RubyRepEc2LiveTest extends AbstractEc2LiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
index 0ef7081..e56b990 100644
--- a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepIntegrationTest.java
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -41,9 +42,10 @@ import brooklyn.entity.database.mysql.MySqlIntegrationTest;
 import brooklyn.entity.database.mysql.MySqlNode;
 import brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
 import brooklyn.entity.database.postgresql.PostgreSqlNode;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.management.internal.LocalManagementContext;
 
 public class RubyRepIntegrationTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java
index da28512..845dce7 100644
--- a/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java
+++ b/software/database/src/test/java/brooklyn/entity/database/rubyrep/RubyRepRackspaceLiveTest.java
@@ -21,14 +21,16 @@ package brooklyn.entity.database.rubyrep;
 import java.util.Arrays;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
 import brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
 import brooklyn.entity.database.postgresql.PostgreSqlNode;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.PortRanges;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.net.Protocol;
 import brooklyn.util.ssh.IptablesCommands;
 import brooklyn.util.ssh.IptablesCommands.Chain;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
index 99020bc..b5b8449 100644
--- a/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
+++ b/software/messaging/src/main/java/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,7 +34,6 @@ import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperNode;
 import brooklyn.event.feed.ConfigToAttributes;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.exceptions.CompoundRuntimeException;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java
index 4c0a73a..75db6ff 100644
--- a/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java
+++ b/software/messaging/src/main/java/brooklyn/entity/zookeeper/ZooKeeperEnsembleImpl.java
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,7 +33,6 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.Lists;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java
index fc58d6f..aaffda8 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQEc2LiveTest.java
@@ -29,12 +29,12 @@ import javax.jms.TextMessage;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java
index 698bc5e..e26dc2d 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQGoogleComputeLiveTest.java
@@ -20,12 +20,12 @@ package brooklyn.entity.messaging.activemq;
 
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java
index d156b4d..e6b6db5 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/activemq/ActiveMQIntegrationTest.java
@@ -32,6 +32,7 @@ import javax.jms.TextMessage;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -46,7 +47,6 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.java.UsesJmx;
 import brooklyn.entity.java.UsesJmx.JmxAgentModes;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java
index d568bd2..39d3e59 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaIntegrationTest.java
@@ -25,6 +25,8 @@ import static org.testng.Assert.assertTrue;
 import java.util.concurrent.Callable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -35,9 +37,9 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.messaging.activemq.ActiveMQBroker;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java
index 0656bc6..7d122c6 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/kafka/KafkaLiveTest.java
@@ -24,11 +24,11 @@ import static org.testng.Assert.assertTrue;
 import java.util.concurrent.Callable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java
index d3a860c..06af482 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidEc2LiveTest.java
@@ -19,11 +19,11 @@
 package brooklyn.entity.messaging.qpid;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java
index 7c5d262..7346297 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/qpid/QpidIntegrationTest.java
@@ -34,6 +34,7 @@ import javax.jms.Session;
 import javax.jms.TextMessage;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -50,7 +51,6 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java
index 7db574b..8eaa991 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitEc2LiveTest.java
@@ -21,6 +21,7 @@ package brooklyn.entity.messaging.rabbit;
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,7 +31,6 @@ import org.testng.annotations.Test;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.messaging.MessageBroker;
 import brooklyn.entity.messaging.amqp.AmqpExchange;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java
index d08eb97..c5f6f22 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/rabbit/RabbitIntegrationTest.java
@@ -24,6 +24,7 @@ import static org.testng.Assert.assertFalse;
 import java.io.IOException;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -37,7 +38,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.messaging.MessageBroker;
 import brooklyn.entity.messaging.amqp.AmqpExchange;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 import com.google.common.base.Charsets;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
index f18af02..a2317ec 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
@@ -29,6 +29,7 @@ import java.io.File;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -50,7 +51,6 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.messaging.storm.topologies.ExclamationBolt;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperEnsemble;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java
index 35a83f4..d949450 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/storm/StormEc2LiveTest.java
@@ -19,6 +19,7 @@
 package brooklyn.entity.messaging.storm;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
@@ -26,7 +27,6 @@ import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperNode;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java
index ccb8f5d..a6c7d2b 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEc2LiveTest.java
@@ -19,6 +19,7 @@
 package brooklyn.entity.messaging.zookeeper;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
@@ -26,7 +27,6 @@ import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperNode;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java b/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java
index 42091fd..cb21c18 100644
--- a/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java
+++ b/software/messaging/src/test/java/brooklyn/entity/messaging/zookeeper/ZooKeeperEnsembleLiveTest.java
@@ -24,7 +24,6 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.zookeeper.ZooKeeperEnsemble;
 import brooklyn.entity.zookeeper.ZooKeeperNode;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
@@ -32,6 +31,7 @@ import com.google.common.util.concurrent.Uninterruptibles;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
index dd712c4..7f71754 100644
--- a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
+++ b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.entity.monitoring.monit;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -28,8 +29,9 @@ import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshPollValue;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.text.Strings;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java
index 28b8548..b9e55af 100644
--- a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java
+++ b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitSshDriver.java
@@ -26,8 +26,10 @@ import java.util.Map;
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
-import org.apache.brooklyn.location.OsDetails;
+
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;
 import brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java b/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
index 4cb8e39..5b58c72 100644
--- a/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
+++ b/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import java.util.concurrent.Callable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.MachineDetails;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -42,8 +43,9 @@ import brooklyn.entity.basic.SameServerEntity;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.database.mysql.MySqlNode;
 import brooklyn.event.basic.DependentConfiguration;
-import org.apache.brooklyn.location.MachineDetails;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.test.Asserts;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java
index a766dd1..20c0e36 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerByonLiveTest.java
@@ -25,7 +25,9 @@ import org.testng.annotations.Parameters;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
+
 import brooklyn.util.text.Strings;
 
 public class BindDnsServerByonLiveTest extends BrooklynAppLiveTestSupport {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java
index e9cbaff..7347a26 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerEc2LiveTest.java
@@ -22,7 +22,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 public class BindDnsServerEc2LiveTest extends AbstractEc2LiveTest {
     private static final Logger LOG = LoggerFactory.getLogger(BindDnsServerEc2LiveTest.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java
index d73eb0c..8a7bbd6 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerLiveTest.java
@@ -22,6 +22,7 @@ import static org.apache.brooklyn.test.EntityTestUtils.assertAttributeEqualsEven
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.EnricherSpec;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -37,7 +38,6 @@ import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SameServerEntity;
 import brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.repeat.Repeater;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java
index ffe391d..01a0d1e 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerSoftlayerLiveTest.java
@@ -21,7 +21,8 @@ package org.apache.brooklyn.entity.network.bind;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 public class BindDnsServerSoftlayerLiveTest extends AbstractSoftlayerLiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
index 44141a6..9ae4edd 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,8 +48,9 @@ import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.Machines;
+
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
index a3cf775..8a5fe34 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
@@ -24,13 +24,13 @@ import org.apache.brooklyn.api.catalog.Catalog;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.annotation.Effector;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.group.DynamicFabric;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Function;
 import com.google.common.collect.Multimap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java
index 6ae43b5..1922c10 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,7 +39,6 @@ import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicFabricImpl;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
index 41c3d97..2d82d19 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
@@ -34,6 +34,8 @@ import javax.management.ObjectName;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,10 +54,10 @@ import brooklyn.event.feed.jmx.JmxAttributePollConfig;
 import brooklyn.event.feed.jmx.JmxFeed;
 import brooklyn.event.feed.jmx.JmxHelper;
 import brooklyn.event.feed.jmx.JmxOperationPollConfig;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.Machines;
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
index 88a66c2..c3a57b0 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
@@ -29,6 +29,7 @@ import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.TaskWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,10 +45,11 @@ import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
 import brooklyn.entity.java.UsesJmx;
 import brooklyn.entity.software.SshEffectorTasks;
 import brooklyn.event.basic.DependentConfiguration;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import org.apache.brooklyn.location.basic.Machines;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
index eaf8794..07b34b4 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
@@ -29,6 +29,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.http.auth.UsernamePasswordCredentials;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,9 +41,10 @@ import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.event.feed.http.JsonFunctions;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
index cf80118..41bef9f 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
@@ -31,6 +31,7 @@ import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.http.auth.UsernamePasswordCredentials;
 
@@ -43,9 +44,10 @@ import brooklyn.entity.drivers.downloads.DownloadProducerFromUrlAttribute;
 import brooklyn.entity.software.SshEffectorTasks;
 import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.location.OsDetails;
+
 import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
index f3d7636..5d598e5 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
@@ -29,13 +29,15 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
+import org.apache.brooklyn.api.location.OsDetails;
 
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.event.basic.DependentConfiguration;
-import org.apache.brooklyn.location.OsDetails;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.ssh.BashCommands;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java
index 308aede..845c3a0 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java
@@ -29,8 +29,10 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Attributes;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
index 6a4c052..c7f6723 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
@@ -23,14 +23,16 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
-import org.apache.brooklyn.location.OsDetails;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;



[11/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationTest.java
deleted file mode 100644
index 5821a07..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLocationTest.java
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.jclouds.scriptbuilder.domain.OsFamily;
-import org.jclouds.scriptbuilder.domain.StatementList;
-import org.mockito.Mockito;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.reflect.TypeToken;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineLocationCustomizer;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.cloud.names.CustomMachineNamer;
-import brooklyn.location.geo.HostGeoInfo;
-import brooklyn.location.jclouds.JcloudsLocation.UserCreation;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.exceptions.Exceptions;
-
-/**
- * @author Shane Witbeck
- */
-public class JcloudsLocationTest implements JcloudsLocationConfig {
-
-    private static final Logger log = LoggerFactory.getLogger(JcloudsLocationTest.class);
-    
-    public static Predicate<ConfigBag> checkerFor(final String user, final Integer minRam, final Integer minCores) {
-        return new Predicate<ConfigBag>() {
-            @Override
-            public boolean apply(@Nullable ConfigBag input) {
-                Assert.assertEquals(input.get(USER), user);
-                Assert.assertEquals(input.get(MIN_RAM), minRam);
-                Assert.assertEquals(input.get(MIN_CORES), minCores);
-                return true;
-            }
-        };
-    }
-    
-    public static Predicate<ConfigBag> templateCheckerFor(final String ports) {
-        return new Predicate<ConfigBag>() {
-            @Override
-            public boolean apply(@Nullable ConfigBag input) {
-                Assert.assertEquals(input.get(INBOUND_PORTS), ports);
-                return false;
-            }
-        };
-    }
-    
-    private LocalManagementContext managementContext;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance(BrooklynProperties.Factory.builderEmpty().build());
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearUp() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testCreateWithFlagsDirectly() throws Exception {
-        BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
-        jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 2), checkerFor("fred", 16, 2));
-    }
-
-    @Test
-    public void testCreateWithFlagsDirectlyAndOverride() throws Exception {
-        BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
-        jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 2, MIN_RAM, 8), checkerFor("fred", 8, 2));
-    }
-
-    @Test
-    public void testCreateWithFlagsSubLocation() throws Exception {
-        BailOutJcloudsLocation jcl = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
-        jcl = (BailOutJcloudsLocation) jcl.newSubLocation(MutableMap.of(USER, "jon", MIN_CORES, 2));
-        jcl.tryObtainAndCheck(MutableMap.of(MIN_CORES, 3), checkerFor("jon", 16, 3));
-    }
-
-    @Test
-    public void testStringListToIntArray() {
-        String listString = "[1, 2, 3, 4]";
-        int[] intArray = new int[] {1, 2, 3, 4};
-        Assert.assertEquals(JcloudsLocation.toIntArray(listString), intArray);
-    }
-    
-    @Test(expectedExceptions = IllegalArgumentException.class)
-    public void testMalformedStringListToIntArray() {
-        String listString = "1, 2, 3, 4";
-        JcloudsLocation.toIntArray(listString);
-    }
-    
-    @Test
-    public void testEmptyStringListToIntArray() {
-        String listString = "[]";
-        int[] intArray = new int[] {};
-        Assert.assertEquals(JcloudsLocation.toIntArray(listString), intArray);
-    }
-    
-    @Test
-    public void testIntArrayToIntArray() {
-        int[] intArray = new int[] {1, 2, 3, 4};
-        Assert.assertEquals(JcloudsLocation.toIntArray(intArray), intArray);
-    }
-    
-    @Test
-    public void testObjectArrayToIntArray() {
-        Object[] longArray = new Object[] {1, 2, 3, 4};
-        int[] intArray = new int[] {1, 2, 3, 4};
-        Assert.assertEquals(JcloudsLocation.toIntArray(longArray), intArray);
-    }
-    
-    @Test(expectedExceptions = ClassCastException.class)
-    public void testInvalidObjectArrayToIntArray() {
-        String[] stringArray = new String[] {"1", "2", "3"};
-        JcloudsLocation.toIntArray(stringArray);
-    }
-
-    @Test
-    public void testVMCreationIsRetriedOnFailure() {
-        final AtomicInteger count = new AtomicInteger();
-        Function<ConfigBag, Void> countingInterceptor = new Function<ConfigBag, Void>() {
-            @Override public Void apply(ConfigBag input) {
-                count.incrementAndGet();
-                return null;
-            }
-        };
-        BailOutJcloudsLocation loc = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
-                MACHINE_CREATE_ATTEMPTS, 3,
-                BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, countingInterceptor));
-        loc.tryObtain();
-        Assert.assertEquals(count.get(), 3);
-    }
-
-    @Test(groups={"Live", "Live-sanity"})
-    public void testCreateWithInboundPorts() {
-        BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocationForLiveTest(managementContext);
-        jcloudsLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
-        jcloudsLocation.tryObtainAndCheck(MutableMap.of(), templateCheckerFor("[22, 80, 9999]"));
-        int[] ports = new int[] {22, 80, 9999};
-        Assert.assertEquals(jcloudsLocation.getTemplate().getOptions().getInboundPorts(), ports);
-    }
-    
-    @Test(groups={"Live", "Live-sanity"})
-    public void testCreateWithInboundPortsOverride() {
-        BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocationForLiveTest(managementContext);
-        jcloudsLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
-        jcloudsLocation.tryObtainAndCheck(MutableMap.of(INBOUND_PORTS, "[23, 81, 9998]"), templateCheckerFor("[23, 81, 9998]"));
-        int[] ports = new int[] {23, 81, 9998};
-        Assert.assertEquals(jcloudsLocation.getTemplate().getOptions().getInboundPorts(), ports);
-    }
-
-    @Test
-    public void testCreateWithMaxConcurrentCallsUnboundedByDefault() throws Exception {
-        final int numCalls = 20;
-        ConcurrencyTracker interceptor = new ConcurrencyTracker();
-        ExecutorService executor = Executors.newCachedThreadPool();
-
-        try {
-            final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
-                    managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
-                            BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor));
-            for (int i = 0; i < numCalls; i++) {
-                executor.execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        jcloudsLocation.tryObtain();
-                    }
-                });
-            }
-            interceptor.assertCallCountEventually(numCalls);
-            interceptor.unblock();
-            executor.shutdown();
-            executor.awaitTermination(10, TimeUnit.SECONDS);
-        } finally {
-            executor.shutdownNow();
-        }
-    }
-
-    @Test(groups="Integration") // because takes 1 sec
-    public void testCreateWithMaxConcurrentCallsRespectsConfig() throws Exception {
-        final int numCalls = 4;
-        final int maxConcurrentCreations = 2;
-        ConcurrencyTracker interceptor = new ConcurrencyTracker();
-        ExecutorService executor = Executors.newCachedThreadPool();
-        
-        try {
-            final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
-                    managementContext, ImmutableMap.of(
-                            BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor,
-                            JcloudsLocation.MAX_CONCURRENT_MACHINE_CREATIONS, maxConcurrentCreations));
-
-            for (int i = 0; i < numCalls; i++) {
-                executor.execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        jcloudsLocation.tryObtain();
-                    }
-                });
-            }
-
-            interceptor.assertCallCountEventually(maxConcurrentCreations);
-            interceptor.assertCallCountContinually(maxConcurrentCreations);
-
-            interceptor.unblock();
-            interceptor.assertCallCountEventually(numCalls);
-            executor.shutdown();
-            executor.awaitTermination(10, TimeUnit.SECONDS);
-
-        } finally {
-            executor.shutdownNow();
-        }
-    }
-
-    @Test(groups="Integration") // because takes 1 sec
-    public void testCreateWithMaxConcurrentCallsAppliesToSubLocations() throws Exception {
-        final int numCalls = 4;
-        final int maxConcurrentCreations = 2;
-        ConcurrencyTracker interceptor = new ConcurrencyTracker();
-        ExecutorService executor = Executors.newCachedThreadPool();
-
-        try {
-            final BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
-                    managementContext, ImmutableMap.of(
-                            BailOutJcloudsLocation.BUILD_TEMPLATE_INTERCEPTOR, interceptor,
-                            JcloudsLocation.MAX_CONCURRENT_MACHINE_CREATIONS, maxConcurrentCreations));
-
-            for (int i = 0; i < numCalls; i++) {
-                final BailOutJcloudsLocation subLocation = (BailOutJcloudsLocation) jcloudsLocation.newSubLocation(MutableMap.of());
-                executor.execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        subLocation.tryObtain();
-                    }
-                });
-            }
-
-            interceptor.assertCallCountEventually(maxConcurrentCreations);
-            interceptor.assertCallCountContinually(maxConcurrentCreations);
-
-            interceptor.unblock();
-            interceptor.assertCallCountEventually(numCalls);
-            executor.shutdown();
-            executor.awaitTermination(10, TimeUnit.SECONDS);
-
-        } finally {
-            executor.shutdownNow();
-        }
-    }
-    
-    @Test
-    public void testCreateWithCustomMachineNamer() {
-        final String machineNamerClass = CustomMachineNamer.class.getName();
-        BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(
-                managementContext, ImmutableMap.<ConfigKey<?>, Object>of(
-                        LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS, machineNamerClass));
-        jcloudsLocation.tryObtainAndCheck(ImmutableMap.of(CustomMachineNamer.MACHINE_NAME_TEMPLATE, "ignored"), new Predicate<ConfigBag>() {
-            public boolean apply(ConfigBag input) {
-                Assert.assertEquals(input.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS), machineNamerClass);
-                return true;
-            }
-        });
-    }
-    
-    @Test
-    public void testCreateWithCustomMachineNamerOnObtain() {
-        final String machineNamerClass = CustomMachineNamer.class.getName();
-        BailOutJcloudsLocation jcloudsLocation = BailOutJcloudsLocation.newBailOutJcloudsLocation(managementContext);
-        ImmutableMap<ConfigKey<String>, String> flags = ImmutableMap.of(
-                CustomMachineNamer.MACHINE_NAME_TEMPLATE, "ignored",
-                LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS, machineNamerClass);
-        jcloudsLocation.tryObtainAndCheck(flags, new Predicate<ConfigBag>() {
-            public boolean apply(ConfigBag input) {
-                Assert.assertEquals(input.get(LocationConfigKeys.CLOUD_MACHINE_NAMER_CLASS), machineNamerClass);
-                return true;
-            }
-        });
-    }
-
-    public static class ConcurrencyTracker implements Function<ConfigBag,Void> {
-        final AtomicInteger concurrentCallsCounter = new AtomicInteger();
-        final CountDownLatch continuationLatch = new CountDownLatch(1);
-        
-        @Override public Void apply(ConfigBag input) {
-            concurrentCallsCounter.incrementAndGet();
-            try {
-                continuationLatch.await();
-            } catch (InterruptedException e) {
-                throw Exceptions.propagate(e);
-            }
-            return null;
-        }
-        
-        public void unblock() {
-            continuationLatch.countDown();
-        }
-
-        public void assertCallCountEventually(final int expected) {
-            Asserts.succeedsEventually(new Runnable() {
-                @Override public void run() {
-                    Assert.assertEquals(concurrentCallsCounter.get(), expected);
-                }
-            });
-        }
-        
-        public void assertCallCountContinually(final int expected) {
-            Asserts.succeedsContinually(new Runnable() {
-                @Override public void run() {
-                    Assert.assertEquals(concurrentCallsCounter.get(), expected);
-                }
-            });
-        }
-    }
-
-    
-    @SuppressWarnings("serial")
-    public static class FakeLocalhostWithParentJcloudsLocation extends JcloudsLocation {
-        public static final ConfigKey<Function<ConfigBag,Void>> BUILD_TEMPLATE_INTERCEPTOR = ConfigKeys.newConfigKey(new TypeToken<Function<ConfigBag,Void>>() {}, "buildtemplateinterceptor");
-        
-        ConfigBag lastConfigBag;
-
-        public FakeLocalhostWithParentJcloudsLocation() {
-            super();
-        }
-
-        public FakeLocalhostWithParentJcloudsLocation(Map<?, ?> conf) {
-            super(conf);
-        }
-
-        @Override
-        public JcloudsSshMachineLocation obtain(Map<?, ?> flags) throws NoMachinesAvailableException {
-            JcloudsSshMachineLocation result = getManagementContext().getLocationManager().createLocation(LocationSpec.create(JcloudsSshMachineLocation.class)
-                .configure("address", "127.0.0.1") 
-                .configure("port", 22) 
-                .configure("user", "bob")
-                .configure("jcloudsParent", this));
-            registerJcloudsMachineLocation("bogus", result);
-            
-            // explicitly invoke this customizer, to comply with tests
-            for (JcloudsLocationCustomizer customizer : getCustomizers(config().getBag())) {
-                customizer.customize(this, null, (JcloudsMachineLocation)result);
-            }
-            for (MachineLocationCustomizer customizer : getMachineCustomizers(config().getBag())) {
-                customizer.customize((JcloudsMachineLocation)result);
-            }
-
-            return result;
-        }
-        
-        @Override
-        protected void releaseNode(String instanceId) {
-            // no-op
-        }
-    }
-
-    @Test
-    public void testInheritsGeo() throws Exception {
-        ConfigBag allConfig = ConfigBag.newInstance()
-            .configure(IMAGE_ID, "bogus")
-            .configure(CLOUD_PROVIDER, "aws-ec2")
-            .configure(CLOUD_REGION_ID, "bogus")
-            .configure(ACCESS_IDENTITY, "bogus")
-            .configure(ACCESS_CREDENTIAL, "bogus")
-            .configure(LocationConfigKeys.LATITUDE, 42d)
-            .configure(LocationConfigKeys.LONGITUDE, -20d)
-            .configure(JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 1);
-        FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class).configure(allConfig.getAllConfig()));
-        MachineLocation l = ll.obtain();
-        log.info("loc:" +l);
-        HostGeoInfo geo = HostGeoInfo.fromLocation(l);
-        log.info("geo: "+geo);
-        Assert.assertEquals(geo.latitude, 42d, 0.00001);
-        Assert.assertEquals(geo.longitude, -20d, 0.00001);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testInheritsGeoFromLocationMetadataProperties() throws Exception {
-        // in location-metadata.properties:
-//        brooklyn.location.jclouds.softlayer@wdc01.latitude=38.909202
-//        brooklyn.location.jclouds.softlayer@wdc01.longitude=-77.47314
-        ConfigBag allConfig = ConfigBag.newInstance()
-            .configure(IMAGE_ID, "bogus")
-            .configure(CLOUD_PROVIDER, "softlayer")
-            .configure(CLOUD_REGION_ID, "wdc01")
-            .configure(ACCESS_IDENTITY, "bogus")
-            .configure(ACCESS_CREDENTIAL, "bogus")
-            .configure(JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 1);
-        FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class)
-            .configure(new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties("softlayer", "wdc01", null, managementContext.getBrooklynProperties()))
-            .configure(allConfig.getAllConfig()));
-        MachineLocation l = ll.obtain();
-        log.info("loc:" +l);
-        HostGeoInfo geo = HostGeoInfo.fromLocation(l);
-        log.info("geo: "+geo);
-        Assert.assertEquals(geo.latitude, 38.909202d, 0.00001);
-        Assert.assertEquals(geo.longitude, -77.47314d, 0.00001);
-    }
-
-    @Test
-    public void testInvokesCustomizerCallbacks() throws Exception {
-        JcloudsLocationCustomizer customizer = Mockito.mock(JcloudsLocationCustomizer.class);
-        MachineLocationCustomizer machineCustomizer = Mockito.mock(MachineLocationCustomizer.class);
-//        Mockito.when(customizer.customize(Mockito.any(JcloudsLocation.class), Mockito.any(ComputeService.class), Mockito.any(JcloudsSshMachineLocation.class)));
-        ConfigBag allConfig = ConfigBag.newInstance()
-            .configure(CLOUD_PROVIDER, "aws-ec2")
-            .configure(ACCESS_IDENTITY, "bogus")
-            .configure(ACCESS_CREDENTIAL, "bogus")
-            .configure(JcloudsLocationConfig.JCLOUDS_LOCATION_CUSTOMIZERS, ImmutableList.of(customizer))
-            .configure(JcloudsLocation.MACHINE_LOCATION_CUSTOMIZERS, ImmutableList.of(machineCustomizer))
-            .configure(JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 1);
-        FakeLocalhostWithParentJcloudsLocation ll = managementContext.getLocationManager().createLocation(LocationSpec.create(FakeLocalhostWithParentJcloudsLocation.class).configure(allConfig.getAllConfig()));
-        JcloudsMachineLocation l = (JcloudsMachineLocation)ll.obtain();
-        Mockito.verify(customizer, Mockito.times(1)).customize(ll, null, l);
-        Mockito.verify(customizer, Mockito.never()).preRelease(l);
-        Mockito.verify(customizer, Mockito.never()).postRelease(l);
-        Mockito.verify(machineCustomizer, Mockito.times(1)).customize(l);
-        Mockito.verify(machineCustomizer, Mockito.never()).preRelease(l);
-        
-        ll.release(l);
-        Mockito.verify(customizer, Mockito.times(1)).preRelease(l);
-        Mockito.verify(customizer, Mockito.times(1)).postRelease(l);
-        Mockito.verify(machineCustomizer, Mockito.times(1)).preRelease(l);
-    }
-
-    // now test creating users
-    
-    protected String getCreateUserStatementsFor(Map<ConfigKey<?>,?> config) {
-        BailOutJcloudsLocation jl = BailOutJcloudsLocation.newBailOutJcloudsLocation(
-                managementContext, MutableMap.<ConfigKey<?>, Object>builder()
-                        .put(JcloudsLocationConfig.LOGIN_USER, "root").put(JcloudsLocationConfig.LOGIN_USER_PASSWORD, "m0ck")
-                        .put(JcloudsLocationConfig.USER, "bob").put(JcloudsLocationConfig.LOGIN_USER_PASSWORD, "b0b")
-                        .putAll(config).build());
-
-        UserCreation creation = jl.createUserStatements(null, jl.config().getBag());
-        return new StatementList(creation.statements).render(OsFamily.UNIX);
-    }
-    
-    @Test
-    public void testDisablesRoot() {
-        String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of());
-        Assert.assertTrue(statements.contains("PermitRootLogin"), "Error:\n"+statements);
-        Assert.assertTrue(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
-    }
-
-    @Test
-    public void testDisableRootFalse() {
-        String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of(
-                JcloudsLocationConfig.DISABLE_ROOT_AND_PASSWORD_SSH, false));
-        Assert.assertFalse(statements.contains("PermitRootLogin"), "Error:\n"+statements);
-        Assert.assertTrue(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
-    }
-    
-    @Test
-    public void testDisableRootAndSudoFalse() {
-        String statements = getCreateUserStatementsFor(ImmutableMap.<ConfigKey<?>, Object>of(
-            JcloudsLocationConfig.DISABLE_ROOT_AND_PASSWORD_SSH, false,
-            JcloudsLocationConfig.GRANT_USER_SUDO, false));
-        Assert.assertFalse(statements.contains("PermitRootLogin"), "Error:\n"+statements);
-        Assert.assertFalse(statements.matches("(?s).*sudoers.*useradd.*bob.*wheel.*"), "Error:\n"+statements);
-    }
-
-    // TODO more tests, where flags come in from resolver, named locations, etc
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLoginLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
deleted file mode 100644
index ef0862f..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-
-import java.io.File;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.os.Os;
-import brooklyn.util.stream.Streams;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * Tests different login options for ssh keys, passwords, etc.
- */
-public class JcloudsLoginLiveTest extends AbstractJcloudsLiveTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(JcloudsLoginLiveTest.class);
-
-    public static final String AWS_EC2_REGION_NAME = AWS_EC2_USEAST_REGION_NAME;
-    public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + (AWS_EC2_REGION_NAME == null ? "" : ":" + AWS_EC2_REGION_NAME);
-    
-    // Image: {id=us-east-1/ami-7d7bfc14, providerId=ami-7d7bfc14, name=RightImage_CentOS_6.3_x64_v5.8.8.5, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=centos, arch=paravirtual, version=6.0, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_CentOS_6.3_x64_v5.8.8.5.manifest.xml, version=5.8.8.5, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
-    public static final String AWS_EC2_CENTOS_IMAGE_ID = "us-east-1/ami-7d7bfc14";
-
-    // Image: {id=us-east-1/ami-d0f89fb9, providerId=ami-d0f89fb9, name=ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=12.04, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, is64Bit=true}, description=099720109477/ubuntu/images/ebs/ubuntu-precise-12.04-amd64-server-20130411.1, version=20130411.1, status=AVAILABLE[available], loginUser=ubuntu, userMetadata={owner=099720109477, rootDeviceType=ebs, virtualizationType=paravirtual, hypervisor=xen}}
-    public static final String AWS_EC2_UBUNTU_IMAGE_ID = "us-east-1/ami-d0f89fb9";
-    
-    // Image: {id=us-east-1/ami-5e008437, providerId=ami-5e008437, name=RightImage_Ubuntu_10.04_x64_v5.8.8.3, location={scope=REGION, id=us-east-1, description=us-east-1, parent=aws-ec2, iso3166Codes=[US-VA]}, os={family=ubuntu, arch=paravirtual, version=10.04, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, is64Bit=true}, description=rightscale-us-east/RightImage_Ubuntu_10.04_x64_v5.8.8.3.manifest.xml, version=5.8.8.3, status=AVAILABLE[available], loginUser=root, userMetadata={owner=411009282317, rootDeviceType=instance-store, virtualizationType=paravirtual, hypervisor=xen}}
-    // Uses "root" as loginUser
-    public static final String AWS_EC2_UBUNTU_10_IMAGE_ID = "us-east-1/ami-5e008437";
-
-    public static final String RACKSPACE_LOCATION_SPEC = "jclouds:" + RACKSPACE_PROVIDER;
-    
-    // Image: {id=LON/c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, providerId=c52a0ca6-c1f2-4cd1-b7d6-afbcd1ebda22, name=CentOS 6.0, location={scope=ZONE, id=LON, description=LON, parent=rackspace-cloudservers-uk, iso3166Codes=[GB-SLG]}, os={family=centos, name=CentOS 6.0, version=6.0, description=CentOS 6.0, is64Bit=true}, description=CentOS 6.0, status=AVAILABLE, loginUser=root, userMetadata={os_distro=centos, com.rackspace__1__visible_core=1, com.rackspace__1__build_rackconnect=1, com.rackspace__1__options=0, image_type=base, cache_in_nova=True, com.rackspace__1__source=kickstart, org.openstack__1__os_distro=org.centos, com.rackspace__1__release_build_date=2013-07-25_18-56-29, auto_disk_config=True, com.rackspace__1__release_version=5, os_type=linux, com.rackspace__1__visible_rackconnect=1, com.rackspace__1__release_id=210, com.rackspace__1__visible_managed=0, com.rackspace__1__build_core=1, org.openstack__1__os_version=6.0, org.openstack__1__architecture=x64, com.rackspace__1__build_ma
 naged=0}}
-    public static final String RACKSPACE_CENTOS_IMAGE_NAME_REGEX = "CentOS 6.0";
-    
-    // Image: {id=LON/29fe3e2b-f119-4715-927b-763e99ebe23e, providerId=29fe3e2b-f119-4715-927b-763e99ebe23e, name=Debian 6.06 (Squeeze), location={scope=ZONE, id=LON, description=LON, parent=rackspace-cloudservers-uk, iso3166Codes=[GB-SLG]}, os={family=debian, name=Debian 6.06 (Squeeze), version=6.0, description=Debian 6.06 (Squeeze), is64Bit=true}, description=Debian 6.06 (Squeeze), status=AVAILABLE, loginUser=root, userMetadata={os_distro=debian, com.rackspace__1__visible_core=1, com.rackspace__1__build_rackconnect=1, com.rackspace__1__options=0, image_type=base, cache_in_nova=True, com.rackspace__1__source=kickstart, org.openstack__1__os_distro=org.debian, com.rackspace__1__release_build_date=2013-08-06_13-05-36, auto_disk_config=True, com.rackspace__1__release_version=4, os_type=linux, com.rackspace__1__visible_rackconnect=1, com.rackspace__1__release_id=300, com.rackspace__1__visible_managed=0, com.rackspace__1__build_core=1, org.openstack__1__os_version=6.06, org.openstack__1_
 _architecture=x64, com.rackspace__1__build_managed=0}}
-    public static final String RACKSPACE_DEBIAN_IMAGE_NAME_REGEX = "Debian 6";
-    
-    protected JcloudsSshMachineLocation machine;
-    
-    private File privateRsaFile = new File(Os.tidyPath("~/.ssh/id_rsa"));
-    private File privateDsaFile = new File(Os.tidyPath("~/.ssh/id_dsa"));
-    private File privateRsaFileTmp = new File(privateRsaFile.getAbsoluteFile()+".tmp");
-    private File privateDsaFileTmp = new File(privateDsaFile.getAbsoluteFile()+".tmp");
-    private File publicRsaFile = new File(Os.tidyPath("~/.ssh/id_rsa.pub"));
-    private File publicDsaFile = new File(Os.tidyPath("~/.ssh/id_dsa.pub"));
-    private File publicRsaFileTmp = new File(publicRsaFile.getAbsoluteFile()+".tmp");
-    private File publicDsaFileTmp = new File(publicDsaFile.getAbsoluteFile()+".tmp");
-    private boolean privateRsaFileMoved;
-    private boolean privateDsaFileMoved;
-    private boolean publicRsaFileMoved;
-    private boolean publicDsaFileMoved;
-
-    @Test(groups = {"Live"})
-    protected void testAwsEc2SpecifyingJustPrivateSshKeyInDeprecatedForm() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.LEGACY_PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
-        
-        machine = createEc2Machine(ImmutableMap.<String,Object>of());
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "myname")
-                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-                .build());
-    }
-    
-    @Test(groups = {"Live"})
-    protected void testAwsEc2SpecifyingPrivateAndPublicSshKeyInDeprecatedForm() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.LEGACY_PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.LEGACY_PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
-        
-        machine = createEc2Machine(ImmutableMap.<String,Object>of());
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "myname")
-                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-                .build());
-    }
-
-    // Uses default key files
-    @Test(groups = {"Live"})
-    protected void testAwsEc2SpecifyingNoKeyFiles() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
-        
-        machine = createEc2Machine(ImmutableMap.<String,Object>of());
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "myname")
-                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-                .build());
-    }
-    
-    @Test(groups = {"Live"})
-    public void testSpecifyingPasswordAndNoDefaultKeyFilesExist() throws Exception {
-        try {
-            moveSshKeyFiles();
-            
-            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
-            jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
-            
-            machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
-            assertSshable(machine);
-            
-            assertSshable(ImmutableMap.builder()
-                    .put("address", machine.getAddress())
-                    .put("user", "myname")
-                    .put(SshMachineLocation.PASSWORD, "mypassword")
-                    .build());
-        } finally {
-            restoreSshKeyFiles();
-        }
-    }
-
-    // Generates and uses a random password
-    @Test(groups = {"Live"})
-    protected void testSpecifyingNothingAndNoDefaultKeyFilesExist() throws Exception {
-        try {
-            moveSshKeyFiles();
-            
-            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-            jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
-            
-            machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
-            assertSshable(machine);
-            assertEquals(machine.getUser(), "myname");
-        } finally {
-            restoreSshKeyFiles();
-        }
-    }
-
-    @Test(groups = {"Live"})
-    protected void testSpecifyingPasswordAndSshKeysPrefersKeys() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
-        
-        machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "myname")
-                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-                .build());
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "myname")
-                .put(SshMachineLocation.PASSWORD, "mypassword")
-                .build());
-    }
-
-    @Test(groups = {"Live"})
-    protected void testSpecifyingPasswordIgnoresDefaultSshKeys() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
-        
-        machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "myname")
-                .put(SshMachineLocation.PASSWORD, "mypassword")
-                .build());
-        
-        assertNotSshable(ImmutableMap.builder()
-            .put("address", machine.getAddress())
-            .put("user", "myname")
-            .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-            .build());
-    }
-
-    @Test(groups = {"Live"})
-    protected void testSpecifyingPasswordWithPublicKeyAllowsKeyAccess() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
-        
-        machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "myname")
-                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-                .build());
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "myname")
-                .put(SshMachineLocation.PASSWORD, "mypassword")
-                .build());
-    }
-
-    // user "root" matches the loginUser=root
-    @Test(groups = {"Live"})
-    protected void testSpecifyingPasswordWhenNoDefaultKeyFilesExistWithRootUser() throws Exception {
-        try {
-            moveSshKeyFiles();
-            
-            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "root");
-            brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PASSWORD.getName(), "mypassword");
-            jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(RACKSPACE_LOCATION_SPEC);
-            
-            machine = createRackspaceMachine(ImmutableMap.of("imageNameRegex", RACKSPACE_DEBIAN_IMAGE_NAME_REGEX));
-            assertSshable(machine);
-            
-            assertSshable(ImmutableMap.builder()
-                    .put("address", machine.getAddress())
-                    .put("user", "root")
-                    .put(SshMachineLocation.PASSWORD, "mypassword")
-                    .build());
-        } finally {
-            restoreSshKeyFiles();
-        }
-    }
-
-    @Test(groups = {"Live"})
-    protected void testAwsEc2SpecifyingRootUser() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "root");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
-        
-        machine = createEc2Machine(ImmutableMap.<String,Object>of("imageId", AWS_EC2_UBUNTU_10_IMAGE_ID));
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "root")
-                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-                .build());
-    }
-    
-    @Test(groups = {"Live"})
-    protected void testAwsEc2WhenBlankUserSoUsesRootLoginUser() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
-        
-        machine = createEc2Machine(ImmutableMap.<String,Object>of("imageId", AWS_EC2_UBUNTU_10_IMAGE_ID));
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "root")
-                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-                .build());
-    }
-    
-    // In JcloudsLocation.NON_ADDABLE_USERS, "ec2-user" was treated special and was not added!
-    // That was very bad for if someone is running brooklyn on a new AWS VM, and just installs brooklyn+runs as the default ec2-user.
-    @Test(groups = {"Live"})
-    protected void testAwsEc2SpecifyingSpecialUser() throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "ec2-user");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PRIVATE_KEY_FILE.getName(), "~/.ssh/id_rsa");
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.PUBLIC_KEY_FILE.getName(), "~/.ssh/id_rsa.pub");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
-        
-        machine = createEc2Machine(ImmutableMap.<String,Object>of("imageId", AWS_EC2_UBUNTU_10_IMAGE_ID));
-        assertSshable(machine);
-        
-        assertSshable(ImmutableMap.builder()
-                .put("address", machine.getAddress())
-                .put("user", "ec2-user")
-                .put(SshMachineLocation.PRIVATE_KEY_FILE, Os.tidyPath("~/.ssh/id_rsa"))
-                .build());
-    }
-    
-    @Override
-    protected void releaseMachine(JcloudsSshMachineLocation machine) {
-        jcloudsLocation.release(machine);
-    }
-    
-    private JcloudsSshMachineLocation createEc2Machine(Map<String,? extends Object> conf) throws Exception {
-        return obtainMachine(MutableMap.<String,Object>builder()
-                .putAll(conf)
-                .putIfAbsent("imageId", AWS_EC2_CENTOS_IMAGE_ID)
-                .putIfAbsent("hardwareId", AWS_EC2_SMALL_HARDWARE_ID)
-                .putIfAbsent("inboundPorts", ImmutableList.of(22))
-                .build());
-    }
-    
-    private JcloudsSshMachineLocation createRackspaceMachine(Map<String,? extends Object> conf) throws Exception {
-        return obtainMachine(MutableMap.<String,Object>builder()
-                .putAll(conf)
-                .putIfAbsent("inboundPorts", ImmutableList.of(22))
-                .build());
-    }
-    
-    protected void assertSshable(Map<?,?> machineConfig) {
-        SshMachineLocation machineWithThatConfig = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure(machineConfig));
-        try {
-            assertSshable(machineWithThatConfig);
-        } finally {
-            Streams.closeQuietly(machineWithThatConfig);
-        }
-    }
-    
-    protected void assertNotSshable(Map<?,?> machineConfig) {
-        try {
-            assertSshable(machineConfig);
-            Assert.fail("ssh should not have succeeded "+machineConfig);
-        } catch (Exception e) {
-            // expected
-            LOG.debug("Exception as expected when testing sshable "+machineConfig);
-        }
-    }
-    
-    private void moveSshKeyFiles() throws Exception {
-        privateRsaFileMoved = false;
-        privateDsaFileMoved = false;
-        publicRsaFileMoved = false;
-        publicDsaFileMoved = false;
-
-        if (privateRsaFile.exists()) {
-            LOG.info("Moving {} to {}", privateRsaFile, privateRsaFileTmp);
-            Runtime.getRuntime().exec("mv "+privateRsaFile.getAbsolutePath()+" "+privateRsaFileTmp.getAbsolutePath());
-            privateRsaFileMoved = true;
-        }
-        if (privateDsaFile.exists()) {
-            LOG.info("Moving {} to {}", privateDsaFile, privateDsaFileTmp);
-            Runtime.getRuntime().exec("mv "+privateDsaFile.getAbsolutePath()+" "+privateDsaFileTmp.getAbsolutePath());
-            privateDsaFileMoved = true;
-        }
-        if (publicRsaFile.exists()) {
-            LOG.info("Moving {} to {}", publicRsaFile, publicRsaFileTmp);
-            Runtime.getRuntime().exec("mv "+publicRsaFile.getAbsolutePath()+" "+publicRsaFileTmp.getAbsolutePath());
-            publicRsaFileMoved = true;
-        }
-        if (publicDsaFile.exists()) {
-            LOG.info("Moving {} to {}", publicDsaFile, publicDsaFileTmp);
-            Runtime.getRuntime().exec("mv "+publicDsaFile.getAbsolutePath()+" "+publicDsaFileTmp.getAbsolutePath());
-            publicDsaFileMoved = true;
-        }
-    }
-    
-    private void restoreSshKeyFiles() throws Exception {
-        if (privateRsaFileMoved) {
-            LOG.info("Restoring {} form {}", privateRsaFile, privateRsaFileTmp);
-            Runtime.getRuntime().exec("mv "+privateRsaFileTmp.getAbsolutePath()+" "+privateRsaFile.getAbsolutePath());
-            privateRsaFileMoved = false;
-        }
-        if (privateDsaFileMoved) {
-            LOG.info("Restoring {} form {}", privateDsaFile, privateDsaFileTmp);
-            Runtime.getRuntime().exec("mv "+privateDsaFileTmp.getAbsolutePath()+" "+privateDsaFile.getAbsolutePath());
-            privateDsaFileMoved = false;
-        }
-        if (publicRsaFileMoved) {
-            LOG.info("Restoring {} form {}", publicRsaFile, publicRsaFileTmp);
-            Runtime.getRuntime().exec("mv "+publicRsaFileTmp.getAbsolutePath()+" "+publicRsaFile.getAbsolutePath());
-            publicRsaFileMoved = false;
-        }
-        if (publicDsaFileMoved) {
-            LOG.info("Restoring {} form {}", publicDsaFile, publicDsaFileTmp);
-            Runtime.getRuntime().exec("mv "+publicDsaFileTmp.getAbsolutePath()+" "+publicDsaFile.getAbsolutePath());
-            publicDsaFileMoved = false;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsMachineNamerTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsMachineNamerTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsMachineNamerTest.java
deleted file mode 100644
index da21750..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsMachineNamerTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.text.Strings;
-
-public class JcloudsMachineNamerTest {
-
-    private static final Logger log = LoggerFactory.getLogger(JcloudsMachineNamerTest.class);
-    
-    @Test
-    public void testGenerateGroupIdInVcloud() {
-        ConfigBag cfg = new ConfigBag()
-            .configure(JcloudsLocationConfig.CLOUD_PROVIDER, "vcloud")
-            .configure(JcloudsLocationConfig.CALLER_CONTEXT, "!mycontext!");
-        
-        String result = new JcloudsMachineNamer().generateNewGroupId(cfg);
-        
-        log.info("test mycontext vcloud group id gives: "+result);
-        // brooklyn-user-!mycontext!-1234
-        // br-<code>-<user>-myco-1234
-        Assert.assertTrue(result.length() <= 24-4-1, "result: "+result);
-        
-        String user = Strings.maxlen(System.getProperty("user.name"), 2).toLowerCase();
-        // (length 2 will happen if user is brooklyn, to avoid brooklyn-brooklyn at start!)
-        Assert.assertTrue(result.indexOf(user) >= 0);
-        Assert.assertTrue(result.indexOf("-myc") >= 0);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynPropertiesTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynPropertiesTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynPropertiesTest.java
deleted file mode 100644
index d3134a4..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynPropertiesTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Map;
-
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.Maps;
-
-public class JcloudsPropertiesFromBrooklynPropertiesTest {
-    
-    protected static Map<String, Object> sampleProviderOrApiProps() {
-        Map<String, Object> map = Maps.newHashMap();
-        map.put("brooklyn.location.jclouds.FooServers.identity", "bob");
-        map.put("brooklyn.location.jclouds.FooServers.credential", "s3cr3t");
-        map.put("brooklyn.location.jclouds.FooServers.jclouds.ssh.max-retries", "100");
-        return map;
-    }
-
-    protected static Map<String, Object> sampleNamedProps() {
-        Map<String, Object> map = Maps.newHashMap();
-        map.put("brooklyn.location.named.cloudfirst", "jclouds:openstack-nova");
-        map.put("brooklyn.location.named.cloudfirst.identity", "myId");
-        map.put("brooklyn.location.named.cloudfirst.credential", "password");
-        map.put("brooklyn.location.named.cloudfirst.imageId", "RegionOne/1");
-        map.put("brooklyn.location.named.cloudfirst.securityGroups", "universal");
-        return map;
-    }
-
-    protected static Map<String, Object> unsupportedSampleProviderOrApiProps() {
-        Map<String, Object> map = Maps.newHashMap();
-        map.put("brooklyn.location.jclouds.FooServers.image-id", "invalid-image-id");
-        return map;
-    }
-    
-    protected static Map<String, Object> unsupportedNamedProps() {
-        Map<String, Object> map = Maps.newHashMap();
-        map.put("brooklyn.location.named.cloudfirst", "jclouds:openstack-nova");
-        map.put("brooklyn.location.named.cloudfirst.hardware-id", "invalid-hardware-id");
-        return map;
-    }
-    
-    private JcloudsPropertiesFromBrooklynProperties parser;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        parser = new JcloudsPropertiesFromBrooklynProperties();
-    }
-    
-    @Test
-    public void testProviderOrApiProperties() {
-        Map<String, Object> map = parser.getJcloudsProperties("FooServers", null, null, sampleProviderOrApiProps());
-        Assert.assertEquals(map.get("identity"), "bob");
-        Assert.assertEquals(map.get("credential"), "s3cr3t");
-        Assert.assertEquals(map.get("provider"), "FooServers");
-    }
-
-    @Test
-    public void testNamedProperties() {
-        Map<String, Object> map = parser.getJcloudsProperties("openstack-nova", null, "cloudfirst", sampleNamedProps());
-        Assert.assertEquals(map.get("provider"), "openstack-nova");
-        Assert.assertEquals(map.get("identity"), "myId");
-        Assert.assertEquals(map.get("credential"), "password");
-        Assert.assertEquals(map.get("imageId"), "RegionOne/1");
-        Assert.assertEquals(map.get("securityGroups"), "universal");
-    }
-    
-    @Test
-    public void testOrderOfPreference() {
-        Map<String, Object> allProperties = Maps.newHashMap();
-        allProperties.putAll(sampleProviderOrApiProps());
-        allProperties.putAll(sampleNamedProps());
-        Map<String, Object> map = parser.getJcloudsProperties("openstack-nova", null, "cloudfirst", allProperties);
-        Assert.assertEquals(map.get("provider"), "openstack-nova");
-        Assert.assertEquals(map.get("identity"), "myId");
-        Assert.assertEquals(map.get("credential"), "password");
-        Assert.assertEquals(map.get("imageId"), "RegionOne/1");
-        Assert.assertEquals(map.get("securityGroups"), "universal");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsSshingLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsSshingLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsSshingLiveTest.java
deleted file mode 100644
index bc89fe6..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/JcloudsSshingLiveTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-
-import org.testng.annotations.Test;
-
-import brooklyn.util.collections.MutableMap;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * Tests the initial ssh command execution (e.g. user creation), using jclouds TemplateOptions
- * and using just brooklyn.
- */
-public class JcloudsSshingLiveTest extends AbstractJcloudsLiveTest {
-
-    public static final String SOFTLAYER_REGION_NAME = SOFTLAYER_AMS01_REGION_NAME;
-    public static final String SOTLAYER_LOCATION_SPEC = "jclouds:" + SOFTLAYER_PROVIDER + (SOFTLAYER_REGION_NAME == null ? "" : ":" + SOFTLAYER_REGION_NAME);
-    
-    protected JcloudsSshMachineLocation machine;
-    
-    @Test(groups = {"Live"})
-    public void testCreatesUserUsingJcloudsTemplateOptions() throws Exception {
-        runCreatesUser(true);
-    }
-    
-    @Test(groups = {"Live"})
-    public void testCreatesUserWithoutUsingJcloudsTemplateOptions() throws Exception {
-        runCreatesUser(false);
-    }
-    
-    protected void runCreatesUser(boolean useJcloudsSshInit) throws Exception {
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USE_JCLOUDS_SSH_INIT.getName(), Boolean.toString(useJcloudsSshInit));
-        brooklynProperties.put(BROOKLYN_PROPERTIES_PREFIX+JcloudsLocationConfig.USER.getName(), "myname");
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(SOTLAYER_LOCATION_SPEC);
-        
-        JcloudsSshMachineLocation machine = obtainMachine(MutableMap.<String,Object>builder()
-                .putIfAbsent("inboundPorts", ImmutableList.of(22))
-                .build());
-        assertSshable(machine);
-        assertEquals(machine.getUser(), "myname");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/LiveTestEntity.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/LiveTestEntity.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/LiveTestEntity.java
deleted file mode 100644
index c8db561..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/LiveTestEntity.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.util.Collection;
-
-import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.apache.brooklyn.test.entity.TestEntityImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.location.Location;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.LocationInternal;
-
-import com.google.common.base.Predicates;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-@ImplementedBy(LiveTestEntity.LiveTestEntityImpl.class)
-public interface LiveTestEntity extends TestEntity {
-
-    MachineProvisioningLocation<?> getProvisioningLocation();
-    JcloudsSshMachineLocation getObtainedLocation();
-
-    public static class LiveTestEntityImpl extends TestEntityImpl implements LiveTestEntity {
-
-        private static final Logger LOG = LoggerFactory.getLogger(LiveTestEntityImpl.class);
-        private JcloudsLocation provisioningLocation;
-        private JcloudsSshMachineLocation obtainedLocation;
-
-        @Override
-        public void start(final Collection<? extends Location> locs) {
-            LOG.trace("Starting {}", this);
-            callHistory.add("start");
-            setAttribute(SERVICE_STATE, Lifecycle.STARTING);
-            counter.incrementAndGet();
-            addLocations(locs);
-            provisioningLocation = (JcloudsLocation) Iterables.find(locs, Predicates.instanceOf(JcloudsLocation.class));
-            try {
-                obtainedLocation = (JcloudsSshMachineLocation)provisioningLocation.obtain(((LocationInternal)provisioningLocation).config().getBag().getAllConfig());
-            } catch (NoMachinesAvailableException e) {
-                throw Throwables.propagate(e);
-            }
-            addLocations(ImmutableList.of(obtainedLocation));
-            setAttribute(SERVICE_STATE, Lifecycle.RUNNING);
-        }
-
-        @Override
-        public void stop() {
-            LOG.trace("Stopping {}", this);
-            callHistory.add("stop");
-            setAttribute(SERVICE_STATE, Lifecycle.STOPPING);
-            counter.decrementAndGet();
-            if (provisioningLocation != null && obtainedLocation != null) {
-                provisioningLocation.release(obtainedLocation);
-            }
-            setAttribute(SERVICE_STATE, Lifecycle.STOPPED);
-        }
-
-        public MachineProvisioningLocation<?> getProvisioningLocation() {
-            return provisioningLocation;
-        }
-
-        public JcloudsSshMachineLocation getObtainedLocation() {
-            return obtainedLocation;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
deleted file mode 100644
index 6d73e59..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-import java.io.File;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.location.OsDetails;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.io.Files;
-
-public class RebindJcloudsLocationLiveTest extends AbstractJcloudsLiveTest {
-
-    public static final String AWS_EC2_REGION_NAME = AWS_EC2_USEAST_REGION_NAME;
-    public static final String AWS_EC2_LOCATION_SPEC = "jclouds:" + AWS_EC2_PROVIDER + ":" + AWS_EC2_REGION_NAME;
-
-    private ClassLoader classLoader = getClass().getClassLoader();
-    private TestApplication origApp;
-    private LiveTestEntity origEntity;
-    private File mementoDir;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        origApp = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class), managementContext);
-        origEntity = origApp.createAndManageChild(EntitySpec.create(LiveTestEntity.class));
-
-        jcloudsLocation = (JcloudsLocation) managementContext.getLocationRegistry().resolve(AWS_EC2_LOCATION_SPEC);
-        jcloudsLocation.setConfig(JcloudsLocation.HARDWARE_ID, AWS_EC2_SMALL_HARDWARE_ID);
-    }
-
-    @AfterMethod(alwaysRun = true)
-    @Override
-    public void tearDown() throws Exception {
-        super.tearDown();
-        if (origApp != null) Entities.destroyAll(origApp.getManagementContext());
-        if (mementoDir != null) RebindTestUtils.deleteMementoDir(mementoDir);
-    }
-    
-    @Override
-    protected LocalManagementContext newManagementContext() {
-        mementoDir = Files.createTempDir();
-        return RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
-    }
-    
-    @Test(groups="Live")
-    public void testRebindsToJcloudsMachine() throws Exception {
-        origApp.start(ImmutableList.of(jcloudsLocation));
-        JcloudsLocation origJcloudsLocation = jcloudsLocation;
-        System.out.println("orig locations: " + origEntity.getLocations());
-        JcloudsSshMachineLocation origMachine = (JcloudsSshMachineLocation) Iterables.find(origEntity.getLocations(), Predicates.instanceOf(JcloudsSshMachineLocation.class));
-
-        TestApplication newApp = rebind();
-        LiveTestEntity newEntity = (LiveTestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(LiveTestEntity.class));
-        JcloudsSshMachineLocation newMachine = (JcloudsSshMachineLocation) Iterables.find(newEntity.getLocations(), Predicates.instanceOf(JcloudsSshMachineLocation.class));
-
-        assertMachineEquals(newMachine, origMachine);
-        assertTrue(newMachine.isSshable());
-
-        JcloudsLocation newJcloudsLoction = newMachine.getParent();
-        assertJcloudsLocationEquals(newJcloudsLoction, origJcloudsLocation);
-    }
-
-    private void assertMachineEquals(JcloudsSshMachineLocation actual, JcloudsSshMachineLocation expected) {
-        String errmsg = "actual="+actual.toVerboseString()+"; expected="+expected.toVerboseString();
-        assertEquals(actual.getId(), expected.getId(), errmsg);
-        assertEquals(actual.getJcloudsId(), expected.getJcloudsId(), errmsg);
-        assertOsDetailEquals(actual.getOsDetails(), expected.getOsDetails());
-        assertEquals(actual.getSshHostAndPort(), expected.getSshHostAndPort());
-        assertEquals(actual.getPrivateAddress(), expected.getPrivateAddress());
-        assertConfigBagEquals(actual.config().getBag(), expected.config().getBag(), errmsg);
-    }
-
-    private void assertOsDetailEquals(OsDetails actual, OsDetails expected) {
-        String errmsg = "actual="+actual+"; expected="+expected;
-        if (actual == null) assertNull(expected, errmsg);
-        assertEquals(actual.isWindows(), expected.isWindows());
-        assertEquals(actual.isLinux(), expected.isLinux());
-        assertEquals(actual.isMac(), expected.isMac());
-        assertEquals(actual.getName(), expected.getName());
-        assertEquals(actual.getArch(), expected.getArch());
-        assertEquals(actual.getVersion(), expected.getVersion());
-        assertEquals(actual.is64bit(), expected.is64bit());
-    }
-
-    private void assertJcloudsLocationEquals(JcloudsLocation actual, JcloudsLocation expected) {
-        String errmsg = "actual="+actual.toVerboseString()+"; expected="+expected.toVerboseString();
-        assertEquals(actual.getId(), expected.getId(), errmsg);
-        assertEquals(actual.getProvider(), expected.getProvider(), errmsg);
-        assertEquals(actual.getRegion(), expected.getRegion(), errmsg);
-        assertEquals(actual.getIdentity(), expected.getIdentity(), errmsg);
-        assertEquals(actual.getCredential(), expected.getCredential(), errmsg);
-        assertEquals(actual.getHostGeoInfo(), expected.getHostGeoInfo(), errmsg);
-        assertConfigBagEquals(actual.config().getBag(), expected.config().getBag(), errmsg);
-    }
-
-    private void assertConfigBagEquals(ConfigBag actual, ConfigBag expected, String errmsg) {
-        // TODO revisit the strong assertion that configBags are equal
-        
-//        // TODO Can we include all of these things (e.g. when locations are entities, so flagged fields not treated special)?
-//        List<String> configToIgnore = ImmutableList.of("id", "template", "usedPorts", "machineCreationSemaphore", "config");
-//        MutableMap<Object, Object> actualMap = MutableMap.builder().putAll(actual.getAllConfig())
-//                .removeAll(configToIgnore)
-//                .build();
-//        MutableMap<Object, Object> expectedMap = MutableMap.builder().putAll(expected.getAllConfig())
-//                .removeAll(configToIgnore)
-//                .build();
-//        
-//        assertEquals(actualMap, expectedMap, errmsg+"; actualBag="+actualMap+"; expectedBag="+expectedMap);
-    }
-    
-    private TestApplication rebind() throws Exception {
-        RebindTestUtils.waitForPersisted(origApp);
-        return (TestApplication) RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/RebindJcloudsLocationTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/RebindJcloudsLocationTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/RebindJcloudsLocationTest.java
deleted file mode 100644
index 7ce0ad3..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/RebindJcloudsLocationTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertNull;
-
-import org.jclouds.domain.LoginCredentials;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.config.ConfigBag;
-
-import com.google.common.net.HostAndPort;
-
-public class RebindJcloudsLocationTest extends RebindTestFixtureWithApp {
-
-    public static final String LOC_SPEC = "jclouds:aws-ec2:us-east-1";
-
-    private JcloudsLocation origLoc;
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        origLoc = (JcloudsLocation) origManagementContext.getLocationRegistry().resolve(LOC_SPEC);
-    }
-
-    // Previously, the rebound config contained "id" which was then passed to createTemporarySshMachineLocation, causing
-    // that to fail (because the LocationSpec should not have had "id" in its config)
-    @Test
-    public void testReboundConfigDoesNotContainId() throws Exception {
-        rebind();
-        
-        JcloudsLocation newLoc = (JcloudsLocation) newManagementContext.getLocationManager().getLocation(origLoc.getId());
-        
-        ConfigBag newLocConfig = newLoc.config().getBag();
-        ConfigBag config = ConfigBag.newInstanceCopying(newLocConfig);
-        
-        assertNull(newLocConfig.getStringKey(("id")));
-        
-        SshMachineLocation tempMachine = newLoc.createTemporarySshMachineLocation(
-                HostAndPort.fromParts("localhost", 1234), 
-                LoginCredentials.builder().identity("myuser").password("mypass").noPrivateKey().build(), 
-                config);
-        assertNotEquals(tempMachine.getId(), newLoc.getId());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java b/locations/jclouds/src/test/java/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
deleted file mode 100644
index 193f108..0000000
--- a/locations/jclouds/src/test/java/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * 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 brooklyn.location.jclouds;
-
-import java.io.ByteArrayOutputStream;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.ssh.BashCommands;
-import brooklyn.util.text.Identifiers;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-public class SimpleJcloudsLocationUserLoginAndConfigLiveTest extends AbstractJcloudsLiveTest {
-
-    // FIXME And tidy up this one
-    
-    private static final String LOCATION_SPEC = AWS_EC2_PROVIDER + ":" + AWS_EC2_USEAST_REGION_NAME;
-    
-    private static final Logger log = LoggerFactory.getLogger(SimpleJcloudsLocationUserLoginAndConfigLiveTest.class);
-    
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        jcloudsLocation = resolve(LOCATION_SPEC);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    @Test(groups="Live")
-    public void testJcloudsCreateBogStandard() throws Exception {
-        log.info("TEST testJcloudsCreateBogStandard");
-        JcloudsSshMachineLocation m1 = obtainMachine(ImmutableMap.of());
-
-        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
-        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
-        String result;
-        // echo conflates spaces of arguments
-        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m1"));
-        
-        log.info("now trying rebind "+m1);
-        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
-        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m2"));
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Test(groups="Live")
-    public void testJcloudsCreateBogStandardWithUserBrooklyn() throws Exception {
-        log.info("TEST testJcloudsCreateBogStandardWithUserBrooklyn");
-        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of("user", "brooklyn"));
-
-        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
-        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
-        String result;
-        // echo conflates spaces of arguments
-        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m1"));
-        
-        log.info("now trying rebind "+m1);
-        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
-        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m2"));
-        
-        Assert.assertEquals(m2.getUser(), "brooklyn");
-    }
-    
-    @SuppressWarnings("rawtypes")
-    @Test(groups="Live")
-    public void testJcloudsCreateUserMetadata() throws Exception {
-        log.info("TEST testJcloudsCreateBogStandard");
-        String key = "brooklyn-test-user-data";
-        String value = "test-"+Identifiers.makeRandomId(4);
-        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of("userMetadata", key+"="+value));
-
-        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser(),
-                "userMetadata", key+"="+value);
-        Assert.assertEquals(m1.node.getUserMetadata().get(key), value);
-        
-        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
-        String result;
-        // echo conflates spaces of arguments
-        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m1"));
-        
-        log.info("now trying rebind "+m1);
-        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
-        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m2"));
-        Assert.assertEquals(m2.node.getUserMetadata().get(key), value);
-    }
-
-    // a curious image, centos, but user is ec2-user, and handily not correctly auto-detected
-    // test we can specify a loginUser different from user, and that user is created etc...
-    // imageId=us-east-1/ami-f95cf390
-    public static final String EC2_CENTOS_IMAGE = "us-east-1/ami-f95cf390";
-    
-    @Test(groups="Live")
-    public void testJcloudsMissingUser() throws Exception {
-        log.info("TEST testJcloudsMissingUser");
-        try {
-            // wait up to 30s for login (override default of 5m so test runs faster)
-            obtainMachine(MutableMap.of("imageId", EC2_CENTOS_IMAGE, "waitForSshable", 30*1000));
-            log.info("whoops we logged in");
-        } catch (NoMachinesAvailableException e) {
-            log.info("got error as expected, for missing user: "+e); // success
-        }
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Test(groups="Live")
-    public void testJcloudsWithSpecificLoginUserAndSameUser() throws Exception {
-        log.info("TEST testJcloudsWithSpecificLoginUserAndSameUser");
-        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of(
-                "imageId", EC2_CENTOS_IMAGE,
-                "loginUser", "ec2-user",
-                "user", "ec2-user",
-                "waitForSshable", 30*1000));
-
-        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
-        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
-        String result;
-        // echo conflates spaces of arguments
-        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m1"));
-        
-        log.info("now trying rebind "+m1);
-        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
-        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m2"));
-        
-        Assert.assertEquals(m2.getUser(), "ec2-user");
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Test(groups="Live")
-    public void testJcloudsWithSpecificLoginUserAndNewUser() throws Exception {
-        log.info("TEST testJcloudsWithSpecificLoginUserAndNewUser");
-        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of(
-                "imageId", EC2_CENTOS_IMAGE,
-                "loginUser", "ec2-user",
-                "user", "newbob",
-                "waitForSshable", 30*1000));
-
-        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
-        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
-        String result;
-        // echo conflates spaces of arguments
-        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m1"));
-        
-        log.info("now trying rebind "+m1);
-        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
-        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m2"));
-        
-        Assert.assertEquals(m2.getUser(), "newbob");
-    }
-
-    @SuppressWarnings("rawtypes")
-    @Test(groups="Live")
-    public void testJcloudsWithSpecificLoginUserAndDefaultUser() throws Exception {
-        log.info("TEST testJcloudsWithSpecificLoginUserAndDefaultUser");
-        JcloudsSshMachineLocation m1 = obtainMachine(MutableMap.of(
-                "imageId", EC2_CENTOS_IMAGE,
-                "loginUser", "ec2-user",
-                "waitForSshable", 30*1000));
-
-        Map details = MutableMap.of("id", m1.getJcloudsId(), "hostname", m1.getAddress().getHostAddress(), "user", m1.getUser());
-        log.info("got machine "+m1+" at "+jcloudsLocation+": "+details+"; now trying to rebind");
-        String result;
-        // echo conflates spaces of arguments
-        result = execWithOutput(m1, Arrays.asList("echo trying  m1", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m1"));
-        
-        log.info("now trying rebind "+m1);
-        JcloudsSshMachineLocation m2 = jcloudsLocation.rebindMachine(details);
-        result = execWithOutput(m2, Arrays.asList("echo trying  m2", "hostname", "date"));
-        Assert.assertTrue(result.contains("trying m2"));
-    }
-
-    @Test(groups="Live")
-    public void testJcloudsCreateWithNoSudoGranted() throws Exception {
-        log.info("TEST testJcloudsCreateWithNoSudoGranted");
-        JcloudsSshMachineLocation m = obtainMachine(MutableMap.of(
-                "grantUserSudo", false,
-                "waitForSshable", 30*1000));
-
-        int exitCode = execWithExitCode(m, ImmutableList.of(BashCommands.sudo("echo yes")));
-        Assert.assertFalse(exitCode == 0, "exit code for sudo command should not have been 0");
-    }
-
-    private String execWithOutput(SshMachineLocation m, List<String> commands) {
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-        exec(m, commands, stdout, stderr);
-        return new String(stdout.toByteArray());
-    }
-
-    private int execWithExitCode(SshMachineLocation m, List<String> commands) {
-        ByteArrayOutputStream stdout = new ByteArrayOutputStream();
-        ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-        return exec(m, commands, stdout, stderr);
-    }
-
-    private int exec(SshMachineLocation m, List<String> commands, ByteArrayOutputStream stdout, ByteArrayOutputStream stderr) {
-        Map<String, Object> flags = Maps.newLinkedHashMap();
-        flags.put("out", stdout);
-        flags.put("err", stderr);
-        int exitCode = m.execCommands(flags, "test", commands);
-        log.info("stdout from "+commands+":\n"+new String(stdout.toByteArray()));
-        log.info("stderr from "+commands+":\n"+new String(stderr.toByteArray()));
-        log.info("exit code: " + exitCode);
-        return exitCode;
-    }
-
-    private JcloudsLocation resolve(String spec) {
-        return (JcloudsLocation) managementContext.getLocationRegistry().resolve("jclouds:"+spec);
-    }
-}



[28/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java b/core/src/test/java/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
deleted file mode 100644
index ab73a25..0000000
--- a/core/src/test/java/brooklyn/location/basic/FixedListMachineProvisioningLocationTest.java
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
-
-import java.net.Inet4Address;
-import java.net.UnknownHostException;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.RecordingMachineLocationCustomizer.Call;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Networking;
-import brooklyn.util.stream.Streams;
-
-/**
- * Provisions {@link SshMachineLocation}s in a specific location from a list of known machines
- */
-public class FixedListMachineProvisioningLocationTest {
-    
-    private static final Logger LOG = LoggerFactory.getLogger(FixedListMachineProvisioningLocationTest.class);
-
-    SshMachineLocation machine;
-    LocalManagementContext mgmt;
-    FixedListMachineProvisioningLocation<SshMachineLocation> provisioner;
-    FixedListMachineProvisioningLocation<SshMachineLocation> provisioner2;
-    
-    @SuppressWarnings("unchecked")
-    @BeforeMethod(alwaysRun=true)
-    public void createProvisioner() throws UnknownHostException {
-        mgmt = LocalManagementContextForTests.newInstance();
-        
-        machine = mgmt.getLocationManager().createLocation(MutableMap.of("address", Inet4Address.getByName("192.168.144.200")), SshMachineLocation.class);
-        provisioner = mgmt.getLocationManager().createLocation(
-                MutableMap.of("machines", MutableList.of(machine)),
-                FixedListMachineProvisioningLocation.class);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (provisioner != null) Streams.closeQuietly(provisioner);
-        if (provisioner2 != null) Streams.closeQuietly(provisioner2);
-        Entities.destroyAll(mgmt);
-    }
-    
-    @Test
-    public void testSetsChildLocations() throws NoMachinesAvailableException {
-        // Available machines should be listed as children
-        assertEquals(ImmutableList.copyOf(provisioner.getChildren()), ImmutableList.of(machine));
-        
-        // In-use machines should also be listed as children
-        provisioner.obtain();
-        assertEquals(ImmutableList.copyOf(provisioner.getChildren()), ImmutableList.of(machine));
-    }
-
-    @Test
-    public void canObtainMachine() throws NoMachinesAvailableException {
-        SshMachineLocation obtained = provisioner.obtain();
-        assertEquals(obtained, machine);
-    }
-
-    @SuppressWarnings("unused")
-    @Test(expectedExceptions = { NoMachinesAvailableException.class })
-    public void throwsExceptionIfNoMachinesAvailable() throws NoMachinesAvailableException {
-        SshMachineLocation machine1 = provisioner.obtain();
-        SshMachineLocation machine2 = provisioner.obtain();
-        fail("Did not throw NoMachinesAvailableException as expected");
-    }
-
-    @Test
-    public void canGetAMachineReturnItAndObtainItAgain() throws NoMachinesAvailableException {
-        SshMachineLocation obtained = provisioner.obtain();
-        provisioner.release(obtained);
-        SshMachineLocation obtained2 = provisioner.obtain();
-        assertEquals(obtained2, machine);
-    }
-
-    @Test
-    public void theBuilder() throws NoMachinesAvailableException {
-        provisioner2 =
-            new FixedListMachineProvisioningLocation.Builder(mgmt.getLocationManager()).
-                user("u1").
-                addAddress("192.168.0.1").
-                addAddress("u2@192.168.0.2").
-                addAddress("192.168.0.{3,4}").
-                addAddresses("192.168.0.{6-8}").
-                addAddressMultipleTimes("192.168.0.{8,7}", 2).
-                addAddress("u3@192.168.0.{11-20}").
-                build();
-        assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0.1");
-        assertUserAndHost(provisioner2.obtain(), "u2", "192.168.0.2");
-        for (int i=3; i<=4; i++) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
-        for (int i=6; i<=8; i++) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
-        for (int j=0; j<2; j++)
-            for (int i=8; i>=7; i--) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
-        for (int i=11; i<=20; i++) assertUserAndHost(provisioner2.obtain(), "u3", "192.168.0."+i);
-        try { 
-            provisioner2.obtain();
-            fail("Should not have obtained");  //throws error so not caught below
-        } catch (Exception e) {
-            /** expected */
-        }
-    }
-    
-    @Test
-    public void theBuilderLegacy() throws NoMachinesAvailableException {
-        provisioner2 =
-            new FixedListMachineProvisioningLocation.Builder(mgmt.getLocationManager()).
-                user("u1").
-                addAddress("192.168.0.1").
-                addAddress("u2@192.168.0.2").
-                addAddress("192.168.0.{3,4}").
-                addAddresses("192.168.0.{6-8}").
-                addAddressMultipleTimes("192.168.0.{8,7}", 2).
-                addAddress("u3@192.168.0.{11-20}").
-                build();
-        assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0.1");
-        assertUserAndHost(provisioner2.obtain(), "u2", "192.168.0.2");
-        for (int i=3; i<=4; i++) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
-        for (int i=6; i<=8; i++) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
-        for (int j=0; j<2; j++)
-            for (int i=8; i>=7; i--) assertUserAndHost(provisioner2.obtain(), "u1", "192.168.0."+i);
-        for (int i=11; i<=20; i++) assertUserAndHost(provisioner2.obtain(), "u3", "192.168.0."+i);
-        try { 
-            provisioner2.obtain();
-            fail("Should not have obtained");  //throws error so not caught below
-        } catch (Exception e) {
-            /** expected */
-        }
-    }
-    
-    @Test(expectedExceptions = { IllegalStateException.class })
-    public void throwsExceptionIfTryingToReleaseUnallocationMachine() throws NoMachinesAvailableException, UnknownHostException {
-        @SuppressWarnings("unused")
-        SshMachineLocation obtained = provisioner.obtain();
-        provisioner.release(new SshMachineLocation(MutableMap.of("address", Inet4Address.getByName("192.168.144.201"))));
-        fail("Did not throw IllegalStateException as expected");
-    }
-    
-    @Test
-    public void testCanAddMachineToPool() throws UnknownHostException, NoMachinesAvailableException {
-        SshMachineLocation machine2 = new SshMachineLocation(
-                MutableMap.of("address", Inet4Address.getByName("192.168.144.200")));
-        provisioner2 = new FixedListMachineProvisioningLocation<SshMachineLocation>(
-                MutableMap.of("machines", MutableList.of()));
-        provisioner2.addMachine(machine2);
-        
-        assertEquals(ImmutableList.copyOf(provisioner2.getChildren()), ImmutableList.of(machine2));
-        assertEquals(ImmutableSet.copyOf(provisioner2.getAvailable()), ImmutableSet.of(machine2));
-        
-        SshMachineLocation obtained = provisioner2.obtain();
-        assertEquals(obtained, machine2);
-        
-        // Can only obtain the added machien once though (i.e. not added multiple times somehow)
-        try {
-            SshMachineLocation obtained2 = provisioner2.obtain();
-            fail("obtained="+obtained2);
-        } catch (NoMachinesAvailableException e) {
-            // success
-        }
-    }
-
-    @Test
-    public void testCanRemoveAvailableMachineFromPool() {
-        provisioner.removeMachine(machine);
-        
-        Assert.assertTrue(provisioner.getChildren().isEmpty());
-        Assert.assertTrue(provisioner.getAvailable().isEmpty());
-        
-        try {
-            SshMachineLocation obtained = provisioner.obtain();
-            fail("obtained="+obtained);
-        } catch (NoMachinesAvailableException e) {
-            // success
-        }
-    }
-
-    @Test
-    public void testCanRemoveObtainedMachineFromPoolSoNotReallocated() throws NoMachinesAvailableException {
-        SshMachineLocation obtained = provisioner.obtain();
-        provisioner.removeMachine(obtained);
-        
-        // Continue to know about the machine until it is returned
-        assertEquals(ImmutableList.copyOf(provisioner.getChildren()), ImmutableList.of(machine));
-        Assert.assertTrue(provisioner.getAvailable().isEmpty());
-
-        // When released, the machine is then removed entirely
-        provisioner.release(obtained);
-
-        Assert.assertTrue(provisioner.getChildren().isEmpty());
-        Assert.assertTrue(provisioner.getAvailable().isEmpty());
-
-        // So no machines left; cannot re-obtain
-        try {
-            SshMachineLocation obtained2 = provisioner.obtain();
-            fail("obtained="+obtained2);
-        } catch (NoMachinesAvailableException e) {
-            // success
-        }
-    }
-
-    @Test
-    public void testObtainDesiredMachineThrowsIfNotKnown() throws Exception {
-        SshMachineLocation machine2 = new SshMachineLocation(
-                MutableMap.of("address", Inet4Address.getByName("192.168.144.201")));
-        try {
-            SshMachineLocation obtained = provisioner.obtain(MutableMap.of("desiredMachine", machine2));
-            fail("obtained="+obtained);
-        } catch (IllegalStateException e) {
-            if (!e.toString().contains("machine unknown")) throw e;
-        }
-    }
-
-    @Test
-    public void testObtainDesiredMachineThrowsIfInUse() throws Exception {
-        provisioner.addMachine(new SshMachineLocation(
-                MutableMap.of("address", Inet4Address.getByName("192.168.144.201"))));
-        SshMachineLocation obtained = provisioner.obtain();
-        try {
-            SshMachineLocation obtained2 = provisioner.obtain(MutableMap.of("desiredMachine", obtained));
-            fail("obtained2="+obtained2);
-        } catch (IllegalStateException e) {
-            if (!e.toString().contains("machine in use")) throw e;
-        }
-    }
-
-    @Test
-    public void testObtainDesiredMachineReturnsDesired() throws Exception {
-        int desiredMachineIndex = 10;
-        SshMachineLocation desiredMachine = null;
-        for (int i = 0; i < 20; i++) {
-            SshMachineLocation newMachine = new SshMachineLocation(
-                    MutableMap.of("address", Inet4Address.getByName("192.168.144."+(201+i))));
-            if (i == desiredMachineIndex) desiredMachine = newMachine;
-            provisioner.addMachine(newMachine);
-        }
-        SshMachineLocation obtained = provisioner.obtain(MutableMap.of("desiredMachine", desiredMachine));
-        assertEquals(obtained, desiredMachine);
-    }
-
-    @Test
-    public void testAddAndRemoveChildUpdatesMachinesSet() throws Exception {
-        SshMachineLocation anotherMachine = new SshMachineLocation(
-                MutableMap.of("address", Inet4Address.getByName("192.168.144.201")));
-        provisioner.addChild(anotherMachine);
-        assertEquals(provisioner.getAllMachines(), ImmutableSet.of(machine, anotherMachine));
-        
-        provisioner.removeChild(anotherMachine);
-        assertEquals(provisioner.getAllMachines(), ImmutableSet.of(machine));
-    }
-    
-    @Test
-    public void testCanAddAlreadyParentedMachine() throws UnknownHostException, NoMachinesAvailableException {
-        provisioner.obtain(); // so no machines left
-        
-        FixedListMachineProvisioningLocation<SshMachineLocation> provisioner2 = new FixedListMachineProvisioningLocation.Builder(mgmt.getLocationManager())
-            .addAddress("1.2.3.4")
-            .build();
-        SshMachineLocation machine = provisioner2.obtain();
-        
-        provisioner.addMachine(machine);
-        assertEquals(provisioner.obtain(), machine);
-    }
-
-    @Test
-    public void testCanCreateWithAlreadyParentedMachine() throws UnknownHostException, NoMachinesAvailableException {
-        machine = provisioner.obtain();
-        
-        FixedListMachineProvisioningLocation<SshMachineLocation> provisioner2 = new FixedListMachineProvisioningLocation.Builder(mgmt.getLocationManager())
-            .add(machine)
-            .build();
-        assertEquals(provisioner2.obtain(), machine);
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testMachinesObtainedInOrder() throws Exception {
-        List<SshMachineLocation> machines = ImmutableList.of(
-                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.1"))),
-                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.6"))),
-                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.3"))),
-                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.4"))),
-                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.5"))));
-        
-        provisioner2 = mgmt.getLocationManager().createLocation(
-                MutableMap.of("machines", machines),
-                FixedListMachineProvisioningLocation.class);
-
-        for (SshMachineLocation expected : machines) {
-            assertEquals(provisioner2.obtain(), expected);
-        }
-    }
-    
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testMachineChooser() throws Exception {
-        List<SshMachineLocation> machines = Lists.newArrayList();
-        for (int i = 0; i < 10; i++) {
-            machines.add(mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1."+i))));
-        }
-        final List<SshMachineLocation> desiredOrder = randomized(machines);
-        
-        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
-            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
-                for (SshMachineLocation contender : desiredOrder) {
-                    if (Iterables.contains(input, contender)) {
-                        return contender;
-                    }
-                }
-                Assert.fail("No intersection of input="+input+" and desiredOrder="+desiredOrder);
-                return null; // unreachable code
-            }
-        };
-        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .configure("machines", machines)
-                .configure(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser));
-
-        List<SshMachineLocation> result = Lists.newArrayList();
-        for (int i = 0; i < machines.size(); i++) {
-            result.add(provisioner2.obtain());
-        }
-        assertEquals(result, desiredOrder, "result="+result+"; desired="+desiredOrder);
-        LOG.debug("chooser's desiredOrder="+desiredOrder);
-    }
-    
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testMachineChooserPassedToObtain() throws Exception {
-        List<SshMachineLocation> machines = Lists.newArrayList();
-        for (int i = 0; i < 10; i++) {
-            machines.add(mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1."+i))));
-        }
-        final List<SshMachineLocation> desiredOrder = randomized(machines);
-        
-        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
-            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
-                for (SshMachineLocation contender : desiredOrder) {
-                    if (Iterables.contains(input, contender)) {
-                        return contender;
-                    }
-                }
-                Assert.fail("No intersection of input="+input+" and desiredOrder="+desiredOrder);
-                return null; // unreachable code
-            }
-        };
-        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .configure("machines", machines));
-
-        List<SshMachineLocation> result = Lists.newArrayList();
-        for (int i = 0; i < machines.size(); i++) {
-            result.add(provisioner2.obtain(ImmutableMap.of(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser)));
-        }
-        assertEquals(result, desiredOrder, "result="+result+"; desired="+desiredOrder);
-        LOG.debug("chooser's desiredOrder="+desiredOrder);
-    }
-    
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testMachineChooserNotCalledWhenNoMachines() throws Exception {
-        List<SshMachineLocation> machines = ImmutableList.of(
-                mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.1"))));
-        final AtomicInteger callCount = new AtomicInteger();
-        
-        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
-            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
-                callCount.incrementAndGet();
-                return Iterables.get(input, 0);
-            }
-        };
-        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .configure("machines", machines)
-                .configure(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser));
-        provisioner2.obtain();
-
-        // When no machines available should fail gracefully, without asking the "chooser"
-        try {
-            provisioner2.obtain();
-            fail("Expected "+NoMachinesAvailableException.class.getSimpleName());
-        } catch (NoMachinesAvailableException e) {
-            // Pass; sensible exception
-        }
-        assertEquals(callCount.get(), 1);
-    }
-    
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testFailsWhenMachineChooserReturnsAlreadyAllocatedMachine() throws Exception {
-        final SshMachineLocation machine1 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.1")));
-        final SshMachineLocation machine2 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.2")));
-        List<SshMachineLocation> machines = ImmutableList.of(machine1, machine2);
-        
-        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
-            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
-                return machine1;
-            }
-        };
-        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .configure("machines", machines)
-                .configure(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser));
-        provisioner2.obtain();
-
-        // Should fail when tries to return same machine for a second time
-        try {
-            provisioner2.obtain();
-            fail("Expected "+IllegalStateException.class.getSimpleName());
-        } catch (IllegalStateException e) {
-            if (!e.toString().contains("Machine chooser attempted to choose ")) throw e;
-        }
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testFailsWhenMachineChooserReturnsInvalidMachine() throws Exception {
-        final SshMachineLocation machine1 = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("1.1.1.1")));
-        final SshMachineLocation machineOther = mgmt.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class).configure("address", Networking.getInetAddressWithFixedName("2.2.2.1")));
-        List<SshMachineLocation> machines = ImmutableList.of(machine1);
-        
-        Function<Iterable<? extends MachineLocation>, MachineLocation> chooser = new Function<Iterable<? extends MachineLocation>, MachineLocation>() {
-            @Override public MachineLocation apply(Iterable<? extends MachineLocation> input) {
-                return machineOther;
-            }
-        };
-        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .configure("machines", machines)
-                .configure(FixedListMachineProvisioningLocation.MACHINE_CHOOSER, chooser));
-
-        // Call when no machines available should fail gracefully, without asking the "chooser"
-        try {
-            provisioner2.obtain();
-            fail("Expected "+IllegalStateException.class.getSimpleName());
-        } catch (IllegalStateException e) {
-            if (!e.toString().contains("Machine chooser attempted to choose ")) throw e;
-        }
-    }
-
-    @Test
-    @SuppressWarnings("unchecked")
-    public void testMachineCustomizerSetOnByon() throws Exception {
-        machine = mgmt.getLocationManager().createLocation(MutableMap.of("address", Inet4Address.getByName("192.168.144.200")), SshMachineLocation.class);
-        RecordingMachineLocationCustomizer customizer = new RecordingMachineLocationCustomizer();
-        
-        provisioner2 = mgmt.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .configure("machines", ImmutableList.of(machine))
-                .configure(FixedListMachineProvisioningLocation.MACHINE_LOCATION_CUSTOMIZERS.getName(), ImmutableList.of(customizer)));
-                
-        SshMachineLocation obtained = provisioner2.obtain();
-        assertEquals(Iterables.getOnlyElement(customizer.calls), new Call("customize", ImmutableList.of(obtained)));
-        
-        provisioner2.release(obtained);
-        assertEquals(customizer.calls.size(), 2);
-        assertEquals(Iterables.get(customizer.calls, 1), new Call("preRelease", ImmutableList.of(obtained)));
-    }
-
-    @Test
-    public void testMachineCustomizerSetOnObtainCall() throws Exception {
-        RecordingMachineLocationCustomizer customizer = new RecordingMachineLocationCustomizer();
-        
-        SshMachineLocation obtained = provisioner.obtain(ImmutableMap.of(FixedListMachineProvisioningLocation.MACHINE_LOCATION_CUSTOMIZERS, ImmutableList.of(customizer)));
-        assertEquals(Iterables.getOnlyElement(customizer.calls), new Call("customize", ImmutableList.of(obtained)));
-        
-        provisioner.release(obtained);
-        assertEquals(customizer.calls.size(), 2);
-        assertEquals(customizer.calls.get(1), new Call("preRelease", ImmutableList.of(obtained)));
-    }
-
-    @Test
-    public void testMachineGivenCustomFlagForDurationOfUsage() throws Exception {
-        boolean origContains = machine.config().getBag().getAllConfig().containsKey("mykey");
-        SshMachineLocation obtained = provisioner.obtain(ImmutableMap.of("mykey", "myNewVal"));
-        Object obtainedVal = obtained.config().getBag().getAllConfig().get("mykey");
-        provisioner.release(obtained);
-        boolean releasedContains = obtained.config().getBag().getAllConfig().containsKey("mykey");
-        
-        assertEquals(obtained, machine);
-        assertFalse(origContains);
-        assertEquals(obtainedVal, "myNewVal");
-        assertFalse(releasedContains);
-    }
-    
-    @Test
-    public void testMachineConfigRestoredToDefaultsOnRelease() throws Exception {
-        ConfigKey<String> mykey = ConfigKeys.newStringConfigKey("mykey");
-        
-        boolean origContains = machine.config().getBag().getAllConfig().containsKey("mykey");
-        SshMachineLocation obtained = provisioner.obtain();
-        obtained.config().set(mykey, "myNewVal");
-        Object obtainedVal = obtained.config().getBag().getAllConfig().get("mykey");
-        
-        provisioner.release(obtained);
-        boolean releasedContains = machine.config().getBag().getAllConfig().containsKey("mykey");
-        releasedContains |= (machine.config().get(mykey) != null);
-        
-        assertEquals(obtained, machine);
-        assertFalse(origContains);
-        assertEquals(obtainedVal, "myNewVal");
-        assertFalse(releasedContains);
-    }
-    
-    @Test
-    public void testMachineGivenOverriddenFlagForDurationOfUsage() throws Exception {
-        SshMachineLocation machine2 = new SshMachineLocation(
-                MutableMap.of("address", Inet4Address.getByName("192.168.144.200"), "mykey", "myval"));
-        provisioner2 = new FixedListMachineProvisioningLocation<SshMachineLocation>(
-                MutableMap.of("machines", MutableList.of(machine2)));
-
-        Object origVal = machine2.config().getBag().getAllConfig().get("mykey");
-        SshMachineLocation obtained = provisioner2.obtain(ImmutableMap.of("mykey", "myNewVal"));
-        Object obtainedVal = obtained.config().getBag().getAllConfig().get("mykey");
-        provisioner2.release(obtained);
-        Object releasedVal = obtained.config().getBag().getAllConfig().get("mykey");
-        
-        assertEquals(obtained, machine2);
-        assertEquals(origVal, "myval");
-        assertEquals(obtainedVal, "myNewVal");
-        assertEquals(releasedVal, "myval");
-    }
-
-    private static <T> List<T> randomized(Iterable<T> list) {
-        // TODO inefficient implementation, but don't care for small tests
-        Random random = new Random();
-        List<T> result = Lists.newLinkedList();
-        for (T element : list) {
-            int index = (result.isEmpty() ? 0 : random.nextInt(result.size()));
-            result.add(index, element);
-        }
-        return result;
-    }
-    
-    private static void assertUserAndHost(SshMachineLocation l, String user, String host) {
-        assertEquals(l.getUser(), user);
-        assertEquals(l.getAddress().getHostAddress(), host);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/HostLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/HostLocationResolverTest.java b/core/src/test/java/brooklyn/location/basic/HostLocationResolverTest.java
deleted file mode 100644
index ddb8ae4..0000000
--- a/core/src/test/java/brooklyn/location/basic/HostLocationResolverTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-import java.net.InetAddress;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.management.internal.LocalManagementContext;
-
-import com.google.common.collect.ImmutableMap;
-
-public class HostLocationResolverTest {
-    
-    private BrooklynProperties brooklynProperties;
-    private LocalManagementContext managementContext;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-        brooklynProperties = managementContext.getBrooklynProperties();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testThrowsOnInvalid() throws Exception {
-        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
-        assertThrowsIllegalArgument("host");
-    }
-    
-    @Test
-    public void testThrowsOnInvalidTarget() throws Exception {
-        assertThrowsIllegalArgument("host:()");
-    }
-    
-    @Test
-    public void resolveHosts() {
-        resolve("host:(\"1.1.1.1\")");
-        resolve("host:(\"localhost\")");
-    }
-    
-    @Test(groups="Integration")
-    public void resolveRealHosts() {
-        // must be online to resolve this
-        resolve("host:(\"www.foo.com\")");
-    }
-    
-    @Test
-    public void testNamedByonLocation() throws Exception {
-        brooklynProperties.put("brooklyn.location.named.mynamed", "host:(\"1.1.1.1\")");
-        
-        MachineProvisioningLocation<SshMachineLocation> loc = resolve("named:mynamed");
-        assertEquals(loc.obtain(ImmutableMap.of()).getAddress(), InetAddress.getByName("1.1.1.1"));
-    }
-
-    @Test
-    public void testPropertyScopePrescedence() throws Exception {
-        brooklynProperties.put("brooklyn.location.named.mynamed", "host:(\"1.1.1.1\")");
-        
-        // prefer those in "named" over everything else
-        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
-        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
-
-        // prefer location-generic if nothing else
-        brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
-
-        Map<String, Object> conf = resolve("named:mynamed").obtain(ImmutableMap.of()).config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
-        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
-    }
-
-    private void assertThrowsNoSuchElement(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (NoSuchElementException e) {
-            // success
-        }
-    }
-    
-    private void assertThrowsIllegalArgument(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-    }
-    
-    @SuppressWarnings("unchecked")
-    private MachineProvisioningLocation<SshMachineLocation> resolve(String val) {
-        return (MachineProvisioningLocation<SshMachineLocation>) managementContext.getLocationRegistry().resolve(val);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LegacyAbstractLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LegacyAbstractLocationTest.java b/core/src/test/java/brooklyn/location/basic/LegacyAbstractLocationTest.java
deleted file mode 100644
index fa4f6d7..0000000
--- a/core/src/test/java/brooklyn/location/basic/LegacyAbstractLocationTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.collect.ImmutableList;
-
-public class LegacyAbstractLocationTest {
-
-    private static class ConcreteLocation extends AbstractLocation {
-        @SetFromFlag(defaultVal="mydefault")
-        String myfield;
-
-        public ConcreteLocation() {
-            super();
-        }
-
-        public ConcreteLocation(Map properties) {
-            super(properties);
-        }
-    }
-
-    @AfterMethod(alwaysRun = true)
-    public void tearDown(){
-        // nothing to tear down; did not create a management context
-    }
-
-    @Test
-    public void testEquals() {
-        AbstractLocation l1 = new ConcreteLocation(MutableMap.of("id", "1", "name", "bob"));
-        AbstractLocation l2 = new ConcreteLocation(MutableMap.of("id", "1", "name", "frank"));
-        AbstractLocation l3 = new ConcreteLocation(MutableMap.of("id", "2", "name", "frank"));
-        assertEquals(l1, l2);
-        assertNotEquals(l2, l3);
-    }
-
-    @Test
-    public void nullNameAndParentLocationIsAcceptable() {
-        AbstractLocation location = new ConcreteLocation(MutableMap.of("name", null, "parentLocation", null));
-        assertEquals(location.getDisplayName(), null);
-        assertEquals(location.getParent(), null);
-    }
-
-    @Test
-    public void testSettingParentLocation() {
-        AbstractLocation location = new ConcreteLocation();
-        AbstractLocation locationSub = new ConcreteLocation();
-        locationSub.setParent(location);
-        
-        assertEquals(ImmutableList.copyOf(location.getChildren()), ImmutableList.of(locationSub));
-        assertEquals(locationSub.getParent(), location);
-    }
-
-    @Test
-    public void testClearingParentLocation() {
-        AbstractLocation location = new ConcreteLocation();
-        AbstractLocation locationSub = new ConcreteLocation();
-        locationSub.setParent(location);
-        
-        locationSub.setParent(null);
-        assertEquals(ImmutableList.copyOf(location.getChildren()), Collections.emptyList());
-        assertEquals(locationSub.getParent(), null);
-    }
-    
-    @Test
-    public void testContainsLocation() {
-        AbstractLocation location = new ConcreteLocation();
-        AbstractLocation locationSub = new ConcreteLocation();
-        locationSub.setParent(location);
-        
-        assertTrue(location.containsLocation(location));
-        assertTrue(location.containsLocation(locationSub));
-        assertFalse(locationSub.containsLocation(location));
-    }
-
-
-    @Test
-    public void queryingNameReturnsNameGivenInConstructor() {
-        String name = "Outer Mongolia";
-        AbstractLocation location = new ConcreteLocation(MutableMap.of("name", "Outer Mongolia"));
-        assertEquals(location.getDisplayName(), name);;
-    }
-
-    @Test
-    public void constructorParentLocationReturnsExpectedLocation() {
-        AbstractLocation parent = new ConcreteLocation(MutableMap.of("name", "Middle Earth"));
-        AbstractLocation child = new ConcreteLocation(MutableMap.of("name", "The Shire", "parentLocation", parent));
-        assertEquals(child.getParent(), parent);
-        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
-    }
-
-    @Test
-    public void setParentLocationReturnsExpectedLocation() {
-        AbstractLocation parent = new ConcreteLocation(MutableMap.of("name", "Middle Earth"));
-        AbstractLocation child = new ConcreteLocation(MutableMap.of("name", "The Shire"));
-        child.setParent(parent);
-        assertEquals(child.getParent(), parent);
-        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
-    }
-    
-    @Test
-    public void testAddChildToParentLocationReturnsExpectedLocation() {
-        AbstractLocation parent = new ConcreteLocation(MutableMap.of("id", "1"));
-        AbstractLocation child = new ConcreteLocation(MutableMap.of("id", "2"));
-        parent.addChild(child);
-        assertEquals(child.getParent(), parent);
-        assertEquals(ImmutableList.copyOf(parent.getChildren()), ImmutableList.of(child));
-    }
-
-    @Test
-    public void testFieldSetFromFlag() {
-        ConcreteLocation loc = new ConcreteLocation(MutableMap.of("myfield", "myval"));
-        assertEquals(loc.myfield, "myval");
-    }
-    
-    @Test
-    public void testFieldSetFromFlagUsesDefault() {
-        ConcreteLocation loc = new ConcreteLocation();
-        assertEquals(loc.myfield, "mydefault");
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocalhostLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocalhostLocationResolverTest.java b/core/src/test/java/brooklyn/location/basic/LocalhostLocationResolverTest.java
deleted file mode 100644
index 67d59f1..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocalhostLocationResolverTest.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.text.StringEscapes.JavaStringEscapes;
-
-import com.google.common.collect.ImmutableList;
-
-public class LocalhostLocationResolverTest {
-
-    private BrooklynProperties brooklynProperties;
-    private LocalManagementContext managementContext;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-        brooklynProperties = managementContext.getBrooklynProperties();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testTakesLocalhostScopedProperties() {
-        brooklynProperties.put("brooklyn.location.localhost.privateKeyFile", "myprivatekeyfile");
-        brooklynProperties.put("brooklyn.location.localhost.publicKeyFile", "mypublickeyfile");
-        brooklynProperties.put("brooklyn.location.localhost.privateKeyData", "myprivateKeyData");
-        brooklynProperties.put("brooklyn.location.localhost.publicKeyData", "myPublicKeyData");
-        brooklynProperties.put("brooklyn.location.localhost.privateKeyPassphrase", "myprivateKeyPassphrase");
-
-        Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
-        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
-        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
-        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
-        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
-    }
-
-    @Test
-    public void testTakesLocalhostDeprecatedScopedProperties() {
-        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "myprivatekeyfile");
-        brooklynProperties.put("brooklyn.localhost.publicKeyFile", "mypublickeyfile");
-        brooklynProperties.put("brooklyn.localhost.privateKeyData", "myprivateKeyData");
-        brooklynProperties.put("brooklyn.localhost.publicKeyData", "myPublicKeyData");
-        brooklynProperties.put("brooklyn.localhost.privateKeyPassphrase", "myprivateKeyPassphrase");
-
-        Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
-        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
-        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
-        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
-        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
-    }
-
-    @Test
-    public void testTakesDeprecatedProperties() {
-        brooklynProperties.put("brooklyn.localhost.private-key-file", "myprivatekeyfile");
-        brooklynProperties.put("brooklyn.localhost.public-key-file", "mypublickeyfile");
-        brooklynProperties.put("brooklyn.localhost.private-key-data", "myprivateKeyData");
-        brooklynProperties.put("brooklyn.localhost.public-key-data", "myPublicKeyData");
-        brooklynProperties.put("brooklyn.localhost.private-key-passphrase", "myprivateKeyPassphrase");
-        Map<String, Object> conf = resolve("localhost").config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("privateKeyFile"), "myprivatekeyfile");
-        assertEquals(conf.get("publicKeyFile"), "mypublickeyfile");
-        assertEquals(conf.get("privateKeyData"), "myprivateKeyData");
-        assertEquals(conf.get("publicKeyData"), "myPublicKeyData");
-        assertEquals(conf.get("privateKeyPassphrase"), "myprivateKeyPassphrase");
-    }
-    
-    @Test
-    public void testPropertyScopePrescedence() {
-        brooklynProperties.put("brooklyn.location.named.mynamed", "localhost");
-        
-        // prefer those in "named" over everything else
-        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
-        brooklynProperties.put("brooklyn.location.localhost.privateKeyFile", "privateKeyFile-inProviderSpecific");
-        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
-
-        // prefer those in provider-specific over generic
-        brooklynProperties.put("brooklyn.location.localhost.publicKeyFile", "publicKeyFile-inProviderSpecific");
-        brooklynProperties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inGeneric");
-
-        // prefer location-generic if nothing else
-        brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
-
-        Map<String, Object> conf = resolve("named:mynamed").config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
-        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
-        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
-    }
-
-    @Test
-    public void testLocalhostLoads() {
-        Assert.assertTrue(resolve("localhost") instanceof LocalhostMachineProvisioningLocation);
-    }
-
-    @Test
-    public void testThrowsOnInvalid() throws Exception {
-        assertThrowsNoSuchElement("wrongprefix");
-        assertThrowsIllegalArgument("localhost(name=abc"); // no closing bracket
-        assertThrowsIllegalArgument("localhost(name)"); // no value for name
-        assertThrowsIllegalArgument("localhost(name=)"); // no value for name
-    }
-    
-
-    @Test
-    public void testAcceptsList() {
-        List<Location> l = getLocationResolver().resolve(ImmutableList.of("localhost"));
-        assertEquals(l.size(), 1, "l="+l);
-        assertTrue(l.get(0) instanceof LocalhostMachineProvisioningLocation, "l="+l);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testRegistryCommaResolution() throws NoMachinesAvailableException {
-        List<Location> l;
-        l = getLocationResolver().resolve(JavaStringEscapes.unwrapJsonishListIfPossible("localhost,localhost,localhost"));
-        assertEquals(l.size(), 3, "l="+l);
-        assertTrue(l.get(0) instanceof LocalhostMachineProvisioningLocation, "l="+l);
-        assertTrue(l.get(1) instanceof LocalhostMachineProvisioningLocation, "l="+l);
-        assertTrue(l.get(2) instanceof LocalhostMachineProvisioningLocation, "l="+l);
-
-        // And check works if comma in brackets
-        l = getLocationResolver().resolve(JavaStringEscapes.unwrapJsonishListIfPossible(
-            "[ \"byon:(hosts=\\\"192.168.0.1\\\",user=bob)\", \"byon:(hosts=\\\"192.168.0.2\\\",user=bob2)\" ]"));
-        assertEquals(l.size(), 2, "l="+l);
-        assertTrue(l.get(0) instanceof FixedListMachineProvisioningLocation, "l="+l);
-        assertTrue(l.get(1) instanceof FixedListMachineProvisioningLocation, "l="+l);
-        assertEquals(((FixedListMachineProvisioningLocation<SshMachineLocation>)l.get(0)).obtain().getUser(), "bob");
-        assertEquals(((FixedListMachineProvisioningLocation<SshMachineLocation>)l.get(1)).obtain().getUser(), "bob2");
-    }
-
-    @Test(expectedExceptions={NoSuchElementException.class})
-    public void testRegistryCommaResolutionInListNotAllowed1() throws NoMachinesAvailableException {
-        // disallowed since 0.7.0
-        getLocationResolver().resolve(ImmutableList.of("localhost,localhost,localhost"));
-    }
-
-    @Test(expectedExceptions={IllegalArgumentException.class})
-    public void testRegistryCommaResolutionInListNotAllowed2() throws NoMachinesAvailableException {
-        // disallowed since 0.7.0
-        // fails because it interprets the entire string as a single spec, which does not parse
-        getLocationResolver().resolve(ImmutableList.of("localhost(),localhost()"));
-    }
-
-    @Test(expectedExceptions={IllegalArgumentException.class})
-    public void testRegistryCommaResolutionInListNotAllowed3() throws NoMachinesAvailableException {
-        // disallowed since 0.7.0
-        // fails because it interprets the entire string as a single spec, which does not parse
-        getLocationResolver().resolve(ImmutableList.of("localhost(name=a),localhost(name=b)"));
-    }
-
-    @Test(expectedExceptions={IllegalArgumentException.class})
-    public void testDoesNotAcceptsListOLists() {
-        ((BasicLocationRegistry)managementContext.getLocationRegistry()).resolve(ImmutableList.of(ImmutableList.of("localhost")));
-    }
-
-    @Test
-    public void testResolvesExplicitName() throws Exception {
-        Location location = resolve("localhost(name=myname)");
-        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
-        assertEquals(location.getDisplayName(), "myname");
-    }
-    
-    @Test
-    public void testWithOldStyleColon() throws Exception {
-        Location location = resolve("localhost:(name=myname)");
-        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
-        assertEquals(location.getDisplayName(), "myname");
-    }
-    
-    @Test
-    public void testResolvesPropertiesInSpec() throws Exception {
-        LocationInternal location = resolve("localhost(privateKeyFile=myprivatekeyfile,name=myname)");
-        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
-        assertEquals(location.getDisplayName(), "myname");
-        assertEquals(location.config().getBag().getStringKey("privateKeyFile"), "myprivatekeyfile");
-    }
-    
-    @Test
-    public void testResolvesDefaultName() throws Exception {
-        Location location = resolve("localhost");
-        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
-        assertEquals(location.getDisplayName(), "localhost");
-
-        Location location2 = resolve("localhost()");
-        assertTrue(location2 instanceof LocalhostMachineProvisioningLocation);
-        assertEquals(location2.getDisplayName(), "localhost");
-    }
-    
-    private BasicLocationRegistry getLocationResolver() {
-        return (BasicLocationRegistry) managementContext.getLocationRegistry();
-    }
-    
-    private LocationInternal resolve(String val) {
-        Location l = managementContext.getLocationRegistry().resolve(val);
-        Assert.assertNotNull(l);
-        return (LocationInternal) l;
-    }
-    
-    private void assertThrowsNoSuchElement(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (NoSuchElementException e) {
-            // success
-        }
-
-        // and check the long form returns an Absent (not throwing)
-        Assert.assertTrue(managementContext.getLocationRegistry().resolve(val, false, null).isAbsent());
-    }
-    
-    private void assertThrowsIllegalArgument(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-        
-        // and check the long form returns an Absent (not throwing)
-        Assert.assertTrue(managementContext.getLocationRegistry().resolve(val, false, null).isAbsent());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java b/core/src/test/java/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
deleted file mode 100644
index b824032..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocalhostMachineProvisioningLocationTest.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.fail;
-
-import java.net.ServerSocket;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.PortRange;
-import brooklyn.location.geo.HostGeoInfo;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Networking;
-
-public class LocalhostMachineProvisioningLocationTest {
-
-    private static final Logger log = LoggerFactory.getLogger(LocalhostMachineProvisioningLocationTest.class);
-    
-    private LocalManagementContext mgmt;
-
-    @BeforeMethod
-    @AfterClass
-    protected void clearStatics() {
-        LocalhostMachineProvisioningLocation.clearStaticData();
-    }
-    
-    @BeforeClass
-    protected void setup() {
-        mgmt = LocalManagementContextForTests.newInstance();
-    }
-    
-    @AfterClass
-    protected void teardown() {
-        Entities.destroyAll(mgmt);
-    }
-    
-    protected LocalhostMachineProvisioningLocation newLocalhostProvisioner() {
-        return mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
-    }
-    
-    protected LocalhostMachineProvisioningLocation newLocalhostProvisionerWithAddress(String address) {
-        return mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class)
-            .configure("address", address));
-    }
-    
-    @Test
-    public void defaultInvocationCanProvisionALocalhostInstance() throws Exception {
-        LocalhostMachineProvisioningLocation provisioner = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
-        SshMachineLocation machine = provisioner.obtain();
-        assertNotNull(machine);
-        assertEquals(machine.address, Networking.getLocalHost());
-    }
-
-    @Test
-    public void testUsesLocationNameProvided() throws Exception {
-        LocalhostMachineProvisioningLocation provisioner = newLocalhostProvisionerWithAddress("localhost");
-        assertEquals(((SshMachineLocation)provisioner.obtain()).getAddress().getHostName(), "localhost");
-
-        LocalhostMachineProvisioningLocation provisioner2 = newLocalhostProvisionerWithAddress("1.2.3.4");
-        assertEquals(((SshMachineLocation)provisioner2.obtain()).getAddress().getHostName(), "1.2.3.4");
-        
-        LocalhostMachineProvisioningLocation provisioner3 = newLocalhostProvisionerWithAddress("127.0.0.1");
-        assertEquals(((SshMachineLocation)provisioner3.obtain()).getAddress().getHostName(), "127.0.0.1");
-    }
-    
-    public void provisionWithASpecificNumberOfInstances() throws NoMachinesAvailableException {
-        LocalhostMachineProvisioningLocation provisioner = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class)
-            .configure("count", 2));
-
-        // first machine
-        SshMachineLocation first = provisioner.obtain();
-        assertNotNull(first);
-        assertEquals(first.address, Networking.getLocalHost());
-
-        // second machine
-        SshMachineLocation second = provisioner.obtain();
-        assertNotNull(second);
-        assertEquals(second.address, Networking.getLocalHost());
-
-        // third machine - fails
-        try {
-            SshMachineLocation third = provisioner.obtain();
-            fail("did not throw expected exception; got "+third);
-        } catch (NoMachinesAvailableException e) {
-            /* expected */
-        }
-    }
-    
-    @Test
-    public void obtainTwoAddressesInRangeThenDontObtain() throws Exception {
-        LocalhostMachineProvisioningLocation p = newLocalhostProvisioner();
-        SshMachineLocation m = p.obtain();
-
-        // Find two ports that are free, rather than risk false-negatives if a port was left open by something else.
-        int start = 48311;
-        while (true) {
-            if (Networking.isPortAvailable(m.getAddress(), start) && Networking.isPortAvailable(m.getAddress(), start+1)) {
-                break;
-            } else {
-                start++;
-            }
-        }
-        PortRange r = PortRanges.fromString(""+start+"-"+(start+1));
-        
-        try {
-            int i1 = m.obtainPort(r);
-            Assert.assertEquals(i1, start);
-            int i2 = m.obtainPort(r);
-            Assert.assertEquals(i2, start+1);
-            
-            //should fail
-            int i3 = m.obtainPort(r);
-            Assert.assertEquals(i3, -1);
-
-            //releasing and reapplying should succed
-            m.releasePort(i2);
-            int i4 = m.obtainPort(r);
-            Assert.assertEquals(i4, i2);
-
-        } finally {
-            m.releasePort(start);
-            m.releasePort(start+1);
-        }
-    }
-    
-    @Test
-    public void obtainLowNumberedPortsAutomatically() throws Exception {
-        LocalhostMachineProvisioningLocation p = newLocalhostProvisioner();
-        SshMachineLocation m = p.obtain();
-        int start = 983;  //random rarely used port, not that it matters
-        try {
-            int actual = m.obtainPort(PortRanges.fromInteger(start));
-            Assert.assertEquals(actual, start);
-        } finally {
-            m.releasePort(start);
-        }
-
-    }
-
-    @Test
-    public void obtainPortFailsIfInUse() throws Exception {
-        LocalhostMachineProvisioningLocation p = newLocalhostProvisioner();
-        SshMachineLocation m = p.obtain();
-        
-        // Find two ports that are free, rather than risk false-negatives if a port was left open by something else.
-        int start = 48311;
-        while (true) {
-            if (Networking.isPortAvailable(m.getAddress(), start) && Networking.isPortAvailable(m.getAddress(), start+1)) {
-                break;
-            } else {
-                start++;
-            }
-        }
-        PortRange r = PortRanges.fromString(""+start+"-"+(start+1));
-
-        ServerSocket ss = null;
-        try {
-            ss = new ServerSocket(start, 0, m.getAddress());
-            int i1 = m.obtainPort(r);
-            Assert.assertEquals(i1, start+1);
-        } finally {
-            if (ss!=null) ss.close();
-            m.releasePort(start);
-            m.releasePort(start+1);
-        }
-    }
-
-    @Test
-    public void obtainLocationWithGeography() throws Exception {
-        mgmt.getBrooklynProperties().put("brooklyn.location.named.lhx", "localhost");
-        // bogus location so very little chance of it being what maxmind returns!
-        mgmt.getBrooklynProperties().put("brooklyn.location.named.lhx.latitude", 42d);
-        mgmt.getBrooklynProperties().put("brooklyn.location.named.lhx.longitude", -20d);
-        MachineProvisioningLocation<?> p = (MachineProvisioningLocation<?>) mgmt.getLocationRegistry().resolve("named:lhx");
-        SshMachineLocation m = (SshMachineLocation) p.obtain(MutableMap.of());
-        HostGeoInfo geo = HostGeoInfo.fromLocation(m);
-        log.info("Geo info for "+m+" is: "+geo);
-        Assert.assertEquals(geo.latitude, 42d, 0.00001);
-        Assert.assertEquals(geo.longitude, -20d, 0.00001);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java b/core/src/test/java/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
deleted file mode 100644
index c5eeb12..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocalhostProvisioningAndAccessTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Arrays;
-
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.management.internal.LocalManagementContext;
-
-public class LocalhostProvisioningAndAccessTest {
-
-    private LocalManagementContext mgmt;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        mgmt = new LocalManagementContext(BrooklynProperties.Factory.newDefault());
-    }
-    
-    @AfterMethod(alwaysRun = true)
-    public void tearDown(){
-        if (mgmt != null) Entities.destroyAll(mgmt);
-    }
-
-    @Test(groups="Integration")
-    public void testProvisionAndConnect() throws Exception {
-        Location location = mgmt.getLocationRegistry().resolve("localhost");
-        assertTrue(location instanceof LocalhostMachineProvisioningLocation);
-        SshMachineLocation m = ((LocalhostMachineProvisioningLocation)location).obtain();
-        int result = m.execCommands("test", Arrays.asList("echo hello world"));
-        assertEquals(result, 0);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java b/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java
deleted file mode 100644
index 0df4677..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocationConfigTest.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.collect.ImmutableMap;
-
-public class LocationConfigTest {
-
-    // TODO Duplication of LocationConfigTest, but with locations instead of entities
-    
-    private ManagementContext managementContext;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-
-    @Test
-    public void testConfigBagContainsMatchesForConfigKeyName() throws Exception {
-        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
-                .configure("mylocation.myconfig", "myval1")
-                .configure("mylocation.myconfigwithflagname", "myval2"));
-        
-        assertEquals(loc.config().getBag().getAllConfig(), ImmutableMap.of("mylocation.myconfig", "myval1", "mylocation.myconfigwithflagname", "myval2"));
-        assertEquals(loc.config().getLocalBag().getAllConfig(), ImmutableMap.of("mylocation.myconfig", "myval1", "mylocation.myconfigwithflagname", "myval2"));
-        assertEquals(loc.getAllConfig(true), ImmutableMap.of("mylocation.myconfig", "myval1", "mylocation.myconfigwithflagname", "myval2"));
-        assertEquals(loc.getAllConfig(false), ImmutableMap.of("mylocation.myconfig", "myval1", "mylocation.myconfigwithflagname", "myval2"));
-    }
-
-    // TODO Note difference compared to Location, where both flag-name + config-key-name are in the ConfigBag
-    @Test
-    public void testConfigBagContainsMatchesForFlagName() throws Exception {
-        // Prefers flag-name, over config-key's name
-        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
-                .configure("myconfigflagname", "myval"));
-        
-        assertEquals(loc.config().getBag().getAllConfig(), ImmutableMap.of("mylocation.myconfigwithflagname", "myval", "myconfigflagname", "myval"));
-        assertEquals(loc.config().getLocalBag().getAllConfig(), ImmutableMap.of("mylocation.myconfigwithflagname", "myval", "myconfigflagname", "myval"));
-        assertEquals(loc.getAllConfig(true), ImmutableMap.of("mylocation.myconfigwithflagname", "myval", "myconfigflagname", "myval"));
-        assertEquals(loc.getAllConfig(false), ImmutableMap.of("mylocation.myconfigwithflagname", "myval", "myconfigflagname", "myval"));
-    }
-
-    @Test
-    public void testConfigBagContainsUnmatched() throws Exception {
-        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
-                .configure("notThere", "notThereVal"));
-        
-        assertEquals(loc.config().getBag().getAllConfig(), ImmutableMap.of("notThere", "notThereVal"));
-        assertEquals(loc.config().getLocalBag().getAllConfig(), ImmutableMap.of("notThere", "notThereVal"));
-        assertEquals(loc.getAllConfig(true), ImmutableMap.of("notThere", "notThereVal"));
-        assertEquals(loc.getAllConfig(false), ImmutableMap.of("notThere", "notThereVal"));
-    }
-    
-    // TODO Note difference from entity: child's bag contains both the flag-name and the config-key-name
-    @Test
-    public void testChildConfigBagInheritsUnmatchedAtParent() throws Exception {
-        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
-                .configure("mychildlocation.myconfig", "myval1")
-                .configure("notThere", "notThereVal"));
-
-        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
-                .parent(loc));
-
-        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfig", "myval1", "notThere", "notThereVal"));
-        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of());
-        assertEquals(child.getAllConfig(true), ImmutableMap.of("mychildlocation.myconfig", "myval1", "notThere", "notThereVal"));
-        assertEquals(child.getAllConfig(false), ImmutableMap.of());
-    }
-    
-    // TODO Fails for location, but passes for entity; not worth fixing here; locations will soon be entities!
-    @Test(groups="WIP")
-    public void testChildConfigBagInheritsFlagNameFromParentSetsOwnConfigKey() throws Exception {
-        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
-                .configure("mychildconfigflagname", "myval"));
-
-        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
-                .parent(loc));
-
-        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "myval"));
-        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of());
-        assertEquals(child.getAllConfig(true), ImmutableMap.of("mychildlocation.myconfigwithflagname", "myval"));
-        assertEquals(child.getAllConfig(false), ImmutableMap.of());
-    }
-    
-    @Test
-    public void testChildInheritsFromParent() throws Exception {
-        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
-                .configure("mylocation.myconfig", "myval1"));
-
-        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
-                .parent(loc));
-
-        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mylocation.myconfig", "myval1"));
-        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of());
-        assertEquals(child.getAllConfig(true), ImmutableMap.of("mylocation.myconfig", "myval1"));
-        assertEquals(child.getAllConfig(false), ImmutableMap.of());
-    }
-    
-    @Test
-    public void testChildCanOverrideConfigUsingKeyName() throws Exception {
-        LocationInternal location = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
-                .configure("mychildlocation.myconfigwithflagname", "myval")
-                .configure("notThere", "notThereVal"));
-
-        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
-                .parent(location)
-                .configure("mychildlocation.myconfigwithflagname", "overrideMyval")
-                .configure("notThere", "overrideNotThereVal"));
-
-        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal"));
-        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal"));
-        assertEquals(child.getAllConfig(true), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal"));
-        assertEquals(child.getAllConfig(false), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "notThere", "overrideNotThereVal"));
-    }
-    
-    // TODO Note difference compared to Location, where both flag-name + config-key-name are in the ConfigBag
-    @Test
-    public void testChildCanOverrideConfigUsingFlagName() throws Exception {
-        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class)
-                .configure("mychildlocation.myconfigwithflagname", "myval"));
-
-        LocationInternal child = managementContext.getLocationManager().createLocation(LocationSpec.create(MyChildLocation.class)
-                .parent(loc)
-                .configure("mychildconfigflagname", "overrideMyval"));
-
-        assertEquals(child.config().getBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "mychildconfigflagname", "overrideMyval"));
-        assertEquals(child.config().getLocalBag().getAllConfig(), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "mychildconfigflagname", "overrideMyval"));
-        assertEquals(child.getAllConfig(true), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "mychildconfigflagname", "overrideMyval"));
-        assertEquals(child.getAllConfig(false), ImmutableMap.of("mychildlocation.myconfigwithflagname", "overrideMyval", "mychildconfigflagname", "overrideMyval"));
-    }
-    
-    @Test
-    public void testLocationCanOverrideConfigDefaultValue() throws Exception {
-        LocationInternal loc = managementContext.getLocationManager().createLocation(LocationSpec.create(MyLocation.class));
-        LocationInternal subloc = managementContext.getLocationManager().createLocation(LocationSpec.create(MySubLocation.class));
-
-        assertEquals(loc.getConfig(MyLocation.MY_CONFIG_WITH_DEFAULT), "mydefault");
-        assertEquals(loc.getConfig(ConfigKeys.newStringConfigKey("mylocation.myconfigwithdefault", "", "differentdefault")), "mydefault");
-        
-        assertEquals(subloc.getConfig(MySubLocation.MY_CONFIG_WITH_DEFAULT), "mysubdefault");
-        assertEquals(subloc.getConfig(MyLocation.MY_CONFIG_WITH_DEFAULT), "mysubdefault");
-    }
-    
-    @SuppressWarnings("serial")
-    public static class MyLocation extends AbstractLocation {
-        public static final ConfigKey<String> MY_CONFIG = ConfigKeys.newStringConfigKey("mylocation.myconfig");
-
-        @SetFromFlag("myconfigflagname")
-        public static final ConfigKey<String> MY_CONFIG_WITH_FLAGNAME = ConfigKeys.newStringConfigKey("mylocation.myconfigwithflagname");
-        
-        public static final ConfigKey<String> MY_CONFIG_WITH_DEFAULT = ConfigKeys.newStringConfigKey("mylocation.myconfigwithdefault", "", "mydefault");
-    }
-    
-    @SuppressWarnings("serial")
-    public static class MyChildLocation extends AbstractLocation {
-        public static final ConfigKey<String> MY_CHILD_CONFIG = ConfigKeys.newStringConfigKey("mychildlocation.myconfig");
-
-        @SetFromFlag("mychildconfigflagname")
-        public static final ConfigKey<String> MY_CHILD_CONFIG_WITH_FLAGNAME = ConfigKeys.newStringConfigKey("mychildlocation.myconfigwithflagname");
-    }
-    
-    @SuppressWarnings("serial")
-    public static class MySubLocation extends MyLocation {
-        public static final ConfigKey<String> MY_CONFIG_WITH_DEFAULT = ConfigKeys.newConfigKeyWithDefault(MyLocation.MY_CONFIG_WITH_DEFAULT, "mysubdefault");
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocationConfigUtilsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocationConfigUtilsTest.java b/core/src/test/java/brooklyn/location/basic/LocationConfigUtilsTest.java
deleted file mode 100644
index ba580eb..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocationConfigUtilsTest.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.io.File;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.location.basic.LocationConfigUtils.OsCredential;
-import brooklyn.util.config.ConfigBag;
-
-@Test
-public class LocationConfigUtilsTest {
-
-    // set these system properties differently if needed to fix your tests
-    public static final String SSH_PRIVATE_KEY_FILE_WITH_TILDE = System.getProperty("sshPrivateKey", "~/.ssh/id_rsa");
-    public static final String SSH_PUBLIC_KEY_FILE_WITH_TILDE = System.getProperty("sshPublicKey", "~/.ssh/id_rsa.pub");
-    // these should work as they are on classpath
-    public static final String SSH_PRIVATE_KEY_FILE_WITH_PASSPHRASE = System.getProperty("sshPrivateKeyWithPassphrase", "/brooklyn/util/crypto/sample_rsa_passphrase.pem");
-    public static final String SSH_PRIVATE_KEY_FILE = System.getProperty("sshPrivateKeySample", "/brooklyn/location/basic/sample_id_rsa");
-    public static final String SSH_PUBLIC_KEY_FILE = System.getProperty("sshPublicKeySample", "/brooklyn/location/basic/sample_id_rsa.pub");
-    
-    public void testPreferPrivateKeyDataOverFile() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PRIVATE_KEY_DATA, "mydata");
-        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE);
-        
-        OsCredential creds = LocationConfigUtils.getOsCredential(config).doKeyValidation(false);
-        Assert.assertTrue(creds.hasKey());
-        // warnings, as it is malformed
-        Assert.assertFalse(creds.getWarningMessages().isEmpty());
-
-        String data = creds.getPrivateKeyData();
-        assertEquals(data, "mydata");
-    }
-
-    @Test(expectedExceptions=IllegalStateException.class)
-    public void testInvalidKeyData() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PRIVATE_KEY_DATA, "mydata");
-        
-        OsCredential creds = LocationConfigUtils.getOsCredential(config).doKeyValidation(false);
-        Assert.assertTrue(creds.hasKey());
-        Assert.assertFalse(creds.getWarningMessages().isEmpty());
-        
-        creds.checkNoErrors();
-    }
-
-    public void testPreferPublicKeyDataOverFileAndNoPrivateKeyRequired() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PUBLIC_KEY_DATA, "mydata");
-        config.put(LocationConfigKeys.PUBLIC_KEY_FILE, SSH_PUBLIC_KEY_FILE);
-        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, "");
-        
-        OsCredential creds = LocationConfigUtils.getOsCredential(config);
-        String data = creds.getPublicKeyData();
-        assertEquals(data, "mydata");
-        Assert.assertNull(creds.getPreferredCredential());
-        Assert.assertFalse(creds.hasPassword());
-        Assert.assertFalse(creds.hasKey());
-        // and not even any warnings here
-        Assert.assertTrue(creds.getWarningMessages().isEmpty());
-    }
-    
-    @Test(groups="Integration")  // requires ~/.ssh/id_rsa
-    public void testReadsPrivateKeyFileWithTildePath() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE_WITH_TILDE);
-
-        // don't mind if it has a passphrase
-        String data = LocationConfigUtils.getOsCredential(config).doKeyValidation(false).getPreferredCredential();
-        assertTrue(data != null && data.length() > 0);
-    }
-    
-    @Test(groups="Integration")
-    public void testReadsPrivateKeyFileWithPassphrase() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE_WITH_PASSPHRASE);
-
-        OsCredential cred = LocationConfigUtils.getOsCredential(config).doKeyValidation(false);
-        String data = cred.getPreferredCredential();
-        assertTrue(data != null && data.length() > 0);
-        Assert.assertFalse(data.isEmpty());
-        
-        cred.doKeyValidation(true);
-        try {
-            cred.checkNoErrors();
-            Assert.fail("check should fail as passphrase needed");
-        } catch (IllegalStateException exception) {
-        }
-
-        config.put(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE, "passphrase");
-        cred.checkNoErrors();
-        
-        config.put(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE, "wrong_passphrase");
-        try {
-            cred.checkNoErrors();
-            Assert.fail("check should fail as passphrase needed");
-        } catch (IllegalStateException exception) {
-        }
-    }
-    
-    public void testReadsPrivateKeyFileWithMultipleColonSeparatedFilesWithGoodLast() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, "/path/does/not/exist"+File.pathSeparator+SSH_PRIVATE_KEY_FILE);
-        
-        String data = LocationConfigUtils.getOsCredential(config).getPreferredCredential();
-        assertTrue(data != null && data.length() > 0);
-    }
-    
-    public void testReadsPrivateKeyFileWithMultipleColonSeparatedFilesWithGoodFirst() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE+File.pathSeparator+"/path/does/not/exist");
-
-        String data = LocationConfigUtils.getOsCredential(config).getPreferredCredential();
-        assertTrue(data != null && data.length() > 0);
-    }
-    
-    @Test(groups="Integration")  // requires ~/.ssh/id_rsa
-    public void testReadsPublicKeyFileWithTildePath() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PUBLIC_KEY_FILE, SSH_PUBLIC_KEY_FILE_WITH_TILDE);
-        
-        // don't mind if it has a passphrase
-        String data = LocationConfigUtils.getOsCredential(config).doKeyValidation(false).getPublicKeyData();
-        assertTrue(data != null && data.length() > 0);
-    }
-    
-    public void testInfersPublicKeyFileFromPrivateKeyFile() throws Exception {
-        ConfigBag config = ConfigBag.newInstance();
-        config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE);
-        
-        String data = LocationConfigUtils.getOsCredential(config).getPublicKeyData();
-        assertTrue(data != null && data.length() > 0);
-    }
-}


[49/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
index 5a17a5a..74b408c 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLoginLiveTest.java
@@ -27,9 +27,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.Test;
-
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;
 import brooklyn.util.stream.Streams;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java
index 0ff4474..b1896d7 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/LiveTestEntity.java
@@ -21,15 +21,16 @@ package org.apache.brooklyn.location.jclouds;
 import java.util.Collection;
 
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.apache.brooklyn.test.entity.TestEntityImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Lifecycle;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.LocationInternal;
 
 import com.google.common.base.Predicates;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
index 535b6a8..e3b749d 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/RebindJcloudsLocationLiveTest.java
@@ -25,6 +25,7 @@ import static org.testng.Assert.assertTrue;
 import java.io.File;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
@@ -33,7 +34,6 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.rebind.RebindTestUtils;
-import org.apache.brooklyn.location.OsDetails;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.config.ConfigBag;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
index 3e33ce8..9ae5729 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SimpleJcloudsLocationUserLoginAndConfigLiveTest.java
@@ -23,7 +23,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
index e9b9dd8..ce6aa58 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/SingleMachineProvisioningLocationJcloudsLiveTest.java
@@ -31,7 +31,8 @@ import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.MachineLocation;
+
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.location.basic.SingleMachineProvisioningLocation;
 
 public class SingleMachineProvisioningLocationJcloudsLiveTest extends AbstractJcloudsLiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
index fd93a7a..d302187 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AbstractJcloudsLocationTest.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertTrue;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,9 +35,10 @@ import org.testng.collections.Lists;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
index 12e89e3..84c90ab 100644
--- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
@@ -23,7 +23,7 @@ import static org.testng.Assert.assertTrue;
 
 import java.util.List;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.jclouds.AbstractJcloudsLiveTest;
 import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import org.jclouds.domain.LocationScope;
@@ -32,7 +32,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
+
 import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.base.Predicates;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 020d652..4512b1d 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1150,7 +1150,6 @@
                   <exclude>**/*.psd</exclude>
                   <exclude>**/*.json</exclude>
                   <exclude>**/*.plxarc</exclude>
-                  <exclude>**/services/org.apache.brooklyn.location.LocationResolver</exclude>
                   <exclude>**/src/test/resources/brooklyn/entity/basic/template_with_extra_substitutions.txt</exclude>
                   <exclude>**/src/main/resources/banner.txt</exclude>
                   <exclude>**/src/test/resources/ssl/certs/localhost/info.txt</exclude>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java b/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java
index 51d9ae0..922b33d 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java
@@ -32,8 +32,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.AbstractLocation;
 
 import com.google.common.annotations.VisibleForTesting;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java
index a76e37c..a181ae4 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java
@@ -21,7 +21,7 @@ package brooklyn.policy.followthesun;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * Captures the state of items, containers and locations for the purpose of moving items around

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java
index 9283c7f..2b2d9af 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java
@@ -23,8 +23,7 @@ import java.util.Set;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 public class FollowTheSunParameters {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java
index d89f1a8..1747424 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java
@@ -36,12 +36,12 @@ import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.Sensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Attributes;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.policy.followthesun.FollowTheSunPool.ContainerItemPair;
 import brooklyn.policy.loadbalancing.Movable;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java
index 078299d..e8ca636 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java
@@ -26,10 +26,10 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.brooklyn.location.Location;
 import brooklyn.policy.loadbalancing.Movable;
 
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java b/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java
index f3e6b6a..33f9e0b 100644
--- a/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java
+++ b/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java
@@ -21,7 +21,7 @@ package brooklyn.policy.loadbalancing;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * Captures the state of a balanceable cluster of containers and all their constituent items, including workrates,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java b/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java
index fa7f3bb..714b70c 100644
--- a/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java
+++ b/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java
@@ -26,11 +26,10 @@ import java.util.Map.Entry;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.brooklyn.location.Location;
-
 /**
  * Represents an abstract algorithm for optimally balancing worker "items" among several "containers" based on the workloads
  * of the items, and corresponding high- and low-thresholds on the containers.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java b/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java
index 1a37ed6..7e273ba 100644
--- a/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java
+++ b/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java
@@ -28,8 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.HashMultimap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java b/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java
index 5399e89..5ae5723 100644
--- a/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java
+++ b/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java
@@ -18,7 +18,7 @@
  */
 package brooklyn.policy.loadbalancing;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * Temporary stub to resolve dependencies in ported LoadBalancingPolicy.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java b/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
index d317029..03f3f1d 100644
--- a/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
+++ b/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -36,8 +37,9 @@ import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
 import brooklyn.event.basic.BasicNotificationSensor;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.time.Duration;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java b/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java
index 5f12e62..c8855f2 100644
--- a/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java
+++ b/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java
@@ -29,6 +29,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -40,9 +42,9 @@ import org.testng.annotations.BeforeMethod;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.policy.loadbalancing.BalanceableContainer;
 import brooklyn.policy.loadbalancing.MockContainerEntity;
 import brooklyn.policy.loadbalancing.MockItemEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java
index 84f4808..9b16a2a 100644
--- a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java
+++ b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java
@@ -25,9 +25,9 @@ import static org.testng.Assert.assertTrue;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.policy.loadbalancing.MockContainerEntity;
 import brooklyn.policy.loadbalancing.MockContainerEntityImpl;
 import brooklyn.policy.loadbalancing.MockItemEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
index 24c1476..a67e24d 100644
--- a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
+++ b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
@@ -29,13 +29,15 @@ import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.policy.loadbalancing.BalanceableContainer;
 import brooklyn.policy.loadbalancing.MockContainerEntity;
 import brooklyn.policy.loadbalancing.MockItemEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
index feef57d..1f5e5db 100644
--- a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
+++ b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
@@ -31,13 +31,15 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.policy.loadbalancing.MockContainerEntity;
 import brooklyn.policy.loadbalancing.MockItemEntity;
 import brooklyn.policy.loadbalancing.Movable;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java b/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
index 3088e78..12a5e1e 100644
--- a/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
+++ b/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
@@ -30,6 +30,8 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.Sensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.policy.EnricherSpec;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -42,9 +44,9 @@ import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.policy.ha.HASensors.FailureDescriptor;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java b/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
index b8e5379..f92f921 100644
--- a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
+++ b/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
@@ -31,6 +31,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.apache.brooklyn.test.EntityTestUtils;
@@ -53,9 +55,9 @@ import brooklyn.entity.basic.QuorumCheck;
 import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.FailingEntity;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.policy.ha.HASensors.FailureDescriptor;
 import brooklyn.test.Asserts;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java b/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java
index f72fed3..672addb 100644
--- a/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java
+++ b/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java
@@ -28,12 +28,12 @@ import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractGroupImpl;
 import brooklyn.entity.basic.Attributes;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.time.Time;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
index 7fc4ea7..bf7454d 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
@@ -28,11 +28,11 @@ import java.io.StringReader;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java
index f7d2122..1a926a5 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java
@@ -23,6 +23,9 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.api.management.TaskAdaptable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -36,10 +39,9 @@ import com.google.common.reflect.TypeToken;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.trait.StartableMethods;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.PortRange;
+
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
+
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java
index 09f8dea..080cb87 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java
@@ -23,12 +23,12 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.BasicAttributeSensor;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.QuorumCheck;
 import brooklyn.util.flags.SetFromFlag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
index 7bfdb59..32050fd 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
@@ -22,11 +22,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.Collection;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 
 import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.QuorumCheck;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.DynamicTasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
index de12a0c..cf0dd6b 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.Lifecycle.Transition;
@@ -31,7 +32,6 @@ import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.basic.MapConfigKey;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
index 5af5a27..1067333 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
@@ -20,6 +20,8 @@ package brooklyn.entity.basic;
 
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.api.management.TaskAdaptable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -29,8 +31,6 @@ import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters;
 import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters.RestartMachineMode;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.trait.StartableMethods;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
index f96b961..87d4710 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
@@ -36,6 +36,10 @@ import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriverManager;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.policy.EnricherSpec;
 import org.slf4j.Logger;
@@ -47,13 +51,11 @@ import brooklyn.entity.basic.Lifecycle.Transition;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.PortRange;
+
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
index ca7d561..9f6bf82 100644
--- a/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,8 +31,9 @@ import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.basic.Machines;
+
 import brooklyn.util.collections.Jsonya;
 import brooklyn.util.collections.Jsonya.Navigator;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java b/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
index 6bc9de4..141c5e5 100644
--- a/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
+++ b/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
@@ -23,6 +23,7 @@ import java.security.cert.Certificate;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.PortRange;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
@@ -30,8 +31,9 @@ import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.location.PortRange;
+
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.util.flags.SetFromFlag;
 
 public interface UsesJmx extends UsesJava {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java
index c0b2b5f..65c1a4c 100644
--- a/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java
+++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java
@@ -28,6 +28,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.annotation.Effector;
@@ -37,8 +39,7 @@ import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.machine.MachineEntity;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import org.apache.brooklyn.location.dynamic.LocationOwner;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java
index 2876b31..871e111 100644
--- a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java
@@ -24,6 +24,10 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.LocationManager;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.policy.PolicySpec;
@@ -40,13 +44,11 @@ import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.BasicLocationDefinition;
 import org.apache.brooklyn.location.basic.Machines;
 import org.apache.brooklyn.location.dynamic.DynamicLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.task.DynamicTasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java
index 7123760..704459b 100644
--- a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java
+++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java
@@ -30,11 +30,13 @@ import com.google.common.collect.Maps;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.dynamic.DynamicLocation;
+
 import brooklyn.util.flags.SetFromFlag;
 
 public class ServerPoolLocation extends AbstractLocation implements MachineProvisioningLocation<MachineLocation>,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java
index 2de1da2..0383dda 100644
--- a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java
+++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java
@@ -27,6 +27,10 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationResolver.EnableableLocationResolver;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,14 +39,11 @@ import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver.EnableableLocationResolver;
-import org.apache.brooklyn.location.LocationSpec;
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 import org.apache.brooklyn.location.basic.LocationInternal;
 import org.apache.brooklyn.location.basic.LocationPropertiesFromBrooklynProperties;
 import org.apache.brooklyn.location.dynamic.DynamicLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.text.KeyValueParser;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
index 8c68442..97add55 100644
--- a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
@@ -30,8 +30,13 @@ import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineManagementMixins;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.MachineManagementMixins.SuspendsMachines;
 import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.location.MachineManagementMixins;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,17 +68,14 @@ import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
 import brooklyn.event.feed.ConfigToAttributes;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineManagementMixins.SuspendsMachines;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.Locations;
 import org.apache.brooklyn.location.basic.Machines;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java b/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java
index 28888e9..91c6666 100644
--- a/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java
+++ b/software/base/src/main/java/brooklyn/entity/software/ProvidesProvisioningFlags.java
@@ -18,7 +18,8 @@
  */
 package brooklyn.entity.software;
 
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+
 import brooklyn.util.config.ConfigBag;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java
index c3590b4..e40170c 100644
--- a/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/SshEffectorTasks.java
@@ -25,6 +25,7 @@ import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -39,9 +40,10 @@ import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.effector.EffectorTasks;
 import brooklyn.entity.effector.EffectorTasks.EffectorTaskFactory;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocationInternal;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver b/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
new file mode 100644
index 0000000..8ab42e7
--- /dev/null
+++ b/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+brooklyn.entity.pool.ServerPoolLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver b/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
deleted file mode 100644
index 2a041b4..0000000
--- a/software/base/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
+++ /dev/null
@@ -1 +0,0 @@
-brooklyn.entity.pool.ServerPoolLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
index 40a906c..7a8b099 100644
--- a/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/AbstractEc2LiveTest.java
@@ -25,9 +25,11 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.jclouds.JcloudsLocation;
 import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig;
+
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
index 72bf949..ecc4adc 100644
--- a/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/AbstractGoogleComputeLiveTest.java
@@ -21,6 +21,7 @@ package brooklyn.entity;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -30,7 +31,6 @@ import org.testng.annotations.Test;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java b/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
index 3afd6c3..a8f15f5 100644
--- a/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/AbstractSoftlayerLiveTest.java
@@ -21,6 +21,7 @@ package brooklyn.entity;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -34,7 +35,6 @@ import com.google.common.collect.ImmutableMap;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.text.StringShortener;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java b/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
index 602eefe..0e6db9e 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SameServerEntityTest.java
@@ -24,14 +24,13 @@ import static org.testng.Assert.assertTrue;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java
index 21ba4e8..aa46dd1 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityLatchTest.java
@@ -27,6 +27,7 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.Task;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,9 +39,10 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.SoftwareProcessEntityTest.MyService;
 import brooklyn.entity.basic.SoftwareProcessEntityTest.SimulatedDriver;
 import brooklyn.event.basic.DependentConfiguration;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.task.TaskInternal;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java
index fd70e7e..7ae7b54 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityRebindTest.java
@@ -30,6 +30,9 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
@@ -41,11 +44,10 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.basic.SoftwareProcessEntityTest.MyService;
 import brooklyn.entity.rebind.RebindTestUtils;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.flags.SetFromFlag;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java
index b66e3dd..3d8ddda 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessEntityTest.java
@@ -34,6 +34,9 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.management.EntityManager;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.api.management.TaskAdaptable;
@@ -63,13 +66,12 @@ import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.software.MachineLifecycleEffectorTasksTest;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.Locations;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java
index 65d9037..485b287 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSshDriverIntegrationTest.java
@@ -32,6 +32,7 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -39,9 +40,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.BrooklynNetworkUtils;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java
index 388d78d..3c5784e 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/SoftwareProcessSubclassTest.java
@@ -25,6 +25,7 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.BeforeMethod;
@@ -32,7 +33,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.effector.EffectorAndBody;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
index 0bd1b09..8b516ad 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -32,7 +33,6 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.SoftwareProcess.ChildStartableMode;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java
index 52929a9..5ab4228 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/NaiveScriptRunnerTest.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
 
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.Task;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,8 +34,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.BrooklynTaskTags.WrappedStream;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.repeat.Repeater;
 import brooklyn.util.task.BasicExecutionContext;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java
index c5efb0e..108e9d5 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/lifecycle/ScriptHelperTest.java
@@ -24,6 +24,7 @@ import java.util.concurrent.Callable;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,9 +41,10 @@ import brooklyn.entity.basic.SoftwareProcessEntityTest.MyServiceImpl;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Functions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
index d07cc89..7b3c8ea 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
@@ -25,6 +25,7 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -37,8 +38,9 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.ConfigToAttributes;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
index 4268998..749a9cb 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
@@ -21,6 +21,7 @@ package brooklyn.entity.brooklynnode;
 import java.util.Collection;
 
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.AbstractEntity;
@@ -29,7 +30,6 @@ import brooklyn.entity.brooklynnode.CallbackEntityHttpClient.Request;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityPriorityEffectorBody;
 import brooklyn.event.basic.BasicAttributeSensor;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Function;
 import com.google.common.reflect.TypeToken;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
index 8aae8a2..565dffb 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
@@ -26,7 +26,8 @@ import brooklyn.entity.brooklynnode.BrooklynNodeImpl.DeployBlueprintEffectorBody
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 /** Implementation of BrooklynNode which just presents the node where this is running, for convenience;
  * 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java b/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java
index 50176e0..a04d9fa 100644
--- a/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java
+++ b/software/base/src/test/java/brooklyn/entity/chef/ChefLiveTestSupport.java
@@ -22,6 +22,8 @@ import java.io.File;
 import java.io.IOException;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -29,9 +31,9 @@ import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.EntityInternal;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.io.FileUtil;
 import brooklyn.util.stream.InputStreamSupplier;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java b/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java
index 23a6255..92bb587 100644
--- a/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/chef/mysql/AbstractChefToyMySqlEntityLiveTest.java
@@ -22,7 +22,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.chef.ChefLiveTestSupport;
 import brooklyn.entity.software.mysql.AbstractToyMySqlEntityTest;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 public abstract class AbstractChefToyMySqlEntityLiveTest extends AbstractToyMySqlEntityTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java b/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java
index 42d7429..adfde4f 100644
--- a/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java
+++ b/software/base/src/test/java/brooklyn/entity/driver/MockSshDriver.java
@@ -19,9 +19,10 @@
 package brooklyn.entity.driver;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.entity.basic.SoftwareProcessDriver;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 public class MockSshDriver implements SoftwareProcessDriver {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java b/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
index c9e85f4..02e63da 100644
--- a/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesMultiLocationTest.java
@@ -26,6 +26,10 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -33,12 +37,10 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.basic.SoftwareProcess;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.MultiLocation;
+
 import brooklyn.test.Asserts;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java b/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
index 8505ba7..2a791fd 100644
--- a/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
@@ -22,6 +22,7 @@ import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -36,8 +37,9 @@ import brooklyn.entity.java.UsesJmx.JmxAgentModes;
 import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.event.feed.jmx.JmxAttributePollConfig;
 import brooklyn.event.feed.jmx.JmxFeed;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.test.JmxService;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java b/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
index 1896ed5..b7034e0 100644
--- a/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/JavaOptsTest.java
@@ -29,6 +29,8 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterMethod;
@@ -36,9 +38,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java
index ec825ec..101223e 100644
--- a/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/JavaSoftwareProcessSshDriverIntegrationTest.java
@@ -24,6 +24,8 @@ import static org.testng.Assert.assertTrue;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,9 +37,9 @@ import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.lifecycle.MyEntity;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java b/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java
index 344f8f3..c33e4f9 100644
--- a/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java
+++ b/software/base/src/test/java/brooklyn/entity/machine/MachineEntityEc2LiveTest.java
@@ -22,12 +22,12 @@ import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 public class MachineEntityEc2LiveTest extends AbstractEc2LiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java b/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java
index 0996b88..db5da66 100644
--- a/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java
+++ b/software/base/src/test/java/brooklyn/entity/pool/AbstractServerPoolTest.java
@@ -23,6 +23,9 @@ import static org.testng.Assert.fail;
 import java.util.List;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
@@ -35,10 +38,9 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.ImmutableList;



[47/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
index f63fd48..4c9f314 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -49,7 +50,6 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
index 9f84a7f..a65ce5f 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
@@ -21,13 +21,13 @@ package org.apache.brooklyn.entity.nosql.mongodb.sharding;
 import java.util.Collection;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.enricher.Enrichers;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SameServerEntityImpl;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.DependentConfiguration;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java
index 05cf7ac..b26938a 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java
@@ -22,9 +22,9 @@ import java.util.Collection;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java
index 1b1a2d6..ab2ee07 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java
@@ -24,13 +24,13 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.PolicySpec;
 
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java
index 0e66638..3ac71b6 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBClientSupport;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
@@ -38,7 +39,6 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.group.DynamicClusterImpl;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.Duration;
 import brooklyn.util.time.Time;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
index 420cd93..05a7a7d 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
@@ -26,6 +26,7 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,7 +41,6 @@ import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
index c977b02..508d2c4 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 
 import brooklyn.enricher.Enrichers;
 import brooklyn.entity.basic.AbstractEntity;
@@ -32,7 +33,6 @@ import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChild
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.QuorumCheck.QuorumChecks;
 import brooklyn.util.exceptions.CompoundRuntimeException;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
index 01a8de6..4a03b3d 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
@@ -30,8 +30,9 @@ import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshPollValue;
 import brooklyn.event.feed.ssh.SshValueFunctions;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineLocation;
+
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java
index de60319..be9ab20 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java
@@ -27,8 +27,10 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;
 import brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
index 9c9c93b..587ffe3 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.entity.webapp.WebAppServiceMethods;
 
 import brooklyn.enricher.Enrichers;
@@ -37,9 +38,10 @@ import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.guava.Functionals;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
index d137007..f115ab3 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
@@ -37,6 +37,7 @@ import java.util.List;
 import java.util.Map;
 
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,8 +45,10 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.OsDetails;
+
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java
index 2569fea..5f7335a 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java
@@ -26,12 +26,15 @@ import java.util.Set;
 
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
 import brooklyn.entity.java.UsesJmx;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.file.ArchiveUtils;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java
index d977785..95ce165 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java
@@ -21,7 +21,8 @@ package org.apache.brooklyn.entity.nosql.cassandra;
 import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * Cassandra test framework for integration and live tests.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java
index 216531e..452a2a1 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java
@@ -25,6 +25,7 @@ import static org.testng.Assert.assertTrue;
 import java.math.BigInteger;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.nosql.cassandra.TokenGenerators.PosNeg63TokenGenerator;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
@@ -36,7 +37,6 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java
index b15f7b1..bb96368 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java
@@ -31,6 +31,7 @@ import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.nosql.cassandra.AstyanaxSupport.AstyanaxSample;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
@@ -44,7 +45,6 @@ import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java
index 83adf75..1841cf7 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java
@@ -26,6 +26,7 @@ import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,8 +39,9 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.EmptySoftwareProcessSshDriver;
 import brooklyn.entity.basic.EntityInternal;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.text.TemplateProcessor;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java
index 6ff8d3f..fc0ea66 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java
@@ -27,6 +27,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,9 +43,9 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java
index 234cad2..0c97a9c 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java
@@ -19,13 +19,13 @@
 package org.apache.brooklyn.entity.nosql.cassandra;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.nosql.cassandra.AstyanaxSupport.AstyanaxSample;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java
index 3b5bfb6..e592e03 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java
@@ -22,13 +22,13 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
index 46be4a1..c5c732b 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
@@ -26,8 +26,10 @@ import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.util.internal.TimeExtras;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java
index e09637b..a289865 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.entity.nosql.couchdb;
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -30,7 +31,6 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java
index 66ff739..2b71a65 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java
@@ -19,13 +19,13 @@
 package org.apache.brooklyn.entity.nosql.couchdb;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
index 6a235b5..8e695c9 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
@@ -26,6 +26,7 @@ import java.net.URISyntaxException;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.http.client.methods.HttpGet;
 import org.bouncycastle.util.Strings;
@@ -39,7 +40,6 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
index 27b9170..8d5f0d1 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
@@ -24,6 +24,7 @@ import java.net.URI;
 import java.net.URISyntaxException;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.http.client.methods.HttpGet;
@@ -37,8 +38,9 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
index 0de6fdd..5c499d6 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
@@ -19,7 +19,6 @@
 package org.apache.brooklyn.entity.nosql.mongodb;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.mongodb.DBObject;
@@ -31,6 +30,7 @@ import org.testng.annotations.Test;
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 
 public class MongoDBEc2LiveTest extends AbstractEc2LiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java
index e0c57fb..4995623 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java
@@ -21,7 +21,6 @@ package org.apache.brooklyn.entity.nosql.mongodb;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;
@@ -31,6 +30,7 @@ import com.mongodb.DBObject;
 import groovy.time.TimeDuration;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java
index 0972ea5..e9dfdda 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.entity.nosql.mongodb;
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,7 +31,6 @@ import com.google.common.collect.ImmutableList;
 import com.mongodb.DBObject;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import org.apache.brooklyn.location.Location;
 
 public class MongoDBSoftLayerLiveTest extends AbstractSoftlayerLiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java
index aab8518..8706987 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java
@@ -22,6 +22,7 @@ import groovy.time.TimeDuration;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.testng.Assert;
@@ -29,7 +30,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java
index 650ce61..6659569 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java
@@ -25,6 +25,7 @@ import java.util.List;
 import java.util.concurrent.Callable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -35,8 +36,9 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java
index f655b8c..49ae708 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java
@@ -21,13 +21,13 @@ package org.apache.brooklyn.entity.nosql.redis;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java
index aace8d6..68ec275 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.entity.nosql.redis;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -29,8 +30,9 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java
index 27ebc35..0aef9b9 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java
@@ -19,6 +19,7 @@
 package org.apache.brooklyn.entity.nosql.riak;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -26,7 +27,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Attributes;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java
index 6f768b8..29e9284 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java
@@ -19,6 +19,7 @@
 package org.apache.brooklyn.entity.nosql.riak;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -27,7 +28,6 @@ import org.testng.annotations.Test;
 import com.google.common.collect.ImmutableList;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 
 public class RiakNodeEc2LiveTest extends AbstractEc2LiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java
index c93b318..500b0d8 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java
@@ -19,6 +19,7 @@
 package org.apache.brooklyn.entity.nosql.riak;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
@@ -26,7 +27,6 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
-import org.apache.brooklyn.location.Location;
 
 public class RiakNodeGoogleComputeLiveTest extends AbstractGoogleComputeLiveTest {
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java
index 249cfc9..2dafc89 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSoftlayerLiveTest.java
@@ -19,13 +19,13 @@
 package org.apache.brooklyn.entity.nosql.riak;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.BeforeMethod;
 
 import com.google.common.collect.ImmutableList;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import org.apache.brooklyn.location.Location;
 
 public class RiakNodeSoftlayerLiveTest extends AbstractSoftlayerLiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java
index 3e144e2..f7152da 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/AbstractSolrServerTest.java
@@ -21,7 +21,8 @@ package org.apache.brooklyn.entity.nosql.solr;
 import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * Solr test framework for integration and live tests.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java
index 5196ede..106d060 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/solr/SolrServerEc2LiveTest.java
@@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.solr.common.SolrDocument;
 import org.slf4j.Logger;
@@ -29,7 +30,6 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java
index ad39164..4bbff6c 100644
--- a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java
+++ b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerEc2LiveTest.java
@@ -19,13 +19,13 @@
 package org.apache.brooklyn.entity.osgi.karaf;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.text.Identifiers;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
index bd2d46a..1bd561a 100644
--- a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
+++ b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
@@ -25,6 +25,7 @@ import java.net.URL;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.Assert;
@@ -35,8 +36,9 @@ import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.software.SshEffectorTasks;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
index 3c0421b..66d2277 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
@@ -28,6 +28,7 @@ import java.util.Set;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,7 +38,6 @@ import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.Cluster;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.ConfigToAttributes;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.guava.Maybe;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java
index 6c7b093..da9bbf9 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxSshDriver.java
@@ -24,9 +24,10 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.proxy.AbstractController;
-import org.apache.brooklyn.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,8 +37,9 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
-import org.apache.brooklyn.location.OsDetails;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
index 9b80173..9d19a11 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
@@ -27,6 +27,7 @@ import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.entity.proxy.LoadBalancer;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
@@ -45,7 +46,6 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.trait.Startable;
 import brooklyn.entity.trait.StartableMethods;
 import brooklyn.event.feed.ConfigToAttributes;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.QuorumCheck.QuorumChecks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java
index 8a6b133..e3407aa 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ElasticJavaWebAppService.java
@@ -22,13 +22,13 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 
 import brooklyn.entity.basic.AbstractConfigurableEntityFactory;
 import brooklyn.entity.basic.ConfigurableEntityFactory;
 import brooklyn.entity.basic.EntityFactoryForLocation;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 
 public interface ElasticJavaWebAppService extends JavaWebAppService, Startable {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java
index 5935940..166d2ad 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppService.java
@@ -22,14 +22,16 @@ import java.util.List;
 
 import org.apache.brooklyn.api.catalog.Catalog;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.entity.webapp.WebAppService;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.SoftwareProcess;
-import org.apache.brooklyn.location.PortRange;
+
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.util.flags.SetFromFlag;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
index 2bf6067..01ad82f 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
@@ -27,6 +27,10 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.dns.AbstractGeoDnsService;
 import org.apache.brooklyn.entity.dns.AbstractGeoDnsServiceImpl;
@@ -50,10 +54,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.group.DynamicFabric;
 import brooklyn.entity.group.DynamicRegionsFabric;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.basic.Locations;
@@ -61,6 +62,7 @@ import org.apache.brooklyn.location.basic.Machines;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.geo.HostGeoInfo;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
index c6df429..49e68ce 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingIntegrationTest.java
@@ -24,6 +24,7 @@ import java.net.InetAddress;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingDnsService;
 import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingScriptGenerator;
@@ -38,12 +39,13 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.geo.HostGeoInfo;
 import org.apache.brooklyn.location.geo.HostGeoLookup;
 import org.apache.brooklyn.location.geo.MaxMind2HostGeoLookup;
 import org.apache.brooklyn.location.geo.UtraceHostGeoLookup;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java
index a024cb1..facde8d 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/AbstractControllerTest.java
@@ -33,6 +33,11 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.apache.brooklyn.test.entity.TestEntityImpl;
 import org.slf4j.Logger;
@@ -47,13 +52,10 @@ import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.group.Cluster;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+
 import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
index 3e1ee85..d6c1252 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
@@ -24,15 +24,15 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.base.Throwables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java
index 1c43f95..cfe99c3 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/UrlMappingTest.java
@@ -27,6 +27,7 @@ import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.entity.proxy.nginx.UrlMapping;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
@@ -44,8 +45,9 @@ import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindTestUtils;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
index 7212424..f6c13ab 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxClusterIntegrationTest.java
@@ -26,6 +26,7 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.EntityManager;
 import org.apache.brooklyn.entity.proxy.LoadBalancerCluster;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
@@ -43,8 +44,9 @@ import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java
index dc97eb5..cdf7eaf 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxEc2LiveTest.java
@@ -19,6 +19,7 @@
 package org.apache.brooklyn.entity.proxy.nginx;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.HttpTestUtils;
@@ -28,7 +29,6 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.SoftwareProcess;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
index 044d7e0..64242c5 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
@@ -25,6 +25,7 @@ import java.io.File;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.proxy.LoadBalancer;
 import org.apache.brooklyn.entity.proxy.ProxySslConfig;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
@@ -43,8 +44,9 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
index b3327e7..e0b30ba 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxIntegrationTest.java
@@ -29,6 +29,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
 import org.apache.brooklyn.entity.webapp.WebAppService;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
@@ -44,7 +45,6 @@ import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.time.Duration;
 import brooklyn.util.time.Time;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
index 863280d..cfefbb8 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindIntegrationTest.java
@@ -32,6 +32,7 @@ import java.util.concurrent.Executors;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.entity.proxy.nginx.UrlMapping;
@@ -53,8 +54,9 @@ import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindOptions;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.test.Asserts;
 
 import com.google.common.base.Predicates;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java
index d1ea99b..a96a268 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxRebindWithHaIntegrationTest.java
@@ -27,6 +27,7 @@ import java.util.concurrent.Executors;
 
 import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
@@ -50,9 +51,10 @@ import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
 import brooklyn.entity.rebind.RebindTestUtils;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocationReuseIntegrationTest.RecordingSshjTool;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.util.internal.ssh.SshTool;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java
index 9f62577..a91e27b 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxWebClusterEc2LiveTest.java
@@ -24,6 +24,8 @@ import java.net.URL;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.entity.webapp.JavaWebAppService;
@@ -41,9 +43,9 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.basic.Machines;
+
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java
index 74e8bb2..cf42c5e 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/AbstractWebAppFixtureIntegrationTest.java
@@ -53,8 +53,9 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.Application;
@@ -63,6 +64,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.SubscriptionContext;
 import org.apache.brooklyn.api.management.SubscriptionHandle;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java
index dd27b6b..acf6195 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/TomcatAutoScalerPolicyTest.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
 import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
@@ -35,8 +36,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.policy.autoscaling.AutoScalerPolicy;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
index af21126..9d0e1eb 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppConcurrentDeployTest.java
@@ -31,12 +31,14 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.BrooklynConfigKeys;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
index d8b7457..769e5a5 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
@@ -40,7 +40,7 @@ import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server
 import org.apache.brooklyn.entity.webapp.jboss.JBoss7ServerImpl
 import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
 import org.apache.brooklyn.entity.webapp.tomcat.TomcatServerImpl
-import org.apache.brooklyn.location.Location
+import org.apache.brooklyn.api.location.Location
 import org.apache.brooklyn.location.basic.BasicLocationRegistry
 import org.apache.brooklyn.test.TestUtils
 import org.apache.brooklyn.test.entity.TestApplicationImpl

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java
index 1fe7088..c43efc0 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerAwsEc2LiveTest.java
@@ -22,12 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java
index 212ab31..31ed694 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerAwsEc2LiveTest.java
@@ -22,12 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java
index be1f08b..7650632 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerDockerLiveTest.java
@@ -19,10 +19,10 @@
 package org.apache.brooklyn.entity.webapp.jboss;
 
 import brooklyn.entity.software.AbstractDockerLiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java
index d111aff..65672c8 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/Jboss7ServerGoogleComputeLiveTest.java
@@ -22,12 +22,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static org.testng.Assert.assertNotNull;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.HttpTestUtils;
 import org.apache.brooklyn.test.TestResourceUnavailableException;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;



[33/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocationConfigUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationConfigUtils.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationConfigUtils.java
new file mode 100644
index 0000000..ce3c444
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationConfigUtils.java
@@ -0,0 +1,559 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static brooklyn.util.JavaGroovyEquivalents.groovyTruth;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.internal.BrooklynFeatureEnablement;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.crypto.AuthorizedKeysParser;
+import brooklyn.util.crypto.SecureKeys;
+import brooklyn.util.crypto.SecureKeys.PassphraseProblem;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.os.Os;
+import brooklyn.util.text.StringFunctions;
+import brooklyn.util.text.Strings;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+public class LocationConfigUtils {
+
+    private static final Logger log = LoggerFactory.getLogger(LocationConfigUtils.class);
+
+    /** Creates an instance of {@link OsCredential} by inspecting {@link LocationConfigKeys#PASSWORD}; 
+     * {@link LocationConfigKeys#PRIVATE_KEY_DATA} and {@link LocationConfigKeys#PRIVATE_KEY_FILE};
+     * {@link LocationConfigKeys#PRIVATE_KEY_PASSPHRASE} if needed, and
+     * {@link LocationConfigKeys#PRIVATE_KEY_DATA} and {@link LocationConfigKeys#PRIVATE_KEY_FILE}
+     * (defaulting to the private key file + ".pub"). 
+     **/
+    public static OsCredential getOsCredential(ConfigBag config) {
+        return OsCredential.newInstance(config);
+    }
+    
+    /** Convenience class for holding private/public keys and passwords, inferring from config keys.
+     * See {@link LocationConfigUtils#getOsCredential(ConfigBag)}. */
+    @Beta // would be nice to replace with a builder pattern 
+    public static class OsCredential {
+        private final ConfigBag config;
+        private boolean preferPassword = false;
+        private boolean tryDefaultKeys = true;
+        private boolean requirePublicKey = true;
+        private boolean doKeyValidation = BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_VALIDATE_LOCATION_SSH_KEYS);
+        private boolean warnOnErrors = true;
+        private boolean throwOnErrors = false;
+        
+        private boolean dirty = true;;
+        
+        private String privateKeyData;
+        private String publicKeyData;
+        private String password;
+        
+        private OsCredential(ConfigBag config) {
+            this.config = config;
+        }
+
+        /** throws if there are any problems */
+        public OsCredential checkNotEmpty() {
+            checkNoErrors();
+            
+            if (!hasKey() && !hasPassword()) {
+                if (warningMessages.size()>0)
+                    throw new IllegalStateException("Could not find credentials: "+warningMessages);
+                else 
+                    throw new IllegalStateException("Could not find credentials");
+            }
+            return this;
+        }
+
+        /** throws if there were errors resolving (e.g. explicit keys, none of which were found/valid, or public key required and not found) 
+         * @return */
+        public OsCredential checkNoErrors() {
+            throwOnErrors(true);
+            dirty();
+            infer();
+            return this;
+        }
+        
+        public OsCredential logAnyWarnings() {
+            if (!warningMessages.isEmpty())
+                log.warn("When reading credentials: "+warningMessages);
+            return this;
+        }
+
+        public Set<String> getWarningMessages() {
+            return warningMessages;
+        }
+        
+        /** returns either the key or password or null; if both a key and a password this prefers the key unless otherwise set
+         * via {@link #preferPassword()} */
+        public synchronized String getPreferredCredential() {
+            infer();
+            
+            if (isUsingPassword()) return password;
+            if (hasKey()) return privateKeyData;
+            return null;
+        }
+
+        /** if there is no credential (ignores public key) */
+        public boolean isEmpty() {
+            return !hasKey() && !hasPassword();
+        }
+        public boolean hasKey() {
+            infer();
+            // key has stricter non-blank check than password
+            return Strings.isNonBlank(privateKeyData);
+        }
+        public boolean hasPassword() {
+            infer();
+            // blank, even empty passwords are allowed
+            return password!=null;
+        }
+        /** if a password is available, and either this is preferred over a key or there is no key */
+        public boolean isUsingPassword() {
+            return hasPassword() && (!hasKey() || preferPassword);
+        }
+        
+        public String getPrivateKeyData() {
+            infer();
+            return privateKeyData;
+        }
+        public String getPublicKeyData() {
+            infer();
+            return publicKeyData;
+        }
+        public String getPassword() {
+            infer();
+            return password;
+        }
+        
+        /** if both key and password supplied, prefer the key; the default */
+        public OsCredential preferKey() { preferPassword = false; return dirty(); }
+        /** if both key and password supplied, prefer the password; see {@link #preferKey()} */
+        public OsCredential preferPassword() { preferPassword = true; return dirty(); }
+        
+        /** if false, do not mind if there is no public key corresponding to any private key;
+         * defaults to true; only applies if a private key is set */
+        public OsCredential requirePublicKey(boolean requirePublicKey) {
+            this.requirePublicKey = requirePublicKey;
+            return dirty(); 
+        }
+        /** whether to check the private/public keys and passphrase are coherent; default true */
+        public OsCredential doKeyValidation(boolean doKeyValidation) {
+            this.doKeyValidation = doKeyValidation;
+            return dirty();
+        }
+        /** if true (the default) this will look at default locations set on keys */
+        public OsCredential useDefaultKeys(boolean tryDefaultKeys) {
+            this.tryDefaultKeys = tryDefaultKeys;
+            return dirty(); 
+        }
+        /** whether to log warnings on problems */
+        public OsCredential warnOnErrors(boolean warnOnErrors) {
+            this.warnOnErrors = warnOnErrors;
+            return dirty(); 
+        }
+        /** whether to throw on problems */
+        public OsCredential throwOnErrors(boolean throwOnErrors) {
+            this.throwOnErrors = throwOnErrors;
+            return dirty(); 
+        }
+        
+        private OsCredential dirty() { dirty = true; return this; }
+            
+        public static OsCredential newInstance(ConfigBag config) {
+            return new OsCredential(config);
+        }
+        
+        private synchronized void infer() {
+            if (!dirty) return;
+            warningMessages.clear(); 
+            
+            log.debug("Inferring OS credentials");
+            privateKeyData = config.get(LocationConfigKeys.PRIVATE_KEY_DATA);
+            password = config.get(LocationConfigKeys.PASSWORD);
+            publicKeyData = getKeyDataFromDataKeyOrFileKey(config, LocationConfigKeys.PUBLIC_KEY_DATA, LocationConfigKeys.PUBLIC_KEY_FILE);
+
+            KeyPair privateKey = null;
+            
+            if (Strings.isBlank(privateKeyData)) {
+                // look up private key files
+                String privateKeyFiles = null;
+                boolean privateKeyFilesExplicitlySet = config.containsKey(LocationConfigKeys.PRIVATE_KEY_FILE);
+                if (privateKeyFilesExplicitlySet || (tryDefaultKeys && password==null)) 
+                    privateKeyFiles = config.get(LocationConfigKeys.PRIVATE_KEY_FILE);
+                if (Strings.isNonBlank(privateKeyFiles)) {
+                    Iterator<String> fi = Arrays.asList(privateKeyFiles.split(File.pathSeparator)).iterator();
+                    while (fi.hasNext()) {
+                        String file = fi.next();
+                        if (Strings.isNonBlank(file)) {
+                            try {
+                                // real URL's won't actual work, due to use of path separator above 
+                                // not real important, but we get it for free if "files" is a list instead.
+                                // using ResourceUtils is useful for classpath resources
+                                if (file!=null)
+                                    privateKeyData = ResourceUtils.create().getResourceAsString(file);
+                                // else use data already set
+                                
+                                privateKey = getValidatedPrivateKey(file);
+                                
+                                if (privateKeyData==null) {
+                                    // was cleared due to validation error
+                                } else if (Strings.isNonBlank(publicKeyData)) {
+                                    log.debug("Loaded private key data from "+file+" (public key data explicitly set)");
+                                    break;
+                                } else {
+                                    String publicKeyFile = (file!=null ? file+".pub" : "(data)");
+                                    try {
+                                        publicKeyData = ResourceUtils.create().getResourceAsString(publicKeyFile);
+                                        
+                                        log.debug("Loaded private key data from "+file+
+                                            " and public key data from "+publicKeyFile);
+                                        break;
+                                    } catch (Exception e) {
+                                        Exceptions.propagateIfFatal(e);
+                                        log.debug("No public key file "+publicKeyFile+"; will try extracting from private key");
+                                        publicKeyData = AuthorizedKeysParser.encodePublicKey(privateKey.getPublic());
+                                        
+                                        if (publicKeyData==null) {
+                                            if (requirePublicKey) {
+                                                addWarning("Unable to find or extract public key for "+file, "skipping");
+                                            } else {
+                                                log.debug("Loaded private key data from "+file+" (public key data not found but not required)");
+                                                break;
+                                            }
+                                        } else {
+                                            log.debug("Loaded private key data from "+file+" (public key data extracted)");
+                                            break;
+                                        }
+                                        privateKeyData = null;
+                                    }
+                                }
+
+                            } catch (Exception e) {
+                                Exceptions.propagateIfFatal(e);
+                                String message = "Missing/invalid private key file "+file;
+                                if (privateKeyFilesExplicitlySet) addWarning(message, (!fi.hasNext() ? "no more files to try" : "trying next file")+": "+e);
+                            }
+                        }
+                    }
+                    if (privateKeyFilesExplicitlySet && Strings.isBlank(privateKeyData))
+                        error("No valid private keys found", ""+warningMessages);
+                }
+            } else {
+                privateKey = getValidatedPrivateKey("(data)");
+            }
+            
+            if (privateKeyData!=null) {
+                if (requirePublicKey && Strings.isBlank(publicKeyData)) {
+                    if (privateKey!=null) {
+                        publicKeyData = AuthorizedKeysParser.encodePublicKey(privateKey.getPublic());
+                    }
+                    if (Strings.isBlank(publicKeyData)) {
+                        error("If explicit "+LocationConfigKeys.PRIVATE_KEY_DATA.getName()+" is supplied, then "
+                            + "the corresponding "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" must also be supplied.", null);
+                    } else {
+                        log.debug("Public key data extracted");
+                    }
+                }
+                if (doKeyValidation && privateKey!=null && privateKey.getPublic()!=null && Strings.isNonBlank(publicKeyData)) {
+                    PublicKey decoded = null;
+                    try {
+                        decoded = AuthorizedKeysParser.decodePublicKey(publicKeyData);
+                    } catch (Exception e) {
+                        Exceptions.propagateIfFatal(e);
+                        addWarning("Invalid public key: "+decoded);
+                    }
+                    if (decoded!=null && !privateKey.getPublic().equals( decoded )) {
+                        error("Public key inferred from does not match public key extracted from private key", null);
+                    }
+                }
+            }
+
+            log.debug("OS credential inference: "+this);
+            dirty = false;
+        }
+
+        private KeyPair getValidatedPrivateKey(String label) {
+            KeyPair privateKey = null;
+            String passphrase = config.get(CloudLocationConfig.PRIVATE_KEY_PASSPHRASE);
+            try {
+                privateKey = SecureKeys.readPem(new ByteArrayInputStream(privateKeyData.getBytes()), passphrase);
+                if (passphrase!=null) {
+                    // get the unencrypted key data for our internal use (jclouds requires this)
+                    privateKeyData = SecureKeys.toPem(privateKey);
+                }
+            } catch (PassphraseProblem e) {
+                if (doKeyValidation) {
+                    log.debug("Encountered error handling key "+label+": "+e, e);
+                    if (Strings.isBlank(passphrase))
+                        addWarning("Passphrase required for key '"+label+"'");
+                    else
+                        addWarning("Invalid passphrase for key '"+label+"'");
+                    privateKeyData = null;
+                }
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                if (doKeyValidation) {
+                    addWarning("Unable to parse private key from '"+label+"': unknown format");
+                    privateKeyData = null;
+                }
+            }
+            return privateKey;
+        }
+        
+        Set<String> warningMessages = MutableSet.of();
+        
+        private void error(String msg, String logExtension) {
+            addWarning(msg);
+            if (warnOnErrors) log.warn(msg+(logExtension==null ? "" : ": "+logExtension));
+            if (throwOnErrors) throw new IllegalStateException(msg+(logExtension==null ? "" : "; "+logExtension));
+        }
+
+        private void addWarning(String msg) {
+            addWarning(msg, null);
+        }
+        private void addWarning(String msg, String debugExtension) {
+            log.debug(msg+(debugExtension==null ? "" : "; "+debugExtension));
+            warningMessages.add(msg);
+        }
+
+        @Override
+        public String toString() {
+            return getClass().getSimpleName()+"["+
+                (Strings.isNonBlank(publicKeyData) ? publicKeyData : "no-public-key")+";"+
+                (Strings.isNonBlank(privateKeyData) ? "private-key-present" : "no-private-key")+","+
+                (password!=null ? "password(len="+password.length()+")" : "no-password")+"]";
+        }
+    }
+
+    /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated
+    public static String getPrivateKeyData(ConfigBag config) {
+        return getKeyData(config, LocationConfigKeys.PRIVATE_KEY_DATA, LocationConfigKeys.PRIVATE_KEY_FILE);
+    }
+    
+    /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated
+    public static String getPublicKeyData(ConfigBag config) {
+        String data = getKeyData(config, LocationConfigKeys.PUBLIC_KEY_DATA, LocationConfigKeys.PUBLIC_KEY_FILE);
+        if (groovyTruth(data)) return data;
+        
+        String privateKeyFile = config.get(LocationConfigKeys.PRIVATE_KEY_FILE);
+        if (groovyTruth(privateKeyFile)) {
+            List<String> privateKeyFiles = Arrays.asList(privateKeyFile.split(File.pathSeparator));
+            List<String> publicKeyFiles = ImmutableList.copyOf(Iterables.transform(privateKeyFiles, StringFunctions.append(".pub")));
+            List<String> publicKeyFilesTidied = tidyFilePaths(publicKeyFiles);
+            
+            String fileData = getFileContents(publicKeyFilesTidied);
+            if (groovyTruth(fileData)) {
+                if (log.isDebugEnabled()) log.debug("Loaded "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" from inferred files, based on "+LocationConfigKeys.PRIVATE_KEY_FILE.getName() + ": used " + publicKeyFilesTidied + " for "+config.getDescription());
+                config.put(LocationConfigKeys.PUBLIC_KEY_DATA, fileData);
+                return fileData;
+            } else {
+                log.info("Not able to load "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" from inferred files, based on "+LocationConfigKeys.PRIVATE_KEY_FILE.getName() + ": tried " + publicKeyFilesTidied + " for "+config.getDescription());
+            }
+        }
+        
+        return null;
+    }
+
+    /** @deprecated since 0.7.0, use #getOsCredential(ConfigBag) */ @Deprecated
+    public static String getKeyData(ConfigBag config, ConfigKey<String> dataKey, ConfigKey<String> fileKey) {
+        return getKeyDataFromDataKeyOrFileKey(config, dataKey, fileKey);
+    }
+    
+    private static String getKeyDataFromDataKeyOrFileKey(ConfigBag config, ConfigKey<String> dataKey, ConfigKey<String> fileKey) {
+        boolean unused = config.isUnused(dataKey);
+        String data = config.get(dataKey);
+        if (groovyTruth(data) && !unused) {
+            return data;
+        }
+        
+        String file = config.get(fileKey);
+        if (groovyTruth(file)) {
+            List<String> files = Arrays.asList(file.split(File.pathSeparator));
+            List<String> filesTidied = tidyFilePaths(files);
+            String fileData = getFileContents(filesTidied);
+            if (fileData == null) {
+                log.warn("Invalid file" + (files.size() > 1 ? "s" : "") + " for " + fileKey + " (given " + files + 
+                        (files.equals(filesTidied) ? "" : "; converted to " + filesTidied) + ") " +
+                        "may fail provisioning " + config.getDescription());
+            } else if (groovyTruth(data)) {
+                if (!fileData.trim().equals(data.trim()))
+                    log.warn(dataKey.getName()+" and "+fileKey.getName()+" both specified; preferring the former");
+            } else {
+                data = fileData;
+                config.put(dataKey, data);
+                config.get(dataKey);
+            }
+        }
+        
+        return data;
+    }
+    
+    /**
+     * Reads the given file(s) in-order, returning the contents of the first file that can be read.
+     * Returns the file contents, or null if none of the files can be read.
+     *  
+     * @param files             list of file paths
+     */
+    private static String getFileContents(Iterable<String> files) {
+        Iterator<String> fi = files.iterator();
+        while (fi.hasNext()) {
+            String file = fi.next();
+            if (groovyTruth(file)) {
+                try {
+                    // see comment above
+                    String result = ResourceUtils.create().getResourceAsString(file);
+                    if (result!=null) return result;
+                    log.debug("Invalid file "+file+" ; " + (!fi.hasNext() ? "no more files to try" : "trying next file")+" (null)");
+                } catch (Exception e) {
+                    Exceptions.propagateIfFatal(e);
+                    log.debug("Invalid file "+file+" ; " + (!fi.hasNext() ? "no more files to try" : "trying next file"), e);
+                }
+            }
+        }
+        return null;
+    }
+
+    private static List<String> tidyFilePaths(Iterable<String> files) {
+        List<String> result = Lists.newArrayList();
+        for (String file : files) {
+            result.add(Os.tidyPath(file));
+        }
+        return result;
+    }
+
+    /** @deprecated since 0.6.0 use configBag.getWithDeprecation */
+    @Deprecated
+    @SuppressWarnings("unchecked")
+    public static <T> T getConfigCheckingDeprecatedAlternatives(ConfigBag configBag, ConfigKey<T> preferredKey,
+            ConfigKey<?> ...deprecatedKeys) {
+        T value1 = (T) configBag.getWithDeprecation(preferredKey, deprecatedKeys);
+        T value2 = getConfigCheckingDeprecatedAlternativesInternal(configBag, preferredKey, deprecatedKeys);
+        if (!Objects.equal(value1, value2)) {
+            // points to a bug in one of the get-with-deprecation methods
+            log.warn("Deprecated getConfig with deprecated keys "+Arrays.toString(deprecatedKeys)+" gets different value with " +
+                    "new strategy "+preferredKey+" ("+value1+") and old ("+value2+"); preferring old value for now, but this behaviour will change");
+            return value2;
+        }
+        return value1;
+    }
+    
+    @SuppressWarnings("unchecked")
+    private static <T> T getConfigCheckingDeprecatedAlternativesInternal(ConfigBag configBag, ConfigKey<T> preferredKey,
+            ConfigKey<?> ...deprecatedKeys) {
+        ConfigKey<?> keyProvidingValue = null;
+        T value = null;
+        boolean found = false;
+        if (configBag.containsKey(preferredKey)) {
+            value = configBag.get(preferredKey);
+            found = true;
+            keyProvidingValue = preferredKey;
+        }
+        
+        for (ConfigKey<?> deprecatedKey: deprecatedKeys) {
+            T altValue = null;
+            boolean altFound = false;
+            if (configBag.containsKey(deprecatedKey)) {
+                altValue = (T) configBag.get(deprecatedKey);
+                altFound = true;
+                
+                if (altFound) {
+                    if (found) {
+                        if (Objects.equal(value, altValue)) {
+                            // fine -- nothing
+                        } else {
+                            log.warn("Detected deprecated key "+deprecatedKey+" with value "+altValue+" used in addition to "+keyProvidingValue+" " +
+                                    "with value "+value+" for "+configBag.getDescription()+"; ignoring");
+                            configBag.remove(deprecatedKey);
+                        }
+                    } else {
+                        log.warn("Detected deprecated key "+deprecatedKey+" with value "+altValue+" used instead of recommended "+preferredKey+"; " +
+                                "promoting to preferred key status; will not be supported in future versions");
+                        configBag.put(preferredKey, altValue);
+                        configBag.remove(deprecatedKey);
+                        value = altValue;
+                        found = true;
+                        keyProvidingValue = deprecatedKey;
+                    }
+                }
+            }
+        }
+        
+        if (found) {
+            return value;
+        } else {
+            return configBag.get(preferredKey); // get the default
+        }
+    }
+
+    public static Map<ConfigKey<String>,String> finalAndOriginalSpecs(String finalSpec, Object ...sourcesForOriginalSpec) {
+        // yuck!: TODO should clean up how these things get passed around
+        Map<ConfigKey<String>,String> result = MutableMap.of();
+        if (finalSpec!=null) 
+            result.put(LocationInternal.FINAL_SPEC, finalSpec);
+        
+        String originalSpec = null;
+        for (Object source: sourcesForOriginalSpec) {
+            if (source instanceof CharSequence) originalSpec = source.toString();
+            else if (source instanceof Map) {
+                if (originalSpec==null) originalSpec = Strings.toString( ((Map<?,?>)source).get(LocationInternal.ORIGINAL_SPEC) );
+                if (originalSpec==null) originalSpec = Strings.toString( ((Map<?,?>)source).get(LocationInternal.ORIGINAL_SPEC.getName()) );
+            }
+            if (originalSpec!=null) break; 
+        }
+        if (originalSpec==null) originalSpec = finalSpec;
+        if (originalSpec!=null)
+            result.put(LocationInternal.ORIGINAL_SPEC, originalSpec);
+        
+        return result;
+    }
+
+    public static boolean isEnabled(ManagementContext mgmt, String prefix) {
+        ConfigKey<Boolean> key = ConfigKeys.newConfigKeyWithPrefix(prefix+".", LocationConfigKeys.ENABLED);
+        Boolean enabled = mgmt.getConfig().getConfig(key);
+        if (enabled!=null) return enabled.booleanValue();
+        return true;
+    }
+    
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java
new file mode 100644
index 0000000..a289090
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java
@@ -0,0 +1,39 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import brooklyn.basic.BrooklynDynamicType;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationType;
+
+public class LocationDynamicType extends BrooklynDynamicType<Location, AbstractLocation> {
+
+    public LocationDynamicType(AbstractLocation location) {
+        super(location);
+    }
+    
+    public LocationType getSnapshot() {
+        return (LocationType) super.getSnapshot();
+    }
+
+    @Override
+    protected LocationTypeSnapshot newSnapshot() {
+        return new LocationTypeSnapshot(name, value(configKeys));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
new file mode 100644
index 0000000..429e671
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
@@ -0,0 +1,94 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.rebind.RebindSupport;
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.mementos.LocationMemento;
+
+import brooklyn.basic.BrooklynObjectInternal;
+import brooklyn.config.ConfigInheritance;
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.util.config.ConfigBag;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Information about locations private to Brooklyn.
+ */
+public interface LocationInternal extends BrooklynObjectInternal, Location {
+
+    @Beta
+    public static final ConfigKey<String> ORIGINAL_SPEC = ConfigKeys.newStringConfigKey("spec.original", "The original spec used to instantiate a location");
+    @Beta
+    public static final ConfigKey<String> FINAL_SPEC = ConfigKeys.newStringConfigKey("spec.final", "The actual spec (in a chain) which instantiates a location");
+    @Beta
+    public static final ConfigKey<String> NAMED_SPEC_NAME = ConfigKeys.newStringConfigKey("spec.named.name", "The name on the (first) named spec in a chain");
+    
+    /**
+     * Registers the given extension for the given type. If an extension already existed for
+     * this type, then this will override it.
+     * 
+     * @throws NullPointerException if extensionType or extension are null
+     * @throws IllegalArgumentException if extension does not implement extensionType
+     */
+    <T> void addExtension(Class<T> extensionType, T extension);
+
+    /**
+     * Get a record of the metadata of this location.
+     * <p/>
+     * <p>Metadata records are used to record an audit trail of events relating to location usage
+     * (for billing purposes, for example). Implementations (and subclasses) should override this
+     * method to return information useful for this purpose.</p>
+     *
+     * @return
+     */
+    public Map<String, String> toMetadataRecord();
+
+    /**
+     * @deprecated since 0.7.0; use {@link #config()}, such as {@code ((LocationInternal)location).config().getLocalBag()}
+     */
+    @Deprecated
+    ConfigBag getLocalConfigBag();
+
+    /**
+     * Returns all config, including that inherited from parents.
+     * 
+     * This method does not respect {@link ConfigInheritance} and so usage is discouraged.
+     * 
+     * @deprecated since 0.7.0; use {@link #config()}, such as {@code ((LocationInternal)location).config().getBag()}
+     */
+    @Deprecated
+    ConfigBag getAllConfigBag();
+
+    /**
+     * Users are strongly discouraged from calling or overriding this method.
+     * It is for internal calls only, relating to persisting/rebinding entities.
+     * This method may change (or be removed) in a future release without notice.
+     */
+    @Override
+    @Beta
+    RebindSupport<LocationMemento> getRebindSupport();
+    
+    ManagementContext getManagementContext();
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java
new file mode 100644
index 0000000..d0b781b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java
@@ -0,0 +1,108 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import javax.annotation.Nullable;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.config.ConfigKey.HasConfigKey;
+import org.apache.brooklyn.location.Location;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+
+public class LocationPredicates {
+
+    public static <T> Predicate<Location> idEqualTo(final T val) {
+        return new Predicate<Location>() {
+            @Override
+            public boolean apply(@Nullable Location input) {
+                return (input != null) && Objects.equal(input.getId(), val);
+            }
+        };
+    }
+    
+    public static <T> Predicate<Location> displayNameEqualTo(final T val) {
+        return new Predicate<Location>() {
+            @Override
+            public boolean apply(@Nullable Location input) {
+                return (input != null) && Objects.equal(input.getDisplayName(), val);
+            }
+        };
+    }
+    
+    public static <T> Predicate<Location> configEqualTo(final ConfigKey<T> configKey, final T val) {
+        return new Predicate<Location>() {
+            @Override
+            public boolean apply(@Nullable Location input) {
+                return (input != null) && Objects.equal(input.getConfig(configKey), val);
+            }
+        };
+    }
+
+    public static <T> Predicate<Location> configEqualTo(final HasConfigKey<T> configKey, final T val) {
+        return new Predicate<Location>() {
+            @Override
+            public boolean apply(@Nullable Location input) {
+                return (input != null) && Objects.equal(input.getConfig(configKey), val);
+            }
+        };
+    }
+
+    /**
+     * Returns a predicate that determines if a given location is a direct child of this {@code parent}.
+     */
+    public static <T> Predicate<Location> isChildOf(final Location parent) {
+        return new Predicate<Location>() {
+            @Override
+            public boolean apply(@Nullable Location input) {
+                return (input != null) && Objects.equal(input.getParent(), parent);
+            }
+        };
+    }
+
+    /**
+     * Returns a predicate that determines if a given location is a descendant of this {@code ancestor}.
+     */
+    public static <T> Predicate<Location> isDescendantOf(final Location ancestor) {
+        return new Predicate<Location>() {
+            @Override
+            public boolean apply(@Nullable Location input) {
+                // assumes impossible to have cycles in location-hierarchy
+                Location contenderAncestor = (input == null) ? input : input.getParent();
+                while (contenderAncestor != null) {
+                    if (Objects.equal(contenderAncestor, ancestor)) {
+                        return true;
+                    }
+                    contenderAncestor = contenderAncestor.getParent();
+                }
+                return false;
+            }
+        };
+    }
+
+    public static <T> Predicate<Location> managed() {
+        return new Predicate<Location>() {
+            @Override
+            public boolean apply(@Nullable Location input) {
+                return (input != null) && Locations.isManaged(input);
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocationPropertiesFromBrooklynProperties.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationPropertiesFromBrooklynProperties.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationPropertiesFromBrooklynProperties.java
new file mode 100644
index 0000000..e1feb18
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationPropertiesFromBrooklynProperties.java
@@ -0,0 +1,224 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.io.File;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.config.BrooklynServerConfig;
+import brooklyn.config.ConfigUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.internal.ssh.SshTool;
+import brooklyn.util.os.Os;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Strings;
+import com.google.common.collect.Maps;
+
+/**
+ * The properties to use for locations, loaded from brooklyn.properties file.
+ * 
+ * @author aledsage
+ **/
+public class LocationPropertiesFromBrooklynProperties {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LocationPropertiesFromBrooklynProperties.class);
+
+    @SuppressWarnings("deprecation")
+    protected static final Map<String, String> DEPRECATED_KEYS_MAPPING = new DeprecatedKeysMappingBuilder(LOG)
+            .camelToHyphen(LocationConfigKeys.DISPLAY_NAME)
+            .camelToHyphen(LocationConfigKeys.PRIVATE_KEY_FILE)
+            .camelToHyphen(LocationConfigKeys.PRIVATE_KEY_DATA)
+            .camelToHyphen(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE)
+            .camelToHyphen(LocationConfigKeys.PUBLIC_KEY_FILE)
+            .camelToHyphen(LocationConfigKeys.PUBLIC_KEY_DATA)
+            .camelToHyphen(LocationConfigKeys.CALLER_CONTEXT)
+            .build();
+    
+    /**
+     * Finds the properties that apply to location, stripping off the prefixes.
+     * 
+     * Order of preference (in ascending order) is:
+     * <ol>
+     * <li>brooklyn.location.*
+     * <li>brooklyn.location.provider.*
+     * <li>brooklyn.location.named.namedlocation.*
+     * </ol>
+     * <p>
+     * Converts deprecated hyphenated properties to the non-deprecated camelCase format. 
+     */
+    public Map<String, Object> getLocationProperties(String provider, String namedLocation, Map<String, ?> properties) {
+        ConfigBag result = ConfigBag.newInstance();
+        
+        if (!Strings.isNullOrEmpty(provider)) 
+            result.put(LocationConfigKeys.CLOUD_PROVIDER, provider);
+        // named properties are preferred over providerOrApi properties
+        result.putAll(transformDeprecated(getGenericLocationSingleWordProperties(properties)));
+        if (!Strings.isNullOrEmpty(provider)) result.putAll(transformDeprecated(getScopedLocationProperties(provider, properties)));
+        if (!Strings.isNullOrEmpty(namedLocation)) result.putAll(transformDeprecated(getNamedLocationProperties(namedLocation, properties)));
+        
+        setLocalTempDir(properties, result);
+        
+        return result.getAllConfigRaw();
+    }
+
+    /** allow the temp dir where ssh temporary files on the brooklyn server side are placed */
+    public static void setLocalTempDir(Map<String,?> source, ConfigBag target) {
+        // TODO better would be to use BrooklynServerConfig, requiring management passed in
+        String brooklynDataDir = (String) source.get(BrooklynServerConfig.getMgmtBaseDir(source));
+        if (brooklynDataDir != null && brooklynDataDir.length() > 0) {
+            String tempDir = Os.mergePaths(brooklynDataDir, "tmp", "ssh");
+            target.putIfAbsentAndNotNull(SshTool.PROP_LOCAL_TEMP_DIR, tempDir);
+            Os.deleteOnExitEmptyParentsUpTo(new File(tempDir), new File(brooklynDataDir));
+        }
+    }
+    
+    /**
+     * Gets the named provider (e.g. if using a property like {@code brooklyn.location.named.myfavourite=localhost}, then
+     * {@code getNamedProvider("myfavourite", properties)} will return {@code "localhost"}).
+     */
+    protected String getNamedProvider(String namedLocation, Map<String, ?> properties) {
+        String key = String.format("brooklyn.location.named.%s", namedLocation);
+        return (String) properties.get(key);
+    }
+    
+    /**
+     * Returns those properties in the form "brooklyn.location.xyz", where "xyz" is any
+     * key that does not contain dots. We do this special (sub-optimal!) filtering
+     * because we want to exclude brooklyn.location.named.*, brooklyn.location.jclouds.*, etc.
+     * We only want those properties that are to be generic for all locations.
+     * 
+     * Strips off the prefix in the returned map.
+     */
+    protected Map<String, Object> getGenericLocationSingleWordProperties(Map<String, ?> properties) {
+        return getMatchingSingleWordProperties("brooklyn.location.", properties);
+    }
+
+    /**
+     * Gets all properties that start with {@code "brooklyn.location."+scopeSuffix+"."}, stripping off
+     * the prefix in the returned map.
+     */
+    protected Map<String, Object> getScopedLocationProperties(String scopeSuffix, Map<String, ?> properties) {
+        checkArgument(!scopeSuffix.startsWith("."), "scopeSuffix \"%s\" should not start with \".\"", scopeSuffix);
+        checkArgument(!scopeSuffix.endsWith("."), "scopeSuffix \"%s\" should not end with \".\"", scopeSuffix);
+        String prefix = String.format("brooklyn.location.%s.", scopeSuffix);
+        return ConfigUtils.filterForPrefixAndStrip(properties, prefix).asMapWithStringKeys();
+    }
+
+    /**
+     * Gets all properties that start with the given {@code fullPrefix}, stripping off
+     * the prefix in the returned map.
+     */
+    protected Map<String, Object> getMatchingProperties(String fullPrefix, Map<String, ?> properties) {
+        return ConfigUtils.filterForPrefixAndStrip(properties, fullPrefix).asMapWithStringKeys();
+    }
+
+    /**
+     * Gets all properties that start with either of the given prefixes. The {@code fullPreferredPrefix} 
+     * properties will override any duplicates in {@code fullDeprecatedPrefix}. If there are any
+     * properties that match the {@code fullDeprecatedPrefix}, then a warning will be logged.
+     * 
+     * @see #getMatchingProperties(String, Map)
+     */
+    protected Map<String, Object> getMatchingProperties(String fullPreferredPrefix, String fullDeprecatedPrefix, Map<String, ?> properties) {
+        Map<String, Object> deprecatedResults = getMatchingProperties(fullDeprecatedPrefix, properties);
+        Map<String, Object> results = getMatchingProperties(fullPreferredPrefix, properties);
+        
+        if (deprecatedResults.size() > 0) {
+            LOG.warn("Deprecated use of properties prefix "+fullDeprecatedPrefix+"; instead use "+fullPreferredPrefix);
+            return MutableMap.<String, Object>builder()
+                    .putAll(deprecatedResults)
+                    .putAll(results)
+                    .build();
+        } else {
+            return results;
+        }
+    }
+
+    /**
+     * Gets all properties that start with the given {@code fullPrefix}, stripping off
+     * the prefix in the returned map.
+     * 
+     * Returns only those properties whose key suffix is a single word (i.e. contains no dots).
+     * We do this special (sub-optimal!) filtering because we want sub-scoped things 
+     * (e.g. could want brooklyn.location.privateKeyFile, but not brooklyn.location.named.*). 
+     */
+    protected Map<String, Object> getMatchingSingleWordProperties(String fullPrefix, Map<String, ?> properties) {
+        BrooklynProperties filteredProperties = ConfigUtils.filterForPrefixAndStrip(properties, fullPrefix);
+        return ConfigUtils.filterFor(filteredProperties, Predicates.not(Predicates.containsPattern("\\."))).asMapWithStringKeys();
+    }
+
+    /**
+     * Gets all single-word properties that start with either of the given prefixes. The {@code fullPreferredPrefix} 
+     * properties will override any duplicates in {@code fullDeprecatedPrefix}. If there are any
+     * properties that match the {@code fullDeprecatedPrefix}, then a warning will be logged.
+     * 
+     * @see #getMatchingSingleWordProperties(String, Map)
+     */
+    protected Map<String, Object> getMatchingSingleWordProperties(String fullPreferredPrefix, String fullDeprecatedPrefix, Map<String, ?> properties) {
+        Map<String, Object> deprecatedResults = getMatchingSingleWordProperties(fullDeprecatedPrefix, properties);
+        Map<String, Object> results = getMatchingSingleWordProperties(fullPreferredPrefix, properties);
+        
+        if (deprecatedResults.size() > 0) {
+            LOG.warn("Deprecated use of properties prefix "+fullDeprecatedPrefix+"; instead use "+fullPreferredPrefix);
+            return MutableMap.<String, Object>builder()
+                    .putAll(deprecatedResults)
+                    .putAll(results)
+                    .build();
+        } else {
+            return results;
+        }
+    }
+
+    protected Map<String, Object> getNamedLocationProperties(String locationName, Map<String, ?> properties) {
+        checkArgument(!Strings.isNullOrEmpty(locationName), "locationName should not be blank");
+        String prefix = String.format("brooklyn.location.named.%s.", locationName);
+        return ConfigUtils.filterForPrefixAndStrip(properties, prefix).asMapWithStringKeys();
+    }
+
+    protected Map<String, Object> transformDeprecated(Map<String, ?> properties) {
+        Map<String,Object> result = Maps.newLinkedHashMap();
+        Map<String, String> deprecatedKeysMapping = getDeprecatedKeysMapping();
+        
+        for (Map.Entry<String,?> entry : properties.entrySet()) {
+            String key = entry.getKey();
+            Object value = entry.getValue();
+            if (deprecatedKeysMapping.containsKey(key)) {
+                String transformedKey = deprecatedKeysMapping.get(key);
+                LOG.warn("Deprecated key {}, transformed to {}; will not be supported in future versions", new Object[] {key, transformedKey});
+                result.put(transformedKey, value);
+            } else {
+                result.put(key, value);
+            }
+        }
+        
+        return result;
+    }
+    
+    protected Map<String,String> getDeprecatedKeysMapping() {
+        return DEPRECATED_KEYS_MAPPING;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/LocationTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationTypeSnapshot.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationTypeSnapshot.java
new file mode 100644
index 0000000..4dec614
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationTypeSnapshot.java
@@ -0,0 +1,41 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.util.Map;
+
+import org.apache.brooklyn.policy.EnricherType;
+
+import brooklyn.basic.BrooklynTypeSnapshot;
+import brooklyn.config.ConfigKey;
+
+public class LocationTypeSnapshot extends BrooklynTypeSnapshot implements EnricherType {
+    
+    private static final long serialVersionUID = 9150132836104748237L;
+
+    LocationTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
+        super(name, configKeys);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        return (obj instanceof LocationTypeSnapshot) && super.equals(obj);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java b/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java
new file mode 100644
index 0000000..31855ed
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java
@@ -0,0 +1,159 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.management.LocationManager;
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.MachineLocation;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.yaml.Yamls;
+
+import com.google.common.collect.ImmutableList;
+
+public class Locations {
+
+    private static final Logger log = LoggerFactory.getLogger(Locations.class);
+
+    public static final LocationsFilter USE_FIRST_LOCATION = new LocationsFilter() {
+        private static final long serialVersionUID = 3100091615409115890L;
+
+        @Override
+        public List<Location> filterForContext(List<Location> locations, Object context) {
+            if (locations.size()<=1) return locations;
+            return ImmutableList.of(locations.get(0));
+        }
+    };
+
+    public interface LocationsFilter extends Serializable {
+        public List<Location> filterForContext(List<Location> locations, Object context);
+    }
+    
+    /** as {@link Machines#findUniqueMachineLocation(Iterable)} */
+    public static Maybe<MachineLocation> findUniqueMachineLocation(Iterable<? extends Location> locations) {
+        return Machines.findUniqueMachineLocation(locations);
+    }
+    
+    /** as {@link Machines#findUniqueSshMachineLocation(Iterable)} */
+    public static Maybe<SshMachineLocation> findUniqueSshMachineLocation(Iterable<? extends Location> locations) {
+        return Machines.findUniqueSshMachineLocation(locations);
+    }
+
+    /** if no locations are supplied, returns locations on the entity, or in the ancestors, until it finds a non-empty set,
+     * or ultimately the empty set if no locations are anywhere */ 
+    public static Collection<? extends Location> getLocationsCheckingAncestors(Collection<? extends Location> locations, Entity entity) {
+        // look in ancestors if location not set here
+        Entity ancestor = entity;
+        while ((locations==null || locations.isEmpty()) && ancestor!=null) {
+            locations = ancestor.getLocations();
+            ancestor = ancestor.getParent();
+        }
+        return locations;
+    }
+    
+    public static boolean isManaged(Location loc) {
+        ManagementContext mgmt = ((LocationInternal)loc).getManagementContext();
+        return (mgmt != null) && mgmt.isRunning() && mgmt.getLocationManager().isManaged(loc);
+    }
+
+    public static void unmanage(Location loc) {
+        if (isManaged(loc)) {
+            ManagementContext mgmt = ((LocationInternal)loc).getManagementContext();
+            mgmt.getLocationManager().unmanage(loc);
+        }
+    }
+    
+    /**
+     * Registers the given location (and all its children) with the management context. 
+     * @throws IllegalStateException if the parent location is not already managed
+     * 
+     * @since 0.6.0 (added only for backwards compatibility, where locations are being created directly; previously in {@link Entities}).
+     * @deprecated in 0.6.0; use {@link LocationManager#createLocation(LocationSpec)} instead.
+     */
+    public static void manage(Location loc, ManagementContext managementContext) {
+        if (!managementContext.getLocationManager().isManaged(loc)) {
+            log.warn("Deprecated use of unmanaged location ("+loc+"); will be managed automatically now but not supported in future versions");
+            // FIXME this occurs MOST OF THE TIME e.g. including BrooklynLauncher.location(locationString)
+            // not sure what is the recommend way to convert from locationString to locationSpec, or the API we want to expose;
+            // deprecating some of the LocationRegistry methods seems sensible?
+            log.debug("Stack trace for location of: Deprecated use of unmanaged location; will be managed automatically now but not supported in future versions", new Exception("TRACE for: Deprecated use of unmanaged location"));
+            managementContext.getLocationManager().manage(loc);
+        }
+    }
+
+    public static Location coerce(ManagementContext mgmt, Object rawO) {
+        if (rawO==null)
+            return null;
+        if (rawO instanceof Location)
+            return (Location)rawO;
+        
+        Object raw = rawO;
+        if (raw instanceof String)
+            raw = Yamls.parseAll((String)raw).iterator().next();
+        
+        String name;
+        Map<?, ?> flags = null;
+        if (raw instanceof Map) {
+            // for yaml, take the key, and merge with locationFlags
+            Map<?,?> tm = ((Map<?,?>)raw);
+            if (tm.size()!=1) {
+                throw new IllegalArgumentException("Location "+rawO+" is invalid; maps must have only one key, being the location spec string");
+            }
+            name = (String) tm.keySet().iterator().next();
+            flags = (Map<?, ?>) tm.values().iterator().next();
+            
+        } else if (raw instanceof String) {
+            name = (String)raw;
+            
+        } else {
+            throw new IllegalArgumentException("Location "+rawO+" is invalid; can only parse strings or maps");
+        }
+        return mgmt.getLocationRegistry().resolve(name, flags);
+    }
+    
+    public static Collection<? extends Location> coerceToCollection(ManagementContext mgmt, Object rawO) {
+        if (rawO==null) return null;
+        Object raw = rawO;
+        if (raw instanceof Collection) {
+            List<Location> result = MutableList.<Location>of();
+            for (Object o: (Collection<?>)raw)
+                result.add(coerce(mgmt, o));
+            return result;
+        }
+        if (raw instanceof String) {
+            raw = Yamls.parseAll((String)raw).iterator().next();
+            if (raw instanceof Collection)
+                return coerceToCollection(mgmt, raw);
+        }
+        return Collections.singletonList( coerce(mgmt, raw) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java b/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java
new file mode 100644
index 0000000..621e1e2
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java
@@ -0,0 +1,188 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import java.net.InetAddress;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.location.Location;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Iterables;
+
+import brooklyn.entity.basic.Attributes;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+import brooklyn.util.guava.Maybe;
+import brooklyn.util.net.HasNetworkAddresses;
+
+/** utilities for working with MachineLocations */
+public class Machines {
+
+    private static final Logger log = LoggerFactory.getLogger(Machines.class);
+    
+    public static Maybe<String> getSubnetHostname(Location where) {
+        // TODO Should we look at HasNetworkAddresses? But that's not a hostname.
+        String hostname = null;
+        if (where instanceof HasSubnetHostname) {
+            hostname = ((HasSubnetHostname) where).getSubnetHostname();
+        }
+        if (hostname == null && where instanceof MachineLocation) {
+            InetAddress addr = ((MachineLocation) where).getAddress();
+            if (addr != null) hostname = addr.getHostAddress();
+        }
+        log.debug("computed subnet hostname {} for {}", hostname, where);
+        // TODO if Maybe.absent(message) appears, could/should use that
+        // TODO If no machine available, should we throw new IllegalStateException("Cannot find hostname for "+where);
+        return Maybe.fromNullable(hostname);
+    }
+
+    public static Maybe<String> getSubnetIp(Location where) {
+        // TODO Too much duplication between the ip and hostname methods
+        String result = null;
+        if (where instanceof HasSubnetHostname) {
+            result = ((HasSubnetHostname) where).getSubnetIp();
+        }
+        if (where instanceof HasNetworkAddresses) {
+            Set<String> privateAddrs = ((HasNetworkAddresses) where).getPrivateAddresses();
+            if (privateAddrs.size() > 0) {
+                result = Iterables.get(privateAddrs, 0);
+            }
+        }
+        if (result == null && where instanceof MachineLocation) {
+            InetAddress addr = ((MachineLocation) where).getAddress();
+            if (addr != null) result = addr.getHostAddress();
+        }
+        log.debug("computed subnet host ip {} for {}", result, where);
+        return Maybe.fromNullable(result);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> Maybe<T> findUniqueElement(Iterable<?> items, Class<T> type) {
+        if (items==null) return null;
+        Iterator<?> i = items.iterator();
+        T result = null;
+        while (i.hasNext()) {
+            Object candidate = i.next();
+            if (type.isInstance(candidate)) {
+                if (result==null) result = (T)candidate;
+                else {
+                    if (log.isTraceEnabled())
+                        log.trace("Multiple instances of "+type+" in "+items+"; ignoring");
+                    return Maybe.absent(new IllegalStateException("Multiple instances of "+type+" in "+items+"; expected a single one"));
+                }
+            }
+        }
+        if (result==null) 
+            return Maybe.absent(new IllegalStateException("No instances of "+type+" available (in "+items+")"));
+        return Maybe.of(result);
+    }
+    
+    public static Maybe<MachineLocation> findUniqueMachineLocation(Iterable<? extends Location> locations) {
+        return findUniqueElement(locations, MachineLocation.class);
+    }
+
+    public static Maybe<SshMachineLocation> findUniqueSshMachineLocation(Iterable<? extends Location> locations) {
+        return findUniqueElement(locations, SshMachineLocation.class);
+    }
+
+    public static Maybe<WinRmMachineLocation> findUniqueWinRmMachineLocation(Iterable<? extends Location> locations) {
+        return findUniqueElement(locations, WinRmMachineLocation.class);
+    }
+
+    public static Maybe<String> findSubnetHostname(Iterable<? extends Location> ll) {
+        Maybe<MachineLocation> l = findUniqueMachineLocation(ll);
+        if (!l.isPresent()) {
+            return Maybe.absent();
+//            throw new IllegalStateException("Cannot find hostname for among "+ll);
+        }
+        return Machines.getSubnetHostname(l.get());
+    }
+
+    public static Maybe<String> findSubnetHostname(Entity entity) {
+        String sh = entity.getAttribute(Attributes.SUBNET_HOSTNAME);
+        if (sh!=null) return Maybe.of(sh);
+        return findSubnetHostname(entity.getLocations());
+    }
+    
+    public static Maybe<String> findSubnetOrPublicHostname(Entity entity) {
+        String hn = entity.getAttribute(Attributes.HOSTNAME);
+        if (hn!=null) {
+            // attributes already set, see if there was a SUBNET_HOSTNAME set
+            // note we rely on (public) hostname being set _after_ subnet_hostname,
+            // to prevent tiny possibility of races resulting in hostname being returned
+            // becasue subnet is still being looked up -- see MachineLifecycleEffectorTasks
+            Maybe<String> sn = findSubnetHostname(entity);
+            if (sn.isPresent()) return sn;
+            // short-circuit discovery if attributes have been set already
+            return Maybe.of(hn);
+        }
+        
+        Maybe<MachineLocation> l = findUniqueMachineLocation(entity.getLocations());
+        if (!l.isPresent()) return Maybe.absent();
+        InetAddress addr = l.get().getAddress();
+        if (addr==null) return Maybe.absent();
+        return Maybe.fromNullable(addr.getHostName());
+    }
+
+    public static Maybe<String> findSubnetOrPrivateIp(Entity entity) {
+        // see comments in findSubnetOrPrivateHostname
+        String hn = entity.getAttribute(Attributes.ADDRESS);
+        if (hn!=null) {
+            Maybe<String> sn = findSubnetIp(entity);
+            if (sn.isPresent()) return sn;
+            return Maybe.of(hn);
+        }
+        
+        Maybe<MachineLocation> l = findUniqueMachineLocation(entity.getLocations());
+        if (!l.isPresent()) return Maybe.absent();
+        InetAddress addr = l.get().getAddress();
+        if (addr==null) return Maybe.absent();
+        return Maybe.fromNullable(addr.getHostAddress());
+    }
+
+    public static Maybe<String> findSubnetIp(Entity entity) {
+        String sh = entity.getAttribute(Attributes.SUBNET_ADDRESS);
+        if (sh!=null) return Maybe.of(sh);
+        return findSubnetIp(entity.getLocations());
+    }
+    
+    public static Maybe<String> findSubnetIp(Iterable<? extends Location> ll) {
+        // TODO Or if can't find MachineLocation, should we throw new IllegalStateException("Cannot find hostname for among "+ll);
+        Maybe<MachineLocation> l = findUniqueMachineLocation(ll);
+        return (l.isPresent()) ? Machines.getSubnetIp(l.get()) : Maybe.<String>absent();
+    }
+
+    /** returns whether it is localhost (and has warned) */
+    public static boolean warnIfLocalhost(Collection<? extends Location> locations, String message) {
+        if (locations.size()==1) {
+            Location l = locations.iterator().next();
+            if (l instanceof LocalhostMachineProvisioningLocation || l instanceof LocalhostMachine) {
+                log.warn(message);
+                return true;
+            }
+        }
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java
new file mode 100644
index 0000000..bbf45f0
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java
@@ -0,0 +1,167 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
+import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import brooklyn.util.collections.MutableList;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.CompoundRuntimeException;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.flags.SetFromFlag;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.reflect.TypeToken;
+
+/** A location which consists of multiple locations stitched together to form availability zones.
+ * The first location will be used by default, but if an {@link AvailabilityZoneExtension}-aware entity
+ * is used, it may stripe across each of the locations.  See notes at {@link AvailabilityZoneExtension}. */
+public class MultiLocation<T extends MachineLocation> extends AbstractLocation implements MachineProvisioningLocation<T> {
+
+    private static final long serialVersionUID = 7993091317970457862L;
+    
+    @SuppressWarnings("serial")
+    @SetFromFlag("subLocations")
+    public static final ConfigKey<List<MachineProvisioningLocation<?>>> SUB_LOCATIONS = ConfigKeys.newConfigKey(
+            new TypeToken<List<MachineProvisioningLocation<?>>>() {},
+            "subLocations", 
+            "The sub-machines that this location can delegate to");
+    
+    @Override
+    public void init() {
+        super.init();
+        List<MachineProvisioningLocation<?>> subLocs = getSubLocations();
+        checkState(subLocs.size() >= 1, "sub-locations must not be empty");
+        AvailabilityZoneExtension azExtension = new AvailabilityZoneExtensionImpl(getManagementContext(), subLocs);
+        addExtension(AvailabilityZoneExtension.class, azExtension);
+    }
+
+    public T obtain() throws NoMachinesAvailableException {
+        return obtain(MutableMap.of());
+    }
+    
+    /** finds (creates) and returns a {@link MachineLocation}; 
+     * this always tries the first sub-location, moving on the second and subsequent if the first throws {@link NoMachinesAvailableException}.
+     * (if you want striping across locations, see notes in {@link AvailabilityZoneExtension}.) */
+    @SuppressWarnings("unchecked")
+    @Override
+    public T obtain(Map<?, ?> flags) throws NoMachinesAvailableException {
+        List<MachineProvisioningLocation<?>> sublocsList = getSubLocations();
+        Iterator<MachineProvisioningLocation<?>> sublocs = sublocsList.iterator();
+        List<NoMachinesAvailableException> errors = MutableList.of();
+        while (sublocs.hasNext()) {
+            try {
+                return (T) sublocs.next().obtain(flags);
+            } catch (NoMachinesAvailableException e) {
+                errors.add(e);
+            }
+        }
+        Exception wrapped;
+        String msg;
+        if (errors.size()>1) {
+            wrapped = new CompoundRuntimeException(errors.size()+" sublocation exceptions, including: "+
+                Exceptions.collapseText(errors.get(0)), errors);
+            msg = Exceptions.collapseText(wrapped);
+        } else if (errors.size()==1) {
+            wrapped = errors.get(0);
+            msg = wrapped.getMessage();
+            if (Strings.isBlank(msg)) msg = wrapped.toString();
+        } else {
+            msg = "no sub-locations set for this multi-location";
+            wrapped = null;
+        }
+        throw new NoMachinesAvailableException("No machines available in any of the "+sublocsList.size()+" location"+Strings.s(sublocsList.size())+
+            " configured here: "+msg, wrapped);
+    }
+
+    public List<MachineProvisioningLocation<?>> getSubLocations() {
+        return getRequiredConfig(SUB_LOCATIONS);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public MachineProvisioningLocation<T> newSubLocation(Map<?, ?> newFlags) {
+        // TODO shouldn't have to copy config bag as it should be inherited (but currently it is not used inherited everywhere; just most places)
+        return getManagementContext().getLocationManager().createLocation(LocationSpec.create(getClass())
+                .parent(this)
+                .configure(config().getLocalBag().getAllConfig())  // FIXME Should this just be inherited?
+                .configure(newFlags));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public void release(T machine) {
+        ((MachineProvisioningLocation<T>)machine.getParent()).release(machine);
+    }
+
+    @Override
+    public Map<String, Object> getProvisioningFlags(Collection<String> tags) {
+        return Maps.<String,Object>newLinkedHashMap();
+    }
+
+    @SuppressWarnings("unchecked")
+    protected MachineProvisioningLocation<T> firstSubLoc() {
+        return (MachineProvisioningLocation<T>) Iterables.get(getSubLocations(), 0);
+    }
+
+    protected <K> K getRequiredConfig(ConfigKey<K> key) {
+        return checkNotNull(getConfig(key), key.getName());
+    }
+
+    public static class AvailabilityZoneExtensionImpl extends AbstractAvailabilityZoneExtension implements AvailabilityZoneExtension {
+
+        private final List<MachineProvisioningLocation<?>> subLocations;
+        
+        public AvailabilityZoneExtensionImpl(ManagementContext managementContext, List<MachineProvisioningLocation<?>> subLocations) {
+            super(managementContext);
+            this.subLocations = ImmutableList.copyOf(subLocations);
+        }
+        
+        @Override
+        protected List<Location> doGetAllSubLocations() {
+            return ImmutableList.<Location>copyOf(subLocations);
+        }
+        
+        @Override
+        protected boolean isNameMatch(Location loc, Predicate<? super String> namePredicate) {
+            return namePredicate.apply(loc.getDisplayName());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java
new file mode 100644
index 0000000..ac4b7b3
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java
@@ -0,0 +1,146 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+import org.apache.brooklyn.location.LocationSpec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.text.KeyValueParser;
+import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+
+import com.google.common.collect.Lists;
+
+public class MultiLocationResolver implements LocationResolver {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MultiLocationResolver.class);
+
+    private static final String MULTI = "multi";
+    
+    private static final Pattern PATTERN = Pattern.compile("(" + MULTI + "|" + MULTI.toUpperCase() + ")" + ":" + "\\((.*)\\)$");
+    
+    private volatile ManagementContext managementContext;
+
+    @Override
+    public void init(ManagementContext managementContext) {
+        this.managementContext = checkNotNull(managementContext, "managementContext");
+    }
+
+    @Override
+    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        // FIXME pass all flags into the location
+        
+        Map globalProperties = registry.getProperties();
+        Map<String,?> locationArgs;
+        if (spec.equalsIgnoreCase(MULTI)) {
+            locationArgs = MutableMap.copyOf(locationFlags);
+        } else {
+            Matcher matcher = PATTERN.matcher(spec);
+            if (!matcher.matches()) {
+                throw new IllegalArgumentException("Invalid location '" + spec + "'; must specify something like multi(targets=named:foo)");
+            }
+            String args = matcher.group(2);
+            // TODO we are ignoring locationFlags after this (apart from named), looking only at these args
+            locationArgs = KeyValueParser.parseMap(args);
+        }
+        String namedLocation = (String) locationFlags.get("named");
+
+        Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties().getLocationProperties(null, namedLocation, globalProperties);
+        MutableMap<String, Object> flags = MutableMap.<String, Object>builder()
+                .putAll(filteredProperties)
+                .putAll(locationFlags)
+                .removeAll("named")
+                .putAll(locationArgs).build();
+        
+        if (locationArgs.get("targets") == null) {
+            throw new IllegalArgumentException("target must be specified in single-machine spec");
+        }
+        
+        // TODO do we need to pass location flags etc into the children to ensure they are inherited?
+        List<Location> targets = Lists.newArrayList();
+        Object targetSpecs = locationArgs.remove("targets");
+        try {
+            if (targetSpecs instanceof String) {
+                for (String targetSpec : JavaStringEscapes.unwrapJsonishListIfPossible((String)targetSpecs)) {
+                    targets.add(managementContext.getLocationRegistry().resolve(targetSpec));
+                }
+            } else if (targetSpecs instanceof Iterable) {
+                for (Object targetSpec: (Iterable<?>)targetSpecs) {
+                    if (targetSpec instanceof String) {
+                        targets.add(managementContext.getLocationRegistry().resolve((String)targetSpec));
+                    } else {
+                        Set<?> keys = ((Map<?,?>)targetSpec).keySet();
+                        if (keys.size()!=1) 
+                            throw new IllegalArgumentException("targets supplied to MultiLocation must be a list of single-entry maps (got map of size "+keys.size()+": "+targetSpec+")");
+                        Object key = keys.iterator().next();
+                        Object flagsS = ((Map<?,?>)targetSpec).get(key);
+                        targets.add(managementContext.getLocationRegistry().resolve((String)key, (Map<?,?>)flagsS));
+                    }
+                }
+            } else throw new IllegalArgumentException("targets must be supplied to MultiLocation, either as string spec or list of single-entry maps each being a location spec");
+            
+            MultiLocation result = managementContext.getLocationManager().createLocation(LocationSpec.create(MultiLocation.class)
+                    .configure(flags)
+                    .configure("subLocations", targets)
+                    .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, locationFlags, globalProperties, namedLocation)));
+
+            // TODO Important workaround for BasicLocationRegistry.resolveForPeeking.
+            // That creates a location (from the resolver) and immediately unmanages it.
+            // The unmanage *must* remove all the targets created here; otherwise we have a leak.
+            // Adding the targets as children achieves this.
+            for (Location target : targets) {
+                target.setParent(result);
+            }
+            return result;
+
+        } catch (Exception e) {
+            // Must clean up after ourselves: don't leak sub-locations on error
+            if (LOG.isDebugEnabled()) LOG.debug("Problem resolving MultiLocation; cleaning up any sub-locations and rethrowing: "+e);
+            for (Location target : targets) {
+                Locations.unmanage(target);
+            }
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    @Override
+    public String getPrefix() {
+        return MULTI;
+    }
+
+    @Override
+    public boolean accepts(String spec, LocationRegistry registry) {
+        return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true);
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java
new file mode 100644
index 0000000..048c28c
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java
@@ -0,0 +1,97 @@
+/*
+ * 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.apache.brooklyn.location.basic;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.text.Strings;
+
+/**
+ * Allows you to say, in your brooklyn.properties:
+ * 
+ * brooklyn.location.named.foo=localhost
+ * brooklyn.location.named.foo.user=bob
+ * brooklyn.location.named.foo.privateKeyFile=~/.ssh/custom-key-for-bob
+ * brooklyn.location.named.foo.privateKeyPassphrase=WithAPassphrase
+ * <p>
+ * or
+ * <p>
+ * brooklyn.location.named.bob-aws-east=jclouds:aws-ec2:us-east-1
+ * brooklyn.location.named.bob-aws-east.identity=BobId
+ * brooklyn.location.named.bob-aws-east.credential=BobCred
+ * <p>
+ * then you can simply refer to:   foo   or   named:foo   (or bob-aws-east or named:bob-aws-east)   in any location spec
+ */
+public class NamedLocationResolver implements LocationResolver {
+
+    public static final Logger log = LoggerFactory.getLogger(NamedLocationResolver.class);
+
+    public static final String NAMED = "named";
+    
+    @SuppressWarnings("unused")
+    private ManagementContext managementContext;
+
+    @Override
+    public void init(ManagementContext managementContext) {
+        this.managementContext = checkNotNull(managementContext, "managementContext");
+    }
+    
+    @Override
+    @SuppressWarnings({ "rawtypes" })
+    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
+        String name = spec;
+        ConfigBag lfBag = ConfigBag.newInstance(locationFlags).putIfAbsent(LocationInternal.ORIGINAL_SPEC, name);
+        name = Strings.removeFromStart(spec, getPrefix()+":");
+        if (name.toLowerCase().startsWith(NAMED+":")) {
+            // since 0.7.0
+            log.warn("Deprecated use of 'named:' prefix with wrong case ("+spec+"); support may be removed in future versions");
+            name = spec.substring( (NAMED+":").length() );
+        }
+        
+        LocationDefinition ld = registry.getDefinedLocationByName(name);
+        if (ld==null) throw new NoSuchElementException("No named location defined matching '"+name+"'");
+        return ((BasicLocationRegistry)registry).resolveLocationDefinition(ld, lfBag.getAllConfig(), name);
+    }
+
+    @Override
+    public String getPrefix() {
+        return NAMED;
+    }
+    
+    /** accepts anything starting  named:xxx  or  xxx where xxx is a defined location name */
+    @Override
+    public boolean accepts(String spec, LocationRegistry registry) {
+        if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, false)) return true;
+        if (registry.getDefinedLocationByName(spec)!=null) return true;
+        return false;
+    }
+
+}



[27/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocationExtensionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocationExtensionsTest.java b/core/src/test/java/brooklyn/location/basic/LocationExtensionsTest.java
deleted file mode 100644
index 44e659f..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocationExtensionsTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class LocationExtensionsTest {
-
-    public static class ConcreteLocation extends AbstractLocation {
-        private static final long serialVersionUID = 2407231019435442876L;
-
-        public ConcreteLocation() {
-            super();
-        }
-    }
-
-    public interface MyExtension {
-    }
-    
-    public static class MyExtensionImpl implements MyExtension {
-    }
-    
-    private ManagementContext mgmt;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        mgmt = new LocalManagementContextForTests();
-    }
-    
-    @AfterMethod(alwaysRun = true)
-    public void tearDown(){
-        if (mgmt!=null) Entities.destroyAll(mgmt);
-    }
-
-    private ConcreteLocation createConcrete() {
-        return mgmt.getLocationManager().createLocation(LocationSpec.create(ConcreteLocation.class));
-    }
-    
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    private ConcreteLocation createConcrete(Class<?> extensionType, Object extension) {
-        // this cast is needed to make IntelliJ happy
-        return (ConcreteLocation) mgmt.getLocationManager().createLocation(LocationSpec.create(ConcreteLocation.class).extension((Class)extensionType, extension));
-    }
-    
-    @Test
-    public void testHasExtensionWhenMissing() {
-        Location loc = createConcrete();
-        assertFalse(loc.hasExtension(MyExtension.class));
-    }
-
-    @Test
-    public void testWhenExtensionPresent() {
-        MyExtension extension = new MyExtensionImpl();
-        ConcreteLocation loc = createConcrete();
-        loc.addExtension(MyExtension.class, extension);
-        
-        assertTrue(loc.hasExtension(MyExtension.class));
-        assertEquals(loc.getExtension(MyExtension.class), extension);
-    }
-
-    @Test
-    public void testAddExtensionThroughLocationSpec() {
-        MyExtension extension = new MyExtensionImpl();
-        Location loc = createConcrete(MyExtension.class, extension);
-        
-        assertTrue(loc.hasExtension(MyExtension.class));
-        assertEquals(loc.getExtension(MyExtension.class), extension);
-    }
-
-    @Test
-    public void testGetExtensionWhenMissing() {
-        Location loc = createConcrete();
-
-        try {
-            loc.getExtension(MyExtension.class);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-        
-        try {
-            loc.getExtension(null);
-            fail();
-        } catch (NullPointerException e) {
-            // success
-        }
-    }
-
-    @Test
-    public void testWhenExtensionDifferent() {
-        MyExtension extension = new MyExtensionImpl();
-        ConcreteLocation loc = createConcrete();
-        loc.addExtension(MyExtension.class, extension);
-        
-        assertFalse(loc.hasExtension(Object.class));
-        
-        try {
-            loc.getExtension(Object.class);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-    }
-
-    @Test
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public void testAddExtensionIllegally() {
-        MyExtension extension = new MyExtensionImpl();
-        ConcreteLocation loc = createConcrete();
-        
-        try {
-            loc.addExtension((Class)MyExtension.class, "not an extension");
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-        
-        try {
-            loc.addExtension(MyExtension.class, null);
-            fail();
-        } catch (NullPointerException e) {
-            // success
-        }
-        
-        try {
-            loc.addExtension(null, extension);
-            fail();
-        } catch (NullPointerException e) {
-            // success
-        }
-    }
-
-    @Test
-    public void testAddExtensionThroughLocationSpecIllegally() {
-        MyExtension extension = new MyExtensionImpl();
-        
-        try {
-            Location loc = createConcrete(MyExtension.class, "not an extension");
-            fail("loc="+loc);
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-        
-        try {
-            Location loc = createConcrete(MyExtension.class, null);
-            fail("loc="+loc);
-        } catch (NullPointerException e) {
-            // success
-        }
-        
-        try {
-            Location loc = createConcrete(null, extension);
-            fail("loc="+loc);
-        } catch (NullPointerException e) {
-            // success
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocationManagementTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocationManagementTest.java b/core/src/test/java/brooklyn/location/basic/LocationManagementTest.java
deleted file mode 100644
index 2a1faa5..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocationManagementTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-
-import org.apache.brooklyn.api.management.LocationManager;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.BrooklynAppUnitTestSupport;
-import brooklyn.location.LocationSpec;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public class LocationManagementTest extends BrooklynAppUnitTestSupport {
-
-    private LocationManager locationManager;
-
-    @BeforeMethod(alwaysRun=true)
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        locationManager = mgmt.getLocationManager();
-    }
-    
-    @Test
-    public void testCreateLocationUsingSpec() {
-        SshMachineLocation loc = locationManager.createLocation(LocationSpec.create(SshMachineLocation.class)
-                .configure("address", "1.2.3.4"));
-        
-        assertEquals(loc.getAddress().getHostAddress(), "1.2.3.4");
-        assertSame(locationManager.getLocation(loc.getId()), loc);
-    }
-    
-    @Test
-    public void testCreateLocationUsingResolver() {
-        String spec = "byon:(hosts=\"1.1.1.1\")";
-        FixedListMachineProvisioningLocation<SshMachineLocation> loc = (FixedListMachineProvisioningLocation<SshMachineLocation>) mgmt.getLocationRegistry().resolve(spec);
-        SshMachineLocation machine = Iterables.getOnlyElement(loc.getAllMachines());
-        
-        assertSame(locationManager.getLocation(loc.getId()), loc);
-        assertSame(locationManager.getLocation(machine.getId()), machine);
-    }
-    
-    @Test
-    public void testChildrenOfManagedLocationAutoManaged() {
-        String spec = "byon:(hosts=\"1.1.1.1\")";
-        FixedListMachineProvisioningLocation<SshMachineLocation> loc = (FixedListMachineProvisioningLocation<SshMachineLocation>) mgmt.getLocationRegistry().resolve(spec);
-        SshMachineLocation machine = new SshMachineLocation(ImmutableMap.of("address", "1.2.3.4"));
-
-        loc.addChild(machine);
-        assertSame(locationManager.getLocation(machine.getId()), machine);
-        assertTrue(machine.isManaged());
-        
-        loc.removeChild(machine);
-        assertNull(locationManager.getLocation(machine.getId()));
-        assertFalse(machine.isManaged());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocationPredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocationPredicatesTest.java b/core/src/test/java/brooklyn/location/basic/LocationPredicatesTest.java
deleted file mode 100644
index b9124ac..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocationPredicatesTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestEntity;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.management.internal.LocalManagementContext;
-
-public class LocationPredicatesTest {
-
-    private LocalManagementContext managementContext;
-    private LocalhostMachineProvisioningLocation loc;
-    private SshMachineLocation childLoc;
-    private Location grandchildLoc;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-        loc = (LocalhostMachineProvisioningLocation) managementContext.getLocationRegistry().resolve("localhost:(name=mydisplayname)");
-        childLoc = loc.obtain();
-        grandchildLoc = managementContext.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class).parent(childLoc));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testIdEqualTo() throws Exception {
-        assertTrue(LocationPredicates.idEqualTo(loc.getId()).apply(loc));
-        assertFalse(LocationPredicates.idEqualTo("wrongid").apply(loc));
-    }
-    
-    @Test
-    public void testConfigEqualTo() throws Exception {
-        loc.setConfig(TestEntity.CONF_NAME, "myname");
-        assertTrue(LocationPredicates.configEqualTo(TestEntity.CONF_NAME, "myname").apply(loc));
-        assertFalse(LocationPredicates.configEqualTo(TestEntity.CONF_NAME, "wrongname").apply(loc));
-    }
-    
-    @Test
-    public void testDisplayNameEqualTo() throws Exception {
-        assertTrue(LocationPredicates.displayNameEqualTo("mydisplayname").apply(loc));
-        assertFalse(LocationPredicates.displayNameEqualTo("wrongname").apply(loc));
-    }
-    
-    @Test
-    public void testIsChildOf() throws Exception {
-        assertTrue(LocationPredicates.isChildOf(loc).apply(childLoc));
-        assertFalse(LocationPredicates.isChildOf(loc).apply(loc));
-        assertFalse(LocationPredicates.isChildOf(childLoc).apply(loc));
-    }
-    
-    @Test
-    public void testIsDescendantOf() throws Exception {
-        assertTrue(LocationPredicates.isDescendantOf(loc).apply(grandchildLoc));
-        assertTrue(LocationPredicates.isDescendantOf(loc).apply(childLoc));
-        assertFalse(LocationPredicates.isDescendantOf(loc).apply(loc));
-        assertFalse(LocationPredicates.isDescendantOf(childLoc).apply(loc));
-    }
-    
-    @Test
-    public void testManaged() throws Exception {
-        // TODO get exception in LocalhostMachineProvisioningLocation.removeChild because childLoc is "in use";
-        // this happens from the call to unmanage(loc), which first unmanaged the children.
-        loc.release(childLoc);
-        
-        assertTrue(LocationPredicates.managed().apply(loc));
-        Locations.unmanage(loc);
-        assertFalse(LocationPredicates.managed().apply(loc));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocationPropertiesFromBrooklynPropertiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocationPropertiesFromBrooklynPropertiesTest.java b/core/src/test/java/brooklyn/location/basic/LocationPropertiesFromBrooklynPropertiesTest.java
deleted file mode 100644
index 03c7c7c..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocationPropertiesFromBrooklynPropertiesTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.Maps;
-
-public class LocationPropertiesFromBrooklynPropertiesTest {
-
-    private LocationPropertiesFromBrooklynProperties parser;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        parser = new LocationPropertiesFromBrooklynProperties();
-    }
-    
-    @Test
-    public void testExtractProviderProperties() throws Exception {
-        String provider = "myprovider";
-        String namedLocation = null;
-        
-        Map<String, String> properties = Maps.newLinkedHashMap();
-        
-        // prefer those in "named" over everything else
-        properties.put("brooklyn.location.myprovider.privateKeyFile", "privateKeyFile-inProviderSpecific");
-        properties.put("brooklyn.location.privateKeyFile", "privateKeyFile-inLocationGeneric");
-
-        // prefer location-generic if nothing else
-        properties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inLocationGeneric");
-        
-        Map<String, Object> conf = parser.getLocationProperties(provider, namedLocation, properties);
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inProviderSpecific");
-        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inLocationGeneric");
-    }
-
-    @Test
-    public void testExtractNamedLocationProperties() throws Exception {
-        String provider = "myprovider";
-        String namedLocation = "mynamed";
-        
-        Map<String, String> properties = Maps.newLinkedHashMap();
-        
-        properties.put("brooklyn.location.named.mynamed", "myprovider");
-        
-        // prefer those in "named" over everything else
-        properties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
-        properties.put("brooklyn.location.myprovider.privateKeyFile", "privateKeyFile-inProviderSpecific");
-        properties.put("brooklyn.location.privateKeyFile", "privateKeyFile-inGeneric");
-
-        // prefer those in provider-specific over generic
-        properties.put("brooklyn.location.myprovider.publicKeyFile", "publicKeyFile-inProviderSpecific");
-        properties.put("brooklyn.location.publicKeyFile", "publicKeyFile-inGeneric");
-
-        // prefer location-generic if nothing else
-        properties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
-
-        Map<String, Object> conf = parser.getLocationProperties(provider, namedLocation, properties);
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
-        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
-        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
-    }
-
-    @Test
-    public void testConvertsDeprecatedFormats() throws Exception {
-        String provider = "myprovider";
-        String namedLocation = "mynamed";
-        
-        Map<String, String> properties = Maps.newLinkedHashMap();
-        
-        properties.put("brooklyn.location.named.mynamed", "myprovider");
-        
-        // prefer those in "named" over everything else
-        properties.put("brooklyn.location.named.mynamed.private-key-file", "privateKeyFile-inNamed");
-        properties.put("brooklyn.location.myprovider.public-key-file", "publicKeyFile-inProviderSpecific");
-        properties.put("brooklyn.location.private-key-data", "privateKeyData-inGeneric");
-
-        Map<String, Object> conf = parser.getLocationProperties(provider, namedLocation, properties);
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
-        assertEquals(conf.get("publicKeyFile"), "publicKeyFile-inProviderSpecific");
-        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
-    }
-    
-
-    @Test
-    public void testThrowsIfProviderDoesNotMatchNamed() throws Exception {
-        String provider = "myprovider";
-        String namedLocation = "mynamed";
-        
-        Map<String, String> properties = Maps.newLinkedHashMap();
-        
-        properties.put("brooklyn.location.named.mynamed", "completelydifferent");
-
-        try {
-            Map<String, Object> conf = parser.getLocationProperties(provider, namedLocation, properties);
-        } catch (IllegalStateException e) {
-            if (!e.toString().contains("Conflicting configuration")) throw e;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/LocationRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/LocationRegistryTest.java b/core/src/test/java/brooklyn/location/basic/LocationRegistryTest.java
deleted file mode 100644
index 6d718fe..0000000
--- a/core/src/test/java/brooklyn/location/basic/LocationRegistryTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.management.internal.LocalManagementContext;
-
-public class LocationRegistryTest {
-    
-    private static final Logger log = LoggerFactory.getLogger(LocationRegistryTest.class);
-    
-    private LocalManagementContext mgmt;
-    private LocationDefinition locdef;
-
-    @AfterMethod(alwaysRun = true)
-    public void tearDown(){
-        if (mgmt != null) Entities.destroyAll(mgmt);
-    }
-
-    @Test
-    public void testNamedLocationsPropertyDefinedLocations() {
-        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
-        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
-        properties.put("brooklyn.location.named.foo.privateKeyFile", "~/.ssh/foo.id_rsa");
-        mgmt = LocalManagementContextForTests.newInstance(properties);
-        log.info("foo properties gave defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
-        locdef = mgmt.getLocationRegistry().getDefinedLocationByName("foo");
-        Assert.assertNotNull(locdef, "Expected 'foo' location; but had "+mgmt.getLocationRegistry().getDefinedLocations());
-        Assert.assertEquals(locdef.getConfig().get("privateKeyFile"), "~/.ssh/foo.id_rsa");
-    }
-    
-    @Test(dependsOnMethods="testNamedLocationsPropertyDefinedLocations")
-    public void testResolvesByNamedAndId() {
-        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
-        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
-        properties.put("brooklyn.location.named.foo.privateKeyFile", "~/.ssh/foo.id_rsa");
-        mgmt = LocalManagementContextForTests.newInstance(properties);
-
-        locdef = mgmt.getLocationRegistry().getDefinedLocationByName("foo");
-        log.info("testResovlesBy has defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
-        
-        Location l = mgmt.getLocationRegistry().resolve("named:foo");
-        Assert.assertNotNull(l);
-        Assert.assertEquals(l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), "~/.ssh/foo.id_rsa");
-        
-        l = mgmt.getLocationRegistry().resolve("foo");
-        Assert.assertNotNull(l);
-        Assert.assertEquals(l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), "~/.ssh/foo.id_rsa");
-        
-        l = mgmt.getLocationRegistry().resolve("id:"+locdef.getId());
-        Assert.assertNotNull(l);
-        Assert.assertEquals(l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), "~/.ssh/foo.id_rsa");
-        
-        l = mgmt.getLocationRegistry().resolve(locdef.getId());
-        Assert.assertNotNull(l);
-        Assert.assertEquals(l.getConfig(LocationConfigKeys.PRIVATE_KEY_FILE), "~/.ssh/foo.id_rsa");
-    }
-
-    @Test
-    public void testLocationGetsDisplayName() {
-        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
-        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
-        properties.put("brooklyn.location.named.foo.displayName", "My Foo");
-        mgmt = LocalManagementContextForTests.newInstance(properties);
-        Location l = mgmt.getLocationRegistry().resolve("foo");
-        Assert.assertEquals(l.getDisplayName(), "My Foo");
-    }
-    
-    @Test
-    public void testLocationGetsDefaultDisplayName() {
-        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
-        properties.put("brooklyn.location.named.foo", "byon:(hosts=\"root@192.168.1.{1,2,3,4}\")");
-        mgmt = LocalManagementContextForTests.newInstance(properties);
-        Location l = mgmt.getLocationRegistry().resolve("foo");
-        Assert.assertNotNull(l.getDisplayName());
-        Assert.assertTrue(l.getDisplayName().startsWith(FixedListMachineProvisioningLocation.class.getSimpleName()), "name="+l.getDisplayName());
-        // TODO currently it gives default name; it would be nice to use 'foo', 
-        // or at least to have access to the spec (and use it e.g. in places such as DynamicFabric)
-        // Assert.assertEquals(l.getDisplayName(), "foo");
-    }
-    
-    @Test
-    public void testSetupForTesting() {
-        mgmt = LocalManagementContextForTests.newInstance();
-        BasicLocationRegistry.setupLocationRegistryForTesting(mgmt);
-        Assert.assertNotNull(mgmt.getLocationRegistry().getDefinedLocationByName("localhost"));
-    }
-
-    @Test
-    public void testCircularReference() {
-        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
-        properties.put("brooklyn.location.named.bar", "named:bar");
-        mgmt = LocalManagementContextForTests.newInstance(properties);
-        log.info("bar properties gave defined locations: "+mgmt.getLocationRegistry().getDefinedLocations());
-        boolean resolved = false;
-        try {
-            mgmt.getLocationRegistry().resolve("bar");
-            resolved = true;
-        } catch (IllegalStateException e) {
-            //expected
-            log.info("bar properties correctly caught circular reference: "+e);
-        }
-        if (resolved)
-            // probably won't happen, if test fails will loop endlessly above
-            Assert.fail("Circular reference resolved location");
-    }
-
-    protected boolean findLocationMatching(String regex) {
-        for (LocationDefinition d: mgmt.getLocationRegistry().getDefinedLocations().values()) {
-            if (d.getName()!=null && d.getName().matches(regex)) return true;
-        }
-        return false;
-    }
-    
-    @Test
-    public void testLocalhostEnabled() {
-        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
-        properties.put("brooklyn.location.localhost.enabled", true);
-        mgmt = LocalManagementContextForTests.newInstance(properties);
-        Assert.assertTrue( findLocationMatching("localhost") );
-    }
-
-    @Test
-    public void testLocalhostDisabled() {
-        BrooklynProperties properties = BrooklynProperties.Factory.newEmpty();
-        properties.put("brooklyn.location.localhost.enabled", false);
-        mgmt = LocalManagementContextForTests.newInstance(properties);
-        log.info("RESOLVERS: "+mgmt.getLocationRegistry().getDefinedLocations());
-        log.info("DEFINED LOCATIONS: "+mgmt.getLocationRegistry().getDefinedLocations());
-        Assert.assertFalse( findLocationMatching("localhost") );
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/MachineDetailsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/MachineDetailsTest.java b/core/src/test/java/brooklyn/location/basic/MachineDetailsTest.java
deleted file mode 100644
index 4041d1e..0000000
--- a/core/src/test/java/brooklyn/location/basic/MachineDetailsTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-
-import java.util.Arrays;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.OsDetails;
-
-public class MachineDetailsTest {
-
-    private static final Logger LOG = LoggerFactory.getLogger(SshMachineLocationTest.class);
-
-    TestApplication app;
-    ManagementContext mgmt;
-    SshMachineLocation host;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setup() throws Exception {
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        mgmt = app.getManagementContext();
-
-        LocalhostMachineProvisioningLocation localhost = mgmt.getLocationManager().createLocation(
-                LocationSpec.create(LocalhostMachineProvisioningLocation.class));
-        host = localhost.obtain();
-        app.start(Arrays.asList(host));
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (mgmt != null) Entities.destroyAll(mgmt);
-        mgmt = null;
-    }
-
-    @Test(groups = "Integration")
-    public void testGetMachineDetails() {
-        Task<BasicMachineDetails> detailsTask = app.getExecutionContext().submit(
-                BasicMachineDetails.taskForSshMachineLocation(host));
-        MachineDetails machine = detailsTask.getUnchecked();
-        LOG.info("Found the following on localhost: {}", machine);
-        assertNotNull(machine);
-        OsDetails details = machine.getOsDetails();
-        assertNotNull(details);
-        assertNotNull(details.getArch());
-        assertNotNull(details.getName());
-        assertNotNull(details.getVersion());
-        assertFalse(details.getArch().startsWith("architecture:"), "architecture prefix not removed from details");
-        assertFalse(details.getName().startsWith("name:"), "name prefix not removed from details");
-        assertFalse(details.getVersion().startsWith("version:"), "version prefix not removed from details");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/MultiLocationRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/MultiLocationRebindTest.java b/core/src/test/java/brooklyn/location/basic/MultiLocationRebindTest.java
deleted file mode 100644
index 440405c..0000000
--- a/core/src/test/java/brooklyn/location/basic/MultiLocationRebindTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.io.File;
-import java.util.List;
-
-import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.rebind.RebindTestUtils;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.cloud.AvailabilityZoneExtension;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.net.Networking;
-import brooklyn.util.os.Os;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-public class MultiLocationRebindTest {
-
-    private ClassLoader classLoader = getClass().getClassLoader();
-    private ManagementContext origManagementContext;
-    private ManagementContext newManagementContext;
-    private File mementoDir;
-    
-    private TestApplication origApp;
-    private TestApplication newApp;
-    private SshMachineLocation mac1a;
-    private SshMachineLocation mac2a;
-    private FixedListMachineProvisioningLocation<SshMachineLocation> loc1;
-    private FixedListMachineProvisioningLocation<SshMachineLocation> loc2;
-    private MultiLocation<SshMachineLocation> multiLoc;
-    
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        mementoDir = Os.newTempDir(getClass());
-        origManagementContext = RebindTestUtils.newPersistingManagementContext(mementoDir, classLoader, 1);
-        origApp = ApplicationBuilder.newManagedApp(EntitySpec.create(TestApplication.class), origManagementContext);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (origManagementContext != null) Entities.destroyAll(origManagementContext);
-        if (newApp != null) Entities.destroyAll(newApp.getManagementContext());
-        if (newManagementContext != null) Entities.destroyAll(newManagementContext);
-        if (mementoDir != null) RebindTestUtils.deleteMementoDir(mementoDir);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testRebindsMultiLocation() throws Exception {
-        mac1a = origManagementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .displayName("mac1a")
-                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.1")));
-        mac2a = origManagementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .displayName("mac2a")
-                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.3")));
-        loc1 = origManagementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .displayName("loc1")
-                .configure("machines", MutableSet.of(mac1a)));
-        loc2 = origManagementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .displayName("loc2")
-                .configure("machines", MutableSet.of(mac2a)));
-        multiLoc = origManagementContext.getLocationManager().createLocation(LocationSpec.create(MultiLocation.class)
-                        .displayName("multiLoc")
-                        .configure("subLocations", ImmutableList.of(loc1, loc2)));
-        
-        newApp = rebind();
-        newManagementContext = newApp.getManagementContext();
-        
-        MultiLocation newMultiLoc = (MultiLocation) Iterables.find(newManagementContext.getLocationManager().getLocations(), Predicates.instanceOf(MultiLocation.class));
-        AvailabilityZoneExtension azExtension = newMultiLoc.getExtension(AvailabilityZoneExtension.class);
-        List<Location> newSublLocs = azExtension.getAllSubLocations();
-        Iterable<String> newSubLocNames = Iterables.transform(newSublLocs, new Function<Location, String>() {
-            @Override public String apply(Location input) {
-                return (input == null) ? null : input.getDisplayName();
-            }});
-        Asserts.assertEqualsIgnoringOrder(newSubLocNames, ImmutableList.of("loc1", "loc2"));
-    }
-    
-    private TestApplication rebind() throws Exception {
-        return rebind(true);
-    }
-    
-    private TestApplication rebind(boolean checkSerializable) throws Exception {
-        RebindTestUtils.waitForPersisted(origApp);
-        if (checkSerializable) {
-            RebindTestUtils.checkCurrentMementoSerializable(origApp);
-        }
-        return (TestApplication) RebindTestUtils.rebind(mementoDir, getClass().getClassLoader());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/MultiLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/MultiLocationResolverTest.java b/core/src/test/java/brooklyn/location/basic/MultiLocationResolverTest.java
deleted file mode 100644
index c4ff215..0000000
--- a/core/src/test/java/brooklyn/location/basic/MultiLocationResolverTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.net.InetAddress;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.cloud.AvailabilityZoneExtension;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.exceptions.Exceptions;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public class MultiLocationResolverTest {
-
-    private BrooklynProperties brooklynProperties;
-    private LocalManagementContext managementContext;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-        brooklynProperties = managementContext.getBrooklynProperties();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testThrowsOnInvalid() throws Exception {
-        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
-        assertThrowsIllegalArgument("single");
-    }
-    
-    @Test
-    public void testThrowsOnInvalidTarget() throws Exception {
-        assertThrowsIllegalArgument("multi:()");
-        assertThrowsIllegalArgument("multi:(wrongprefix:(hosts=\"1.1.1.1\"))");
-        assertThrowsIllegalArgument("multi:(foo:bar)");
-    }
-
-    @Test
-    public void testCleansUpOnInvalidTarget() {
-        assertThrowsNoSuchElement("multi:(targets=\"localhost:(name=testCleansUpOnInvalidTarget),thisNamedLocationDoesNotExist\")");
-        Optional<Location> subtarget = Iterables.tryFind(managementContext.getLocationManager().getLocations(), LocationPredicates.displayNameEqualTo("testCleansUpOnInvalidTarget"));
-        assertFalse(subtarget.isPresent(), "subtarget="+subtarget);
-    }
-
-
-    @Test
-    public void testResolvesSubLocs() {
-        assertMultiLocation(resolve("multi:(targets=localhost)"), 1, ImmutableList.of(Predicates.instanceOf(LocalhostMachineProvisioningLocation.class)));
-        assertMultiLocation(resolve("multi:(targets=\"localhost,localhost\")"), 2, Collections.nCopies(2, Predicates.instanceOf(LocalhostMachineProvisioningLocation.class)));
-        assertMultiLocation(resolve("multi:(targets=\"localhost,localhost,localhost\")"), 3, Collections.nCopies(3, Predicates.instanceOf(LocalhostMachineProvisioningLocation.class)));
-        assertMultiLocation(resolve("multi:(targets=\"localhost:(name=mysubname)\")"), 1, ImmutableList.of(displayNameEqualTo("mysubname")));
-        assertMultiLocation(resolve("multi:(targets=byon:(hosts=\"1.1.1.1\"))"), 1, ImmutableList.of(Predicates.and(
-                Predicates.instanceOf(FixedListMachineProvisioningLocation.class),
-                new Predicate<MachineProvisioningLocation>() {
-                    @Override public boolean apply(MachineProvisioningLocation input) {
-                        SshMachineLocation machine;
-                        try {
-                            machine = (SshMachineLocation) input.obtain(ImmutableMap.of());
-                        } catch (NoMachinesAvailableException e) {
-                            throw Exceptions.propagate(e);
-                        }
-                        try {
-                            String addr = ((SshMachineLocation)machine).getAddress().getHostAddress();
-                            return addr != null && addr.equals("1.1.1.1");
-                        } finally {
-                            input.release(machine);
-                        }
-                    }
-                })));
-        assertMultiLocation(resolve("multi:(targets=\"byon:(hosts=1.1.1.1),byon:(hosts=1.1.1.2)\")"), 2, Collections.nCopies(2, Predicates.instanceOf(FixedListMachineProvisioningLocation.class)));
-    }
-
-    @Test
-    public void testResolvesName() {
-        MultiLocation<SshMachineLocation> multiLoc = resolve("multi:(name=myname,targets=localhost)");
-        assertEquals(multiLoc.getDisplayName(), "myname");
-    }
-    
-    @Test
-    public void testNamedByonLocation() throws Exception {
-        brooklynProperties.put("brooklyn.location.named.mynamed", "multi:(targets=byon:(hosts=\"1.1.1.1\"))");
-        
-        MultiLocation<SshMachineLocation> loc = resolve("named:mynamed");
-        assertEquals(loc.obtain(ImmutableMap.of()).getAddress(), InetAddress.getByName("1.1.1.1"));
-    }
-
-    @Test
-    public void testResolvesFromMap() throws NoMachinesAvailableException {
-        Location l = managementContext.getLocationRegistry().resolve("multi", MutableMap.of("targets", 
-            MutableList.of("localhost", MutableMap.of("byon", MutableMap.of("hosts", "127.0.0.127")))));
-        MultiLocation<?> ml = (MultiLocation<?>)l;
-        Iterator<MachineProvisioningLocation<?>> ci = ml.getSubLocations().iterator();
-        
-        l = ci.next();
-        Assert.assertTrue(l instanceof LocalhostMachineProvisioningLocation, "Expected localhost, got "+l);
-        
-        l = ci.next();
-        Assert.assertTrue(l instanceof FixedListMachineProvisioningLocation, "Expected fixed, got "+l);
-        MachineLocation sl = ((FixedListMachineProvisioningLocation<?>)l).obtain();
-        Assert.assertEquals(sl.getAddress().getHostAddress(), "127.0.0.127");
-        
-        Assert.assertFalse(ci.hasNext());
-    }
-
-
-    private void assertThrowsNoSuchElement(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (NoSuchElementException e) {
-            // success
-        }
-    }
-    
-    private void assertThrowsIllegalArgument(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-    }
-    
-    @SuppressWarnings("unchecked")
-    private MultiLocation<SshMachineLocation> resolve(String val) {
-        return (MultiLocation<SshMachineLocation>) managementContext.getLocationRegistry().resolve(val);
-    }
-    
-    @SuppressWarnings("rawtypes")
-    private void assertMultiLocation(MultiLocation<?> multiLoc, int expectedSize, List<? extends Predicate> expectedSubLocationPredicates) {
-        AvailabilityZoneExtension zones = multiLoc.getExtension(AvailabilityZoneExtension.class);
-        List<Location> subLocs = zones.getAllSubLocations();
-        assertEquals(subLocs.size(), expectedSize, "zones="+subLocs);
-        for (int i = 0; i < subLocs.size(); i++) {
-            MachineProvisioningLocation subLoc = (MachineProvisioningLocation) subLocs.get(i);
-            assertTrue(expectedSubLocationPredicates.get(i).apply(subLoc), "index="+i+"; subLocs="+subLocs);
-        }
-    }
-    
-    public static <T> Predicate<Location> displayNameEqualTo(final T val) {
-        return new Predicate<Location>() {
-            @Override
-            public boolean apply(@Nullable Location input) {
-                return Objects.equal(input.getDisplayName(), val);
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/MultiLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/MultiLocationTest.java b/core/src/test/java/brooklyn/location/basic/MultiLocationTest.java
deleted file mode 100644
index f4cf2cd..0000000
--- a/core/src/test/java/brooklyn/location/basic/MultiLocationTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertTrue;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.cloud.AvailabilityZoneExtension;
-import brooklyn.management.internal.LocalManagementContext;
-import brooklyn.test.Asserts;
-import brooklyn.util.collections.MutableSet;
-import brooklyn.util.net.Networking;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class MultiLocationTest {
-
-    private static final Logger log = LoggerFactory.getLogger(MultiLocationTest.class);
-    
-    private LocalManagementContext managementContext;
-    private SshMachineLocation mac1a;
-    private SshMachineLocation mac1b;
-    private SshMachineLocation mac2a;
-    private SshMachineLocation mac2b;
-    private FixedListMachineProvisioningLocation<SshMachineLocation> loc1;
-    private FixedListMachineProvisioningLocation<SshMachineLocation> loc2;
-    private MultiLocation<SshMachineLocation> multiLoc;
-    
-    @SuppressWarnings("unchecked")
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-        mac1a = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .displayName("mac1a")
-                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.1")));
-        mac1b = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .displayName("mac1b")
-                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.2")));
-        mac2a = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .displayName("mac2a")
-                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.3")));
-        mac2b = managementContext.getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
-                .displayName("mac2b")
-                .configure("address", Networking.getInetAddressWithFixedName("1.1.1.4")));
-        loc1 = managementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .displayName("loc1")
-                .configure("machines", MutableSet.of(mac1a, mac1b)));
-        loc2 = managementContext.getLocationManager().createLocation(LocationSpec.create(FixedListMachineProvisioningLocation.class)
-                .displayName("loc2")
-                .configure("machines", MutableSet.of(mac2a, mac2b)));
-        multiLoc = managementContext.getLocationManager().createLocation(LocationSpec.create(MultiLocation.class)
-                        .displayName("multiLoc")
-                        .configure("subLocations", ImmutableList.of(loc1, loc2)));
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testHasAvailabilityZonesAsSubLocations() throws Exception {
-        multiLoc.hasExtension(AvailabilityZoneExtension.class);
-        AvailabilityZoneExtension extension = multiLoc.getExtension(AvailabilityZoneExtension.class);
-        Asserts.assertEqualsIgnoringOrder(extension.getAllSubLocations(), ImmutableList.of(loc1, loc2));
-        Asserts.assertEqualsIgnoringOrder(extension.getSubLocations(2), ImmutableList.of(loc1, loc2));
-        assertTrue(ImmutableList.of(loc1, loc2).containsAll(extension.getSubLocations(1)));
-    }
-    
-    @Test
-    public void testObtainAndReleaseDelegateToSubLocation() throws Exception {
-        SshMachineLocation obtained = multiLoc.obtain(ImmutableMap.of());
-        assertTrue(ImmutableList.of(mac1a, mac1b, mac2a, mac2b).contains(obtained));
-        multiLoc.release(obtained);
-    }
-    
-    @Test
-    public void testObtainsMovesThroughSubLocations() throws Exception {
-        Assert.assertEquals(multiLoc.obtain().getAddress().getHostAddress(), "1.1.1.1");
-        Assert.assertEquals(multiLoc.obtain().getAddress().getHostAddress(), "1.1.1.2");
-        Assert.assertEquals(multiLoc.obtain().getAddress().getHostAddress(), "1.1.1.3");
-        Assert.assertEquals(multiLoc.obtain().getAddress().getHostAddress(), "1.1.1.4");
-        try {
-            multiLoc.obtain();
-            Assert.fail();
-        } catch (NoMachinesAvailableException e) {
-            log.info("Error when no machines available across locations is: "+e);
-            Assert.assertTrue(e.toString().contains("loc1"), "Message should have referred to sub-location message: "+e);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/PaasLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/PaasLocationTest.java b/core/src/test/java/brooklyn/location/basic/PaasLocationTest.java
deleted file mode 100644
index e9eb457..0000000
--- a/core/src/test/java/brooklyn/location/basic/PaasLocationTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import brooklyn.location.paas.PaasLocation;
-import brooklyn.test.location.TestPaasLocation;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-public class PaasLocationTest {
-
-    private PaasLocation location;
-    
-    @Test
-    public void testProviderName(){
-        location = new TestPaasLocation();
-        Assert.assertEquals(location.getPaasProviderName(), "TestPaas");
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/PortRangesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/PortRangesTest.java b/core/src/test/java/brooklyn/location/basic/PortRangesTest.java
deleted file mode 100644
index 506628b..0000000
--- a/core/src/test/java/brooklyn/location/basic/PortRangesTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.Iterator;
-
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.PortRanges.LinearPortRange;
-import brooklyn.util.flags.TypeCoercions;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-public class PortRangesTest {
-
-    @Test
-    public void testSingleRange() {
-        PortRange r = PortRanges.fromInteger(1234);
-        assertContents(r, 1234);
-    }
-
-    @Test
-    public void testFromCollection() {
-        PortRange r = PortRanges.fromCollection(ImmutableList.of(1234, 2345));
-        assertContents(r, 1234, 2345);
-    }
-
-    @Test
-    public void testFromString() {
-        PortRange r = PortRanges.fromString("80,8080,8000,8080-8099");
-        assertContents(r, 80, 8080, 8000, 
-                8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089,
-                8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099);
-    }
-
-    @Test
-    public void testFromStringWithSpaces() {
-        PortRange r = PortRanges.fromString(" 80 , 8080  , 8000 , 8080  - 8099 ");
-        assertContents(r, 80, 8080, 8000, 
-                8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089,
-                8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099);
-    }
-
-    @Test
-    public void testFromStringWithSpacesToString() {
-        PortRange r = PortRanges.fromString(" 80 , 8080  , 8000 , 8080  - 8099 ");
-        Assert.assertEquals(r.toString(), "80,8080,8000,8080-8099");
-    }
-    
-    @Test
-    public void testFromStringThrowsIllegalArgumentException() {
-        assertFromStringThrowsIllegalArgumentException("80-100000");
-        assertFromStringThrowsIllegalArgumentException("0-80");
-    }
-
-    @Test
-    public void testCoercion() {
-        PortRanges.init();
-        PortRange r = TypeCoercions.coerce("80", PortRange.class);
-        assertContents(r, 80);
-    }
-
-    @Test
-    public void testCoercionInt() {
-        PortRanges.init();
-        PortRange r = TypeCoercions.coerce(80, PortRange.class);
-        assertContents(r, 80);
-    }
-    
-    @Test
-    public void testLinearRangeOfSizeOne() throws Exception {
-        LinearPortRange range = new LinearPortRange(80, 80);
-        assertEquals(Lists.newArrayList(range), ImmutableList.of(80));
-    }
-
-    @Test
-    public void testLinearRangeCountingUpwards() throws Exception {
-        LinearPortRange range = new LinearPortRange(80, 81);
-        assertEquals(Lists.newArrayList(range), ImmutableList.of(80, 81));
-    }
-    
-    @Test
-    public void testLinearRangeCountingDownwards() throws Exception {
-        LinearPortRange range = new LinearPortRange(80, 79);
-        assertEquals(Lists.newArrayList(range), ImmutableList.of(80, 79));
-    }
-    
-    protected void assertFromStringThrowsIllegalArgumentException(String range) {
-        try {
-            PortRanges.fromString(range);
-            Assert.fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-    }
-
-    private static <T> void assertContents(Iterable<T> actual, T ...expected) {
-        Iterator<T> i = actual.iterator();
-        int c = 0;
-        while (i.hasNext()) {
-            if (expected.length<=c) {
-                Assert.fail("Iterable contained more than the "+c+" expected elements");
-            }
-            Assert.assertEquals(i.next(), expected[c++]);
-        }
-        if (expected.length>c) {
-            Assert.fail("Iterable contained only "+c+" elements, "+expected.length+" expected");
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/RecordingMachineLocationCustomizer.java b/core/src/test/java/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
deleted file mode 100644
index 0422b36..0000000
--- a/core/src/test/java/brooklyn/location/basic/RecordingMachineLocationCustomizer.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineLocationCustomizer;
-
-public class RecordingMachineLocationCustomizer implements MachineLocationCustomizer {
-    public static class Call {
-        public final String methodName;
-        public final List<?> args;
-        
-        Call(String methodName, List<?> args) {
-            this.methodName = checkNotNull(methodName);
-            this.args = checkNotNull(args);
-        }
-        
-        @Override
-        public String toString() {
-            return methodName+args;
-        }
-        
-        @Override
-        public int hashCode() {
-            return Objects.hashCode(methodName, args);
-        }
-        
-        @Override
-        public boolean equals(Object other) {
-            return (other instanceof RecordingMachineLocationCustomizer.Call) && 
-                    methodName.equals(((RecordingMachineLocationCustomizer.Call)other).methodName) && 
-                    args.equals(((RecordingMachineLocationCustomizer.Call)other).args);
-        }
-    }
-    
-    public final List<RecordingMachineLocationCustomizer.Call> calls = Lists.newCopyOnWriteArrayList();
-    
-    @Override
-    public void customize(MachineLocation machine) {
-        calls.add(new Call("customize", ImmutableList.of(machine)));
-    }
-
-    @Override
-    public void preRelease(MachineLocation machine) {
-        calls.add(new Call("preRelease", ImmutableList.of(machine)));
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/SimulatedLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/SimulatedLocation.java b/core/src/test/java/brooklyn/location/basic/SimulatedLocation.java
deleted file mode 100644
index 83d5455..0000000
--- a/core/src/test/java/brooklyn/location/basic/SimulatedLocation.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.net.InetAddress;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import brooklyn.location.HardwareDetails;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.MachineDetails;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.OsDetails;
-import brooklyn.location.PortRange;
-import brooklyn.location.PortSupplier;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.net.Networking;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-
-
-/** Location for use in dev/test, defining custom start/stop support, and/or tweaking the ports which are permitted to be available
- * (using setPermittedPorts(Iterable))
- */
-public class SimulatedLocation extends AbstractLocation implements MachineProvisioningLocation<MachineLocation>, MachineLocation, PortSupplier {
-
-    private static final long serialVersionUID = 1L;
-    
-    private static final InetAddress address;
-    static {
-        address = Networking.getLocalHost();
-    }
-
-    Iterable<Integer> permittedPorts = PortRanges.fromString("1+");
-    Set<Integer> usedPorts = Sets.newLinkedHashSet();
-
-    public SimulatedLocation() {
-        this(MutableMap.<String,Object>of());
-    }
-    public SimulatedLocation(Map<String,? extends Object> flags) {
-        super(flags);
-    }
-    
-    @Override
-    public SimulatedLocation newSubLocation(Map<?,?> newFlags) {
-        // TODO shouldn't have to copy config bag as it should be inherited (but currently it is not used inherited everywhere; just most places)
-        return getManagementContext().getLocationManager().createLocation(LocationSpec.create(getClass())
-                .parent(this)
-                .configure(config().getLocalBag().getAllConfig())  // FIXME Should this just be inherited?
-                .configure(newFlags));
-    }
-
-    public MachineLocation obtain(Map<?,?> flags) {
-        return this;
-    }
-
-    public void release(MachineLocation machine) {
-    }
-
-    public Map<String,Object> getProvisioningFlags(Collection<String> tags) {
-        return MutableMap.<String,Object>of();
-    }
-    
-    public InetAddress getAddress() {
-        return address;
-    }
-
-    @Override
-    public String getHostname() {
-        String hostname = address.getHostName();
-        return (hostname == null || hostname.equals(address.getHostAddress())) ? null : hostname;
-    }
-    
-    @Override
-    public Set<String> getPublicAddresses() {
-        return ImmutableSet.of(address.getHostAddress());
-    }
-    
-    @Override
-    public Set<String> getPrivateAddresses() {
-        return ImmutableSet.of();
-    }
-
-    public synchronized boolean obtainSpecificPort(int portNumber) {
-        if (!Iterables.contains(permittedPorts, portNumber)) return false;
-        if (usedPorts.contains(portNumber)) return false;
-        usedPorts.add(portNumber);
-        return true;
-    }
-
-    public synchronized int obtainPort(PortRange range) {
-        for (int p: range)
-            if (obtainSpecificPort(p)) return p;
-        return -1;
-    }
-
-    public synchronized void releasePort(int portNumber) {
-        usedPorts.remove(portNumber);
-    }
-    
-    public synchronized void setPermittedPorts(Iterable<Integer> ports) {
-        permittedPorts  = ports;
-    }
-
-    @Override
-    public OsDetails getOsDetails() {
-        return getMachineDetails().getOsDetails();
-    }
-
-    @Override
-    public MachineDetails getMachineDetails() {
-        HardwareDetails hardwareDetails = new BasicHardwareDetails(null, null);
-        OsDetails osDetails = BasicOsDetails.Factory.ANONYMOUS_LINUX;
-        return new BasicMachineDetails(hardwareDetails, osDetails);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/SingleMachineLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/SingleMachineLocationResolverTest.java b/core/src/test/java/brooklyn/location/basic/SingleMachineLocationResolverTest.java
deleted file mode 100644
index 496b7d3..0000000
--- a/core/src/test/java/brooklyn/location/basic/SingleMachineLocationResolverTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-import java.net.InetAddress;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.config.BrooklynProperties;
-import brooklyn.entity.basic.Entities;
-import brooklyn.management.internal.LocalManagementContext;
-
-import com.google.common.collect.ImmutableMap;
-
-public class SingleMachineLocationResolverTest {
-
-    private BrooklynProperties brooklynProperties;
-    private LocalManagementContext managementContext;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-        brooklynProperties = managementContext.getBrooklynProperties();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) Entities.destroyAll(managementContext);
-    }
-    
-    @Test
-    public void testThrowsOnInvalid() throws Exception {
-        assertThrowsNoSuchElement("wrongprefix:(hosts=\"1.1.1.1\")");
-        assertThrowsIllegalArgument("single");
-    }
-    
-    @Test
-    public void testThrowsOnInvalidTarget() throws Exception {
-        assertThrowsIllegalArgument("single()");
-        assertThrowsIllegalArgument("single(wrongprefix:(hosts=\"1.1.1.1\"))");
-        assertThrowsIllegalArgument("single(foo:bar)");
-    }
-
-    @Test
-    public void resolveHosts() {
-        resolve("single(target=localhost)");
-        resolve("single(target=byon(hosts=\"1.1.1.1\"))");
-
-        brooklynProperties.put("brooklyn.location.named.mynamed", "single(target=byon:(hosts=\"1.1.1.1\"))");
-        managementContext.clearLocationRegistry();
-        resolve("single(target=named:mynamed)");
-    }
-    
-    @Test
-    public void resolveWithOldColonFormat() {
-        resolve("single:(target=localhost)");
-    }
-    
-    @Test
-    public void testNamedByonLocation() throws Exception {
-        brooklynProperties.put("brooklyn.location.named.mynamed", "single(target=byon:(hosts=\"1.1.1.1\"))");
-        
-        SingleMachineProvisioningLocation<SshMachineLocation> loc = resolve("named:mynamed");
-        assertEquals(loc.obtain(ImmutableMap.of()).getAddress(), InetAddress.getByName("1.1.1.1"));
-    }
-
-    @Test
-    public void testPropertyScopePrescedence() throws Exception {
-        brooklynProperties.put("brooklyn.location.named.mynamed", "single(target=byon:(hosts=\"1.1.1.1\"))");
-        
-        // prefer those in "named" over everything else
-        brooklynProperties.put("brooklyn.location.named.mynamed.privateKeyFile", "privateKeyFile-inNamed");
-        brooklynProperties.put("brooklyn.localhost.privateKeyFile", "privateKeyFile-inGeneric");
-
-        // prefer location-generic if nothing else
-        brooklynProperties.put("brooklyn.location.privateKeyData", "privateKeyData-inGeneric");
-
-        Map<String, Object> conf = resolve("named:mynamed").obtain(ImmutableMap.of()).config().getBag().getAllConfig();
-        
-        assertEquals(conf.get("privateKeyFile"), "privateKeyFile-inNamed");
-        assertEquals(conf.get("privateKeyData"), "privateKeyData-inGeneric");
-    }
-
-    private void assertThrowsNoSuchElement(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (NoSuchElementException e) {
-            // success
-        }
-    }
-    
-    private void assertThrowsIllegalArgument(String val) {
-        try {
-            resolve(val);
-            fail();
-        } catch (IllegalArgumentException e) {
-            // success
-        }
-    }
-    
-    @SuppressWarnings("unchecked")
-    private SingleMachineProvisioningLocation<SshMachineLocation> resolve(String val) {
-        return (SingleMachineProvisioningLocation<SshMachineLocation>) managementContext.getLocationRegistry().resolve(val);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/SingleMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/SingleMachineProvisioningLocationTest.java b/core/src/test/java/brooklyn/location/basic/SingleMachineProvisioningLocationTest.java
deleted file mode 100644
index 3a8e17d..0000000
--- a/core/src/test/java/brooklyn/location/basic/SingleMachineProvisioningLocationTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import static org.testng.Assert.assertNotNull;
-
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.management.internal.LocalManagementContext;
-
-public class SingleMachineProvisioningLocationTest {
-    
-    private static final Logger log = LoggerFactory.getLogger(SingleMachineProvisioningLocation.class);
-    
-    private LocalManagementContext managementContext;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setUp() throws Exception {
-        managementContext = LocalManagementContextForTests.newInstance();
-    }
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (managementContext != null) managementContext.terminate();
-    }
-    
-    @SuppressWarnings("unchecked") 
-    @Test
-    public void testLocalhostSingle() throws Exception {
-        SingleMachineProvisioningLocation<SshMachineLocation> l = (SingleMachineProvisioningLocation<SshMachineLocation>) 
-            managementContext.getLocationRegistry().resolve("single:(target='localhost')");
-        l.setManagementContext(managementContext);
-        
-        SshMachineLocation m1 = l.obtain();
-        
-        assertNotNull(m1);
-
-        log.info("GOT "+m1);
-        
-        l.release(m1);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/test/java/brooklyn/location/basic/SshMachineLocationIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/SshMachineLocationIntegrationTest.java b/core/src/test/java/brooklyn/location/basic/SshMachineLocationIntegrationTest.java
deleted file mode 100644
index 9b62e41..0000000
--- a/core/src/test/java/brooklyn/location/basic/SshMachineLocationIntegrationTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * 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 brooklyn.location.basic;
-
-import java.io.ByteArrayOutputStream;
-import java.security.KeyPair;
-import java.util.Arrays;
-import java.util.Map;
-
-import brooklyn.util.internal.ssh.SshTool;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.test.entity.TestApplication;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.util.collections.MutableMap;
-import brooklyn.util.crypto.SecureKeys;
-import brooklyn.util.internal.ssh.sshj.SshjTool;
-import brooklyn.util.internal.ssh.sshj.SshjTool.SshjToolBuilder;
-
-import com.google.common.base.Preconditions;
-
-import static org.testng.Assert.assertEquals;
-
-public class SshMachineLocationIntegrationTest {
-
-    protected TestApplication app;
-    protected ManagementContext mgmt;
-
-    @BeforeMethod(alwaysRun=true)
-    public void setup() throws Exception {
-        mgmt = LocalManagementContextForTests.builder(true)
-            .useDefaultProperties()
-            .build();
-        app = TestApplication.Factory.newManagedInstanceForTests(mgmt);
-    }
-
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        if (mgmt != null) Entities.destroyAll(mgmt);
-        mgmt = null;
-    }
-
-    // Note: requires `named:localhost-passphrase` set up with a key whose passphrase is "localhost"
-    // * create the key with:
-    //      ssh-keygen -t rsa -N "brooklyn" -f ~/.ssh/id_rsa_passphrase
-    //      ssh-copy-id localhost
-    // * create brooklyn.properties, containing:
-    //      brooklyn.location.named.localhost-passphrase=localhost
-    //      brooklyn.location.named.localhost-passphrase.privateKeyFile=~/.ssh/id_rsa_passphrase
-    //      brooklyn.location.named.localhost-passphrase.privateKeyPassphrase=brooklyn
-    @Test(groups = "Integration")
-    public void testExtractingConnectablePassphraselessKey() throws Exception {
-        LocalhostMachineProvisioningLocation lhp = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("named:localhost-passphrase", true, null).orNull();
-        Preconditions.checkNotNull(lhp, "This test requires a localhost named location called 'localhost-passphrase' (which should have a passphrase set)");
-        SshMachineLocation sm = lhp.obtain();
-        
-        SshjToolBuilder builder = SshjTool.builder().host(sm.getAddress().getHostName()).user(sm.getUser());
-        
-        KeyPair data = sm.findKeyPair();
-        if (data!=null) builder.privateKeyData(SecureKeys.toPem(data));
-        String password = sm.findPassword();
-        if (password!=null) builder.password(password);
-        SshjTool tool = builder.build();
-        tool.connect();
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        int result = tool.execCommands(MutableMap.<String,Object>of("out", out), Arrays.asList("date"));
-        Assert.assertTrue(out.toString().contains(" 20"), "out="+out);
-        assertEquals(result, 0);
-    }
-
-    @Test(groups = "Integration")
-    public void testExecScriptScriptDirFlagIsRespected() throws Exception {
-        // For explanation of (some of) the magic behind this command, see http://stackoverflow.com/a/229606/68898
-        final String command = "if [[ \"$0\" == \"/var/tmp/\"* ]]; then true; else false; fi";
-
-        LocalhostMachineProvisioningLocation lhp = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("localhost", true, null).orNull();
-        SshMachineLocation sm = lhp.obtain();
-
-        Map<String, Object> props = ImmutableMap.<String, Object>builder()
-                .put(SshTool.PROP_SCRIPT_DIR.getName(), "/var/tmp")
-                .build();
-        int rc = sm.execScript(props, "Test script directory execution", ImmutableList.of(command));
-        assertEquals(rc, 0);
-    }
-
-    @Test(groups = "Integration")
-    public void testLocationScriptDirConfigIsRespected() throws Exception {
-        // For explanation of (some of) the magic behind this command, see http://stackoverflow.com/a/229606/68898
-        final String command = "if [[ \"$0\" == \"/var/tmp/\"* ]]; then true; else false; fi";
-
-        Map<String, Object> locationConfig = ImmutableMap.<String, Object>builder()
-                .put(SshMachineLocation.SCRIPT_DIR.getName(), "/var/tmp")
-                .build();
-
-        LocalhostMachineProvisioningLocation lhp = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("localhost", locationConfig);
-        SshMachineLocation sm = lhp.obtain();
-
-        int rc = sm.execScript("Test script directory execution", ImmutableList.of(command));
-        assertEquals(rc, 0);
-    }
-    
-    @Test(groups = "Integration")
-    public void testMissingLocationScriptDirIsAlsoOkay() throws Exception {
-        final String command = "echo hello";
-
-        Map<String, Object> locationConfig = ImmutableMap.<String, Object>builder()
-//                .put(SshMachineLocation.SCRIPT_DIR.getName(), "/var/tmp")
-                .build();
-
-        LocalhostMachineProvisioningLocation lhp = (LocalhostMachineProvisioningLocation) mgmt.getLocationRegistry().resolve("localhost", locationConfig);
-        SshMachineLocation sm = lhp.obtain();
-
-        int rc = sm.execScript("Test script directory execution", ImmutableList.of(command));
-        assertEquals(rc, 0);
-    }
-}


[37/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/cloud/CloudLocationConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/cloud/CloudLocationConfig.java b/core/src/main/java/brooklyn/location/cloud/CloudLocationConfig.java
deleted file mode 100644
index 66c6065..0000000
--- a/core/src/main/java/brooklyn/location/cloud/CloudLocationConfig.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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 brooklyn.location.cloud;
-
-import java.util.Collection;
-
-import com.google.common.annotations.Beta;
-import com.google.common.reflect.TypeToken;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.location.MachineLocationCustomizer;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.util.flags.SetFromFlag;
-
-public interface CloudLocationConfig {
-
-    public static final ConfigKey<String> CLOUD_ENDPOINT = LocationConfigKeys.CLOUD_ENDPOINT;
-    public static final ConfigKey<String> CLOUD_REGION_ID = LocationConfigKeys.CLOUD_REGION_ID;
-    public static final ConfigKey<String> CLOUD_AVAILABILITY_ZONE_ID = LocationConfigKeys.CLOUD_AVAILABILITY_ZONE_ID;
-        
-    @SetFromFlag("identity")
-    public static final ConfigKey<String> ACCESS_IDENTITY = LocationConfigKeys.ACCESS_IDENTITY;
-    @SetFromFlag("credential")
-    public static final ConfigKey<String> ACCESS_CREDENTIAL = LocationConfigKeys.ACCESS_CREDENTIAL;
-
-    public static final ConfigKey<String> USER = LocationConfigKeys.USER;
-    
-    public static final ConfigKey<String> PASSWORD = LocationConfigKeys.PASSWORD;
-    public static final ConfigKey<String> PUBLIC_KEY_FILE = LocationConfigKeys.PUBLIC_KEY_FILE;
-    public static final ConfigKey<String> PUBLIC_KEY_DATA = LocationConfigKeys.PUBLIC_KEY_DATA;
-    public static final ConfigKey<String> PRIVATE_KEY_FILE = LocationConfigKeys.PRIVATE_KEY_FILE;
-    public static final ConfigKey<String> PRIVATE_KEY_DATA = LocationConfigKeys.PRIVATE_KEY_DATA;
-    public static final ConfigKey<String> PRIVATE_KEY_PASSPHRASE = LocationConfigKeys.PRIVATE_KEY_PASSPHRASE;
-
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PUBLIC_KEY_FILE = LocationConfigKeys.LEGACY_PUBLIC_KEY_FILE;
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PUBLIC_KEY_DATA = LocationConfigKeys.LEGACY_PUBLIC_KEY_DATA;
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_FILE = LocationConfigKeys.LEGACY_PRIVATE_KEY_FILE;
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_DATA = LocationConfigKeys.LEGACY_PRIVATE_KEY_DATA;
-    /** @deprecated since 0.6.0; included here so it gets picked up in auto-detect routines */ @Deprecated
-    public static final ConfigKey<String> LEGACY_PRIVATE_KEY_PASSPHRASE = LocationConfigKeys.LEGACY_PRIVATE_KEY_PASSPHRASE;
-
-    // default is just shy of common 64-char boundary, leaving 4 chars plus our salt allowance (default 4+1) which allows up to -12345678 by jclouds
-    public static final ConfigKey<Integer> VM_NAME_MAX_LENGTH = ConfigKeys.newIntegerConfigKey(
-        "vmNameMaxLength", "Maximum length of VM name", 60);
-
-    public static final ConfigKey<Integer> VM_NAME_SALT_LENGTH = ConfigKeys.newIntegerConfigKey(
-        "vmNameSaltLength", "Number of characters to use for a random identifier inserted in hostname "
-            + "to uniquely identify machines", 4);
-
-    public static final ConfigKey<String> WAIT_FOR_SSHABLE = ConfigKeys.newStringConfigKey("waitForSshable", 
-            "Whether and how long to wait for a newly provisioned VM to be accessible via ssh; " +
-            "if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '5m' (the default) or a number of milliseconds", "5m");
-
-    public static final ConfigKey<String> WAIT_FOR_WINRM_AVAILABLE = ConfigKeys.newStringConfigKey("waitForWinRmAvailable",
-            "Whether and how long to wait for a newly provisioned VM to be accessible via WinRm; " +
-                    "if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '30m' (the default) or a number of milliseconds", "30m");
-
-    public static final ConfigKey<Boolean> LOG_CREDENTIALS = ConfigKeys.newBooleanConfigKey(
-            "logCredentials", 
-            "Whether to log credentials of a new VM - strongly recommended never be used in production, as it is a big security hole!",
-            false);
-
-    public static final ConfigKey<Object> CALLER_CONTEXT = LocationConfigKeys.CALLER_CONTEXT;
-
-    public static final ConfigKey<Boolean> DESTROY_ON_FAILURE = ConfigKeys.newBooleanConfigKey("destroyOnFailure", "Whether to destroy the VM if provisioningLocation.obtain() fails", true);
-    
-    public static final ConfigKey<Object> INBOUND_PORTS = new BasicConfigKey<Object>(Object.class, "inboundPorts", 
-        "Inbound ports to be applied when creating a VM, on supported clouds " +
-            "(either a single port as a String, or an Iterable<Integer> or Integer[])", null);
-    @Beta
-    public static final ConfigKey<Object> ADDITIONAL_INBOUND_PORTS = new BasicConfigKey<Object>(Object.class, "required.ports", 
-            "Required additional ports to be applied when creating a VM, on supported clouds " +
-                    "(either a single port as an Integer, or an Iterable<Integer> or Integer[])", null);
-    
-    public static final ConfigKey<Boolean> OS_64_BIT = ConfigKeys.newBooleanConfigKey("os64Bit", 
-        "Whether to require 64-bit OS images (true), 32-bit images (false), or either (null)");
-    
-    public static final ConfigKey<Object> MIN_RAM = new BasicConfigKey<Object>(Object.class, "minRam",
-        "Minimum amount of RAM, either as string (4gb) or number of MB (4096), for use in selecting the machine/hardware profile", null);
-    
-    public static final ConfigKey<Integer> MIN_CORES = new BasicConfigKey<Integer>(Integer.class, "minCores",
-        "Minimum number of cores, for use in selecting the machine/hardware profile", null);
-    
-    public static final ConfigKey<Object> MIN_DISK = new BasicConfigKey<Object>(Object.class, "minDisk",
-        "Minimum size of disk, either as string (100gb) or number of GB (100), for use in selecting the machine/hardware profile", null);
-
-    public static final ConfigKey<String> DOMAIN_NAME = new BasicConfigKey<String>(String.class, "domainName",
-        "DNS domain where the host should be created, e.g. yourdomain.com (selected clouds only)", null);
-
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Collection<MachineLocationCustomizer>> MACHINE_LOCATION_CUSTOMIZERS = ConfigKeys.newConfigKey(
-            new TypeToken<Collection<MachineLocationCustomizer>>() {},
-            "machineCustomizers", "Optional machine customizers");
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java b/core/src/main/java/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java
deleted file mode 100644
index d165fe1..0000000
--- a/core/src/main/java/brooklyn/location/cloud/names/AbstractCloudMachineNamer.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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 brooklyn.location.cloud.names;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.trait.HasShortName;
-
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.text.Strings;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.CharMatcher;
-
-/** 
- * Implements <b>most</b> of {@link CloudMachineNamer},
- * leaving just one method -- {@link #generateNewIdOfLength(int)} --
- * for subclasses to provide.
- * <p>
- * {@link CloudLocationConfig#VM_NAME_MAX_LENGTH} is used to find the VM length, 
- * unless {@link #getCustomMaxNameLength(ConfigBag)} is overridden or
- * {@link #setDefaultMachineNameMaxLength(int)} invoked on the instance supplied.
- */
-public abstract class AbstractCloudMachineNamer implements CloudMachineNamer {
-
-    int defaultMachineNameMaxLength = CloudLocationConfig.VM_NAME_MAX_LENGTH.getDefaultValue();
-    int defaultMachineNameSaltLength = CloudLocationConfig.VM_NAME_SALT_LENGTH.getDefaultValue();
-    protected String separator = "-";
-
-    public String generateNewMachineUniqueName(ConfigBag setup) {
-        return generateNewIdReservingLength(setup, 0);
-    }
-    
-    public String generateNewMachineUniqueNameFromGroupId(ConfigBag setup, String groupId) {
-        int availSaltLength = getMaxNameLength(setup) - (groupId.length() + separator.length());
-        int requestedSaltLength = getLengthForMachineUniqueNameSalt(setup, false);
-        if (availSaltLength <= 0 || requestedSaltLength <= 0) {
-            return groupId;
-        }
-            
-        return sanitize(groupId + separator + Identifiers.makeRandomId(Math.min(requestedSaltLength, availSaltLength))).toLowerCase();
-    }
-
-    public String generateNewGroupId(ConfigBag setup) {
-        return sanitize(generateNewIdReservingLength(setup, getLengthForMachineUniqueNameSalt(setup, true))).toLowerCase();
-    }
-
-    protected String generateNewIdReservingLength(ConfigBag setup, int lengthToReserve) {
-        int len = getMaxNameLength(setup);
-        // decrement by e.g. 9 chars because jclouds adds that (dash plus 8 for hex id)
-        len -= lengthToReserve;
-        if (len<=0) return "";
-        return Strings.maxlen(generateNewIdOfLength(setup, len), len);
-    }
-    
-    /** Method for subclasses to provide to construct the context-specific part of an identifier,
-     * for use in {@link #generateNewGroupId()} and {@link #generateNewMachineUniqueName()}.
-     * 
-     * @param maxLengthHint an indication of the maximum length permitted for the ID generated,
-     * supplied for implementations which wish to use this information to decide what to truncate.
-     * (This class will truncate any return values longer than this.) 
-     */
-    protected abstract String generateNewIdOfLength(ConfigBag setup, int maxLengthHint);
-
-    /** Returns the max length of a VM name for the cloud specified in setup;
-     * this value is typically decremented by 9 to make room for jclouds labels;
-     * delegates to {@link #getCustomMaxNameLength()} when 
-     * {@link CloudLocationConfig#VM_NAME_MAX_LENGTH} is not set */
-    public int getMaxNameLength(ConfigBag setup) {
-        if (setup.containsKey(CloudLocationConfig.VM_NAME_MAX_LENGTH)) {
-            // if a length is set explicitly, use that (but intercept default behaviour)
-            return setup.get(CloudLocationConfig.VM_NAME_MAX_LENGTH);
-        }
-        
-        Integer custom = getCustomMaxNameLength(setup);
-        if (custom!=null) return custom;
-        
-        // return the default
-        return defaultMachineNameMaxLength;  
-    }
-    
-    // sometimes we create salt string, sometimes jclouds does
-    public int getLengthForMachineUniqueNameSalt(ConfigBag setup, boolean includeSeparator) {
-        int saltLen;
-        if (setup.containsKey(CloudLocationConfig.VM_NAME_SALT_LENGTH)) {
-            saltLen = setup.get(CloudLocationConfig.VM_NAME_SALT_LENGTH);
-        } else {
-            // default value comes from key, but custom default can be set
-            saltLen = defaultMachineNameSaltLength;
-        }
-        
-        if (saltLen>0 && includeSeparator)
-            saltLen += separator.length();
-        
-        return saltLen;
-    }
-    
-    public AbstractCloudMachineNamer setDefaultMachineNameMaxLength(int defaultMaxLength) {
-        this.defaultMachineNameMaxLength = defaultMaxLength;
-        return this;
-    }
-
-    /** Number of chars to use or reserve for the machine identifier when constructing a group identifier;
-     * jclouds for instance uses "-" plus 8 */
-    public AbstractCloudMachineNamer setDefaultMachineNameSeparatorAndSaltLength(String separator, int defaultMachineUniqueNameSaltLength) {
-        this.separator = separator;
-        this.defaultMachineNameSaltLength = defaultMachineUniqueNameSaltLength;
-        return this;
-    }
-    
-    /** Method for overriding to provide custom logic when an explicit config key is not set for the machine length. */
-    public Integer getCustomMaxNameLength(ConfigBag setup) {
-        return null;
-    }
-
-    protected static String shortName(Object x) {
-        if (x instanceof HasShortName) {
-            return ((HasShortName)x).getShortName();
-        }
-        if (x instanceof Entity) {
-            return ((Entity)x).getDisplayName();
-        }
-        return x.toString();
-    }
-
-    @Beta //probably won't live here long-term
-    public static String sanitize(String s) {
-        return CharMatcher.inRange('A', 'Z')
-                .or(CharMatcher.inRange('a', 'z'))
-                .or(CharMatcher.inRange('0', '9'))
-                .negate()
-                .trimAndCollapseFrom(s, '-');
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/cloud/names/BasicCloudMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/cloud/names/BasicCloudMachineNamer.java b/core/src/main/java/brooklyn/location/cloud/names/BasicCloudMachineNamer.java
deleted file mode 100644
index 0b014f2..0000000
--- a/core/src/main/java/brooklyn/location/cloud/names/BasicCloudMachineNamer.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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 brooklyn.location.cloud.names;
-
-import org.apache.brooklyn.api.entity.Application;
-import org.apache.brooklyn.api.entity.Entity;
-
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.text.Identifiers;
-import brooklyn.util.text.StringShortener;
-import brooklyn.util.text.Strings;
-
-/** 
- * Standard implementation of {@link CloudMachineNamer},
- * which looks at several of the properties of the context (entity)
- * and is clever about abbreviating them. */
-public class BasicCloudMachineNamer extends AbstractCloudMachineNamer {
-
-    @Override
-    protected String generateNewIdOfLength(ConfigBag setup, int len) {
-        Object context = setup.peek(CloudLocationConfig.CALLER_CONTEXT);
-        Entity entity = null;
-        if (context instanceof Entity) entity = (Entity) context;
-        
-        StringShortener shortener = Strings.shortener().separator("-");
-        shortener.append("system", "brooklyn");
-        
-        // randId often not necessary, as an 8-char hex identifier is added later (in jclouds? can we override?)
-        // however it can be useful to have this early in the string, to prevent collisions in places where it is abbreviated 
-        shortener.append("randId", Identifiers.makeRandomId(4));
-        
-        String user = System.getProperty("user.name");
-        if (!"brooklyn".equals(user))
-            // include user; unless the user is 'brooklyn', as 'brooklyn-brooklyn-' is just silly!
-            shortener.append("user", user);
-        
-        if (entity!=null) {
-            Application app = entity.getApplication();
-            if (app!=null) {
-                shortener.append("app", shortName(app))
-                        .append("appId", app.getId());
-            }
-            shortener.append("entity", shortName(entity))
-                    .append("entityId", entity.getId());
-        } else if (context!=null) {
-            shortener.append("context", context.toString());
-        }
-        
-        shortener.truncate("user", 12)
-                .truncate("app", 16)
-                .truncate("entity", 16)
-                .truncate("appId", 4)
-                .truncate("entityId", 4)
-                .truncate("context", 12);
-        
-        shortener.canTruncate("user", 8)
-                .canTruncate("app", 5)
-                .canTruncate("entity", 5)
-                .canTruncate("system", 2)
-                .canTruncate("app", 3)
-                .canTruncate("entity", 3)
-                .canRemove("app")
-                .canTruncate("user", 4)
-                .canRemove("entity")
-                .canTruncate("context", 4)
-                .canTruncate("randId", 2)
-                .canRemove("user")
-                .canTruncate("appId", 2)
-                .canRemove("appId");
-        
-        String s = shortener.getStringOfMaxLength(len);
-        return sanitize(s).toLowerCase();
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/cloud/names/CloudMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/cloud/names/CloudMachineNamer.java b/core/src/main/java/brooklyn/location/cloud/names/CloudMachineNamer.java
deleted file mode 100644
index 23dd31b..0000000
--- a/core/src/main/java/brooklyn/location/cloud/names/CloudMachineNamer.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 brooklyn.location.cloud.names;
-
-import org.apache.brooklyn.api.entity.Entity;
-
-import brooklyn.location.Location;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.util.config.ConfigBag;
-
-/**
- * Interface used to construct names for individual cloud machines and for groups of machines.
- * <p>
- * Implementations <b>must</b> provide a constructor which takes a single argument,
- * being the {@link ConfigBag} for the context where the machine is being created
- * (usually a {@link Location}).
- * <p>
- * With that bag, the config key {@link CloudLocationConfig#CALLER_CONTEXT}
- * typically contains the {@link Entity} for which the machine is being created.   
- */
-public interface CloudMachineNamer {
-
-    /**
-     * Generate a name for a new machine, based on context.
-     * <p>
-     * The name should normally be unique, as a context might produce multiple machines,
-     * for example basing it partially on information from the context but also including some random salt.
-     */
-    public String generateNewMachineUniqueName(ConfigBag setup);
-    /**
-     * Generate a name stem for a group of machines, based on context.
-     * <p>
-     * The name does not need to be unique, as uniqueness will be applied by {@link #generateNewMachineUniqueNameFromGroupId(String)}.
-     */
-    public String generateNewGroupId(ConfigBag setup);
-    
-    /**
-     * Generate a unique name from the given name stem.
-     * <p>
-     * The name stem is normally based on context information so the usual
-     * function of this method is to apply a suffix which helps to uniquely distinguish between machines
-     * in cases where the same name stem ({@link #generateNewGroupId()}) is used for multiple machines.
-     */
-    public String generateNewMachineUniqueNameFromGroupId(ConfigBag setup, String groupId);
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/cloud/names/CustomMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/cloud/names/CustomMachineNamer.java b/core/src/main/java/brooklyn/location/cloud/names/CustomMachineNamer.java
deleted file mode 100644
index e5dabe3..0000000
--- a/core/src/main/java/brooklyn/location/cloud/names/CustomMachineNamer.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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 brooklyn.location.cloud.names;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.Entity;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.EntityInternal;
-import brooklyn.location.cloud.CloudLocationConfig;
-import brooklyn.util.config.ConfigBag;
-import brooklyn.util.text.Strings;
-import brooklyn.util.text.TemplateProcessor;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.reflect.TypeToken;
-
-/** Provides a machine namer which looks at a location config key {@link #MACHINE_NAME_TEMPLATE}
- * to construct the hostname.
- * For instance, setting this to <code>${config.entity_hostname}</code>
- * will take the hostname from an <code>entity_hostname</code> key passed as entity <code>brooklyn.config</code>.
- * <p>
- * Note that this is not jclouds aware, so jclouds-specific cloud max lengths are not observed with this class.
- */
-public class CustomMachineNamer extends BasicCloudMachineNamer {
-    
-    public static final ConfigKey<String> MACHINE_NAME_TEMPLATE = ConfigKeys.newStringConfigKey("custom.machine.namer.machine", 
-            "Freemarker template format for custom machine name", "${entity.displayName}");
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Map<String, ?>> EXTRA_SUBSTITUTIONS = ConfigKeys.newConfigKey(new TypeToken<Map<String, ?>>() {}, 
-            "custom.machine.namer.substitutions", "Additional substitutions to be used in the template", ImmutableMap.<String, Object>of());
-    
-    @Override
-    protected String generateNewIdOfLength(ConfigBag setup, int len) {
-        Object context = setup.peek(CloudLocationConfig.CALLER_CONTEXT);
-        Entity entity = null;
-        if (context instanceof Entity) {
-            entity = (Entity) context;
-        }
-        
-        String template = setup.get(MACHINE_NAME_TEMPLATE);
-        
-        String processed;
-        if (entity == null) {
-            processed = TemplateProcessor.processTemplateContents(template, setup.get(EXTRA_SUBSTITUTIONS));
-        } else {
-            processed = TemplateProcessor.processTemplateContents(template, (EntityInternal)entity, setup.get(EXTRA_SUBSTITUTIONS));
-        }
-        
-        processed = Strings.removeFromStart(processed, "#ftl\n");
-        
-        return sanitize(processed);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/dynamic/DynamicLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/dynamic/DynamicLocation.java b/core/src/main/java/brooklyn/location/dynamic/DynamicLocation.java
deleted file mode 100644
index d85d40d..0000000
--- a/core/src/main/java/brooklyn/location/dynamic/DynamicLocation.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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 brooklyn.location.dynamic;
-
-import org.apache.brooklyn.api.entity.Entity;
-
-import com.google.common.annotations.Beta;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.Location;
-import brooklyn.util.flags.SetFromFlag;
-
-/**
- * A location that is created and owned by an entity at runtime.
- * <p>
- * The lifecycle of the location is managed by the owning entity.
- *
- * @param E the entity type
- * @param L the location type
- */
-@Beta
-public interface DynamicLocation<E extends Entity & LocationOwner<L, E>, L extends Location & DynamicLocation<E, L>> {
-
-    @SetFromFlag("owner")
-    ConfigKey<Entity> OWNER =
-            ConfigKeys.newConfigKey(Entity.class, "owner", "The entity owning this location");
-
-    @SetFromFlag("maxLocations")
-    ConfigKey<Integer> MAX_SUB_LOCATIONS =
-            ConfigKeys.newIntegerConfigKey("maxLocations", "The maximum number of sub-locations that can be created; 0 for unlimited", 0);
-
-    E getOwner();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/dynamic/LocationOwner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/dynamic/LocationOwner.java b/core/src/main/java/brooklyn/location/dynamic/LocationOwner.java
deleted file mode 100644
index b001023..0000000
--- a/core/src/main/java/brooklyn/location/dynamic/LocationOwner.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 brooklyn.location.dynamic;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.event.AttributeSensor;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
-import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.reflect.TypeToken;
-
-/**
- * An entity that owns a particular location.
- * <p>
- * The entity should be able to dynamically create an instance of the required type of location, and will manage
- * the lifecycle of the location in parallel with its own.
- *
- * @param L the location type
- * @param E the entity type
- */
-@Beta
-public interface LocationOwner<L extends Location & DynamicLocation<E, L>, E extends Entity & LocationOwner<L, E>> {
-
-    @SetFromFlag("locationPrefix")
-    ConfigKey<String> LOCATION_NAME_PREFIX = ConfigKeys.newStringConfigKey(
-            "entity.dynamicLocation.prefix", "The name prefix for the location owned by this entity", "dynamic");
-
-    @SetFromFlag("locationSuffix")
-    ConfigKey<String> LOCATION_NAME_SUFFIX = ConfigKeys.newStringConfigKey(
-            "entity.dynamicLocation.suffix", "The name suffix for the location owned by this entity");
-
-    @SetFromFlag("locationName")
-    BasicAttributeSensorAndConfigKey<String> LOCATION_NAME = new BasicAttributeSensorAndConfigKey<String>(String.class,
-            "entity.dynamicLocation.name", "The name of the location owned by this entity (default is auto-generated using prefix and suffix keys)");
-
-    ConfigKey<Map<String, Object>> LOCATION_FLAGS = ConfigKeys.newConfigKey(new TypeToken<Map<String, Object>>() { },
-            "entity.dynamicLocation.flags", "Extra creation flags for the Location owned by this entity",
-            ImmutableMap.<String, Object>of());
-
-    AttributeSensor<Location> DYNAMIC_LOCATION = Sensors.newSensor(Location.class,
-            "entity.dynamicLocation", "The location owned by this entity");
-
-    AttributeSensor<String> LOCATION_SPEC = Sensors.newStringSensor(
-            "entity.dynamicLocation.spec", "The specification string for the location owned by this entity");
-
-    AttributeSensor<Boolean> DYNAMIC_LOCATION_STATUS = Sensors.newBooleanSensor(
-            "entity.dynamicLocation.status", "The status of the location owned by this entity");
-
-    AttributeSensor<LocationDefinition> LOCATION_DEFINITION = Sensors.newSensor(
-        LocationDefinition.class, "entity.dynamicLocation.definition", "The location definition for the location owned by this entity");
-
-    L getDynamicLocation();
-
-    L createLocation(Map<String, ?> flags);
-
-    boolean isLocationAvailable();
-
-    void deleteLocation();
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/geo/GeoBytesHostGeoLookup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/geo/GeoBytesHostGeoLookup.java b/core/src/main/java/brooklyn/location/geo/GeoBytesHostGeoLookup.java
deleted file mode 100644
index 1c68000..0000000
--- a/core/src/main/java/brooklyn/location/geo/GeoBytesHostGeoLookup.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.net.Networking;
-
-/** @deprecated Mar 2015 - the API has changed; GetLocation now discouraged for free access, and valuepairs.txt not supported */
-@Deprecated
-public class GeoBytesHostGeoLookup implements HostGeoLookup {
-
-    public static final Logger log = LoggerFactory.getLogger(GeoBytesHostGeoLookup.class);
-    
-    /*
-    curl "http://www.geobytes.com/IpLocator.htm?GetLocation&template=valuepairs.txt&IpAddress=geobytes.com"
-    known=1
-    countryid=254
-    country=United States
-    fips104=US
-    iso2=US
-    iso3=USA
-    ison=840
-    internet=US
-    comment=
-    regionid=142
-    region=Maryland
-    code=MD
-    adm1code=    
-    cityid=8909
-    city=Baltimore
-    latitude=39.2894
-    longitude=-76.6384
-    timezone=-05:00
-    dmaid=512
-    dma=512
-    market=Baltimore
-    certainty=78
-    isproxy=false
-    mapbytesremaining=Free
-    */
-    
-    public String getPropertiesLookupUrlForPublicIp(String ip) {
-        return "http://www.geobytes.com/IpLocator.htm?GetLocation&template=valuepairs.txt&IpAddress="+ip.trim();
-    }
-
-    public String getPropertiesLookupUrlForLocalhost() {
-        return "http://www.geobytes.com/IpLocator.htm?GetLocation&template=valuepairs.txt";
-    }
-
-    /** returns URL to get properties for the given address (assuming localhost if address is on a subnet) */
-    public String getPropertiesLookupUrlFor(InetAddress address) {
-        if (Networking.isPrivateSubnet(address)) return getPropertiesLookupUrlForLocalhost();
-        return getPropertiesLookupUrlForPublicIp(address.getHostAddress());
-    }
-    
-    private static boolean LOGGED_GEO_LOOKUP_UNAVAILABLE = false;
-    
-    public HostGeoInfo getHostGeoInfo(InetAddress address) throws MalformedURLException, IOException {
-        String url = getPropertiesLookupUrlFor(address);
-        if (log.isDebugEnabled())
-            log.debug("Geo info lookup for "+address+" at "+url);
-        Properties props = new Properties();
-        try {
-            props.load( new URL(url).openStream() );
-            HostGeoInfo geo = new HostGeoInfo(address.getHostName(), props.getProperty("city")+" ("+props.getProperty("iso2")+")", 
-                Double.parseDouble(props.getProperty("latitude")), Double.parseDouble(props.getProperty("longitude")));
-            log.info("Geo info lookup for "+address+" returned: "+geo);
-            return geo;
-        } catch (Exception e) {
-            // may be web not available, or gateway giving us funny crap
-            if (log.isDebugEnabled())
-                log.debug("Geo info lookup for "+address+" failed: "+e);
-            if (!LOGGED_GEO_LOOKUP_UNAVAILABLE) {
-                LOGGED_GEO_LOOKUP_UNAVAILABLE = true;
-                log.info("Geo info lookup unavailable (for "+address+"; cause "+e+")");
-            }
-            return null;
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/geo/HasHostGeoInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/geo/HasHostGeoInfo.java b/core/src/main/java/brooklyn/location/geo/HasHostGeoInfo.java
deleted file mode 100644
index 86920e8..0000000
--- a/core/src/main/java/brooklyn/location/geo/HasHostGeoInfo.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-public interface HasHostGeoInfo {
-
-    HostGeoInfo getHostGeoInfo();
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/geo/HostGeoInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/geo/HostGeoInfo.java b/core/src/main/java/brooklyn/location/geo/HostGeoInfo.java
deleted file mode 100644
index 43ee4ad..0000000
--- a/core/src/main/java/brooklyn/location/geo/HostGeoInfo.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import java.io.Serializable;
-import java.net.InetAddress;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.location.AddressableLocation;
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.guava.Maybe;
-import brooklyn.util.internal.BrooklynSystemProperties;
-
-import com.google.common.base.Objects;
-
-/**
- * Encapsulates geo-IP information for a given host.
- */
-public class HostGeoInfo implements Serializable {
-    
-    private static final long serialVersionUID = -5866759901535266181L;
-
-    public static final Logger log = LoggerFactory.getLogger(HostGeoInfo.class);
-
-    /** the IP address */
-    public final String address;
-    
-    public final String displayName;
-    
-    public final double latitude;
-    public final double longitude;
-    
-    private static Maybe<HostGeoLookup> cachedLookup = null;
-
-    public static HostGeoInfo create(String address, String displayName, double latitude, double longitude) {
-        return new HostGeoInfo(address, displayName, latitude, longitude);
-    }
-    
-    public static HostGeoInfo fromIpAddress(InetAddress address) {
-        try {
-            HostGeoLookup lookup = getDefaultLookup();
-            if (lookup!=null)
-                return lookup.getHostGeoInfo(address);
-        } catch (Exception e) {
-            if (log.isDebugEnabled())
-                log.debug("unable to look up geo DNS info for "+address, e);
-        }
-        return null;
-    }
-
-    @Nullable
-    public static HostGeoLookup getDefaultLookup() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-        if (cachedLookup==null) {
-            cachedLookup = Maybe.of(findHostGeoLookupImpl());
-        }                
-        return cachedLookup.get();
-    }
-    
-    public static void clearCachedLookup() {
-        cachedLookup = null;
-    }
-    
-    /** returns null if cannot be set */
-    public static HostGeoInfo fromLocation(Location l) {
-        if (l==null) return null;
-        
-        Location la = l;
-        HostGeoInfo resultFromLocation = null;
-        while (la!=null) {
-            if (la instanceof HasHostGeoInfo) {
-                resultFromLocation = ((HasHostGeoInfo)l).getHostGeoInfo();
-                if (resultFromLocation!=null) break;
-            }
-            la = la.getParent();
-        }
-        if (resultFromLocation!=null && l==la) {
-            // from the location
-            return resultFromLocation;
-        }
-        // resultFromLocation may be inherited, in which case we will copy it later
-        
-        InetAddress address = findIpAddress(l);
-        Object latitude = l.getConfig(LocationConfigKeys.LATITUDE);
-        Object longitude = l.getConfig(LocationConfigKeys.LONGITUDE);
-
-        if (resultFromLocation!=null && (latitude == null || longitude == null)) {
-            latitude = resultFromLocation.latitude;
-            longitude = resultFromLocation.longitude;            
-        }
-        if (address!=null && (latitude == null || longitude == null)) {
-            HostGeoInfo geo = fromIpAddress(address);
-            if (geo==null) return null;
-            latitude = geo.latitude;
-            longitude = geo.longitude;
-        }
-        
-        if (latitude==null || longitude==null)
-            return null;
-        
-        Exception error=null;
-        try {
-            latitude = TypeCoercions.castPrimitive(latitude, Double.class);
-            longitude = TypeCoercions.castPrimitive(longitude, Double.class);
-        } catch (Exception e) {
-            Exceptions.propagateIfFatal(e);
-            error = e;
-        }
-        if (error!=null || !(latitude instanceof Double) || !(longitude instanceof Double))
-            throw new IllegalArgumentException("Location "+l+" specifies invalid type of lat/long: " +
-                    "lat="+latitude+" (type "+(latitude==null ? null : latitude.getClass())+"); " +
-                    "lon="+longitude+" (type "+(longitude==null ? null : longitude.getClass())+")", error);
-        
-        HostGeoInfo result = new HostGeoInfo(address!=null ? address.getHostAddress() : null, l.getDisplayName(), (Double) latitude, (Double) longitude);
-        if (l instanceof AbstractLocation) {
-            ((AbstractLocation)l).setHostGeoInfo(result);
-        }
-        return result;
-    }
-    
-    private static HostGeoLookup findHostGeoLookupImpl() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
-        String type = BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getValue();
-        /* utrace seems more accurate than geobytes, and it gives a report of how many tokens are left;
-         * but maxmind if it's installed locally is even better (does not require remote lookup),
-         * so use it if available */
-        if (type==null) {
-            if (MaxMind2HostGeoLookup.getDatabaseReader()!=null)
-                return new MaxMind2HostGeoLookup();
-            log.debug("Using Utrace remote for geo lookup because MaxMind2 is not available");
-            return new UtraceHostGeoLookup();
-        }
-        if (type.isEmpty()) return null;
-        return (HostGeoLookup) Class.forName(type).newInstance();
-    }
-
-    public static HostGeoInfo fromEntity(Entity e) {
-        for (Location l : e.getLocations()) {
-            HostGeoInfo hgi = fromLocation(l);
-            if (hgi != null)
-                return hgi;
-        }
-        return null;
-    }
-    
-    public static InetAddress findIpAddress(Location l) {
-        if (l == null)
-            return null;
-        if (l instanceof AddressableLocation)
-            return ((AddressableLocation) l).getAddress();
-        return findIpAddress(l.getParent());
-    }
-    
-    public HostGeoInfo(String address, String displayName, double latitude, double longitude) {
-        this.address = address;
-        this.displayName = displayName==null ? "" : displayName;
-        this.latitude = latitude;
-        this.longitude = longitude;
-    }
-
-    public String getAddress() {
-        return address;
-    }
-    
-    @Override
-    public String toString() {
-        return "HostGeoInfo["+displayName+": "+(address!=null ? address : "(no-address)")+" at ("+latitude+","+longitude+")]";
-    }
-    
-    @Override
-    public boolean equals(Object o) {
-        // Slight cheat: only includes the address + displayName field (displayName to allow overloading localhost etc)
-        return (o instanceof HostGeoInfo) && Objects.equal(address, ((HostGeoInfo) o).address)
-                && Objects.equal(displayName, ((HostGeoInfo) o).displayName);
-    }
-    
-    @Override
-    public int hashCode() {
-        // Slight cheat: only includes the address + displayName field (displayName to allow overloading localhost etc)
-        return Objects.hashCode(address, displayName);
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/geo/HostGeoLookup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/geo/HostGeoLookup.java b/core/src/main/java/brooklyn/location/geo/HostGeoLookup.java
deleted file mode 100644
index ef9d043..0000000
--- a/core/src/main/java/brooklyn/location/geo/HostGeoLookup.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import java.net.InetAddress;
-
-public interface HostGeoLookup {
-
-    public HostGeoInfo getHostGeoInfo(InetAddress address) throws Exception;
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/geo/LocalhostExternalIpLoader.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/geo/LocalhostExternalIpLoader.java b/core/src/main/java/brooklyn/location/geo/LocalhostExternalIpLoader.java
deleted file mode 100644
index 74056bc..0000000
--- a/core/src/main/java/brooklyn/location/geo/LocalhostExternalIpLoader.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.ResourceUtils;
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.text.StringPredicates;
-import brooklyn.util.time.Duration;
-import brooklyn.util.time.Durations;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicates;
-import com.google.common.base.Splitter;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-public class LocalhostExternalIpLoader {
-
-    public static final Logger LOG = LoggerFactory.getLogger(LocalhostExternalIpLoader.class);
-
-    private static final AtomicBoolean retrievingLocalExternalIp = new AtomicBoolean(false);
-    private static final CountDownLatch triedLocalExternalIp = new CountDownLatch(1);
-    private static volatile String localExternalIp;
-
-    private static class IpLoader implements Callable<String> {
-        private static final Pattern ipPattern = Pattern.compile(
-                "\\b((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\b");
-        final String url;
-
-        protected IpLoader(String url) {
-            this.url = url;
-        }
-
-        @Override
-        public String call() {
-            String response = ResourceUtils.create(LocalhostExternalIpLoader.class)
-                    .getResourceAsString(url).trim();
-            return postProcessResponse(response);
-        }
-
-        String postProcessResponse(String response) {
-            Matcher matcher = ipPattern.matcher(response);
-            boolean matched = matcher.find();
-            if (!matched) {
-                LOG.error("No IP address matched in output from {}: {}", url, response);
-                return null;
-            } else {
-                return matcher.group();
-            }
-        }
-    }
-
-    @VisibleForTesting
-    static List<String> getIpAddressWebsites() {
-        String file = new ResourceUtils(LocalhostExternalIpLoader.class)
-                .getResourceAsString("classpath://brooklyn/location/geo/external-ip-address-resolvers.txt");
-        Iterable<String> lines = Splitter.on('\n')
-                .omitEmptyStrings()
-                .trimResults()
-                .split(file);
-        List<String> urls = Lists.newArrayList(Iterables.filter(lines, Predicates.not(StringPredicates.startsWith("#"))));
-        Collections.shuffle(urls);
-        return urls;
-    }
-
-    @VisibleForTesting
-    static String getIpAddressFrom(String url) {
-        return new IpLoader(url).call();
-    }
-    
-    /** As {@link #getLocalhostIpWithin(Duration)} but returning 127.0.0.1 if not accessible */
-    public static String getLocalhostIpQuicklyOrDefault() {
-        String result = doLoad(Duration.seconds(2));
-        if (result==null) return "127.0.0.1";
-        return result;
-    }
-
-    /** As {@link #getLocalhostIpWithin(Duration)} but without the time limit cut-off, failing if the load gives an error. */
-    public static String getLocalhostIpWaiting() {
-        return getLocalhostIpWithin(null);
-    }
-
-    /**
-     * Attempts to load the public IP address of localhost, failing if the load
-     * does not complete within the given duration.
-     * @return The public IP address of localhost
-     */
-    public static String getLocalhostIpWithin(Duration timeout) {
-        String result = doLoad(timeout);
-        if (result == null) {
-            throw new IllegalStateException("Unable to retrieve external IP for localhost; network may be down or slow or remote service otherwise not responding");
-        }
-        return result;
-    }
-
-    /**
-     * Requests URLs returned by {@link #getIpAddressWebsites()} until one returns an IP address.
-     * The address is assumed to be the external IP address of localhost.
-     * @param blockFor The maximum duration to wait for the IP address to be resolved.
-     *                 An indefinite way if null.
-     * @return A string in IPv4 format, or null if no such address could be ascertained.
-     */
-    private static String doLoad(Duration blockFor) {
-        if (localExternalIp != null) {
-            return localExternalIp;
-        }
-
-        final List<String> candidateUrls = getIpAddressWebsites();
-        if (candidateUrls.isEmpty()) {
-            LOG.debug("No candidate URLs to use to determine external IP of localhost");
-            return null;
-        }
-
-        // do in private thread, otherwise blocks for 30s+ on dodgy network!
-        // (we can skip it if someone else is doing it, we have synch lock so we'll get notified)
-        if (retrievingLocalExternalIp.compareAndSet(false, true)) {
-            new Thread() {
-                public void run() {
-                    for (String url : candidateUrls) {
-                        try {
-                            LOG.debug("Looking up external IP of this host from {} in private thread {}", url, Thread.currentThread());
-                            localExternalIp = new IpLoader(url).call();
-                            LOG.debug("Finished looking up external IP of this host from {} in private thread, result {}", url, localExternalIp);
-                            break;
-                        } catch (Throwable t) {
-                            LOG.debug("Unable to look up external IP of this host from {}, probably offline {})", url, t);
-                        } finally {
-                            retrievingLocalExternalIp.set(false);
-                            triedLocalExternalIp.countDown();
-                        }
-                    }
-                }
-            }.start();
-        }
-
-        try {
-            if (blockFor!=null) {
-                Durations.await(triedLocalExternalIp, blockFor);
-            } else {
-                triedLocalExternalIp.await();
-            }
-        } catch (InterruptedException e) {
-            throw Exceptions.propagate(e);
-        }
-        if (localExternalIp == null) {
-            return null;
-        }
-        return localExternalIp;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/geo/MaxMind2HostGeoLookup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/geo/MaxMind2HostGeoLookup.java b/core/src/main/java/brooklyn/location/geo/MaxMind2HostGeoLookup.java
deleted file mode 100644
index da79c29..0000000
--- a/core/src/main/java/brooklyn/location/geo/MaxMind2HostGeoLookup.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.internal.BrooklynSystemProperties;
-import brooklyn.util.net.Networking;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-import com.maxmind.geoip2.DatabaseReader;
-import com.maxmind.geoip2.model.CityResponse;
-import com.maxmind.geoip2.record.Subdivision;
-
-public class MaxMind2HostGeoLookup implements HostGeoLookup {
-
-    public static final Logger log = LoggerFactory.getLogger(MaxMind2HostGeoLookup.class);
-    
-    static final String MAXMIND_DB_URL = "http://dev.maxmind.com/geoip/geoip2/geolite2/#Downloads";
-    // TODO this should be configurable from system property or brooklyn.properties
-    // TODO and should use properties BrooklynServerConfig.MGMT_BASE_DIR (but hard to get mgmt properties here!)
-    static final String MAXMIND_DB_PATH = System.getProperty("user.home")+"/"+".brooklyn/"+"GeoLite2-City.mmdb";
-    
-    static boolean lookupFailed = false;
-    static DatabaseReader databaseReader = null;
-    
-    public static synchronized DatabaseReader getDatabaseReader() {
-        if (databaseReader!=null) return databaseReader;
-        try {
-            File f = new File(MAXMIND_DB_PATH);
-            databaseReader = new DatabaseReader.Builder(f).build();
-        } catch (IOException e) {
-            lookupFailed = true;
-            log.debug("MaxMind geo lookup unavailable; either download and unpack the latest "+
-                    "binary from "+MAXMIND_DB_URL+" into "+MAXMIND_DB_PATH+", "+
-                    "or specify a different HostGeoLookup implementation with the key "+
-                    BrooklynSystemProperties.HOST_GEO_LOOKUP_IMPL.getPropertyName()+" (error trying to read: "+e+")");
-        }
-        return databaseReader;
-    }
-    
-    public HostGeoInfo getHostGeoInfo(InetAddress address) throws MalformedURLException, IOException {
-        if (lookupFailed) return null;
-        
-        DatabaseReader ll = getDatabaseReader();
-        if (ll==null) return null;
-        
-        InetAddress extAddress = address;
-        if (Networking.isPrivateSubnet(extAddress)) extAddress = InetAddress.getByName(LocalhostExternalIpLoader.getLocalhostIpQuicklyOrDefault());
-        
-        try {
-            CityResponse l = ll.city(extAddress);
-            if (l==null) {
-                if (log.isDebugEnabled()) log.debug("Geo info failed to find location for address {}, using {}", extAddress, ll);
-                return null;
-            }
-            
-            StringBuilder name = new StringBuilder();
-            
-            if (l.getCity()!=null && l.getCity().getName()!=null) name.append(l.getCity().getName());
-            
-            if (l.getSubdivisions()!=null) {
-                for (Subdivision subd: Lists.reverse(l.getSubdivisions())) {
-                    if (name.length()>0) name.append(", ");
-                    // prefer e.g. USA state codes over state names
-                    if (!Strings.isBlank(subd.getIsoCode())) 
-                        name.append(subd.getIsoCode());
-                    else
-                        name.append(subd.getName());
-                }
-            }
-            
-            if (l.getCountry()!=null) {
-                if (name.length()==0) {
-                    name.append(l.getCountry().getName());
-                } else {
-                    name.append(" ("); name.append(l.getCountry().getIsoCode()); name.append(")");
-                }
-            }
-
-            
-            HostGeoInfo geo = new HostGeoInfo(address.getHostName(), name.toString(), l.getLocation().getLatitude(), l.getLocation().getLongitude());
-            log.debug("Geo info lookup (MaxMind DB) for "+address+" returned: "+geo);
-            return geo;
-        } catch (Exception e) {
-            if (log.isDebugEnabled())
-                log.debug("Geo info lookup failed: "+e);
-            throw Throwables.propagate(e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/geo/UtraceHostGeoLookup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/geo/UtraceHostGeoLookup.java b/core/src/main/java/brooklyn/location/geo/UtraceHostGeoLookup.java
deleted file mode 100644
index 10b21df..0000000
--- a/core/src/main/java/brooklyn/location/geo/UtraceHostGeoLookup.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * 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 brooklyn.location.geo;
-
-import groovy.util.Node;
-import groovy.util.NodeList;
-import groovy.util.XmlParser;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.javalang.JavaClassNames;
-import brooklyn.util.net.Networking;
-import brooklyn.util.time.Duration;
-import brooklyn.util.time.Durations;
-
-import com.google.common.base.Throwables;
-
-public class UtraceHostGeoLookup implements HostGeoLookup {
-
-
-    /*
-     * 
-http://xml.utrace.de/?query=88.198.156.18 
-(IP address or hostname)
-
-The XML result is as follows:
-
-<?xml version="1.0" encoding="iso-8869-1"?>
-<results>
-<result>
-<ip>88.198.156.18</ip>
-<host>utrace.de</host>
-<isp>Hetzner Online AG</isp>
-<org>Pagedesign GmbH</org>
-<region>Hamburg</region>
-<countrycode>DE</countrycode>
-<latitude>53.5499992371</latitude>
-<longitude>10</longitude>
-<queries>10</queries>
-</result>
-</results>
-
-Note the queries count field -- you are permitted 100 per day.
-Beyond this you get blacklisted and requests may time out, or return none.
-(This may last for several days once blacklisting, not sure how long.)
-     */
-    
-    /** after failures, subsequent retries within this time interval are blocked */
-    private static final Duration RETRY_INTERVAL = Duration.FIVE_MINUTES;
-    /** requests taking longer than this period are deemed to have timed out and failed;
-     * set reasonably low so that if we are blacklisted for making too many requests,
-     * the call to get geo info does not take very long */
-    private static final Duration REQUEST_TIMEOUT = Duration.seconds(3);
-    
-    public static final Logger log = LoggerFactory.getLogger(UtraceHostGeoLookup.class);
-    
-    public String getLookupUrlForPublicIp(String ip) {
-        return "http://xml.utrace.de/?query="+ip.trim();
-    }
-
-    /**
-     * @deprecated since 0.7.0. Use {@link brooklyn.location.geo.LocalhostExternalIpLoader} instead.
-     */
-    @Deprecated
-    public static String getLocalhostExternalIp() {
-        return LocalhostExternalIpLoader.getLocalhostIpWithin(Duration.seconds(2));
-    }
-    
-    /**
-     * @deprecated since 0.7.0. Use {@link brooklyn.location.geo.LocalhostExternalIpLoader} instead.
-     */
-    @Deprecated
-    public static String getLocalhostExternalIpImpl() {
-        return LocalhostExternalIpLoader.getLocalhostIpWithin(Duration.seconds(2));
-    }
-    
-    public String getLookupUrlForLocalhost() {
-        return getLookupUrlForPublicIp(LocalhostExternalIpLoader.getLocalhostIpQuicklyOrDefault());
-    }
-
-    /** returns URL to get properties for the given address (assuming localhost if address is on a subnet) */
-    public String getLookupUrlFor(InetAddress address) {
-        if (Networking.isPrivateSubnet(address)) return getLookupUrlForLocalhost();
-        return getLookupUrlForPublicIp(address.getHostAddress());
-    }
-    
-    private static boolean LOGGED_GEO_LOOKUP_UNAVAILABLE = false;
-    private static long LAST_FAILURE_UTC = -1;
-    
-    /** does the {@link #retrieveHostGeoInfo(InetAddress)}, but in the background with a default timeout */
-    public HostGeoInfo getHostGeoInfo(InetAddress address) throws MalformedURLException, IOException {
-        if (Duration.sinceUtc(LAST_FAILURE_UTC).compareTo(RETRY_INTERVAL) < 0) {
-            // wait at least 60s since a failure
-            return null;
-        }
-        return getHostGeoInfo(address, REQUEST_TIMEOUT);
-    }
-    
-    /** does a {@link #retrieveHostGeoInfo(InetAddress)} with a timeout (returning null, interrupting, and setting failure time) */
-    public HostGeoInfo getHostGeoInfo(final InetAddress address, Duration timeout) throws MalformedURLException, IOException {
-        final AtomicReference<HostGeoInfo> result = new AtomicReference<HostGeoInfo>();
-        Thread lt = new Thread() {
-            public void run() {
-                try {
-                    result.set(retrieveHostGeoInfo(address));
-                } catch (Exception e) {
-                    log.warn("Error computing geo info for "+address+"; internet issues or too many requests to (free) servers for "+JavaClassNames.simpleClassName(UtraceHostGeoLookup.this)+": "+e);
-                    log.debug("Detail of host geo error: "+e, e);
-                }
-            }
-        };
-        lt.start();
-
-        try {
-            Durations.join(lt, timeout);
-        } catch (InterruptedException e) {
-            throw Exceptions.propagate(e);
-        }
-        
-        if (lt.isAlive()) {
-            // interrupt and set the failure time so that subsequent attempts do not face this timeout
-            lt.interrupt();
-            LAST_FAILURE_UTC = System.currentTimeMillis();
-            log.debug("Geo info lookup for "+address+" timed out after "+timeout);
-        }
-        
-        return result.get();
-    }
-    
-    public HostGeoInfo retrieveHostGeoInfo(InetAddress address) throws MalformedURLException, IOException {
-        String url = getLookupUrlFor(address);
-        if (log.isDebugEnabled())
-            log.debug("Geo info lookup for "+address+" at "+url);
-        Node xml;
-        try {
-            xml = new XmlParser().parse(getLookupUrlFor(address));
-        } catch (Exception e) {
-            LAST_FAILURE_UTC = System.currentTimeMillis();
-            if (log.isDebugEnabled())
-                log.debug("Geo info lookup for "+address+" failed: "+e);
-            if (!LOGGED_GEO_LOOKUP_UNAVAILABLE) {
-                LOGGED_GEO_LOOKUP_UNAVAILABLE = true;
-                log.info("Geo info lookup unavailable (for "+address+"; cause "+e+")");
-            }
-            return null;
-        }
-        try {
-            String org = getXmlResultsField(xml, "org").trim();
-            if (org.isEmpty()) org = getXmlResultsField(xml, "isp").trim();
-            String region = getXmlResultsField(xml, "region").trim();
-            if (!org.isEmpty()) {
-                if (!region.isEmpty()) region = org+", "+region;
-                else region = org;
-            }
-            if (region.isEmpty()) region = getXmlResultsField(xml, "isp").trim();
-            if (region.isEmpty()) region = address.toString();
-            HostGeoInfo geo = new HostGeoInfo(address.getHostName(), 
-                    region+
-                    " ("+getXmlResultsField(xml, "countrycode")+")", 
-                    Double.parseDouble(""+getXmlResultsField(xml, "latitude")), 
-                    Double.parseDouble(""+getXmlResultsField(xml, "longitude")));
-            log.info("Geo info lookup for "+address+" returned: "+geo);
-            return geo;
-        } catch (Exception e) {
-            if (log.isDebugEnabled())
-                log.debug("Geo info lookup failed, for "+address+" at "+url+", due to "+e+"; response is "+xml);
-            throw Throwables.propagate(e);
-        }
-    }
-    
-    @Nullable
-    private static Node getFirstChild(Node xml, String field) {
-        if (xml==null) return null;
-        NodeList nl = (NodeList)xml.get(field);
-        if (nl==null || nl.isEmpty()) return null;
-        return (Node)nl.get(0);
-    }
-    @Nonnull
-    private static String getXmlResultsField(Node xml, String field) {
-        Node f1 = getFirstChild(getFirstChild(xml, "result"), field);
-        if (f1==null) return "";
-        return f1.text();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/location/paas/PaasLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/paas/PaasLocation.java b/core/src/main/java/brooklyn/location/paas/PaasLocation.java
deleted file mode 100644
index 6165e04..0000000
--- a/core/src/main/java/brooklyn/location/paas/PaasLocation.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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 brooklyn.location.paas;
-
-import brooklyn.location.Location;
-
-/**
- * {@link Location} representing an application container on a PaaS provider.
- */
-public interface PaasLocation extends Location {
-    
-    String getPaasProviderName();
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java b/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
index 8481e6e..b933e6b 100644
--- a/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
+++ b/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
@@ -60,7 +60,7 @@ import brooklyn.entity.rebind.plane.dto.BasicManagementNodeSyncRecord;
 import brooklyn.entity.rebind.plane.dto.ManagementPlaneSyncRecordImpl;
 import brooklyn.entity.rebind.plane.dto.ManagementPlaneSyncRecordImpl.Builder;
 import brooklyn.internal.BrooklynFeatureEnablement;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.ha.BasicMasterChooser.AlphabeticMasterChooser;
 import brooklyn.management.internal.BrooklynObjectManagementMode;
 import brooklyn.management.internal.LocalEntityManager;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
index b85e133..4c790b6 100644
--- a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
@@ -66,8 +66,8 @@ import brooklyn.internal.storage.DataGrid;
 import brooklyn.internal.storage.DataGridFactory;
 import brooklyn.internal.storage.impl.BrooklynStorageImpl;
 import brooklyn.internal.storage.impl.inmemory.InMemoryDataGridFactory;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.basic.BasicLocationRegistry;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 import brooklyn.management.classloading.JavaBrooklynClassLoadingContext;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.ha.HighAvailabilityManagerImpl;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java b/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
index fdf2803..5bb6eac 100644
--- a/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
+++ b/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
@@ -49,7 +49,7 @@ import brooklyn.entity.basic.BrooklynTaskTags.WrappedStream;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
 import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java b/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java
index d169e33..3874d3d 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalAccessManager.java
@@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicReference;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.management.AccessController;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.annotations.Beta;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
index cb9a7e2..3d6acfd 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
@@ -36,11 +36,11 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.ProvisioningLocation;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.ProvisioningLocation;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocationInternal;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java b/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java
index beb568f..73a362f 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java
@@ -53,7 +53,7 @@ import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.internal.BrooklynFeatureEnablement;
 import brooklyn.internal.storage.DataGridFactory;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.ha.OsgiManager;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java b/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
index 9ae12f5..31084a4 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
@@ -41,10 +41,10 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.basic.LocationInternal;
 import brooklyn.management.ManagementContextInjectable;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.usage.ApplicationUsage;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java b/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java
index f36f5df..2d126bc 100644
--- a/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java
+++ b/core/src/main/java/brooklyn/management/internal/LocationManagerInternal.java
@@ -20,7 +20,7 @@ package brooklyn.management.internal;
 
 import org.apache.brooklyn.api.management.LocationManager;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public interface LocationManagerInternal extends LocationManager, BrooklynObjectManagerInternal<Location> {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java b/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java
index 46bdbf8..699b34f 100644
--- a/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java
+++ b/core/src/main/java/brooklyn/management/internal/ManagementContextInternal.java
@@ -36,7 +36,7 @@ import brooklyn.entity.proxying.InternalEntityFactory;
 import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.ha.OsgiManager;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.task.TaskTags;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java b/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java
index 97c10c7..eaad030 100644
--- a/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java
+++ b/core/src/main/java/brooklyn/management/internal/NonDeploymentLocationManager.java
@@ -24,8 +24,8 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.management.ManagementContext;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
 
 public class NonDeploymentLocationManager implements LocationManagerInternal {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java b/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
index cb0e9ef..eff0417 100644
--- a/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
@@ -66,8 +66,8 @@ import brooklyn.entity.proxying.InternalEntityFactory;
 import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.ha.OsgiManager;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java b/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java
index c8508a1..55577d4 100644
--- a/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java
+++ b/core/src/main/java/brooklyn/management/internal/NonDeploymentUsageManager.java
@@ -23,7 +23,7 @@ import java.util.Set;
 import org.apache.brooklyn.api.entity.Application;
 
 import brooklyn.entity.basic.Lifecycle;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.usage.ApplicationUsage;
 import brooklyn.management.usage.LocationUsage;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/UsageListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/UsageListener.java b/core/src/main/java/brooklyn/management/internal/UsageListener.java
index 44c5e67..3914802 100644
--- a/core/src/main/java/brooklyn/management/internal/UsageListener.java
+++ b/core/src/main/java/brooklyn/management/internal/UsageListener.java
@@ -22,7 +22,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Application;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.usage.ApplicationUsage.ApplicationEvent;
 import brooklyn.management.usage.LocationUsage.LocationEvent;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/management/internal/UsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/UsageManager.java b/core/src/main/java/brooklyn/management/internal/UsageManager.java
index 2263691..bc4dfe5 100644
--- a/core/src/main/java/brooklyn/management/internal/UsageManager.java
+++ b/core/src/main/java/brooklyn/management/internal/UsageManager.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.api.entity.Application;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Lifecycle;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.management.usage.ApplicationUsage;
 import brooklyn.management.usage.ApplicationUsage.ApplicationEvent;
 import brooklyn.management.usage.LocationUsage;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/core/src/main/java/brooklyn/util/BrooklynNetworkUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/BrooklynNetworkUtils.java b/core/src/main/java/brooklyn/util/BrooklynNetworkUtils.java
index 86bf827..0c1d39d 100644
--- a/core/src/main/java/brooklyn/util/BrooklynNetworkUtils.java
+++ b/core/src/main/java/brooklyn/util/BrooklynNetworkUtils.java
@@ -21,7 +21,7 @@ package brooklyn.util;
 import java.net.InetAddress;
 
 import brooklyn.config.BrooklynServiceAttributes;
-import brooklyn.location.geo.LocalhostExternalIpLoader;
+import org.apache.brooklyn.location.geo.LocalhostExternalIpLoader;
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.net.Networking;
 



[03/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
index 27fbe3a..44141a6 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
@@ -47,8 +47,8 @@ import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
-import brooklyn.location.Location;
-import brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.Machines;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
index 0275eef..a3cf775 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
@@ -30,7 +30,7 @@ import brooklyn.entity.annotation.Effector;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.group.DynamicFabric;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Function;
 import com.google.common.collect.Multimap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java
index 158a11c..6ae43b5 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricImpl.java
@@ -38,7 +38,7 @@ import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicFabricImpl;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java
index d08f06f..21fbbb7 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java
@@ -38,7 +38,7 @@ import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
index 33ab467..41c3d97 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
@@ -52,10 +52,10 @@ import brooklyn.event.feed.jmx.JmxAttributePollConfig;
 import brooklyn.event.feed.jmx.JmxFeed;
 import brooklyn.event.feed.jmx.JmxHelper;
 import brooklyn.event.feed.jmx.JmxOperationPollConfig;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
index 8e69af0..88a66c2 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
@@ -44,10 +44,10 @@ import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
 import brooklyn.entity.java.UsesJmx;
 import brooklyn.entity.software.SshEffectorTasks;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.Location;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
index c601396..6dbd5b4 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
@@ -52,7 +52,7 @@ import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.event.feed.http.JsonFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import brooklyn.util.collections.CollectionFunctionals;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.collections.QuorumCheck;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
index abe0271..eaf8794 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
@@ -40,9 +40,9 @@ import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.event.feed.http.JsonFunctions;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
index 06634df..cf80118 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
@@ -43,9 +43,9 @@ import brooklyn.entity.drivers.downloads.DownloadProducerFromUrlAttribute;
 import brooklyn.entity.software.SshEffectorTasks;
 import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.OsDetails;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java
index 14d8760..6d52bc4 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java
@@ -23,7 +23,7 @@ import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 
 import com.google.common.base.Functions;
 import com.google.common.net.HostAndPort;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
index d4b22c7..f3d7636 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
@@ -34,8 +34,8 @@ import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.ssh.BashCommands;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java
index 5545f08..308aede 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java
@@ -29,8 +29,8 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Attributes;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java
index 40c69e7..a2d82c0 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java
@@ -31,7 +31,7 @@ import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
index 9223eb8..4478ac3 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
@@ -27,7 +27,7 @@ import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.event.feed.http.JsonFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import brooklyn.util.guava.Functionals;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.guava.MaybeFunctions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeSshDriver.java
index 25383b8..062666b 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeSshDriver.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
index 398d6be..6a4c052 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBSshDriver.java
@@ -29,8 +29,8 @@ import org.slf4j.LoggerFactory;
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.net.Networking;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
index c8896e7..be4bb8e 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
@@ -30,7 +30,7 @@ import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeploymen
 
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.math.MathPredicates;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
index d9997aa..8ca8ee0 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSupport.java
@@ -36,8 +36,7 @@ import com.mongodb.MongoClientOptions;
 import com.mongodb.MongoException;
 import com.mongodb.ServerAddress;
 
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.util.BrooklynNetworkUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 
 /**
  * Manages connections to standalone MongoDB servers.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
index d5429ff..f63fd48 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
@@ -49,7 +49,7 @@ import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
index e41418a..505b557 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
@@ -32,7 +32,7 @@ import brooklyn.config.render.RendererHints;
 import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 
 import com.google.common.base.Functions;
 import com.google.common.base.Objects;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSshDriver.java
index 819014d..fb10378 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSshDriver.java
@@ -19,7 +19,7 @@
 package org.apache.brooklyn.entity.nosql.mongodb;
 
 import static com.google.common.base.Preconditions.checkState;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/ReplicaSetConfig.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/ReplicaSetConfig.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/ReplicaSetConfig.java
index a4ecebb..5d2723d 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/ReplicaSetConfig.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/ReplicaSetConfig.java
@@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Optional;
 import com.google.common.net.HostAndPort;
 
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 
 /**
  * Simplifies the creation of configuration objects for Mongo DB replica sets.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
index eae7485..9f84a7f 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
@@ -27,7 +27,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.SameServerEntityImpl;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.DependentConfiguration;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java
index 6f37fab..05cf7ac 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerClusterImpl.java
@@ -24,13 +24,11 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 
 import brooklyn.entity.group.DynamicClusterImpl;
-import brooklyn.location.Location;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
-import com.google.common.net.HostAndPort;
 
 public class MongoDBConfigServerClusterImpl extends DynamicClusterImpl implements MongoDBConfigServerCluster {
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerSshDriver.java
index 535bab6..d5d5127 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerSshDriver.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.nosql.mongodb.sharding;
 import org.apache.brooklyn.entity.nosql.mongodb.AbstractMongoDBSshDriver;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBDriver;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 public class MongoDBConfigServerSshDriver extends AbstractMongoDBSshDriver implements MongoDBDriver {
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java
index d067d14..1b1a2d6 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterClusterImpl.java
@@ -30,7 +30,7 @@ import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
index 422b9ac..2d2a352 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterSshDriver.java
@@ -22,7 +22,7 @@ import org.apache.brooklyn.entity.nosql.mongodb.AbstractMongoDBSshDriver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java
index 5771b97..0e66638 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardClusterImpl.java
@@ -38,9 +38,8 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.group.DynamicClusterImpl;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.text.Strings;
 import brooklyn.util.time.Duration;
 import brooklyn.util.time.Time;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
index 4e36250..420cd93 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
@@ -40,7 +40,7 @@ import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
index 82ed7b2..c977b02 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
@@ -32,7 +32,7 @@ import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChild
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.QuorumCheck.QuorumChecks;
 import brooklyn.util.exceptions.CompoundRuntimeException;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
index c2d559f..01a8de6 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
@@ -30,9 +30,9 @@ import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshPollValue;
 import brooklyn.event.feed.ssh.SshValueFunctions;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.base.Function;
 import com.google.common.base.Functions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java
index c362e4e..de60319 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreSshDriver.java
@@ -27,8 +27,8 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;
 import brooklyn.util.ssh.BashCommands;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
index 2eeaa4f9..9c9c93b 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
@@ -37,9 +37,9 @@ import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.guava.Functionals;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
index 1815673..d137007 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
@@ -44,8 +44,8 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.OsDetails;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.net.Urls;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java
index 696cb97..f813ced 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java
@@ -32,7 +32,7 @@ import brooklyn.entity.java.UsesJavaMXBeans;
 import brooklyn.entity.java.UsesJmx;
 import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java
index a42d15b..ab076b1 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java
@@ -23,7 +23,7 @@ import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 import com.google.common.base.Functions;
 import com.google.common.net.HostAndPort;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java
index f05624e..2569fea 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerSshDriver.java
@@ -29,10 +29,9 @@ import brooklyn.entity.java.UsesJmx;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.file.ArchiveUtils;
 import brooklyn.util.net.Networking;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java
index ab158bd..d977785 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/AbstractCassandraNodeTest.java
@@ -18,11 +18,10 @@
  */
 package org.apache.brooklyn.entity.nosql.cassandra;
 
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode;
 import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * Cassandra test framework for integration and live tests.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java
index 153f8f6..216531e 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterIntegrationTest.java
@@ -25,8 +25,6 @@ import static org.testng.Assert.assertTrue;
 import java.math.BigInteger;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode;
 import org.apache.brooklyn.entity.nosql.cassandra.TokenGenerators.PosNeg63TokenGenerator;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
@@ -38,7 +36,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java
index 5f15fb7..b15f7b1 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterLiveTest.java
@@ -31,8 +31,6 @@ import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode;
 import org.apache.brooklyn.entity.nosql.cassandra.AstyanaxSupport.AstyanaxSample;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
@@ -46,7 +44,7 @@ import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.text.Identifiers;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterRebindIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterRebindIntegrationTest.java
index 88af1b9..1a3142a 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterRebindIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterRebindIntegrationTest.java
@@ -24,8 +24,6 @@ import java.math.BigInteger;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode;
 import org.apache.brooklyn.entity.proxy.nginx.NginxController;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
@@ -37,7 +35,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.rebind.RebindOptions;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java
index 78d3224..83adf75 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterTest.java
@@ -26,8 +26,6 @@ import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -40,8 +38,8 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.EmptySoftwareProcess;
 import brooklyn.entity.basic.EmptySoftwareProcessSshDriver;
 import brooklyn.entity.basic.EntityInternal;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.text.TemplateProcessor;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java
index a8eee86..6ff8d3f 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabricTest.java
@@ -27,8 +27,6 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraFabric;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,9 +41,9 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java
index 8f8976a..234cad2 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeEc2LiveTest.java
@@ -19,14 +19,13 @@
 package org.apache.brooklyn.entity.nosql.cassandra;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode;
 import org.apache.brooklyn.entity.nosql.cassandra.AstyanaxSupport.AstyanaxSample;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java
index 56294e9..e0053b6 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseOfflineTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.brooklyn.entity.nosql.couchbase;
 
-import org.apache.brooklyn.entity.nosql.couchbase.CouchbaseNodeSshDriver;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -26,8 +25,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.BasicOsDetails;
-import brooklyn.location.basic.BasicOsDetails.OsArchs;
+import org.apache.brooklyn.location.basic.BasicOsDetails;
+import org.apache.brooklyn.location.basic.BasicOsDetails.OsArchs;
 import brooklyn.management.internal.LocalManagementContext;
 
 public class CouchbaseOfflineTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java
index 954e1cb..3b5bfb6 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayEc2LiveTest.java
@@ -22,16 +22,13 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.couchbase.CouchbaseCluster;
-import org.apache.brooklyn.entity.nosql.couchbase.CouchbaseNode;
-import org.apache.brooklyn.entity.nosql.couchbase.CouchbaseSyncGateway;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
index 8429dc4..46be4a1 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.brooklyn.entity.nosql.couchdb;
 
-import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -27,8 +26,8 @@ import org.testng.annotations.BeforeMethod;
 
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.internal.TimeExtras;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java
index 87d94cb..e09637b 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBClusterLiveTest.java
@@ -21,8 +21,6 @@ package org.apache.brooklyn.entity.nosql.couchdb;
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.couchdb.CouchDBCluster;
-import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -32,7 +30,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java
index 677f67c..66ff739 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeEc2LiveTest.java
@@ -19,14 +19,13 @@
 package org.apache.brooklyn.entity.nosql.couchdb;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.couchdb.CouchDBNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
index d0b6ad8..6a235b5 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
@@ -26,8 +26,6 @@ import java.net.URISyntaxException;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchCluster;
-import org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.http.client.methods.HttpGet;
 import org.bouncycastle.util.Strings;
@@ -41,7 +39,7 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
index a9febc1..27b9170 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
@@ -24,7 +24,6 @@ import java.net.URI;
 import java.net.URISyntaxException;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.elasticsearch.ElasticSearchNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.http.client.methods.HttpGet;
@@ -38,8 +37,8 @@ import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.http.HttpTool;
 import brooklyn.util.http.HttpToolResponse;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
index 20ef953..0de6fdd 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBEc2LiveTest.java
@@ -19,7 +19,7 @@
 package org.apache.brooklyn.entity.nosql.mongodb;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.mongodb.DBObject;
@@ -31,7 +31,6 @@ import org.testng.annotations.Test;
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.apache.brooklyn.test.EntityTestUtils;
 
 public class MongoDBEc2LiveTest extends AbstractEc2LiveTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java
index 7b9bef1..1464599 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBIntegrationTest.java
@@ -22,7 +22,6 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -32,7 +31,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 import com.google.common.collect.ImmutableList;
 import com.mongodb.DBObject;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java
index 5f225ea..d929d74 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBRebindIntegrationTest.java
@@ -19,13 +19,12 @@
 package org.apache.brooklyn.entity.nosql.mongodb;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java
index 7c8d34a..e0c57fb 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetEc2LiveTest.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.nosql.mongodb;
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;
@@ -31,8 +31,6 @@ import com.mongodb.DBObject;
 import groovy.time.TimeDuration;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java
index 9d5bbc8..3d1d10f 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetIntegrationTest.java
@@ -28,8 +28,6 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.BeforeMethod;
@@ -38,7 +36,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java
index 8c18bae..0972ea5 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBSoftLayerLiveTest.java
@@ -21,7 +21,6 @@ package org.apache.brooklyn.entity.nosql.mongodb;
 import static org.testng.Assert.assertEquals;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -31,7 +30,7 @@ import com.google.common.collect.ImmutableList;
 import com.mongodb.DBObject;
 
 import brooklyn.entity.AbstractSoftlayerLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class MongoDBSoftLayerLiveTest extends AbstractSoftlayerLiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBTestHelper.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBTestHelper.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBTestHelper.java
index 9b890fa..28befd7 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBTestHelper.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBTestHelper.java
@@ -22,8 +22,6 @@ import java.net.UnknownHostException;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.brooklyn.entity.nosql.mongodb.AbstractMongoDBServer;
-import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.bson.types.ObjectId;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -38,7 +36,7 @@ import com.mongodb.DBObject;
 import com.mongodb.MongoClient;
 import com.mongodb.ReadPreference;
 
-import brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
 
 public class MongoDBTestHelper {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerIntegrationTest.java
index d39851d..162f77e 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerIntegrationTest.java
@@ -23,7 +23,6 @@ import static org.testng.Assert.assertFalse;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBTestHelper;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBConfigServer;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -33,7 +32,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java
index f7e5ce7..aab8518 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentEc2LiveTest.java
@@ -24,15 +24,12 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBConfigServer;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouter;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentIntegrationTest.java
index cdc2767..abc87d6 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentIntegrationTest.java
@@ -24,12 +24,6 @@ import org.apache.brooklyn.entity.nosql.mongodb.AbstractMongoDBServer;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
 import org.apache.brooklyn.entity.nosql.mongodb.MongoDBTestHelper;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBConfigServer;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBConfigServerCluster;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouter;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouterCluster;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardCluster;
-import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
@@ -37,7 +31,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppLiveTestSupport;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java
index 05d36f6..650ce61 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterIntegrationTest.java
@@ -25,9 +25,6 @@ import java.util.List;
 import java.util.concurrent.Callable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.redis.RedisCluster;
-import org.apache.brooklyn.entity.nosql.redis.RedisSlave;
-import org.apache.brooklyn.entity.nosql.redis.RedisStore;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -38,8 +35,8 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java
index f81fe05..f655b8c 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisEc2LiveTest.java
@@ -21,14 +21,13 @@ package org.apache.brooklyn.entity.nosql.redis;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.redis.RedisStore;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java
index 2530aaa..aace8d6 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/redis/RedisIntegrationTest.java
@@ -21,7 +21,6 @@ package org.apache.brooklyn.entity.nosql.redis;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.redis.RedisStore;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -30,8 +29,8 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.Location;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java
index a7364a7..27ebc35 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterEc2LiveTest.java
@@ -19,8 +19,6 @@
 package org.apache.brooklyn.entity.nosql.riak;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.riak.RiakCluster;
-import org.apache.brooklyn.entity.nosql.riak.RiakNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,7 +26,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.AbstractEc2LiveTest;
 import brooklyn.entity.basic.Attributes;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java
index 01004b1..6f768b8 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeEc2LiveTest.java
@@ -19,7 +19,6 @@
 package org.apache.brooklyn.entity.nosql.riak;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.riak.RiakNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -28,7 +27,7 @@ import org.testng.annotations.Test;
 import com.google.common.collect.ImmutableList;
 
 import brooklyn.entity.AbstractEc2LiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class RiakNodeEc2LiveTest extends AbstractEc2LiveTest {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java
index 03c2ca0..c93b318 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeGoogleComputeLiveTest.java
@@ -19,8 +19,6 @@
 package org.apache.brooklyn.entity.nosql.riak;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.riak.RiakCluster;
-import org.apache.brooklyn.entity.nosql.riak.RiakNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.testng.annotations.Test;
 
@@ -28,7 +26,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
 import brooklyn.entity.AbstractGoogleComputeLiveTest;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class RiakNodeGoogleComputeLiveTest extends AbstractGoogleComputeLiveTest {
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java
index c2251fe..0b3d9ba 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeIntegrationTest.java
@@ -21,7 +21,6 @@ package org.apache.brooklyn.entity.nosql.riak;
 import static org.testng.Assert.assertFalse;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
-import org.apache.brooklyn.entity.nosql.riak.RiakNode;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.annotations.AfterMethod;
@@ -32,7 +31,7 @@ import com.google.common.collect.ImmutableList;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 
 public class RiakNodeIntegrationTest {
 



[06/54] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.location

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.groovy
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.groovy b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.groovy
new file mode 100644
index 0000000..092c85c
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/AwsEc2LocationWindowsLiveTest.groovy
@@ -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.apache.brooklyn.location.jclouds.provider;
+
+import static org.testng.Assert.*
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.testng.annotations.AfterMethod
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+
+import brooklyn.entity.basic.Entities
+import org.apache.brooklyn.location.basic.SshMachineLocation
+import org.apache.brooklyn.location.jclouds.JcloudsLocation
+import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation
+import org.apache.brooklyn.api.management.ManagementContext
+
+import com.google.common.collect.ImmutableMap
+
+public class AwsEc2LocationWindowsLiveTest {
+    private static final Logger LOG = LoggerFactory.getLogger(AwsEc2LocationWindowsLiveTest.class)
+    
+    private static final String PROVIDER = "aws-ec2"
+    private static final String EUWEST_REGION_NAME = "eu-west-1" 
+    private static final String EUWEST_IMAGE_ID = EUWEST_REGION_NAME+"/"+"ami-7f0c260b";//"ami-41d3d635"
+    private static final String LOCATION_ID = "jclouds:"+PROVIDER+":"+EUWEST_REGION_NAME;
+    
+    protected JcloudsLocation loc;
+    protected Collection<SshMachineLocation> machines = []
+    protected ManagementContext ctx;
+    
+    @BeforeMethod(groups = "Live")
+    public void setUp() {
+        ctx = Entities.newManagementContext(ImmutableMap.of("provider", PROVIDER));
+
+        loc = ctx.locationRegistry.resolve LOCATION_ID
+    }
+
+    @AfterMethod(groups = "Live")
+    public void tearDown() {
+        List<Exception> exceptions = []
+        machines.each {
+            try {
+                loc?.release(it)
+            } catch (Exception e) {
+                LOG.warn("Error releasing machine $it; continuing...", e)
+                exceptions.add(e)
+            }
+        }
+        if (exceptions) {
+            throw exceptions.get(0)
+        }
+        machines.clear()
+    }
+    
+    // TODO Note careful choice of image due to jclouds 1.4 issue 886
+    // TODO Blocks for long time, waiting for IP:22 to be reachable, before falling back to using public IP
+    //      10*2 minutes per attempt in jclouds 1.4 because done sequentially, and done twice by us so test takes 40 minutes!
+    @Test(enabled=true, groups = [ "Live" ])
+    public void testProvisionWindowsVm() {
+        JcloudsSshMachineLocation machine = obtainMachine([ imageId:EUWEST_IMAGE_ID ]);
+
+        LOG.info("Provisioned Windows VM {}; checking if has password", machine)
+        assertNotNull(machine.waitForPassword())
+    }
+    
+    // Use this utility method to ensure machines are released on tearDown
+    protected SshMachineLocation obtainMachine(Map flags) {
+        SshMachineLocation result = loc.obtain(flags)
+        machines.add(result)
+        return result
+    }
+    
+    protected SshMachineLocation release(SshMachineLocation machine) {
+        machines.remove(machine)
+        loc.release(machine)
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/CarrenzaLocationLiveTest.groovy
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/CarrenzaLocationLiveTest.groovy b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/CarrenzaLocationLiveTest.groovy
new file mode 100644
index 0000000..3c23328
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/CarrenzaLocationLiveTest.groovy
@@ -0,0 +1,133 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.provider;
+
+import static org.testng.Assert.*
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.testng.annotations.AfterMethod
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+
+import brooklyn.config.BrooklynProperties
+import org.apache.brooklyn.location.basic.SshMachineLocation
+import org.apache.brooklyn.location.jclouds.JcloudsLocation
+import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation
+import brooklyn.management.internal.LocalManagementContext
+import brooklyn.util.collections.MutableMap
+
+import com.google.common.collect.ImmutableList
+
+/**
+ * Tests vcloud, with Carrenza. Uses the cloudsoft test account (hard-coding its NAT Mapping, 
+ * and one of its private vApp templates). Note that the template is for a Windows 2008 
+ * machine with winsshd installed.
+ * 
+ * TODO Will only work with >= jclouds 1.5, due to jclouds issues 994 and 995. Therefore it 
+ * will not work in brooklyn 0.4.0-M2 etc.
+ */
+class CarrenzaLocationLiveTest {
+    private static final Logger LOG = LoggerFactory.getLogger(CarrenzaLocationLiveTest.class)
+    
+    private static final String PROVIDER = "vcloud"
+    private static final String ENDPOINT = "https://myvdc.carrenza.net/api"
+    private static final String LOCATION_ID = "jclouds:"+PROVIDER+":"+ENDPOINT;
+    private static final String WINDOWS_IMAGE_ID = "https://myvdc.carrenza.net/api/v1.0/vAppTemplate/vappTemplate-2bd5b0ff-ecd9-405e-8306-2f4f6c092a1b"
+    
+    private BrooklynProperties brooklynProperties;
+    private LocalManagementContext managementContext;
+    private JcloudsLocation loc;
+    private Collection<SshMachineLocation> machines = []
+    
+    // TODO Has not been tested since updating ot remove use of deleted LocationRegistry!
+    @BeforeMethod(groups = "Live")
+    public void setUp() {
+        System.out.println("classpath="+System.getProperty("java.class.path"));
+        
+        brooklynProperties = BrooklynProperties.Factory.newDefault();
+        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-description-regex");
+        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-name-regex");
+        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".image-id");
+        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".inboundPorts");
+        brooklynProperties.remove("brooklyn.jclouds."+PROVIDER+".hardware-id");
+
+        // Also removes scriptHeader (e.g. if doing `. ~/.bashrc` and `. ~/.profile`, then that can cause "stdin: is not a tty")
+        brooklynProperties.remove("brooklyn.ssh.config.scriptHeader");
+        
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".jclouds.endpoint", ENDPOINT)
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".imageId", WINDOWS_IMAGE_ID)
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".noDefaultSshKeys", true)
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".userName", "Administrator")
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".dontCreateUser", true)
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".overrideLoginUser", "Administrator")
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".waitForSshable", false)
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".runAsRoot", false)
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".inboundPorts", [22, 3389])
+        brooklynProperties.put("brooklyn.jclouds."+PROVIDER+".natMapping", [("192.168.0.100"):"195.3.186.200", ("192.168.0.101"):"195.3.186.42"])
+
+        managementContext = new LocalManagementContext(brooklynProperties);
+        loc = (JcloudsLocation) managementContext.getLocationRegistry().resolve(LOCATION_ID);
+    }
+    
+    @AfterMethod(groups = "Live")
+    public void tearDown() {
+        List<Exception> exceptions = []
+        machines.each {
+            try {
+                loc?.release(it)
+            } catch (Exception e) {
+                LOG.warn("Error releasing machine $it; continuing...", e)
+                exceptions.add(e)
+            }
+        }
+        if (exceptions) {
+            throw exceptions.get(0)
+        }
+        machines.clear()
+    }
+    
+    // FIXME Disabled because of jclouds issues #994 and #995 (fixed in jclouds 1.5, so not in brooklyn 0.4.0-M2 etc)
+    // Note the careful settings in setUp (e.g. so don't try to install ssh-keys etc
+    // Also, the windows image used has winsshd installed
+    @Test(enabled=false, groups = [ "Live" ])
+    public void testProvisionWindowsVm() {
+        JcloudsSshMachineLocation machine = obtainMachine(MutableMap.of(
+                "imageId", WINDOWS_IMAGE_ID));
+        
+        LOG.info("Provisioned Windows VM {}; checking if has password", machine)
+        String password = machine.waitForPassword();
+        assertNotNull(password);
+        
+        LOG.info("Checking can ssh to windows machine {} using password {}", machine, password);
+        assertEquals(machine.execCommands(MutableMap.of("password", password), "check-reachable", ImmutableList.of("hostname")), 0);
+    }
+    
+    // Use this utility method to ensure machines are released on tearDown
+    protected SshMachineLocation obtainMachine(Map flags) {
+        SshMachineLocation result = loc.obtain(flags)
+        machines.add(result)
+        return result
+    }
+    
+    protected SshMachineLocation release(SshMachineLocation machine) {
+        machines.remove(machine)
+        loc.release(machine)
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/GoGridLocationLiveTest.groovy
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/GoGridLocationLiveTest.groovy b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/GoGridLocationLiveTest.groovy
new file mode 100644
index 0000000..5276302
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/GoGridLocationLiveTest.groovy
@@ -0,0 +1,52 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.provider
+
+import org.testng.annotations.DataProvider
+
+public class GoGridLocationLiveTest extends AbstractJcloudsLocationTest {
+    
+    private static final String PROVIDER = "gogrid"
+    private static final String USWEST_REGION_NAME = "1"//"us-west-1"
+    private static final String USWEST_IMAGE_ID = "1532"
+    private static final String IMAGE_NAME_PATTERN = "CentOS 5.3 (64-bit) w/ None"
+    private static final String IMAGE_OWNER = null
+    
+    public GoGridLocationLiveTest() {
+        super(PROVIDER)
+    }
+    
+    @Override
+    @DataProvider(name = "fromImageId")
+    public Object[][] cloudAndImageIds() {
+        return [ [USWEST_REGION_NAME, USWEST_IMAGE_ID, IMAGE_OWNER] ]
+    }
+
+    @Override
+    @DataProvider(name = "fromImageNamePattern")
+    public Object[][] cloudAndImageNamePatterns() {
+        return [ [USWEST_REGION_NAME, IMAGE_NAME_PATTERN, IMAGE_OWNER] ]
+    }
+    
+    @Override
+    @DataProvider(name = "fromImageDescriptionPattern")
+    public Object[][] cloudAndImageDescriptionPatterns() {
+        return []
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/RackspaceLocationLiveTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/RackspaceLocationLiveTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/RackspaceLocationLiveTest.java
new file mode 100644
index 0000000..737723a
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/provider/RackspaceLocationLiveTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.provider;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation;
+import brooklyn.util.collections.MutableMap;
+
+public class RackspaceLocationLiveTest extends AbstractJcloudsLocationTest {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RackspaceLocationLiveTest.class);
+
+    private static final String PROVIDER = "rackspace-cloudservers-uk";
+    private static final String REGION_NAME = null;
+    private static final String IMAGE_ID = "LON/f70ed7c7-b42e-4d77-83d8-40fa29825b85"; // CentOS 6.4
+    private static final String IMAGE_NAME_PATTERN = "CentOS 6.4";
+    private static final String IMAGE_OWNER = null;
+
+    public RackspaceLocationLiveTest() {
+        super(PROVIDER);
+    }
+
+    @Override
+    @DataProvider(name = "fromImageId")
+    public Object[][] cloudAndImageIds() {
+        return new Object[][] {
+            new Object[] { REGION_NAME, IMAGE_ID, IMAGE_OWNER }
+        };
+    }
+
+    @Override
+    @DataProvider(name = "fromImageNamePattern")
+    public Object[][] cloudAndImageNamePatterns() {
+        return new Object[][] {
+            new Object[] { REGION_NAME, IMAGE_NAME_PATTERN, IMAGE_OWNER }
+        };
+    }
+
+    @Override
+    @DataProvider(name = "fromImageDescriptionPattern")
+    public Object[][] cloudAndImageDescriptionPatterns() {
+        return new Object[0][0];
+    }
+
+    @Test(groups = "Live")
+    public void testVmMetadata() {
+        loc = (JcloudsLocation) ctx.getLocationRegistry().resolve(PROVIDER + (REGION_NAME == null ? "" : ":" + REGION_NAME));
+        SshMachineLocation machine = obtainMachine(MutableMap.of("imageId", IMAGE_ID, "userMetadata", MutableMap.of("mykey", "myval"), JcloudsLocation.MACHINE_CREATE_ATTEMPTS, 2));
+
+        LOG.info("Provisioned {} vm {}; checking metadata and if ssh'able", PROVIDER, machine);
+
+        Map<String,String> userMetadata = ((JcloudsSshMachineLocation)machine).getNode().getUserMetadata();
+        assertEquals(userMetadata.get("mykey"), "myval", "metadata="+userMetadata);
+        assertTrue(machine.isSshable());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
new file mode 100644
index 0000000..12e89e3
--- /dev/null
+++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/zone/AwsAvailabilityZoneExtensionTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.apache.brooklyn.location.jclouds.zone;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.jclouds.AbstractJcloudsLiveTest;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.jclouds.domain.LocationScope;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation;
+import brooklyn.management.internal.LocalManagementContext;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+public class AwsAvailabilityZoneExtensionTest {
+
+    public static final String PROVIDER = AbstractJcloudsLiveTest.AWS_EC2_PROVIDER;
+    public static final String REGION_NAME = AbstractJcloudsLiveTest.AWS_EC2_USEAST_REGION_NAME;
+    public static final String LOCATION_SPEC = PROVIDER + (REGION_NAME == null ? "" : ":" + REGION_NAME);
+    public static final String SMALL_HARDWARE_ID = AbstractJcloudsLiveTest.AWS_EC2_SMALL_HARDWARE_ID;
+    
+    public static final String US_EAST_IMAGE_ID = "us-east-1/ami-7d7bfc14"; // centos 6.3
+    
+    private LocalManagementContext mgmt;
+    private JcloudsLocation loc;
+    private AwsAvailabilityZoneExtension zoneExtension;
+    
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        mgmt = new LocalManagementContext();
+        loc = (JcloudsLocation) mgmt.getLocationRegistry().resolve(LOCATION_SPEC);
+        zoneExtension = new AwsAvailabilityZoneExtension(mgmt, loc);
+    }
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        if (mgmt != null) Entities.destroyAll(mgmt);
+    }
+    
+    @Test(groups={"Live", "Sanity"})
+    public void testFindsZones() throws Exception {
+        List<Location> subLocations = zoneExtension.getSubLocations(Integer.MAX_VALUE);
+        List<String> zoneNames = getRegionsOf(subLocations);
+        assertTrue(subLocations.size() >= 3, "zones="+subLocations);
+        assertTrue(zoneNames.containsAll(ImmutableList.of(REGION_NAME+"a", REGION_NAME+"b", REGION_NAME+"c")), "zoneNames="+zoneNames);
+    }
+    
+    @Test(groups={"Live", "Sanity"})
+    public void testFiltersZones() throws Exception {
+        List<Location> subLocations = zoneExtension.getSubLocationsByName(Predicates.containsPattern(REGION_NAME+"[ab]"), Integer.MAX_VALUE);
+        List<String> zoneNames = getRegionsOf(subLocations);
+        assertTrue(subLocations.size() == 2, "zones="+subLocations);
+        assertTrue(zoneNames.containsAll(ImmutableList.of(REGION_NAME+"a", REGION_NAME+"b")), "zoneNames="+zoneNames);
+    }
+    
+    // TODO choosing a specific availability zone looks dangerous!
+    // TODO report this on brooklyn issues
+    //      org.jclouds.aws.AWSResponseException: request POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1 failed with code 400, 
+    //      error: AWSError{requestId='5d360cc7-9c43-4683-8093-de3b081de87d', requestToken='null', code='Unsupported', 
+    //      message='The requested Availability Zone is currently constrained and we are no longer accepting new customer requests for t1/m1/c1/m2/m3 instance types. 
+    //              Please retry your request by not specifying an Availability Zone or choosing us-east-1e, us-east-1b, us-east-1c.', context='{Response=, Errors=}'}
+    @Test(groups={"Live"})
+    public void testSubLocationIsUsable() throws Exception {
+        String zoneName = REGION_NAME+"b";
+        List<Location> subLocations = zoneExtension.getSubLocationsByName(Predicates.equalTo(zoneName), Integer.MAX_VALUE);
+        JcloudsLocation subLocation = (JcloudsLocation) Iterables.getOnlyElement(subLocations);
+        JcloudsSshMachineLocation machine = null;
+        try {
+            machine = (JcloudsSshMachineLocation)subLocation.obtain(ImmutableMap.builder()
+                    .put(JcloudsLocation.IMAGE_ID, US_EAST_IMAGE_ID)
+                    .put(JcloudsLocation.HARDWARE_ID, SMALL_HARDWARE_ID)
+                    .put(JcloudsLocation.INBOUND_PORTS, ImmutableList.of(22))
+                    .build());
+            
+            org.jclouds.domain.Location machineLoc = machine.getNode().getLocation();
+            assertEquals(machineLoc.getScope(), LocationScope.ZONE, "machineLoc="+machineLoc);
+            assertEquals(machineLoc.getId(), zoneName, "machineLoc="+machineLoc);
+        } finally {
+            if (machine != null) {
+                subLocation.release(machine);
+            }
+        }
+    }
+    
+    protected List<String> getRegionsOf(List<Location> locs) {
+        List<String> result = Lists.newArrayList();
+        for (Location loc : locs) {
+            result.add(((JcloudsLocation)loc).getRegion());
+        }
+        return result;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/resources/brooklyn/location/jclouds/jclouds-location-test-various-login-credentials.yaml
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/resources/brooklyn/location/jclouds/jclouds-location-test-various-login-credentials.yaml b/locations/jclouds/src/test/resources/brooklyn/location/jclouds/jclouds-location-test-various-login-credentials.yaml
deleted file mode 100644
index 9230c4e..0000000
--- a/locations/jclouds/src/test/resources/brooklyn/location/jclouds/jclouds-location-test-various-login-credentials.yaml
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# 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.
-#
-
-name: various-login-credentials-test
-
-# not live tested, but useful for manual tests
-# assumes the keys listed here exist;
-# some children should pass, some should fail...
-
-services:
-
-- type: brooklyn.entity.basic.EmptySoftwareProcess
-  name: GOOD-default-should-use-id-rsa-or-create
-  location:
-    jclouds:aws-ec2
-    
-# passphrases
-- type: brooklyn.entity.basic.EmptySoftwareProcess
-  name: GOOD-key-w-passphrase-supplied
-  location:
-    jclouds:aws-ec2:
-      privateKeyFile: ~/.ssh/passphrase-id_rsa
-      privateKeyPassphrase: passphrase
-- type: brooklyn.entity.basic.EmptySoftwareProcess
-  name: FAIL-missing-passphrase
-  location:
-    jclouds:aws-ec2:
-      privateKeyFile: ~/.ssh/passphrase-id_rsa
-
-# creating a new key
-- type: brooklyn.entity.basic.EmptySoftwareProcess
-  name: GOOD-no-key-create-key
-  location:
-    jclouds:aws-ec2:
-      privateKeyFile: ""
-      
-# passwords - TODO need an image which doesn't have password-ssh disabled by default!
-- type: brooklyn.entity.basic.EmptySoftwareProcess
-  # depends if image allows password access
-  name: MAYBE-explicit-password
-  location:
-    jclouds:aws-ec2:
-      password: foo
-- type: brooklyn.entity.basic.EmptySoftwareProcess
-  # depends if image allows password access
-  name: MAYBE-explicit-password-used-and-public-key-authed
-  location:
-    jclouds:aws-ec2
-    password: foo
-    privateKeyFile: ""
-    publicKeyFile: "~/.ssh/id_rsa.pub"

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/test/resources/org/apache/brooklyn/location/jclouds/jclouds-location-test-various-login-credentials.yaml
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/test/resources/org/apache/brooklyn/location/jclouds/jclouds-location-test-various-login-credentials.yaml b/locations/jclouds/src/test/resources/org/apache/brooklyn/location/jclouds/jclouds-location-test-various-login-credentials.yaml
new file mode 100644
index 0000000..9230c4e
--- /dev/null
+++ b/locations/jclouds/src/test/resources/org/apache/brooklyn/location/jclouds/jclouds-location-test-various-login-credentials.yaml
@@ -0,0 +1,67 @@
+#
+# 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.
+#
+
+name: various-login-credentials-test
+
+# not live tested, but useful for manual tests
+# assumes the keys listed here exist;
+# some children should pass, some should fail...
+
+services:
+
+- type: brooklyn.entity.basic.EmptySoftwareProcess
+  name: GOOD-default-should-use-id-rsa-or-create
+  location:
+    jclouds:aws-ec2
+    
+# passphrases
+- type: brooklyn.entity.basic.EmptySoftwareProcess
+  name: GOOD-key-w-passphrase-supplied
+  location:
+    jclouds:aws-ec2:
+      privateKeyFile: ~/.ssh/passphrase-id_rsa
+      privateKeyPassphrase: passphrase
+- type: brooklyn.entity.basic.EmptySoftwareProcess
+  name: FAIL-missing-passphrase
+  location:
+    jclouds:aws-ec2:
+      privateKeyFile: ~/.ssh/passphrase-id_rsa
+
+# creating a new key
+- type: brooklyn.entity.basic.EmptySoftwareProcess
+  name: GOOD-no-key-create-key
+  location:
+    jclouds:aws-ec2:
+      privateKeyFile: ""
+      
+# passwords - TODO need an image which doesn't have password-ssh disabled by default!
+- type: brooklyn.entity.basic.EmptySoftwareProcess
+  # depends if image allows password access
+  name: MAYBE-explicit-password
+  location:
+    jclouds:aws-ec2:
+      password: foo
+- type: brooklyn.entity.basic.EmptySoftwareProcess
+  # depends if image allows password access
+  name: MAYBE-explicit-password-used-and-public-key-authed
+  location:
+    jclouds:aws-ec2
+    password: foo
+    privateKeyFile: ""
+    publicKeyFile: "~/.ssh/id_rsa.pub"

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/parent/pom.xml
----------------------------------------------------------------------
diff --git a/parent/pom.xml b/parent/pom.xml
index 6079e35..020d652 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1150,7 +1150,7 @@
                   <exclude>**/*.psd</exclude>
                   <exclude>**/*.json</exclude>
                   <exclude>**/*.plxarc</exclude>
-                  <exclude>**/services/brooklyn.location.LocationResolver</exclude>
+                  <exclude>**/services/org.apache.brooklyn.location.LocationResolver</exclude>
                   <exclude>**/src/test/resources/brooklyn/entity/basic/template_with_extra_substitutions.txt</exclude>
                   <exclude>**/src/main/resources/banner.txt</exclude>
                   <exclude>**/src/test/resources/ssl/certs/localhost/info.txt</exclude>

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java b/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java
index 4e94c3c..51d9ae0 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/DefaultFollowTheSunModel.java
@@ -33,8 +33,8 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.Location;
-import brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.AbstractLocation;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java
index 3e682fe..a76e37c 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunModel.java
@@ -21,7 +21,7 @@ package brooklyn.policy.followthesun;
 import java.util.Map;
 import java.util.Set;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * Captures the state of items, containers and locations for the purpose of moving items around

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java
index 99c51e5..9283c7f 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunParameters.java
@@ -24,7 +24,7 @@ import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 public class FollowTheSunParameters {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java
index 25f4e49..d89f1a8 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunPolicy.java
@@ -40,8 +40,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Attributes;
-import brooklyn.location.Location;
-import brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.policy.followthesun.FollowTheSunPool.ContainerItemPair;
 import brooklyn.policy.loadbalancing.Movable;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java
index ebe09a8..078299d 100644
--- a/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java
+++ b/policy/src/main/java/brooklyn/policy/followthesun/FollowTheSunStrategy.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.policy.loadbalancing.Movable;
 
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/ha/SshMachineFailureDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/ha/SshMachineFailureDetector.java b/policy/src/main/java/brooklyn/policy/ha/SshMachineFailureDetector.java
index 54bdb69..7d31cf7 100644
--- a/policy/src/main/java/brooklyn/policy/ha/SshMachineFailureDetector.java
+++ b/policy/src/main/java/brooklyn/policy/ha/SshMachineFailureDetector.java
@@ -27,8 +27,8 @@ import org.apache.brooklyn.api.catalog.Catalog;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.event.basic.BasicNotificationSensor;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.policy.ha.HASensors.FailureDescriptor;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java b/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java
index dbd58ef..f3e6b6a 100644
--- a/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java
+++ b/policy/src/main/java/brooklyn/policy/loadbalancing/BalanceablePoolModel.java
@@ -21,7 +21,7 @@ package brooklyn.policy.loadbalancing;
 import java.util.Map;
 import java.util.Set;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * Captures the state of a balanceable cluster of containers and all their constituent items, including workrates,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java b/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java
index 0aa5851..fa7f3bb 100644
--- a/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java
+++ b/policy/src/main/java/brooklyn/policy/loadbalancing/BalancingStrategy.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * Represents an abstract algorithm for optimally balancing worker "items" among several "containers" based on the workloads

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java b/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java
index 9722f78..1a37ed6 100644
--- a/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java
+++ b/policy/src/main/java/brooklyn/policy/loadbalancing/DefaultBalanceablePoolModel.java
@@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.HashMultimap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java b/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java
index b1beb6d..5399e89 100644
--- a/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java
+++ b/policy/src/main/java/brooklyn/policy/loadbalancing/LocationConstraint.java
@@ -18,7 +18,7 @@
  */
 package brooklyn.policy.loadbalancing;
 
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 
 /**
  * Temporary stub to resolve dependencies in ported LoadBalancingPolicy.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java b/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java
index 6f21d9d..9777e03 100644
--- a/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java
+++ b/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java
@@ -33,10 +33,9 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.http.BetterMockWebServer;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/entity/brooklyn/BrooklynMetricsTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/entity/brooklyn/BrooklynMetricsTest.java b/policy/src/test/java/brooklyn/entity/brooklyn/BrooklynMetricsTest.java
index 7d14883..bd4fa0c 100644
--- a/policy/src/test/java/brooklyn/entity/brooklyn/BrooklynMetricsTest.java
+++ b/policy/src/test/java/brooklyn/entity/brooklyn/BrooklynMetricsTest.java
@@ -35,9 +35,8 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java b/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
index f0cc623..d317029 100644
--- a/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
+++ b/policy/src/test/java/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
@@ -36,8 +36,8 @@ import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
 import brooklyn.event.basic.BasicNotificationSensor;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.time.Duration;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java b/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java
index ae14af0..5f12e62 100644
--- a/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java
+++ b/policy/src/test/java/brooklyn/policy/followthesun/AbstractFollowTheSunPolicyTest.java
@@ -40,9 +40,9 @@ import org.testng.annotations.BeforeMethod;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.policy.loadbalancing.BalanceableContainer;
 import brooklyn.policy.loadbalancing.MockContainerEntity;
 import brooklyn.policy.loadbalancing.MockItemEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java
index ef45cb0..84f4808 100644
--- a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java
+++ b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunModelTest.java
@@ -26,9 +26,8 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.policy.loadbalancing.MockContainerEntity;
 import brooklyn.policy.loadbalancing.MockContainerEntityImpl;
 import brooklyn.policy.loadbalancing.MockItemEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
index 6c5bcec..24c1476 100644
--- a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
+++ b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicySoakTest.java
@@ -34,8 +34,8 @@ import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.policy.loadbalancing.BalanceableContainer;
 import brooklyn.policy.loadbalancing.MockContainerEntity;
 import brooklyn.policy.loadbalancing.MockItemEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
index b5a0401..feef57d 100644
--- a/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
+++ b/policy/src/test/java/brooklyn/policy/followthesun/FollowTheSunPolicyTest.java
@@ -36,8 +36,8 @@ import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.policy.loadbalancing.MockContainerEntity;
 import brooklyn.policy.loadbalancing.MockItemEntity;
 import brooklyn.policy.loadbalancing.Movable;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java b/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
index a71f58c..3088e78 100644
--- a/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
+++ b/policy/src/test/java/brooklyn/policy/ha/HaPolicyRebindTest.java
@@ -42,9 +42,9 @@ import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.rebind.RebindTestFixtureWithApp;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.policy.ha.HASensors.FailureDescriptor;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java b/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
index e686466..b8e5379 100644
--- a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
+++ b/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
@@ -53,9 +53,9 @@ import brooklyn.entity.basic.QuorumCheck;
 import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.trait.FailingEntity;
-import brooklyn.location.Location;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.policy.ha.HASensors.FailureDescriptor;
 import brooklyn.test.Asserts;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java b/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
index 5306d83..68db44c 100644
--- a/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
+++ b/policy/src/test/java/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
@@ -38,12 +38,11 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 
 import brooklyn.config.ConfigKey;
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.time.Time;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java b/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java
index a816983..e744720 100644
--- a/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java
+++ b/policy/src/test/java/brooklyn/policy/loadbalancing/BalanceableWorkerPoolTest.java
@@ -37,7 +37,7 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Resizable;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java b/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java
index 0217f8c..cf47359 100644
--- a/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java
+++ b/policy/src/test/java/brooklyn/policy/loadbalancing/ItemsInContainersGroupTest.java
@@ -31,7 +31,7 @@ import org.testng.annotations.Test;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.DynamicGroup;
 import brooklyn.entity.basic.Entities;
-import brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java b/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java
index f02a3c6..f72fed3 100644
--- a/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java
+++ b/policy/src/test/java/brooklyn/policy/loadbalancing/MockContainerEntityImpl.java
@@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.AbstractGroupImpl;
 import brooklyn.entity.basic.Attributes;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.time.Time;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
index 103ad49..7fc4ea7 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessDriver.java
@@ -32,7 +32,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java
index 2ca32e9..c8efbb9 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessSshDriver.java
@@ -45,7 +45,7 @@ import brooklyn.entity.basic.lifecycle.ScriptHelper;
 import brooklyn.entity.effector.EffectorTasks;
 import brooklyn.entity.software.SshEffectorTasks;
 import brooklyn.event.feed.ConfigToAttributes;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.internal.ssh.SshTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
index 3e3a9eb..e80af91 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/AbstractSoftwareProcessWinRmDriver.java
@@ -31,7 +31,7 @@ import org.python.core.PyException;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 import brooklyn.util.exceptions.ReferenceWithError;
 import brooklyn.util.repeat.Repeater;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/EmptySoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/EmptySoftwareProcessSshDriver.java b/software/base/src/main/java/brooklyn/entity/basic/EmptySoftwareProcessSshDriver.java
index dbafa65..ce1282b 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/EmptySoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/EmptySoftwareProcessSshDriver.java
@@ -21,7 +21,7 @@ package brooklyn.entity.basic;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 
 public class EmptySoftwareProcessSshDriver extends AbstractSoftwareProcessSshDriver implements EmptySoftwareProcessDriver {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java
index 247ba98..f7d2122 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SameServerDriverLifecycleEffectorTasks.java
@@ -36,10 +36,10 @@ import com.google.common.reflect.TypeToken;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.trait.StartableMethods;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java
index cca5493..09f8dea 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntity.java
@@ -28,7 +28,7 @@ import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.QuorumCheck;
 import brooklyn.util.flags.SetFromFlag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
index 912a2f7..7bfdb59 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SameServerEntityImpl.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.management.Task;
 
 import brooklyn.entity.basic.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
-import brooklyn.location.Location;
+import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.QuorumCheck;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.DynamicTasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
index 4e03fee..de12a0c 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
@@ -31,7 +31,7 @@ import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.basic.MapConfigKey;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.flags.SetFromFlag;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
index f2427f3..5af5a27 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
@@ -29,8 +29,8 @@ import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters;
 import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters.RestartMachineMode;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.trait.StartableMethods;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
index fedaf11..f96b961 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
@@ -47,13 +47,13 @@ import brooklyn.entity.basic.Lifecycle.Transition;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.event.feed.function.FunctionFeed;
 import brooklyn.event.feed.function.FunctionPollConfig;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.LocationConfigKeys;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.LocationConfigKeys;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java
index af89c40..b66bd62 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaSoftwareProcessSshDriver.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
 
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.file.ArchiveUtils;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
index 68a2f16..8be1fa5 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/VanillaWindowsProcessWinRmDriver.java
@@ -20,7 +20,7 @@ package brooklyn.entity.basic;
 
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 
-import brooklyn.location.basic.WinRmMachineLocation;
+import org.apache.brooklyn.location.basic.WinRmMachineLocation;
 import brooklyn.util.net.UserAndHostAndPort;
 
 public class VanillaWindowsProcessWinRmDriver extends AbstractSoftwareProcessWinRmDriver implements VanillaWindowsProcessDriver {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/basic/lifecycle/ScriptHelper.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/lifecycle/ScriptHelper.java b/software/base/src/main/java/brooklyn/entity/basic/lifecycle/ScriptHelper.java
index c8844d5..07532f8 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/lifecycle/ScriptHelper.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/lifecycle/ScriptHelper.java
@@ -40,7 +40,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.BrooklynTaskTags;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.GroovyJavaMethods;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.RuntimeInterruptedException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 0861c34..4250b74 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -59,8 +59,8 @@ import brooklyn.event.feed.http.HttpFeed;
 import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.event.feed.http.JsonFunctions;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.basic.Locations;
 import brooklyn.util.collections.Jsonya;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
index bd1a2d4..ab4ffb2 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
@@ -34,7 +34,7 @@ import brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
 import brooklyn.entity.drivers.downloads.DownloadSubstituters;
 import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.file.ArchiveBuilder;
 import brooklyn.util.file.ArchiveUtils;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
index eca280a..ca7d561 100644
--- a/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
@@ -30,8 +30,8 @@ import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
 import brooklyn.util.collections.Jsonya;
 import brooklyn.util.collections.Jsonya.Navigator;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/chef/ChefServerTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/chef/ChefServerTasks.java b/software/base/src/main/java/brooklyn/entity/chef/ChefServerTasks.java
index 76d3842..743e335 100644
--- a/software/base/src/main/java/brooklyn/entity/chef/ChefServerTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/chef/ChefServerTasks.java
@@ -24,7 +24,7 @@ import java.io.IOException;
 import java.nio.charset.Charset;
 import java.security.KeyPair;
 
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.crypto.SecureKeys;
 
 import com.google.common.base.Throwables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/chef/ChefSoloDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/chef/ChefSoloDriver.java b/software/base/src/main/java/brooklyn/entity/chef/ChefSoloDriver.java
index 963ec8e..0d9935c 100644
--- a/software/base/src/main/java/brooklyn/entity/chef/ChefSoloDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/chef/ChefSoloDriver.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.api.management.TaskFactory;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.task.DynamicTasks;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/chef/KnifeConvergeTaskFactory.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/chef/KnifeConvergeTaskFactory.java b/software/base/src/main/java/brooklyn/entity/chef/KnifeConvergeTaskFactory.java
index 0d4dfdb..f9ec730 100644
--- a/software/base/src/main/java/brooklyn/entity/chef/KnifeConvergeTaskFactory.java
+++ b/software/base/src/main/java/brooklyn/entity/chef/KnifeConvergeTaskFactory.java
@@ -33,7 +33,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.effector.EffectorTasks;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.Jsonya;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java b/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
index de223fb..1853259 100644
--- a/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
@@ -48,7 +48,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.effector.EffectorTasks;
 import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java b/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java
index 463b009..2f88ff8 100644
--- a/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java
+++ b/software/base/src/main/java/brooklyn/entity/java/JmxSupport.java
@@ -33,9 +33,9 @@ import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.event.feed.jmx.JmxHelper;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.Locations;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.location.basic.Locations;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.BrooklynMavenArtifacts;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java b/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
index 4901e02..6bc9de4 100644
--- a/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
+++ b/software/base/src/main/java/brooklyn/entity/java/UsesJmx.java
@@ -30,8 +30,8 @@ import brooklyn.event.basic.AttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.location.basic.PortRanges;
 import brooklyn.util.flags.SetFromFlag;
 
 public interface UsesJmx extends UsesJava {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/java/VanillaJavaAppSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/java/VanillaJavaAppSshDriver.java b/software/base/src/main/java/brooklyn/entity/java/VanillaJavaAppSshDriver.java
index e746677..104dd7d 100644
--- a/software/base/src/main/java/brooklyn/entity/java/VanillaJavaAppSshDriver.java
+++ b/software/base/src/main/java/brooklyn/entity/java/VanillaJavaAppSshDriver.java
@@ -28,7 +28,7 @@ import java.util.Map;
 import javax.annotation.Nullable;
 
 import brooklyn.entity.basic.lifecycle.ScriptHelper;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/machine/MachineEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/machine/MachineEntityImpl.java b/software/base/src/main/java/brooklyn/entity/machine/MachineEntityImpl.java
index a0f45a9..f101e66 100644
--- a/software/base/src/main/java/brooklyn/entity/machine/MachineEntityImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/machine/MachineEntityImpl.java
@@ -31,11 +31,10 @@ import brooklyn.entity.software.SshEffectorTasks;
 import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshPollValue;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.task.DynamicTasks;
-import brooklyn.util.task.system.ProcessTaskStub.ScriptReturnType;
 import brooklyn.util.task.system.ProcessTaskWrapper;
 import brooklyn.util.text.Strings;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java
index 28cf503..c0b2b5f 100644
--- a/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java
+++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPool.java
@@ -37,9 +37,10 @@ import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.entity.machine.MachineEntity;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.dynamic.LocationOwner;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.dynamic.LocationOwner;
 
 /**
  * A preallocated server pool is an entity that other applications can deploy to.
@@ -51,7 +52,7 @@ import brooklyn.location.dynamic.LocationOwner;
  *         The pool does not configure ports appropriately for applications subsequently
  *         deployed. If an entity that is to be run in the pool requires any ports open
  *         other than port 22 then thoses port should be configured with the
- *         {@link brooklyn.location.cloud.CloudLocationConfig#INBOUND_PORTS INBOUND_PORTS}
+ *         {@link CloudLocationConfig#INBOUND_PORTS INBOUND_PORTS}
  *         config key as part of the pool's
  *         {@link brooklyn.entity.basic.SoftwareProcess#PROVISIONING_PROPERTIES PROVISIONING_PROPERTIES}.
  *         For example, in YAML:

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java
index e7fb72d..2876b31 100644
--- a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolImpl.java
@@ -40,13 +40,13 @@ import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
 import brooklyn.entity.group.DynamicClusterImpl;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.basic.Sensors;
-import brooklyn.location.Location;
-import brooklyn.location.LocationDefinition;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.BasicLocationDefinition;
-import brooklyn.location.basic.Machines;
-import brooklyn.location.dynamic.DynamicLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationDefinition;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.BasicLocationDefinition;
+import org.apache.brooklyn.location.basic.Machines;
+import org.apache.brooklyn.location.dynamic.DynamicLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.task.DynamicTasks;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java
index ed04ea2..7123760 100644
--- a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java
+++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocation.java
@@ -30,11 +30,11 @@ import com.google.common.collect.Maps;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.NoMachinesAvailableException;
-import brooklyn.location.basic.AbstractLocation;
-import brooklyn.location.dynamic.DynamicLocation;
+import org.apache.brooklyn.location.MachineLocation;
+import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.location.basic.AbstractLocation;
+import org.apache.brooklyn.location.dynamic.DynamicLocation;
 import brooklyn.util.flags.SetFromFlag;
 
 public class ServerPoolLocation extends AbstractLocation implements MachineProvisioningLocation<MachineLocation>,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java
index ba6608b..2de1da2 100644
--- a/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java
+++ b/software/base/src/main/java/brooklyn/entity/pool/ServerPoolLocationResolver.java
@@ -35,14 +35,14 @@ import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 
-import brooklyn.location.Location;
-import brooklyn.location.LocationRegistry;
-import brooklyn.location.LocationResolver.EnableableLocationResolver;
-import brooklyn.location.LocationSpec;
-import brooklyn.location.basic.BasicLocationRegistry;
-import brooklyn.location.basic.LocationInternal;
-import brooklyn.location.basic.LocationPropertiesFromBrooklynProperties;
-import brooklyn.location.dynamic.DynamicLocation;
+import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.location.LocationResolver.EnableableLocationResolver;
+import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.location.basic.BasicLocationRegistry;
+import org.apache.brooklyn.location.basic.LocationInternal;
+import org.apache.brooklyn.location.basic.LocationPropertiesFromBrooklynProperties;
+import org.apache.brooklyn.location.dynamic.DynamicLocation;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.text.KeyValueParser;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java b/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java
index 4503ef9..3d51ccf 100644
--- a/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java
+++ b/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java
@@ -34,8 +34,8 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.effector.EffectorTasks;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.location.cloud.names.AbstractCloudMachineNamer;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.location.cloud.names.AbstractCloudMachineNamer;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.os.Os;



[51/54] incubator-brooklyn git commit: [BROOKLYN-162] Move ./api/location to the right package

Posted by ha...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java
index 0e5225b..8eb983c 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/HostLocationResolver.java
@@ -20,10 +20,11 @@ package org.apache.brooklyn.location.basic;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.AbstractLocationResolver.SpecParser.ParsedSpec;
+
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java
index 47c8089..859fa99 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostLocationResolver.java
@@ -20,10 +20,11 @@ package org.apache.brooklyn.location.basic;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
+
 import brooklyn.util.config.ConfigBag;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
 
 /**
  * Examples of valid specs:

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
index 44b95b6..cfaf241 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocalhostMachineProvisioningLocation.java
@@ -27,11 +27,11 @@ import java.util.Arrays;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.brooklyn.location.AddressableLocation;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
-import org.apache.brooklyn.location.OsDetails;
-import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.api.location.AddressableLocation;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.api.location.PortRange;
 import org.apache.brooklyn.location.geo.HostGeoInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java
index a289090..f13be4e 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationDynamicType.java
@@ -19,8 +19,9 @@
 package org.apache.brooklyn.location.basic;
 
 import brooklyn.basic.BrooklynDynamicType;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationType;
+
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationType;
 
 public class LocationDynamicType extends BrooklynDynamicType<Location, AbstractLocation> {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
index 429e671..d1ffcb9 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.location.basic;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.rebind.RebindSupport;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
 import org.apache.brooklyn.mementos.LocationMemento;
 
 import brooklyn.basic.BrooklynObjectInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java b/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java
index d0b781b..fc90b38 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationPredicates.java
@@ -22,7 +22,8 @@ import javax.annotation.Nullable;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java b/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java
index 31855ed..9af45a1 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/Locations.java
@@ -25,15 +25,15 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.apache.brooklyn.api.management.LocationManager;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.yaml.Yamls;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java b/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java
index 621e1e2..13f8028 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/Machines.java
@@ -24,15 +24,17 @@ import java.util.Iterator;
 import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Iterables;
 
 import brooklyn.entity.basic.Attributes;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
+
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.net.HasNetworkAddresses;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java
index bbf45f0..b702a92 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocation.java
@@ -26,17 +26,17 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.NoMachinesAvailableException;
 import org.apache.brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
 import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.CompoundRuntimeException;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java
index ac4b7b3..92692ae 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/MultiLocationResolver.java
@@ -26,11 +26,11 @@ import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
-import org.apache.brooklyn.location.LocationSpec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java
index 048c28c..a9f6499 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/NamedLocationResolver.java
@@ -23,11 +23,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import java.util.Map;
 import java.util.NoSuchElementException;
 
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
 import org.apache.brooklyn.api.management.ManagementContext;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationResolver;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java b/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java
index 6a17c1a..2e1bdcc 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/PortRanges.java
@@ -29,7 +29,8 @@ import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.apache.brooklyn.location.PortRange;
+import org.apache.brooklyn.api.location.PortRange;
+
 import brooklyn.util.flags.TypeCoercions;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java
index 06558cb..a6b82ee 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/RegistryLocationResolver.java
@@ -20,9 +20,9 @@ package org.apache.brooklyn.location.basic;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationResolver;
-import org.apache.brooklyn.location.LocationRegistry;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationResolver;
 
 /**
  * Extension to LocationResolver which can take a registry.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java
index 4be135f..fb5f676 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineLocationResolver.java
@@ -20,9 +20,10 @@ package org.apache.brooklyn.location.basic;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationRegistry;
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationRegistry;
+import org.apache.brooklyn.api.location.LocationSpec;
+
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java
index 6c40ba3..5f249d2 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/SingleMachineProvisioningLocation.java
@@ -20,12 +20,12 @@ package org.apache.brooklyn.location.basic;
 
 import java.util.Map;
 
-import org.apache.brooklyn.location.NoMachinesAvailableException;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.NoMachinesAvailableException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
 import brooklyn.util.flags.SetFromFlag;
 
 import com.google.common.collect.ImmutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java
index e83712e..0a8dd44 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/SshMachineLocation.java
@@ -45,10 +45,12 @@ import java.util.concurrent.TimeUnit;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.api.location.PortRange;
+import org.apache.brooklyn.api.location.PortSupplier;
 import org.apache.brooklyn.api.management.Task;
-import org.apache.brooklyn.location.MachineDetails;
-import org.apache.brooklyn.location.OsDetails;
-import org.apache.brooklyn.location.PortRange;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -82,9 +84,9 @@ import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.MapConfigKey;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.PortSupplier;
+
 import org.apache.brooklyn.location.access.PortForwardManager;
+
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java
index 3860eb5..319b9fb 100644
--- a/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/WinRmMachineLocation.java
@@ -33,8 +33,9 @@ import java.util.Set;
 
 import javax.annotation.Nullable;
 
-import org.apache.brooklyn.location.MachineDetails;
-import org.apache.brooklyn.location.OsDetails;
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.OsDetails;
 import org.apache.commons.codec.binary.Base64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -49,8 +50,9 @@ import com.google.common.reflect.TypeToken;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.MachineLocation;
+
 import org.apache.brooklyn.location.access.PortForwardManager;
+
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.stream.Streams;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java b/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
index d399b92..9069dce 100644
--- a/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractAvailabilityZoneExtension.java
@@ -24,10 +24,9 @@ import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 
-import org.apache.brooklyn.location.Location;
-
 import com.google.common.annotations.Beta;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java b/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
index 13707b5..437d49b 100644
--- a/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/AbstractCloudMachineProvisioningLocation.java
@@ -21,10 +21,11 @@ package org.apache.brooklyn.location.cloud;
 import java.util.Collection;
 import java.util.Map;
 
-import org.apache.brooklyn.location.LocationSpec;
-import org.apache.brooklyn.location.MachineLocation;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.AbstractLocation;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.internal.ssh.SshTool;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java b/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java
index 1580440..380fd44 100644
--- a/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/AvailabilityZoneExtension.java
@@ -21,7 +21,8 @@ package org.apache.brooklyn.location.cloud;
 import java.util.List;
 
 import brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.location.Location;
+
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.MultiLocation;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java b/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java
index 9682994..a44ca49 100644
--- a/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/CloudLocationConfig.java
@@ -26,8 +26,10 @@ import com.google.common.reflect.TypeToken;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.event.basic.BasicConfigKey;
-import org.apache.brooklyn.location.MachineLocationCustomizer;
+
+import org.apache.brooklyn.api.location.MachineLocationCustomizer;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
+
 import brooklyn.util.flags.SetFromFlag;
 
 public interface CloudLocationConfig {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java b/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java
index eaf7198..df7fd8b 100644
--- a/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java
+++ b/core/src/main/java/org/apache/brooklyn/location/cloud/names/CloudMachineNamer.java
@@ -19,9 +19,9 @@
 package org.apache.brooklyn.location.cloud.names;
 
 import org.apache.brooklyn.api.entity.Entity;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.cloud.CloudLocationConfig;
+
 import brooklyn.util.config.ConfigBag;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java b/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java
index 78e6d87..4c38b7e 100644
--- a/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/dynamic/DynamicLocation.java
@@ -19,12 +19,12 @@
 package org.apache.brooklyn.location.dynamic;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.annotations.Beta;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.flags.SetFromFlag;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java b/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java
index a2b0bfb..b061b69 100644
--- a/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java
+++ b/core/src/main/java/org/apache/brooklyn/location/dynamic/LocationOwner.java
@@ -22,13 +22,13 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationDefinition;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.event.basic.BasicAttributeSensorAndConfigKey;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationDefinition;
 import brooklyn.util.flags.SetFromFlag;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java b/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java
index d159a95..ad05bbd 100644
--- a/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java
+++ b/core/src/main/java/org/apache/brooklyn/location/geo/HostGeoInfo.java
@@ -24,8 +24,8 @@ import java.net.InetAddress;
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.location.AddressableLocation;
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.AddressableLocation;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.slf4j.Logger;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java b/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java
index e90f757..1d3537b 100644
--- a/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java
+++ b/core/src/main/java/org/apache/brooklyn/location/paas/PaasLocation.java
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.location.paas;
 
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 /**
  * {@link Location} representing an application container on a PaaS provider.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver b/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
new file mode 100644
index 0000000..ec34011
--- /dev/null
+++ b/core/src/main/resources/META-INF/services/org.apache.brooklyn.api.location.LocationResolver
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+org.apache.brooklyn.location.basic.DefinedLocationByIdResolver
+org.apache.brooklyn.location.basic.NamedLocationResolver
+org.apache.brooklyn.location.basic.CatalogLocationResolver
+org.apache.brooklyn.location.basic.LocalhostLocationResolver
+org.apache.brooklyn.location.basic.ByonLocationResolver
+org.apache.brooklyn.location.basic.SingleMachineLocationResolver
+org.apache.brooklyn.location.basic.HostLocationResolver
+org.apache.brooklyn.location.basic.MultiLocationResolver
+org.apache.brooklyn.location.access.PortForwardManagerLocationResolver

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
----------------------------------------------------------------------
diff --git a/core/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver b/core/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
deleted file mode 100644
index 721b7e7..0000000
--- a/core/src/main/resources/META-INF/services/org.apache.brooklyn.location.LocationResolver
+++ /dev/null
@@ -1,9 +0,0 @@
-org.apache.brooklyn.location.basic.DefinedLocationByIdResolver
-org.apache.brooklyn.location.basic.NamedLocationResolver
-org.apache.brooklyn.location.basic.CatalogLocationResolver
-org.apache.brooklyn.location.basic.LocalhostLocationResolver
-org.apache.brooklyn.location.basic.ByonLocationResolver
-org.apache.brooklyn.location.basic.SingleMachineLocationResolver
-org.apache.brooklyn.location.basic.HostLocationResolver
-org.apache.brooklyn.location.basic.MultiLocationResolver
-org.apache.brooklyn.location.access.PortForwardManagerLocationResolver
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java b/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java
index 666e898..d761331 100644
--- a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java
+++ b/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherTest.java
@@ -23,6 +23,7 @@ import java.util.Collection;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.slf4j.Logger;
@@ -34,8 +35,9 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.event.basic.BasicAttributeSensor;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.collections.MutableMap;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java b/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
index 485504e..66daf0b 100644
--- a/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
+++ b/core/src/test/java/brooklyn/entity/EffectorMetadataTest.java
@@ -28,6 +28,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.ParameterType;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -38,7 +39,6 @@ import brooklyn.entity.basic.BasicParameterType;
 import brooklyn.entity.basic.MethodEffector;
 import brooklyn.entity.effector.Effectors;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.internal.EffectorUtils;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/SetFromFlagTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/SetFromFlagTest.java b/core/src/test/java/brooklyn/entity/SetFromFlagTest.java
index e28038f..c5cfc0b 100644
--- a/core/src/test/java/brooklyn/entity/SetFromFlagTest.java
+++ b/core/src/test/java/brooklyn/entity/SetFromFlagTest.java
@@ -23,11 +23,13 @@ import static org.testng.Assert.assertEquals;
 import java.util.Map;
 
 import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.PortRange;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.AbstractEntity;
-import org.apache.brooklyn.location.PortRange;
+
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.flags.SetFromFlag;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java b/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java
index b78562e..5604ed0 100644
--- a/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/AbstractApplicationLegacyTest.java
@@ -25,6 +25,7 @@ import static org.testng.Assert.assertTrue;
 import java.util.List;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
@@ -34,7 +35,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java b/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
index cbd1c8b..b5c1074 100644
--- a/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/BasicStartableTest.java
@@ -27,6 +27,8 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.entity.basic.RecordingSensorEventListener;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
@@ -41,10 +43,9 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
 import org.apache.brooklyn.location.basic.Locations.LocationsFilter;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.collections.MutableSet;
 
 public class BasicStartableTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java b/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java
index 228a6fe..9fc43eb 100644
--- a/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/DataEntityTest.java
@@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.LocalManagementContextForTests;
@@ -34,8 +35,9 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
index 888e2e5..d7e2d1a 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
@@ -25,14 +25,16 @@ import static org.testng.Assert.assertTrue;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableSet;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java b/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java
index 8597942..949a25a 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityFunctionsTest.java
@@ -22,12 +22,12 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNull;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.Location;
 
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java b/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java
index 77ad89a..fbc1010 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityLocationsTest.java
@@ -24,12 +24,12 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.brooklyn.api.event.SensorEvent;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.entity.basic.RecordingSensorEventListener;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.Location;
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java b/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java
index 8b47dd2..bf637c1 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntityPredicatesTest.java
@@ -22,13 +22,13 @@ import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.trait.Changeable;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.text.StringPredicates;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java b/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java
index edd1665..04324e1 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitySuppliersTest.java
@@ -22,13 +22,14 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.fail;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.MachineProvisioningLocation;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 
 import com.google.common.base.Supplier;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java b/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
index e08cf97..c573d62 100644
--- a/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/ServiceStateLogicTest.java
@@ -21,6 +21,7 @@ package brooklyn.entity.basic;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -35,7 +36,6 @@ import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceProblemsLogic;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.collections.QuorumCheck.QuorumChecks;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java b/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java
index 2eb6a29..7595bbd 100644
--- a/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/ReflectiveEntityDriverFactoryTest.java
@@ -19,9 +19,10 @@
 package brooklyn.entity.drivers;
 
 import brooklyn.entity.basic.AbstractEntity;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 import org.apache.brooklyn.location.paas.PaasLocation;
+
 import brooklyn.test.location.TestPaasLocation;
 import brooklyn.util.collections.MutableMap;
 
@@ -29,6 +30,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java b/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java
index 7b45974..446617a 100644
--- a/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/RegistryEntityDriverFactoryTest.java
@@ -24,15 +24,17 @@ import static org.testng.Assert.assertTrue;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
+import org.apache.brooklyn.api.location.Location;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MyDriver;
 import brooklyn.entity.drivers.ReflectiveEntityDriverFactoryTest.MyDriverDependentEntity;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.util.collections.MutableMap;
 
 public class RegistryEntityDriverFactoryTest {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
index 5be9551..64bfcd4 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/BasicDownloadsRegistryTest.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.fail;
 
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.AfterMethod;
@@ -34,8 +35,9 @@ import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Attributes;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
index 07f9f14..2ed52e4 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromLocalRepoTest.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.AfterMethod;
@@ -35,8 +36,9 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java
index dc36f8c..a8d6e31 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadProducerFromPropertiesTest.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadRequirement;
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.AfterMethod;
@@ -35,8 +36,9 @@ import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BrooklynConfigKeys;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java
index 344e16b..2e9a819 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/DownloadSubstitutersTest.java
@@ -25,13 +25,14 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolverManager.DownloadTargets;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.BrooklynConfigKeys;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 
 import com.google.common.base.Functions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java b/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java
index 02154f7..8398030 100644
--- a/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java
+++ b/core/src/test/java/brooklyn/entity/drivers/downloads/MyEntityDriver.java
@@ -21,8 +21,7 @@ package brooklyn.entity.drivers.downloads;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.drivers.EntityDriver;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 public class MyEntityDriver implements EntityDriver {
     private final Entity entity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java b/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
index 1418868..cd300e4 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicClusterTest.java
@@ -54,6 +54,7 @@ import brooklyn.entity.basic.Lifecycle;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.SensorEvent;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.entity.basic.RecordingSensorEventListener;
 import org.apache.brooklyn.test.EntityTestUtils;
@@ -63,8 +64,9 @@ import org.apache.brooklyn.test.entity.TestEntityImpl;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.trait.Changeable;
 import brooklyn.entity.trait.FailingEntity;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java b/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java
index 064f2ac..f0e3105 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicClusterWithAvailabilityZonesTest.java
@@ -31,6 +31,8 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
@@ -40,12 +42,12 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.group.zoneaware.ProportionalZoneFailureDetector;
 import brooklyn.entity.trait.FailingEntity;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocationInternal;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 import org.apache.brooklyn.location.cloud.AbstractAvailabilityZoneExtension;
 import org.apache.brooklyn.location.cloud.AvailabilityZoneExtension;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java b/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java
index 0ce3faf..593ac84 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicFabricTest.java
@@ -34,6 +34,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.test.TestUtils;
 import org.apache.brooklyn.test.entity.BlockingEntity;
@@ -49,9 +50,10 @@ import brooklyn.entity.basic.BasicEntity;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityFactory;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.PortRanges;
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java b/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java
index b0821e5..f75267a 100644
--- a/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java
+++ b/core/src/test/java/brooklyn/entity/group/DynamicRegionsFabricTest.java
@@ -26,13 +26,15 @@ import java.util.Set;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/GroupTest.java b/core/src/test/java/brooklyn/entity/group/GroupTest.java
index ab73812..8d0f9a9 100644
--- a/core/src/test/java/brooklyn/entity/group/GroupTest.java
+++ b/core/src/test/java/brooklyn/entity/group/GroupTest.java
@@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.entity.basic.RecordingSensorEventListener;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
@@ -35,8 +36,9 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 
 public class GroupTest extends BrooklynAppUnitTestSupport {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java b/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java
index 65ab601..f3ee6e9 100644
--- a/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java
+++ b/core/src/test/java/brooklyn/entity/group/MembershipTrackingPolicyTest.java
@@ -28,6 +28,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.Sensor;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.EntityManager;
 import org.apache.brooklyn.policy.PolicySpec;
 import org.apache.brooklyn.test.entity.TestEntity;
@@ -38,8 +39,9 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.trait.Startable;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java b/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java
index b96310e..b6b6788 100644
--- a/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java
+++ b/core/src/test/java/brooklyn/entity/group/QuarantineGroupTest.java
@@ -22,13 +22,14 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java b/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java
index 975db33..f2a08da 100644
--- a/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java
+++ b/core/src/test/java/brooklyn/entity/group/zoneaware/BalancingNodePlacementStrategyTest.java
@@ -22,14 +22,16 @@ import java.util.List;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java b/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java
index 367952b..5c618c5 100644
--- a/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java
+++ b/core/src/test/java/brooklyn/entity/group/zoneaware/ProportionalZoneFailureDetectorTest.java
@@ -25,13 +25,15 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.util.time.Duration;
 
 import com.google.common.base.Ticker;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
index 5e9f9d9..bbd26d0 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEnricherTest.java
@@ -29,6 +29,7 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.policy.Enricher;
 import org.apache.brooklyn.policy.EnricherSpec;
 import org.apache.brooklyn.test.EntityTestUtils;
@@ -49,8 +50,9 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.EntityPredicates;
 import brooklyn.entity.group.DynamicCluster;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.flags.SetFromFlag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
index cf246d1..45c3721 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
@@ -47,6 +47,8 @@ import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
 import org.apache.brooklyn.api.event.AttributeSensor.SensorPersistenceMode;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ha.ManagementNodeState;
 import org.apache.brooklyn.mementos.BrooklynMementoManifest;
 import org.apache.brooklyn.mementos.EntityMemento;
@@ -69,9 +71,9 @@ import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.event.basic.BasicSensorEvent;
 import brooklyn.event.basic.DependentConfiguration;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.LocationConfigTest.MyLocation;
+
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
index 6935a48..db51a91 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
@@ -27,6 +27,7 @@ import java.util.List;
 import org.apache.brooklyn.api.entity.Feed;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.apache.brooklyn.test.entity.TestEntityImpl.TestEntityWithoutEnrichers;
@@ -49,9 +50,10 @@ import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.event.feed.ssh.SshFeed;
 import brooklyn.event.feed.ssh.SshPollConfig;
 import brooklyn.event.feed.ssh.SshValueFunctions;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.management.internal.BrooklynGarbageCollector;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
index aac9b21..54b4b14 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindLocalhostLocationTest.java
@@ -29,8 +29,7 @@ import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
index c245d85..6df2b7f 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindLocationTest.java
@@ -30,6 +30,8 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.rebind.RebindContext;
 import org.apache.brooklyn.api.entity.rebind.RebindSupport;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.mementos.LocationMemento;
 import org.apache.brooklyn.test.entity.TestApplication;
 import org.testng.Assert;
@@ -39,9 +41,9 @@ import org.testng.annotations.Test;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.rebind.RebindEntityTest.MyEntity;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.AbstractLocation;
+
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.flags.SetFromFlag;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
index 0223324..9dcdfc9 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindPolicyTest.java
@@ -28,6 +28,7 @@ import java.util.Map;
 import org.apache.brooklyn.api.entity.Group;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.mementos.BrooklynMementoManifest;
 import org.apache.brooklyn.policy.EnricherSpec;
 import org.apache.brooklyn.policy.Policy;
@@ -42,8 +43,9 @@ import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.rebind.RebindEnricherTest.MyEnricher;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.Locations;
+
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.test.Asserts;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java
index 89c4875..c617311 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindSshMachineLocationTest.java
@@ -27,8 +27,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
-
-import org.apache.brooklyn.location.LocationSpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.location.basic.FixedListMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.SshMachineLocation;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java b/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java
index c7b02d8..104ee7e 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindTestUtils.java
@@ -32,6 +32,7 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.RebindExceptionHandler;
 import org.apache.brooklyn.api.entity.trait.Identifiable;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
 import org.apache.brooklyn.api.management.ha.ManagementNodeState;
@@ -49,7 +50,6 @@ import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
 import brooklyn.entity.rebind.persister.FileBasedObjectStore;
 import brooklyn.entity.rebind.persister.PersistMode;
 import brooklyn.entity.rebind.persister.PersistenceObjectStore;
-import org.apache.brooklyn.location.Location;
 import brooklyn.management.ha.ManagementPlaneSyncRecordPersisterToObjectStore;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.management.internal.ManagementContextInternal;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java b/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
index f6860fc..9ac62a4 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RecordingRebindExceptionHandler.java
@@ -25,8 +25,7 @@ import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.rebind.BrooklynObjectType;
 import org.apache.brooklyn.api.entity.rebind.RebindManager;
-
-import org.apache.brooklyn.location.Location;
+import org.apache.brooklyn.api.location.Location;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java b/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java
index 6806e42..3b63804 100644
--- a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java
+++ b/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterTestFixture.java
@@ -27,6 +27,8 @@ import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.entity.rebind.PersistenceExceptionHandler;
 import org.apache.brooklyn.api.entity.rebind.RebindManager.RebindFailureMode;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.mementos.BrooklynMemento;
 import org.apache.brooklyn.mementos.BrooklynMementoPersister;
@@ -47,9 +49,9 @@ import brooklyn.entity.rebind.PersistenceExceptionHandlerImpl;
 import brooklyn.entity.rebind.RebindContextImpl;
 import brooklyn.entity.rebind.RebindTestUtils;
 import brooklyn.entity.rebind.RecordingRebindExceptionHandler;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
+
 import org.apache.brooklyn.location.basic.SshMachineLocation;
+
 import brooklyn.test.policy.TestPolicy;
 
 import com.google.common.collect.Iterables;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java b/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java
index 3d4acd4..54b97a1 100644
--- a/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/persister/XmlMementoSerializerTest.java
@@ -33,6 +33,8 @@ import java.util.Set;
 import brooklyn.management.osgi.OsgiTestResources;
 
 import org.apache.brooklyn.location.basic.SimulatedLocation;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.mementos.BrooklynMementoPersister.LookupContext;
 import org.apache.brooklyn.policy.Enricher;
@@ -58,8 +60,6 @@ import brooklyn.catalog.internal.CatalogItemDtoAbstract;
 import brooklyn.catalog.internal.CatalogTestUtils;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.location.Location;
-import org.apache.brooklyn.location.LocationSpec;
 import brooklyn.management.osgi.OsgiVersionMoreEntityTest;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java b/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java
index 71cf3f7..4d1d9f9 100644
--- a/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java
+++ b/core/src/test/java/brooklyn/entity/trait/FailingEntityImpl.java
@@ -20,12 +20,12 @@ package brooklyn.entity.trait;
 
 import java.util.Collection;
 
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.test.entity.TestEntityImpl;
 import org.testng.Assert;
 
 import brooklyn.entity.basic.Entities;
-import org.apache.brooklyn.location.Location;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.task.Tasks;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java b/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
index 6683bdd..434f802 100644
--- a/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
+++ b/core/src/test/java/brooklyn/event/feed/function/FunctionFeedTest.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
 import org.apache.brooklyn.api.event.SensorEvent;
 import org.apache.brooklyn.api.event.SensorEventListener;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.slf4j.Logger;
@@ -48,8 +49,9 @@ import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.EntityInternal.FeedSupport;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+
 import brooklyn.test.Asserts;
 
 import com.google.common.base.Function;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d32d672a/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java b/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java
index b2f3ef8..27e3a6e 100644
--- a/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java
+++ b/core/src/test/java/brooklyn/event/feed/http/HttpFeedIntegrationTest.java
@@ -26,6 +26,7 @@ import java.net.URI;
 import org.apache.brooklyn.api.entity.basic.EntityLocal;
 import org.apache.brooklyn.api.entity.proxying.EntitySpec;
 import org.apache.brooklyn.api.event.AttributeSensor;
+import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.test.EntityTestUtils;
 import org.apache.brooklyn.test.entity.TestEntity;
 import org.testng.annotations.AfterMethod;
@@ -34,9 +35,10 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.event.basic.Sensors;
-import org.apache.brooklyn.location.Location;
+
 import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import org.apache.brooklyn.location.basic.PortRanges;
+
 import brooklyn.test.Asserts;
 import brooklyn.test.HttpService;