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

[27/64] incubator-brooklyn git commit: [BROOKLYN-162] Refactor package in ./core/util

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/brooklyn/util/xstream/XmlUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/xstream/XmlUtil.java b/core/src/main/java/brooklyn/util/xstream/XmlUtil.java
deleted file mode 100644
index 1ab1293..0000000
--- a/core/src/main/java/brooklyn/util/xstream/XmlUtil.java
+++ /dev/null
@@ -1,59 +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.util.xstream;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import brooklyn.util.exceptions.Exceptions;
-
-public class XmlUtil {
-
-    public static Object xpath(String xml, String xpath) {
-        // TODO Could share factory/doc in thread-local storage; see http://stackoverflow.com/questions/9828254/is-documentbuilderfactory-thread-safe-in-java-5
-        try {
-            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            DocumentBuilder builder = factory.newDocumentBuilder();
-            Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()));
-            XPathFactory xPathfactory = XPathFactory.newInstance();
-            XPathExpression expr = xPathfactory.newXPath().compile(xpath);
-            
-            return expr.evaluate(doc);
-            
-        } catch (ParserConfigurationException e) {
-            throw Exceptions.propagate(e);
-        } catch (SAXException e) {
-            throw Exceptions.propagate(e);
-        } catch (IOException e) {
-            throw Exceptions.propagate(e);
-        } catch (XPathExpressionException e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index 0e8ec80..ae3f39f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -55,6 +55,7 @@ import org.apache.brooklyn.api.policy.PolicySpec;
 import org.apache.brooklyn.core.catalog.CatalogPredicates;
 import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
 import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.util.flags.TypeCoercions;
 
 import brooklyn.config.BrooklynServerConfig;
 
@@ -64,7 +65,6 @@ import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.javalang.AggregateClassLoader;
 import brooklyn.util.javalang.LoadedClassLoader;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
index 2bf9cca..822a8d2 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
@@ -39,13 +39,13 @@ import org.apache.brooklyn.api.entity.proxying.ImplementedBy;
 import org.apache.brooklyn.api.location.Location;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.util.ResourceUtils;
+import org.apache.brooklyn.core.util.javalang.ReflectionScanner;
+import org.apache.brooklyn.core.util.javalang.UrlClassLoader;
 
 import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.util.ResourceUtils;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.javalang.AggregateClassLoader;
-import brooklyn.util.javalang.ReflectionScanner;
-import brooklyn.util.javalang.UrlClassLoader;
 import brooklyn.util.os.Os;
 import brooklyn.util.stream.Streams;
 import brooklyn.util.text.Strings;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDto.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDto.java
index 847f114..aefb635 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDto.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDto.java
@@ -27,8 +27,8 @@ import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.core.util.ResourceUtils;
 
-import brooklyn.util.ResourceUtils;
 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/699b3f65/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoUtils.java
index e2df123..6a27393 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoUtils.java
@@ -22,10 +22,10 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 
 import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
+import org.apache.brooklyn.core.util.ResourceUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.util.ResourceUtils;
 import brooklyn.util.exceptions.Exceptions;
 
 public class CatalogDtoUtils {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
index 047a168..e00211c 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
@@ -29,14 +29,14 @@ import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.ha.ManagementNodeState;
 import org.apache.brooklyn.core.management.ManagementContextInjectable;
 import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.util.ResourceUtils;
+import org.apache.brooklyn.core.util.flags.TypeCoercions;
 
 import brooklyn.config.BrooklynServerConfig;
-import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.FatalRuntimeException;
 import brooklyn.util.exceptions.RuntimeInterruptedException;
-import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.javalang.JavaClassNames;
 import brooklyn.util.os.Os;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
index 5aa073b..a7e52ee 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
@@ -34,12 +34,12 @@ import brooklyn.basic.AbstractBrooklynObject;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.rebind.RebindSupport;
 import org.apache.brooklyn.api.mementos.CatalogItemMemento;
+import org.apache.brooklyn.core.util.flags.FlagUtils;
+import org.apache.brooklyn.core.util.flags.SetFromFlag;
 
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.rebind.BasicCatalogItemRebindSupport;
 import brooklyn.util.collections.MutableList;
-import brooklyn.util.flags.FlagUtils;
-import brooklyn.util.flags.SetFromFlag;
 
 import com.google.common.base.Objects;
 import com.google.common.collect.ImmutableList;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
index 462e00e..836cac3 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
@@ -24,10 +24,10 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
+import org.apache.brooklyn.core.util.xstream.EnumCaseForgivingSingleValueConverter;
+import org.apache.brooklyn.core.util.xstream.XmlSerializer;
 
 import brooklyn.basic.AbstractBrooklynObject;
-import brooklyn.util.xstream.EnumCaseForgivingSingleValueConverter;
-import brooklyn.util.xstream.XmlSerializer;
 
 public class CatalogXmlSerializer extends XmlSerializer<Object> {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java b/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java
index 24d138b..686fd35 100644
--- a/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynFeatureEnablement.java
@@ -21,12 +21,12 @@ package org.apache.brooklyn.core.internal;
 import java.util.Map;
 
 import org.apache.brooklyn.api.management.ha.HighAvailabilityMode;
+import org.apache.brooklyn.core.util.internal.ssh.ShellTool;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.internal.storage.BrooklynStorage;
-import brooklyn.util.internal.ssh.ShellTool;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.Maps;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java b/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java
index 1858306..d1104af 100644
--- a/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/internal/BrooklynInitialization.java
@@ -20,9 +20,10 @@ package org.apache.brooklyn.core.internal;
 
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import org.apache.brooklyn.core.util.crypto.SecureKeys;
+import org.apache.brooklyn.core.util.flags.TypeCoercions;
 import org.apache.brooklyn.location.basic.PortRanges;
-import brooklyn.util.crypto.SecureKeys;
-import brooklyn.util.flags.TypeCoercions;
+
 import brooklyn.util.net.Networking;
 
 import com.google.common.annotations.Beta;
@@ -52,7 +53,7 @@ public class BrooklynInitialization {
 
     @SuppressWarnings("deprecation")
     public static void initLegacyLanguageExtensions() {
-        brooklyn.util.BrooklynLanguageExtensions.init();
+        org.apache.brooklyn.core.util.BrooklynLanguageExtensions.init();
     }
 
     /* other things:
@@ -74,7 +75,7 @@ public class BrooklynInitialization {
     @SuppressWarnings("deprecation")
     public synchronized static void reinitAll() {
         done.set(false);
-        brooklyn.util.BrooklynLanguageExtensions.reinit();
+        org.apache.brooklyn.core.util.BrooklynLanguageExtensions.reinit();
         initAll();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/entitlement/Entitlements.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/entitlement/Entitlements.java b/core/src/main/java/org/apache/brooklyn/core/management/entitlement/Entitlements.java
index 6bf9329..dc49053 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/entitlement/Entitlements.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/entitlement/Entitlements.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.api.management.entitlement.EntitlementClass;
 import org.apache.brooklyn.api.management.entitlement.EntitlementContext;
 import org.apache.brooklyn.api.management.entitlement.EntitlementManager;
 import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.util.task.Tasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,7 +50,6 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.javalang.Reflections;
-import brooklyn.util.task.Tasks;
 import brooklyn.util.text.Strings;
 
 /** @since 0.7.0 */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerImpl.java
index bda7f6f..f369124 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/ha/HighAvailabilityManagerImpl.java
@@ -51,6 +51,8 @@ import org.apache.brooklyn.core.management.internal.LocalEntityManager;
 import org.apache.brooklyn.core.management.internal.LocationManagerInternal;
 import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.management.internal.ManagementTransitionMode;
+import org.apache.brooklyn.core.util.task.ScheduledTask;
+import org.apache.brooklyn.core.util.task.Tasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -71,8 +73,6 @@ import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.ReferenceWithError;
-import brooklyn.util.task.ScheduledTask;
-import brooklyn.util.task.Tasks;
 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/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/ha/OsgiManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/ha/OsgiManager.java b/core/src/main/java/org/apache/brooklyn/core/management/ha/OsgiManager.java
index 6a133fc..8241479 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/ha/OsgiManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/ha/OsgiManager.java
@@ -39,6 +39,8 @@ import brooklyn.BrooklynVersion;
 
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.core.util.osgi.Osgis;
+import org.apache.brooklyn.core.util.osgi.Osgis.BundleFinder;
 
 import brooklyn.config.BrooklynServerConfig;
 import brooklyn.config.BrooklynServerPaths;
@@ -49,8 +51,6 @@ import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.os.Os;
 import brooklyn.util.os.Os.DeletionResult;
-import brooklyn.util.osgi.Osgis;
-import brooklyn.util.osgi.Osgis.BundleFinder;
 import brooklyn.util.repeat.Repeater;
 import brooklyn.util.text.Strings;
 import brooklyn.util.time.Duration;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java
index 58e2f60..7c1e473 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/AbstractManagementContext.java
@@ -56,6 +56,10 @@ import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.management.classloading.JavaBrooklynClassLoadingContext;
 import org.apache.brooklyn.core.management.entitlement.Entitlements;
 import org.apache.brooklyn.core.management.ha.HighAvailabilityManagerImpl;
+import org.apache.brooklyn.core.util.ResourceUtils;
+import org.apache.brooklyn.core.util.config.ConfigBag;
+import org.apache.brooklyn.core.util.task.BasicExecutionContext;
+import org.apache.brooklyn.core.util.task.Tasks;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.config.StringConfigMap;
@@ -74,13 +78,9 @@ import brooklyn.internal.storage.impl.inmemory.InMemoryDataGridFactory;
 import org.apache.brooklyn.location.basic.BasicLocationRegistry;
 
 import brooklyn.util.GroovyJavaMethods;
-import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
 import brooklyn.util.guava.Maybe;
-import brooklyn.util.task.BasicExecutionContext;
-import brooklyn.util.task.Tasks;
 
 import com.google.common.base.Function;
 import com.google.common.base.Objects;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/AsyncCollectionChangeAdapter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/AsyncCollectionChangeAdapter.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/AsyncCollectionChangeAdapter.java
index 038ec90..1fc1060 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/AsyncCollectionChangeAdapter.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/AsyncCollectionChangeAdapter.java
@@ -21,13 +21,13 @@ package org.apache.brooklyn.core.management.internal;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import org.apache.brooklyn.api.management.ExecutionManager;
+import org.apache.brooklyn.core.util.task.BasicExecutionManager;
+import org.apache.brooklyn.core.util.task.SingleThreadedScheduler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.task.BasicExecutionManager;
-import brooklyn.util.task.SingleThreadedScheduler;
 
 public class AsyncCollectionChangeAdapter<Item> implements CollectionChangeListener<Item> {
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java
index c02ff81..45876c5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/BrooklynGarbageCollector.java
@@ -39,6 +39,9 @@ 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.apache.brooklyn.core.util.task.BasicExecutionManager;
+import org.apache.brooklyn.core.util.task.ExecutionListener;
+import org.apache.brooklyn.core.util.task.Tasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,9 +58,6 @@ import brooklyn.util.collections.MutableMap;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.javalang.MemoryUsageTracker;
-import brooklyn.util.task.BasicExecutionManager;
-import brooklyn.util.task.ExecutionListener;
-import brooklyn.util.task.Tasks;
 import brooklyn.util.text.Strings;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/EffectorUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/EffectorUtils.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/EffectorUtils.java
index 028f2d2..0f3ab99 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/EffectorUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/EffectorUtils.java
@@ -33,6 +33,8 @@ import org.apache.brooklyn.api.entity.Effector;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.ParameterType;
 import org.apache.brooklyn.api.management.Task;
+import org.apache.brooklyn.core.util.config.ConfigBag;
+import org.apache.brooklyn.core.util.flags.TypeCoercions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,10 +43,8 @@ import brooklyn.entity.basic.BrooklynTaskTags;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
-import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.PropagatedRuntimeException;
-import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.guava.Maybe;
 
 import com.google.common.collect.Lists;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/EntityManagementUtils.java
index 3f59774..b243cda 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/EntityManagementUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/EntityManagementUtils.java
@@ -38,6 +38,8 @@ import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.api.management.classloading.BrooklynClassLoadingContext;
 import org.apache.brooklyn.core.management.classloading.JavaBrooklynClassLoadingContext;
+import org.apache.brooklyn.core.util.task.TaskBuilder;
+import org.apache.brooklyn.core.util.task.Tasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,8 +56,6 @@ import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;
-import brooklyn.util.task.TaskBuilder;
-import brooklyn.util.task.Tasks;
 import brooklyn.util.text.Strings;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java
index 53d31eb..23039ba 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalEntityManager.java
@@ -43,6 +43,7 @@ import org.apache.brooklyn.api.policy.Enricher;
 import org.apache.brooklyn.api.policy.EnricherSpec;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.policy.PolicySpec;
+import org.apache.brooklyn.core.util.task.Tasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,7 +63,6 @@ import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.util.collections.MutableSet;
 import brooklyn.util.collections.SetFromLiveMap;
 import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.task.Tasks;
 import brooklyn.util.time.CountdownTimer;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java
index 54708f5..f3e6aef 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalLocationManager.java
@@ -30,6 +30,8 @@ import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.location.ProvisioningLocation;
 import org.apache.brooklyn.api.management.AccessController;
 import org.apache.brooklyn.core.management.entitlement.Entitlements;
+import org.apache.brooklyn.core.util.config.ConfigBag;
+import org.apache.brooklyn.core.util.task.Tasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,11 +46,9 @@ import brooklyn.internal.storage.BrooklynStorage;
 import org.apache.brooklyn.location.basic.AbstractLocation;
 import org.apache.brooklyn.location.basic.LocationInternal;
 
-import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.RuntimeInterruptedException;
 import brooklyn.util.stream.Streams;
-import brooklyn.util.task.Tasks;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalManagementContext.java
index 3c353e2..b29c178 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalManagementContext.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalManagementContext.java
@@ -45,6 +45,11 @@ import org.apache.brooklyn.api.management.TaskAdaptable;
 import org.apache.brooklyn.core.internal.BrooklynFeatureEnablement;
 import org.apache.brooklyn.core.management.entitlement.Entitlements;
 import org.apache.brooklyn.core.management.ha.OsgiManager;
+import org.apache.brooklyn.core.util.task.BasicExecutionContext;
+import org.apache.brooklyn.core.util.task.BasicExecutionManager;
+import org.apache.brooklyn.core.util.task.DynamicTasks;
+import org.apache.brooklyn.core.util.task.TaskTags;
+import org.apache.brooklyn.core.util.task.Tasks;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -58,11 +63,6 @@ import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.internal.storage.DataGridFactory;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;
-import brooklyn.util.task.BasicExecutionContext;
-import brooklyn.util.task.BasicExecutionManager;
-import brooklyn.util.task.DynamicTasks;
-import brooklyn.util.task.TaskTags;
-import brooklyn.util.task.Tasks;
 import brooklyn.util.text.Strings;
 
 import com.google.common.annotations.Beta;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalSubscriptionManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalSubscriptionManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalSubscriptionManager.java
index 99b79ec..9a75621 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalSubscriptionManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalSubscriptionManager.java
@@ -40,12 +40,12 @@ import org.apache.brooklyn.api.event.SensorEventListener;
 import org.apache.brooklyn.api.management.ExecutionManager;
 import org.apache.brooklyn.api.management.SubscriptionHandle;
 import org.apache.brooklyn.api.management.SubscriptionManager;
+import org.apache.brooklyn.core.util.task.BasicExecutionManager;
+import org.apache.brooklyn.core.util.task.SingleThreadedScheduler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import brooklyn.entity.basic.Entities;
-import brooklyn.util.task.BasicExecutionManager;
-import brooklyn.util.task.SingleThreadedScheduler;
 import brooklyn.util.text.Identifiers;
 
 import com.google.common.base.Predicate;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalUsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalUsageManager.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalUsageManager.java
index dc95d11..991f930 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalUsageManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/LocalUsageManager.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.core.management.ManagementContextInjectable;
 import org.apache.brooklyn.core.management.entitlement.Entitlements;
 import org.apache.brooklyn.core.management.usage.ApplicationUsage;
 import org.apache.brooklyn.core.management.usage.LocationUsage;
+import org.apache.brooklyn.core.util.flags.TypeCoercions;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,7 +53,6 @@ import org.apache.brooklyn.location.basic.LocationConfigKeys;
 import org.apache.brooklyn.location.basic.LocationInternal;
 
 import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.flags.TypeCoercions;
 import brooklyn.util.javalang.Reflections;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/management/internal/ManagementContextInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/management/internal/ManagementContextInternal.java b/core/src/main/java/org/apache/brooklyn/core/management/internal/ManagementContextInternal.java
index 6c993d8..3fc0677 100644
--- a/core/src/main/java/org/apache/brooklyn/core/management/internal/ManagementContextInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/core/management/internal/ManagementContextInternal.java
@@ -31,6 +31,7 @@ import org.apache.brooklyn.api.management.ManagementContext;
 import org.apache.brooklyn.api.management.Task;
 import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
 import org.apache.brooklyn.core.management.ha.OsgiManager;
+import org.apache.brooklyn.core.util.task.TaskTags;
 
 import brooklyn.config.BrooklynProperties;
 import brooklyn.entity.basic.BrooklynTaskTags;
@@ -39,7 +40,6 @@ import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.entity.proxying.InternalPolicyFactory;
 import brooklyn.internal.storage.BrooklynStorage;
 import brooklyn.util.guava.Maybe;
-import brooklyn.util.task.TaskTags;
 
 import com.google.common.annotations.Beta;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/util/BrooklynLanguageExtensions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/util/BrooklynLanguageExtensions.java b/core/src/main/java/org/apache/brooklyn/core/util/BrooklynLanguageExtensions.java
new file mode 100644
index 0000000..9e1b80e
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/util/BrooklynLanguageExtensions.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.core.util;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.brooklyn.core.internal.BrooklynInitialization;
+
+import brooklyn.util.internal.TimeExtras;
+
+/** @deprecated since 0.7.0 use {@link BrooklynInitialization} */
+public class BrooklynLanguageExtensions {
+
+    private BrooklynLanguageExtensions() {}
+    
+    private static AtomicBoolean done = new AtomicBoolean(false);
+    
+    public synchronized static void reinit() {
+        done.set(false);
+        init();
+    }
+    
+    /** performs the language extensions required for this project */
+    public synchronized static void init() {
+        if (done.getAndSet(true)) return;
+        TimeExtras.init();
+        BrooklynInitialization.initPortRanges();
+    }
+    
+    static { BrooklynInitialization.initLegacyLanguageExtensions(); }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/util/BrooklynMavenArtifacts.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/util/BrooklynMavenArtifacts.java b/core/src/main/java/org/apache/brooklyn/core/util/BrooklynMavenArtifacts.java
new file mode 100644
index 0000000..c00fec0
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/util/BrooklynMavenArtifacts.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.core.util;
+
+import brooklyn.BrooklynVersion;
+import brooklyn.util.maven.MavenArtifact;
+import brooklyn.util.maven.MavenRetriever;
+import brooklyn.util.text.Strings;
+
+public class BrooklynMavenArtifacts {
+
+    public static MavenArtifact jar(String artifactId) {
+        return artifact(null, artifactId, "jar");
+    }
+    
+    public static MavenArtifact artifact(String subgroupUnderIoBrooklyn, String artifactId, String packaging) {
+        return artifact(subgroupUnderIoBrooklyn, artifactId, packaging, null);
+    }
+
+    public static MavenArtifact artifact(String subgroupUnderIoBrooklyn, String artifactId, String packaging, String classifier) {
+        return new MavenArtifact(
+                Strings.isEmpty(subgroupUnderIoBrooklyn) ? "org.apache.brooklyn" : "org.apache.brooklyn."+subgroupUnderIoBrooklyn,
+                artifactId, packaging, classifier, BrooklynVersion.get());
+    }
+
+    public static String localUrlForJar(String artifactId) {
+        return MavenRetriever.localUrl(jar(artifactId));
+    }
+    
+    public static String localUrl(String subgroupUnderIoBrooklyn, String artifactId, String packaging) {
+        return MavenRetriever.localUrl(artifact(subgroupUnderIoBrooklyn, artifactId, packaging));
+    }
+
+    public static String hostedUrlForJar(String artifactId) {
+        return MavenRetriever.hostedUrl(jar(artifactId));
+    }
+    
+    public static String hostedUrl(String subgroupUnderIoBrooklyn, String artifactId, String packaging) {
+        return MavenRetriever.hostedUrl(artifact(subgroupUnderIoBrooklyn, artifactId, packaging));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/util/BrooklynNetworkUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/util/BrooklynNetworkUtils.java b/core/src/main/java/org/apache/brooklyn/core/util/BrooklynNetworkUtils.java
new file mode 100644
index 0000000..7240425
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/util/BrooklynNetworkUtils.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.core.util;
+
+import java.net.InetAddress;
+
+import brooklyn.config.BrooklynServiceAttributes;
+
+import org.apache.brooklyn.core.util.flags.TypeCoercions;
+import org.apache.brooklyn.location.geo.LocalhostExternalIpLoader;
+
+import brooklyn.util.JavaGroovyEquivalents;
+import brooklyn.util.net.Networking;
+
+public class BrooklynNetworkUtils {
+
+    /** returns the externally-facing IP address from which this host comes, or 127.0.0.1 if not resolvable */
+    public static String getLocalhostExternalIp() {
+        return LocalhostExternalIpLoader.getLocalhostIpQuicklyOrDefault();
+    }
+
+    /** returns a IP address for localhost paying attention to a system property to prevent lookup in some cases */ 
+    public static InetAddress getLocalhostInetAddress() {
+        return TypeCoercions.coerce(JavaGroovyEquivalents.elvis(BrooklynServiceAttributes.LOCALHOST_IP_ADDRESS.getValue(), 
+                Networking.getLocalHost()), InetAddress.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/699b3f65/core/src/main/java/org/apache/brooklyn/core/util/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/util/ResourceUtils.java b/core/src/main/java/org/apache/brooklyn/core/util/ResourceUtils.java
new file mode 100644
index 0000000..bbd88d5
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/util/ResourceUtils.java
@@ -0,0 +1,639 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES 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.core.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.brooklyn.api.management.ManagementContext;
+import org.apache.brooklyn.api.management.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
+import org.apache.brooklyn.core.internal.BrooklynInitialization;
+import org.apache.brooklyn.core.management.classloading.JavaBrooklynClassLoadingContext;
+import org.apache.brooklyn.core.util.http.HttpTool;
+import org.apache.brooklyn.core.util.http.HttpTool.HttpClientBuilder;
+import org.apache.brooklyn.core.util.text.DataUriSchemeParser;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.javalang.Threads;
+import brooklyn.util.net.Urls;
+import brooklyn.util.os.Os;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.text.Strings;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Throwables;
+import com.google.common.collect.Lists;
+
+public class ResourceUtils {
+    
+    private static final Logger log = LoggerFactory.getLogger(ResourceUtils.class);
+    private static final List<Function<Object,BrooklynClassLoadingContext>> classLoaderProviders = Lists.newCopyOnWriteArrayList();
+
+    private BrooklynClassLoadingContext loader = null;
+    private String context = null;
+    private Object contextObject = null;
+    
+    static { BrooklynInitialization.initNetworking(); }
+    
+    /**
+     * Creates a {@link ResourceUtils} object with a specific class loader and context.
+     * <p>
+     * Use the provided {@link ClassLoader} object for class loading with the
+     * {@code contextObject} for context and the {@code contextMessage} string for
+     * error messages.
+     *
+     * @see ResourceUtils#create(Object, String)
+     * @see ResourceUtils#create(Object)
+     */
+    public static final ResourceUtils create(ClassLoader loader, Object contextObject, String contextMessage) {
+        return new ResourceUtils(loader, contextObject, contextMessage);
+    }
+
+    /**
+     * Creates a {@link ResourceUtils} object with a specific class loader and context.
+     * <p>
+     * Use the provided {@link BrooklynClassLoadingContext} object for class loading with the
+     * {@code contextObject} for context and the {@code contextMessage} string for
+     * error messages.
+     *
+     * @see ResourceUtils#create(Object, String)
+     * @see ResourceUtils#create(Object)
+     */
+    public static final ResourceUtils create(BrooklynClassLoadingContext loader, Object contextObject, String contextMessage) {
+        return new ResourceUtils(loader, contextObject, contextMessage);
+    }
+
+    /**
+     * Creates a {@link ResourceUtils} object with the given context.
+     * <p>
+     * Uses the {@link ClassLoader} of the given {@code contextObject} for class
+     * loading and the {@code contextMessage} string for error messages.
+     *
+     * @see ResourceUtils#create(ClassLoader, Object, String)
+     * @see ResourceUtils#create(Object)
+     */
+    public static final ResourceUtils create(Object contextObject, String contextMessage) {
+        return new ResourceUtils(contextObject, contextMessage);
+    }
+
+    /**
+     * Creates a {@link ResourceUtils} object with the given context.
+     * <p>
+     * Uses the {@link ClassLoader} of the given {@code contextObject} for class
+     * loading and its {@link Object#toString()} (preceded by the word 'for') as
+     * the string used in error messages.
+     *
+     * @see ResourceUtils#create(ClassLoader, Object, String)
+     * @see ResourceUtils#create(Object)
+     */
+    public static final ResourceUtils create(Object contextObject) {
+        return new ResourceUtils(contextObject);
+    }
+
+    /**
+     * Creates a {@link ResourceUtils} object with itself as the context.
+     *
+     * @see ResourceUtils#create(Object)
+     */
+    public static final ResourceUtils create() {
+        return new ResourceUtils(null);
+    }
+
+    public ResourceUtils(ClassLoader loader, Object contextObject, String contextMessage) {
+        this(getClassLoadingContextInternal(loader, contextObject), contextObject, contextMessage);
+    }
+    
+    public ResourceUtils(BrooklynClassLoadingContext loader, Object contextObject, String contextMessage) {
+        this.loader = loader;
+        this.contextObject = contextObject;
+        this.context = contextMessage;
+    }
+
+    public ResourceUtils(Object contextObject, String contextMessage) {
+        this(contextObject==null ? null : getClassLoadingContextInternal(null, contextObject), contextObject, contextMessage);
+    }
+
+    public ResourceUtils(Object contextObject) {
+        this(contextObject, Strings.toString(contextObject));
+    }
+    
+    /** used to register custom mechanisms for getting classloaders given an object */
+    public static void addClassLoaderProvider(Function<Object,BrooklynClassLoadingContext> provider) {
+        classLoaderProviders.add(provider);
+    }
+    
+    // TODO rework this class so it accepts but does not require a BCLC ?
+    @SuppressWarnings("deprecation")
+    protected static BrooklynClassLoadingContext getClassLoadingContextInternal(ClassLoader loader, Object contextObject) {
+        if (contextObject instanceof BrooklynClassLoadingContext)
+            return (BrooklynClassLoadingContext) contextObject;
+        
+        for (Function<Object,BrooklynClassLoadingContext> provider: classLoaderProviders) {
+            BrooklynClassLoadingContext result = provider.apply(contextObject);
+            if (result!=null) return result;
+        }
+
+        BrooklynClassLoadingContext bl = BrooklynLoaderTracker.getLoader();
+        ManagementContext mgmt = (bl!=null ? bl.getManagementContext() : null);
+
+        ClassLoader cl = loader;
+        if (cl==null) cl = contextObject instanceof Class ? ((Class<?>)contextObject).getClassLoader() : 
+            contextObject instanceof ClassLoader ? ((ClassLoader)contextObject) : 
+                contextObject.getClass().getClassLoader();
+            
+        return JavaBrooklynClassLoadingContext.create(mgmt, cl);
+    }
+    
+    /** This should not be exposed as it risks it leaking into places where it would be serialized.
+     * Better for callers use {@link CatalogUtils#getClassLoadingContext(org.apache.brooklyn.api.entity.Entity)} or similar. }.
+     */
+    private BrooklynClassLoadingContext getLoader() {
+        return (loader!=null ? loader : getClassLoadingContextInternal(null, contextObject!=null ? contextObject : this));
+    }
+
+    /**
+     * @return all resources in Brooklyn's {@link BrooklynClassLoadingContext} with the given name.
+     */
+    public Iterable<URL> getResources(String name) {
+        return getLoader().getResources(name);
+    }
+    
+    /**
+     * Takes a string which is treated as a URL (with some extended "schemes" also expected),
+     * or as a path to something either on the classpath (absolute only) or the local filesystem (relative or absolute, depending on leading slash)
+     * <p>
+     * URLs can be of the form <b>classpath://com/acme/Foo.properties</b>
+     * as well as <b>file:///home/...</b> and <b>http://acme.com/...</b>.
+     * <p>
+     * Throws exception if not found, using the context parameter passed into the constructor.
+     * <p>
+     * TODO may want OSGi, or typed object; should consider pax url
+     * 
+     * @return a stream, or throws exception (never returns null)
+     */
+    public InputStream getResourceFromUrl(String url) {
+        try {
+            if (url==null) throw new NullPointerException("Cannot read from null");
+            if (url=="") throw new NullPointerException("Cannot read from empty string");
+            String orig = url;
+            String protocol = Urls.getProtocol(url);
+            if (protocol!=null) {
+                if ("classpath".equals(protocol)) {
+                    try {
+                        return getResourceViaClasspath(url);
+                    } catch (IOException e) {
+                        //catch the above because both orig and modified url may be interesting
+                        throw new IOException("Error accessing "+orig+": "+e, e);
+                    }
+                }
+                if ("sftp".equals(protocol)) {
+                    try {
+                        return getResourceViaSftp(url);
+                    } catch (IOException e) {
+                        throw new IOException("Error accessing "+orig+": "+e, e);
+                    }
+                }
+
+                if ("file".equals(protocol))
+                    url = tidyFileUrl(url);
+                
+                if ("data".equals(protocol)) {
+                    return new DataUriSchemeParser(url).lax().parse().getDataAsInputStream();
+                }
+
+                if ("http".equals(protocol) || "https".equals(protocol)) {
+                    return getResourceViaHttp(url);
+                }
+
+                return new URL(url).openStream();
+            }
+
+            try {
+                //try as classpath reference, then as file
+                try {
+                    URL u = getLoader().getResource(url);
+                    if (u!=null) return u.openStream();
+                } catch (IllegalArgumentException e) {
+                    //Felix installs an additional URL to the system classloader
+                    //which throws an IllegalArgumentException when passed a
+                    //windows path. See ExtensionManager.java static initializer.
+
+                    //ignore, not a classpath resource
+                }
+                if (url.startsWith("/")) {
+                    //some getResource calls fail if argument starts with /
+                    String urlNoSlash = url;
+                    while (urlNoSlash.startsWith("/")) urlNoSlash = urlNoSlash.substring(1);
+                    URL u = getLoader().getResource(urlNoSlash);
+                    if (u!=null) return u.openStream();
+//                    //Class.getResource can require a /  (else it attempts to be relative) but Class.getClassLoader doesn't
+//                    u = getLoader().getResource("/"+urlNoSlash);
+//                    if (u!=null) return u.openStream();
+                }
+                File f;
+                // but first, if it starts with tilde, treat specially
+                if (url.startsWith("~/")) {
+                    f = new File(Os.home(), url.substring(2));
+                } else if (url.startsWith("~\\")) {
+                    f = new File(Os.home(), url.substring(2));
+                } else {
+                    f = new File(url);
+                }
+                if (f.exists()) return new FileInputStream(f);
+            } catch (IOException e) {
+                //catch the above because both u and modified url will be interesting
+                throw new IOException("Error accessing "+orig+": "+e, e);
+            }
+            throw new IOException("'"+orig+"' not found on classpath or filesystem");
+        } catch (Exception e) {
+            if (context!=null) {
+                throw new RuntimeException("Error getting resource '"+url+"' for "+context+": "+e, e);
+            } else {
+                throw Exceptions.propagate(e);
+            }
+        }
+    }
+    
+    private final static Pattern pattern = Pattern.compile("^file:/*~/+(.*)$");
+
+    public static URL tidy(URL url) {
+        // File class has helpful methods for URIs but not URLs. So we convert.
+        URI in;
+        try {
+            in = url.toURI();
+        } catch (URISyntaxException e) {
+            throw Exceptions.propagate(e);
+        }
+        URI out;
+
+        Matcher matcher = pattern.matcher(in.toString());
+        if (matcher.matches()) {
+            // home-relative
+            File home = new File(Os.home());
+            File file = new File(home, matcher.group(1));
+            out = file.toURI();
+        } else if (in.getScheme().equals("file:")) {
+            // some other file, so canonicalize
+            File file = new File(in);
+            out = file.toURI();
+        } else {
+            // some other scheme, so no-op
+            out = in;
+        }
+
+        URL urlOut;
+        try {
+            urlOut = out.toURL();
+        } catch (MalformedURLException e) {
+            throw Exceptions.propagate(e);
+        }
+        if (!urlOut.equals(url) && log.isDebugEnabled()) {
+            log.debug("quietly changing " + url + " to " + urlOut);
+        }
+        return urlOut;
+    }
+    
+    public static String tidyFileUrl(String url) {
+        try {
+            return tidy(new URL(url)).toString();
+        } catch (MalformedURLException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    /** @deprecated since 0.7.0; use method {@link Os#mergePaths(String...)} */ @Deprecated
+    public static String mergeFilePaths(String... items) {
+        return Os.mergePaths(items);
+    }
+    
+    /** @deprecated since 0.7.0; use method {@link Os#tidyPath(String)} */ @Deprecated
+    public static String tidyFilePath(String path) {
+        return Os.tidyPath(path);
+    }
+    
+    /** @deprecated since 0.7.0; use method {@link Urls#getProtocol(String)} */ @Deprecated
+    public static String getProtocol(String url) {
+        return Urls.getProtocol(url);
+    }
+    
+    private InputStream getResourceViaClasspath(String url) throws IOException {
+        assert url.startsWith("classpath:");
+        String subUrl = url.substring("classpath:".length());
+        while (subUrl.startsWith("/")) subUrl = subUrl.substring(1);
+        URL u = getLoader().getResource(subUrl);
+        if (u!=null) return u.openStream();
+        else throw new IOException(subUrl+" not found on classpath");
+    }
+    
+    private InputStream getResourceViaSftp(String url) throws IOException {
+        assert url.startsWith("sftp://");
+        String subUrl = url.substring("sftp://".length());
+        String user;
+        String address;
+        String path;
+        int atIndex = subUrl.indexOf("@");
+        int colonIndex = subUrl.indexOf(":", (atIndex > 0 ? atIndex : 0));
+        if (colonIndex <= 0 || colonIndex <= atIndex) {
+            throw new IllegalArgumentException("Invalid sftp url ("+url+"); IP or hostname must be specified, such as sftp://localhost:/path/to/file");
+        }
+        if (subUrl.length() <= (colonIndex+1)) {
+            throw new IllegalArgumentException("Invalid sftp url ("+url+"); must specify path of remote file, such as sftp://localhost:/path/to/file");
+        }
+        if (atIndex >= 0) {
+            user = subUrl.substring(0, atIndex);
+        } else {
+            user = null;
+        }
+        address = subUrl.substring(atIndex + 1, colonIndex);
+        path = subUrl.substring(colonIndex+1);
+        
+        // TODO messy way to get an SCP session 
+        SshMachineLocation machine = new SshMachineLocation(MutableMap.builder()
+                .putIfNotNull("user", user)
+                .put("address", InetAddress.getByName(address))
+                .build());
+        try {
+            final File tempFile = Os.newTempFile("brooklyn-sftp", "tmp");
+            tempFile.setReadable(true, true);
+            machine.copyFrom(path, tempFile.getAbsolutePath());
+            return new FileInputStream(tempFile) {
+                @Override
+                public void close() throws IOException {
+                    super.close();
+                    tempFile.delete();
+                }
+            };
+        } finally {
+            Streams.closeQuietly(machine);
+        }
+    }
+    
+    //For HTTP(S) targets use HttpClient so
+    //we can do authentication
+    private InputStream getResourceViaHttp(String resource) throws IOException {
+        URI uri = URI.create(resource);
+        HttpClientBuilder builder = HttpTool.httpClientBuilder()
+                .laxRedirect(true)
+                .uri(uri);
+        Credentials credentials = getUrlCredentials(uri.getRawUserInfo());
+        if (credentials != null) {
+            builder.credentials(credentials);
+        }
+        HttpClient client = builder.build();
+        HttpResponse result = client.execute(new HttpGet(resource));
+        int statusCode = result.getStatusLine().getStatusCode();
+        if (HttpTool.isStatusCodeHealthy(statusCode)) {
+            HttpEntity entity = result.getEntity();
+            if (entity != null) {
+                return entity.getContent();
+            } else {
+                return new ByteArrayInputStream(new byte[0]);
+            }
+        } else {
+            EntityUtils.consume(result.getEntity());
+            throw new IllegalStateException("Invalid response invoking " + resource + ": response code " + statusCode);
+        }
+    }
+
+    private Credentials getUrlCredentials(String userInfo) {
+        if (userInfo != null) {
+            String[] arr = userInfo.split(":");
+            String username;
+            String password = null;
+            if (arr.length == 1) {
+                username = urlDecode(arr[0]);
+            } else if (arr.length == 2) {
+                username = urlDecode(arr[0]);
+                password = urlDecode(arr[1]);
+            } else {
+                return null;
+            }
+            return new UsernamePasswordCredentials(username, password);
+        } else {
+            return null;
+        }
+    }
+
+    private String urlDecode(String str) {
+        try {
+            return URLDecoder.decode(str, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+
+    /** takes {@link #getResourceFromUrl(String)} and reads fully, into a string */
+    public String getResourceAsString(String url) {
+        try {
+            return readFullyString(getResourceFromUrl(url));
+        } catch (Exception e) {
+            log.debug("ResourceUtils got error reading "+url+(context==null?"":" "+context)+" (rethrowing): "+e);
+            throw Throwables.propagate(e);
+        }
+    }
+
+    /** allows failing-fast if URL cannot be read */
+    public String checkUrlExists(String url) {
+        return checkUrlExists(url, null);
+    }
+    
+    public String checkUrlExists(String url, String message) {
+        if (url==null) throw new NullPointerException("URL "+(message!=null ? message+" " : "")+"must not be null");
+        InputStream s;
+        try {
+            s = getResourceFromUrl(url);
+        } catch (Exception e) {
+            Exceptions.propagateIfFatal(e);
+            throw new IllegalArgumentException("Unable to access URL "+(message!=null ? message : "")+": "+url, e);
+        }
+        Streams.closeQuietly(s); 
+        return url;
+    }
+
+    /** tests whether the url exists, returning true or false */
+    public boolean doesUrlExist(String url) {
+        InputStream s = null;
+        try {
+            s = getResourceFromUrl(url);
+            return true;
+        } catch (Exception e) {
+            return false;
+        } finally {
+            Streams.closeQuietly(s);
+        }
+    }
+    
+    /** returns the first available URL */
+    public Optional<String> firstAvailableUrl(String ...urls) {
+        for (String url: urls) {
+            if (doesUrlExist(url)) return Optional.of(url);
+        }
+        return Optional.absent();
+    }
+    
+    /** returns the base directory or JAR from which the context is class-loaded, if possible;
+     * throws exception if not found */
+    public String getClassLoaderDir() {
+        if (contextObject==null) throw new IllegalArgumentException("No suitable context ("+context+") to auto-detect classloader dir");
+        Class<?> cc = contextObject instanceof Class ? (Class<?>)contextObject : contextObject.getClass();
+        return getClassLoaderDir(cc.getCanonicalName().replace('.', '/')+".class");
+    }
+    
+    public String getClassLoaderDir(String resourceInThatDir) {
+        resourceInThatDir = Strings.removeFromStart(resourceInThatDir, "/");
+        URL resourceUrl = getLoader().getResource(resourceInThatDir);
+        if (resourceUrl==null) throw new NoSuchElementException("Resource ("+resourceInThatDir+") not found");
+
+        URL containerUrl = getContainerUrl(resourceUrl, resourceInThatDir);
+
+        if (!"file".equals(containerUrl.getProtocol())) throw new IllegalStateException("Resource ("+resourceInThatDir+") not on file system (at "+containerUrl+")");
+
+        //convert from file: URL to File
+        File file;
+        try {
+            file = new File(containerUrl.toURI());
+        } catch (URISyntaxException e) {
+            throw new IllegalStateException("Resource ("+resourceInThatDir+") found at invalid URI (" + containerUrl + ")", e);
+        }
+        
+        if (!file.exists()) throw new IllegalStateException("Context class url substring ("+containerUrl+") not found on filesystem");
+        return file.getPath();
+        
+    }
+
+    public static URL getContainerUrl(URL url, String resourceInThatDir) {
+        //Switching from manual parsing of jar: and file: URLs to java provided functionality.
+        //The old code was breaking on any Windows path and instead of fixing it, using
+        //the provided Java APIs seemed like the better option since they are already tested
+        //on multiple platforms.
+        boolean isJar = "jar".equals(url.getProtocol());
+        if(isJar) {
+            try {
+                //let java handle the parsing of jar URL, no network connection is established.
+                //Strips the jar protocol:
+                //  jar:file:/<path to jar>!<resourceInThatDir>
+                //  becomes
+                //  file:/<path to jar>
+                JarURLConnection connection = (JarURLConnection) url.openConnection();
+                url = connection.getJarFileURL();
+            } catch (IOException e) {
+                throw new IllegalStateException(e);
+            }
+        } else {
+            //Remove the trailing resouceInThatDir path from the URL, thus getting the parent folder.
+            String path = url.toString();
+            int i = path.indexOf(resourceInThatDir);
+            if (i==-1) throw new IllegalStateException("Resource path ("+resourceInThatDir+") not in url substring ("+url+")");
+            String parent = path.substring(0, i);
+            try {
+                url = new URL(parent);
+            } catch (MalformedURLException e) {
+                throw new IllegalStateException("Resource ("+resourceInThatDir+") found at invalid URL parent (" + parent + ")", e);
+            }
+        }
+        return url;
+    }
+    
+    /** @deprecated since 0.7.0 use {@link Streams#readFullyString(InputStream) */ @Deprecated
+    public static String readFullyString(InputStream is) throws IOException {
+        return Streams.readFullyString(is);
+    }
+
+    /** @deprecated since 0.7.0 use {@link Streams#readFully(InputStream) */ @Deprecated
+    public static byte[] readFullyBytes(InputStream is) throws IOException {
+        return Streams.readFully(is);
+    }
+    
+    /** @deprecated since 0.7.0 use {@link Streams#copy(InputStream, OutputStream)} */ @Deprecated
+    public static void copy(InputStream input, OutputStream output) throws IOException {
+        Streams.copy(input, output);
+    }
+
+    /** @deprecated since 0.7.0; use same method in {@link Os} */ @Deprecated
+    public static File mkdirs(File dir) {
+        return Os.mkdirs(dir);
+    }
+
+    /** @deprecated since 0.7.0; use same method in {@link Os} */ @Deprecated
+    public static File writeToTempFile(InputStream is, String prefix, String suffix) {
+        return Os.writeToTempFile(is, prefix, suffix);
+    }
+    
+    /** @deprecated since 0.7.0; use same method in {@link Os} */ @Deprecated
+    public static File writeToTempFile(InputStream is, File tempDir, String prefix, String suffix) {
+        return Os.writeToTempFile(is, tempDir, prefix, suffix);
+    }
+
+    /** @deprecated since 0.7.0; use method {@link Os#writePropertiesToTempFile(Properties, String, String)} */ @Deprecated
+    public static File writeToTempFile(Properties props, String prefix, String suffix) {
+        return Os.writePropertiesToTempFile(props, prefix, suffix);
+    }
+    
+    /** @deprecated since 0.7.0; use method {@link Os#writePropertiesToTempFile(Properties, File, String, String)} */ @Deprecated
+    public static File writeToTempFile(Properties props, File tempDir, String prefix, String suffix) {
+        return Os.writePropertiesToTempFile(props, tempDir, prefix, suffix);
+    }
+
+    /** @deprecated since 0.7.0; use method {@link Threads#addShutdownHook(Runnable)} */ @Deprecated
+    public static Thread addShutdownHook(final Runnable task) {
+        return Threads.addShutdownHook(task);
+    }
+    /** @deprecated since 0.7.0; use method {@link Threads#removeShutdownHook(Thread)} */ @Deprecated
+    public static boolean removeShutdownHook(Thread hook) {
+        return Threads.removeShutdownHook(hook);
+    }
+
+    /** returns the items with exactly one "/" between items (whether or not the individual items start or end with /),
+     * except where character before the / is a : (url syntax) in which case it will permit multiple (will not remove any) 
+     * @deprecated since 0.7.0 use either {@link Os#mergePathsUnix(String...)} {@link Urls#mergePaths(String...) */ @Deprecated
+    public static String mergePaths(String ...items) {
+        return Urls.mergePaths(items);
+    }
+}