http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeSensorAndConfigKey.java
 
b/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeSensorAndConfigKey.java
deleted file mode 100644
index b777352..0000000
--- 
a/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeSensorAndConfigKey.java
+++ /dev/null
@@ -1,147 +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.sensor.core;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.reflect.TypeToken;
-
-/**
-* A {@link Sensor} describing an attribute that can be configured with inputs 
that are used to derive the final value.
-* <p>
-* The {@link ConfigKey} will have the same name and description as the sensor 
but not necessarily the same type.
-* Conversion to set the sensor value from the config key must be supplied in a 
subclass.
-* <p>
-* {@link ConfigToAttributes#apply(EntityLocal, AttributeSensorAndConfigKey)} 
is useful to set the attribute from the sensor.
-*/
-public abstract class AttributeSensorAndConfigKey<ConfigType,SensorType> 
extends BasicAttributeSensor<SensorType> 
-        implements ConfigKey.HasConfigKey<ConfigType> {
-    private static final long serialVersionUID = -3103809215973264600L;
-    private static final Logger log = 
LoggerFactory.getLogger(AttributeSensorAndConfigKey.class);
-
-    private ConfigKey<ConfigType> configKey;
-
-    public AttributeSensorAndConfigKey(Class<ConfigType> configType, 
Class<SensorType> sensorType, String name) {
-        this(configType, sensorType, name, name, null);
-    }
-    
-    public AttributeSensorAndConfigKey(Class<ConfigType> configType, 
Class<SensorType> sensorType, String name, String description) {
-        this(TypeToken.of(configType), TypeToken.of(sensorType), name, 
description, null);
-    }
-    
-    public AttributeSensorAndConfigKey(Class<ConfigType> configType, 
Class<SensorType> sensorType, String name, String description, Object 
defaultValue) {
-        this(TypeToken.of(configType), TypeToken.of(sensorType), name, 
description, defaultValue);
-    }
-
-    public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, 
TypeToken<SensorType> sensorType, String name) {
-        this(configType, sensorType, name, null);
-    }
-
-    public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, 
TypeToken<SensorType> sensorType, String name, String description) {
-        this(configType, sensorType, name, description, null);
-    }
-
-    public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, 
TypeToken<SensorType> sensorType, String name, String description, Object 
defaultValue) {
-        super(sensorType, name, description);
-        ConfigType defaultValueTyped;
-        try {
-            defaultValueTyped = TypeCoercions.coerce(defaultValue, configType);
-        } catch (Exception e) {
-            log.warn("Invalid default value '"+defaultValue+"' for "+name+" 
(rethrowing: "+e, e);
-            throw Exceptions.propagate(e);
-        }
-        configKey = new BasicConfigKey<ConfigType>(configType, name, 
description, defaultValueTyped);
-    }
-
-    public 
AttributeSensorAndConfigKey(AttributeSensorAndConfigKey<ConfigType,SensorType> 
orig, ConfigType defaultValue) {
-        super(orig.getTypeToken(), orig.getName(), orig.getDescription());
-        configKey = ConfigKeys.newConfigKeyWithDefault(orig.configKey, 
-                TypeCoercions.coerce(defaultValue, 
orig.configKey.getTypeToken()));
-    }
-
-    public ConfigKey<ConfigType> getConfigKey() { return configKey; }
-    
-    /** returns the sensor value for this attribute on the given entity, if 
present,
-     * otherwise works out what the sensor value should be based on the config 
key's value
-     * <p>
-     * calls to this may allocate resources (e.g. ports) so should be called 
only once and 
-     * then (if non-null) assigned as the sensor's value
-     * <p>
-     * <b>(for this reason this method should generally not be invoked by 
callers except in tests and by the framework,
-     * and similarly should not be overridden; implement {@link 
#convertConfigToSensor(Object, Entity)} instead for single-execution calls.
-     * the framework calls this from {@link 
AbstractEntity#setAttribute(AttributeSensorAndConfigKey)} 
-     * typically via {@link ConfigToAttributes#apply(EntityLocal)} e.g. from 
SoftwareProcessImpl.preStart().)
-     * </b> 
-     */
-    public SensorType getAsSensorValue(Entity e) {
-        SensorType sensorValue = e.getAttribute(this);
-        if (sensorValue!=null) return sensorValue;
-        
-        ConfigType v = ((EntityLocal)e).getConfig(this);
-        try {
-            return convertConfigToSensor(v, e);
-        } catch (Throwable t) {
-            throw new IllegalArgumentException("Cannot convert config value 
"+v+" for sensor "+this+": "+t, t);
-        }
-    }
-
-    /**
-     * @see {@link #getAsSensorValue(Entity)}
-     * 
-     * Differs in that the config value is converted based on just the 
management context, rather
-     * than for a specific entity. For example, useful if using {@link 
BrooklynConfigKeys} in BrooklynWebServer.
-     * </b> 
-     */
-    public SensorType getAsSensorValue(ManagementContext managementContext) {
-        ConfigType v = managementContext.getConfig().getConfig(this);
-        try {
-            return convertConfigToSensor(v, managementContext);
-        } catch (Throwable t) {
-            throw new IllegalArgumentException("Cannot convert config value 
"+v+" for sensor "+this+": "+t, t);
-        }
-    }
-
-    /** converts the given ConfigType value to the corresponding SensorType 
value, 
-     * with respect to the given entity
-     * <p>
-     * this is invoked after checks whether the entity already has a value for 
the sensor,
-     * and the entity-specific config value is passed for convenience if set, 
-     * otherwise the config key default value is passed for convenience
-     * <p>
-     * this message should be allowed to return null if the conversion cannot 
be completed at this time */
-    protected abstract SensorType convertConfigToSensor(ConfigType value, 
Entity entity);
-
-    /**
-     * @see {@link #convertConfigToSensor(Object, Entity)}
-     */
-    protected abstract SensorType convertConfigToSensor(ConfigType value, 
ManagementContext entity);
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensor.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensor.java 
b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensor.java
deleted file mode 100644
index fa50cec..0000000
--- 
a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensor.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 org.apache.brooklyn.sensor.core;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-
-import com.google.common.reflect.TypeToken;
-
-/**
- * A {@link Sensor} describing an attribute change.
- */
-public class BasicAttributeSensor<T> extends BasicSensor<T> implements 
AttributeSensor<T> {
-    private static final long serialVersionUID = -2493209215974820300L;
-    
-    private final SensorPersistenceMode persistence;
-
-    public BasicAttributeSensor(Class<T> type, String name) {
-        this(type, name, name);
-    }
-    
-    public BasicAttributeSensor(Class<T> type, String name, String 
description) {
-        this(TypeToken.of(type), name, description);
-    }
-    
-    public BasicAttributeSensor(TypeToken<T> typeToken, String name) {
-        this(typeToken, name, name);
-    }
-    
-    public BasicAttributeSensor(TypeToken<T> typeToken, String name, String 
description) {
-        this(typeToken, name, description, SensorPersistenceMode.REQUIRED);
-    }
-    
-    public BasicAttributeSensor(TypeToken<T> typeToken, String name, String 
description, SensorPersistenceMode persistence) {
-        super(typeToken, name, description);
-        this.persistence = checkNotNull(persistence, "persistence");
-    }
-
-    @Override
-    public SensorPersistenceMode getPersistenceMode() {
-        // persistence could be null if deserializing state written by an old 
version; in which case default to 'required'
-        return (persistence != null) ? persistence : 
SensorPersistenceMode.REQUIRED;
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensorAndConfigKey.java
 
b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensorAndConfigKey.java
deleted file mode 100644
index 5f473a8..0000000
--- 
a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensorAndConfigKey.java
+++ /dev/null
@@ -1,114 +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.sensor.core;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.config.ConfigKey;
-
-import com.google.common.reflect.TypeToken;
-
-/**
- * A {@link Sensor} describing an attribute that can be configured with a 
default value.
- *
- * The {@link ConfigKey} has the same type, name and description as the sensor,
- * and is typically used to populate the sensor's value at runtime.
- */
-public class BasicAttributeSensorAndConfigKey<T> extends 
AttributeSensorAndConfigKey<T,T> {
-    
-    private static final long serialVersionUID = -2204916730008559688L;
-
-    public BasicAttributeSensorAndConfigKey(Class<T> type, String name) {
-        this(type, name, name, null);
-    }
-    public BasicAttributeSensorAndConfigKey(Class<T> type, String name, String 
description) {
-        this(type, name, description, null);
-    }
-    public BasicAttributeSensorAndConfigKey(Class<T> type, String name, String 
description, T defaultValue) {
-        super(type, type, name, description, defaultValue);
-    }
-
-    public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name) {
-        super(type, type, name);
-    }
-
-    public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name, 
String description) {
-        super(type, type, name, description);
-    }
-
-    public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name, 
String description, Object defaultValue) {
-        super(type, type, name, description, defaultValue);
-    }
-
-    public BasicAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<T,T> 
orig, T defaultValue) {
-        super(orig, defaultValue);
-    }
-    
-    @Override
-    protected T convertConfigToSensor(T value, Entity entity) { return value; }
-
-    @Override
-    protected T convertConfigToSensor(T value, ManagementContext 
managementContext) { return value; }
-    
-    public static class StringAttributeSensorAndConfigKey extends 
BasicAttributeSensorAndConfigKey<String> {
-
-        private static final long serialVersionUID = 810512615528081865L;
-
-        public 
StringAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<String,String> 
orig, String defaultValue) {
-            super(orig, defaultValue);
-        }
-
-        public StringAttributeSensorAndConfigKey(String name, String 
description, String defaultValue) {
-            super(String.class, name, description, defaultValue);
-        }
-
-        public StringAttributeSensorAndConfigKey(String name, String 
description) {
-            super(String.class, name, description);
-        }
-
-        public StringAttributeSensorAndConfigKey(String name) {
-            super(String.class, name);
-        }
-        
-    }
-    
-    public static class IntegerAttributeSensorAndConfigKey extends 
BasicAttributeSensorAndConfigKey<Integer> {
-
-        private static final long serialVersionUID = 7159564523829723929L;
-
-        public 
IntegerAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<Integer,Integer> 
orig, Integer defaultValue) {
-            super(orig, defaultValue);
-        }
-
-        public IntegerAttributeSensorAndConfigKey(String name, String 
description, Integer defaultValue) {
-            super(Integer.class, name, description, defaultValue);
-        }
-
-        public IntegerAttributeSensorAndConfigKey(String name, String 
description) {
-            super(Integer.class, name, description);
-        }
-
-        public IntegerAttributeSensorAndConfigKey(String name) {
-            super(Integer.class, name);
-        }
-        
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicNotificationSensor.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicNotificationSensor.java
 
b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicNotificationSensor.java
deleted file mode 100644
index 627e3c8..0000000
--- 
a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicNotificationSensor.java
+++ /dev/null
@@ -1,36 +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.sensor.core;
-
-import org.apache.brooklyn.api.sensor.Sensor;
-
-/**
- * A {@link Sensor} used to notify subscribers about events.
- */
-public class BasicNotificationSensor<T> extends BasicSensor<T> {
-    private static final long serialVersionUID = -7670909215973264600L;
-
-    public BasicNotificationSensor(Class<T> type, String name) {
-        this(type, name, name);
-    }
-    
-    public BasicNotificationSensor(Class<T> type, String name, String 
description) {
-        super(type, name, description);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensor.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensor.java 
b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensor.java
deleted file mode 100644
index 439fbb2..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensor.java
+++ /dev/null
@@ -1,114 +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.sensor.core;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.util.guava.TypeTokens;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Parent for all {@link Sensor}s.
- */
-public class BasicSensor<T> implements Sensor<T> {
-    private static final long serialVersionUID = -3762018534086101323L;
-    
-    private static final Splitter dots = Splitter.on('.');
-
-    private TypeToken<T> typeToken;
-    private Class<? super T> type;
-    private String name;
-    private String description;
-    private transient List<String> nameParts;
-    
-    // FIXME In groovy, fields were `public final` with a default constructor; 
do we need the gson?
-    public BasicSensor() { /* for gson */ }
-
-    /** name is typically a dot-separated identifier; description is optional 
*/
-    public BasicSensor(Class<T> type, String name) {
-        this(type, name, name);
-    }
-    
-    public BasicSensor(Class<T> type, String name, String description) {
-        this(TypeToken.of(type), name, description);
-    }
-    
-    public BasicSensor(TypeToken<T> typeToken, String name, String 
description) {
-        this.typeToken = 
TypeTokens.getTypeTokenIfNotRaw(checkNotNull(typeToken, "typeToken"));
-        this.type = TypeTokens.getRawTypeIfRaw(typeToken);
-        this.name = checkNotNull(name, "name");
-        this.description = description;
-    }
-
-    /** @see Sensor#getTypeToken() */
-    public TypeToken<T> getTypeToken() { return 
TypeTokens.getTypeToken(typeToken, type); }
-    
-    /** @see Sensor#getType() */
-    public Class<? super T> getType() { return 
TypeTokens.getRawType(typeToken, type); }
- 
-    /** @see Sensor#getTypeName() */
-    public String getTypeName() { 
-        return getType().getName();
-    }
- 
-    /** @see Sensor#getName() */
-    public String getName() { return name; }
- 
-    /** @see Sensor#getNameParts() */
-    public synchronized List<String> getNameParts() {
-        if (nameParts==null) nameParts = 
ImmutableList.copyOf(dots.split(name));
-        return nameParts; 
-    }
- 
-    /** @see Sensor#getDescription() */
-    public String getDescription() { return description; }
-    
-    /** @see Sensor#newEvent(Entity, Object) */
-    public SensorEvent<T> newEvent(Entity producer, T value) {
-        return new BasicSensorEvent<T>(this, producer, value);
-    }
-    
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(getTypeName(), name, description);
-    }
- 
-    @Override
-    public boolean equals(Object other) {
-        if (this==other) return true;
-        if (!(other instanceof BasicSensor)) return false;
-        BasicSensor<?> o = (BasicSensor<?>) other;
-        
-        return Objects.equal(getTypeName(), o.getTypeName()) && 
Objects.equal(name, o.name) && Objects.equal(description, o.description);
-    }
-    
-    @Override
-    public String toString() {
-        return String.format("Sensor: %s (%s)", name, getTypeName());
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensorEvent.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensorEvent.java 
b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensorEvent.java
deleted file mode 100644
index fb0f7a9..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensorEvent.java
+++ /dev/null
@@ -1,112 +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.sensor.core;
-
-import java.util.ConcurrentModificationException;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-
-/**
- * A {@link SensorEvent} containing data from a {@link Sensor} generated by an 
{@link Entity}.
- */
-public class BasicSensorEvent<T> implements SensorEvent<T> {
-    
-    private static final Logger log = 
LoggerFactory.getLogger(BasicSensorEvent.class);
-    
-    private final Sensor<T> sensor;
-    private final Entity source;
-    private final T value;
-    private final long timestamp;
-    
-    public T getValue() { return value; }
-
-    public Sensor<T> getSensor() { return sensor; }
-
-    public Entity getSource() { return source; }
-
-    public long getTimestamp() { return timestamp; }
-
-    /** arguments should not be null (except in certain limited testing 
situations) */
-    public BasicSensorEvent(Sensor<T> sensor, Entity source, T value) {
-        this(sensor, source, value, System.currentTimeMillis());
-    }
-    
-    public BasicSensorEvent(Sensor<T> sensor, Entity source, T value, long 
timestamp) {
-        this.sensor = sensor;
-        this.source = source;
-        this.value = value;
-        this.timestamp = timestamp;
-    }
-    
-    public static <T> SensorEvent<T> of(Sensor<T> sensor, Entity source, T 
value, long timestamp) {
-        return new BasicSensorEvent<T>(sensor, source, value, timestamp);
-    }
-
-    @SuppressWarnings("unchecked")
-    public static <T> SensorEvent<T> ofUnchecked(Sensor<T> sensor, Entity 
source, Object value, long timestamp) {
-        return new BasicSensorEvent<T>(sensor, source, (T)value, timestamp);
-    }
-
-    public static <T> SensorEvent<T> of(Sensor<T> sensor, Entity source, T 
value) {
-        return new BasicSensorEvent<T>(sensor, source, value);
-    }
-
-    @SuppressWarnings("unchecked")
-    public static <T> SensorEvent<T> ofUnchecked(Sensor<T> sensor, Entity 
source, Object value) {
-        return new BasicSensorEvent<T>(sensor, source, (T)value);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(sensor, source, value);
-    }   
-
-    /**
-     * Any SensorEvents are equal if their sensor, source and value are equal.
-     * Ignore timestamp for ease of use in unit tests.   
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof SensorEvent)) return false;
-        SensorEvent<?> other = (SensorEvent<?>) o;
-        return Objects.equal(sensor, other.getSensor()) && 
Objects.equal(source, other.getSource()) &&
-                Objects.equal(value, other.getValue());
-    }
-    
-    @Override
-    public String toString() {
-        try {
-            return source+"."+sensor+"="+value+" @ "+timestamp;
-        } catch (ConcurrentModificationException e) {
-            // TODO occasional CME observed on shutdown, wrt map, e.g. in 
UrlMappingTest
-            // transformations should set a copy of the map; see e.g. in 
ServiceStateLogic.updateMapSensor
-            String result = getClass()+":"+source+"."+sensor+"@"+timestamp;
-            log.warn("Error creating string for " + result + " (ignoring): " + 
e);
-            if (log.isDebugEnabled())
-                log.debug("Trace for error creating string for " + result + " 
(ignoring): " + e, e);
-            return result;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/DependentConfiguration.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/DependentConfiguration.java
 
b/core/src/main/java/org/apache/brooklyn/sensor/core/DependentConfiguration.java
deleted file mode 100644
index 9327b19..0000000
--- 
a/core/src/main/java/org/apache/brooklyn/sensor/core/DependentConfiguration.java
+++ /dev/null
@@ -1,823 +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.sensor.core;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import groovy.lang.Closure;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ExecutionContext;
-import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.util.collections.CollectionFunctionals;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.BasicExecutionContext;
-import org.apache.brooklyn.util.core.task.BasicTask;
-import org.apache.brooklyn.util.core.task.DeferredSupplier;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ParallelTask;
-import org.apache.brooklyn.util.core.task.TaskInternal;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ValueResolver;
-import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.exceptions.NotManagedException;
-import org.apache.brooklyn.util.exceptions.RuntimeTimeoutException;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.text.Strings;
-import org.apache.brooklyn.util.time.CountdownTimer;
-import org.apache.brooklyn.util.time.Duration;
-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.Functions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-/** Conveniences for making tasks which run in entity {@link 
ExecutionContext}s, subscribing to attributes from other entities, possibly 
transforming those;
- * these {@link Task} instances are typically passed in {@link 
EntityLocal#setConfig(ConfigKey, Object)}.
- * <p>
- * If using a lot it may be useful to:
- * <pre>
- * {@code
- *   import static brooklyn.event.basic.DependentConfiguration.*;
- * }
- * </pre>
- */
-public class DependentConfiguration {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(DependentConfiguration.class);
-    
-    //not instantiable, only a static helper
-    private DependentConfiguration() {}
-
-    /**
-     * Default readiness is Groovy truth.
-     * 
-     * @see #attributeWhenReady(Entity, AttributeSensor, Predicate)
-     */
-    public static <T> Task<T> attributeWhenReady(Entity source, 
AttributeSensor<T> sensor) {
-        return attributeWhenReady(source, sensor, 
GroovyJavaMethods.truthPredicate());
-    }
-    
-    public static <T> Task<T> attributeWhenReady(Entity source, 
AttributeSensor<T> sensor, Closure<Boolean> ready) {
-        Predicate<Object> readyPredicate = (ready != null) ? 
GroovyJavaMethods.<Object>predicateFromClosure(ready) : 
GroovyJavaMethods.truthPredicate();
-        return attributeWhenReady(source, sensor, readyPredicate);
-    }
-    
-    /** returns an unsubmitted {@link Task} which blocks until the given 
sensor on the given source entity gives a value that satisfies ready, then 
returns that value;
-     * particular useful in Entity configuration where config will block until 
Tasks have a value
-     */
-    public static <T> Task<T> attributeWhenReady(final Entity source, final 
AttributeSensor<T> sensor, final Predicate<? super T> ready) {
-        Builder<T, T> builder = builder().attributeWhenReady(source, sensor);
-        if (ready != null) builder.readiness(ready);
-        return builder.build();
-
-    }
-
-    public static <T,V> Task<V> attributePostProcessedWhenReady(Entity source, 
AttributeSensor<T> sensor, Closure<Boolean> ready, Closure<V> postProcess) {
-        Predicate<? super T> readyPredicate = (ready != null) ? 
GroovyJavaMethods.predicateFromClosure(ready) : 
GroovyJavaMethods.truthPredicate();
-        Function<? super T, V> postProcessFunction = 
GroovyJavaMethods.<T,V>functionFromClosure(postProcess);
-        return attributePostProcessedWhenReady(source, sensor, readyPredicate, 
postProcessFunction);
-    }
-
-    public static <T,V> Task<V> attributePostProcessedWhenReady(Entity source, 
AttributeSensor<T> sensor, Closure<V> postProcess) {
-        return attributePostProcessedWhenReady(source, sensor, 
GroovyJavaMethods.truthPredicate(), 
GroovyJavaMethods.<T,V>functionFromClosure(postProcess));
-    }
-
-    public static <T> Task<T> valueWhenAttributeReady(Entity source, 
AttributeSensor<T> sensor, T value) {
-        return 
DependentConfiguration.<T,T>attributePostProcessedWhenReady(source, sensor, 
GroovyJavaMethods.truthPredicate(), Functions.constant(value));
-    }
-
-    public static <T,V> Task<V> valueWhenAttributeReady(Entity source, 
AttributeSensor<T> sensor, Function<? super T,V> valueProvider) {
-        return attributePostProcessedWhenReady(source, sensor, 
GroovyJavaMethods.truthPredicate(), valueProvider);
-    }
-    
-    public static <T,V> Task<V> valueWhenAttributeReady(Entity source, 
AttributeSensor<T> sensor, Closure<V> valueProvider) {
-        return attributePostProcessedWhenReady(source, sensor, 
GroovyJavaMethods.truthPredicate(), valueProvider);
-    }
-    
-    public static <T,V> Task<V> attributePostProcessedWhenReady(final Entity 
source, final AttributeSensor<T> sensor, final Predicate<? super T> ready, 
final Closure<V> postProcess) {
-        return attributePostProcessedWhenReady(source, sensor, ready, 
GroovyJavaMethods.<T,V>functionFromClosure(postProcess));
-    }
-    
-    @SuppressWarnings("unchecked")
-    public static <T,V> Task<V> attributePostProcessedWhenReady(final Entity 
source, final AttributeSensor<T> sensor, final Predicate<? super T> ready, 
final Function<? super T,V> postProcess) {
-        Builder<T,T> builder1 = 
DependentConfiguration.builder().attributeWhenReady(source, sensor);
-        // messy generics here to support null postProcess; would be nice to 
disallow that here
-        Builder<T,V> builder;
-        if (postProcess != null) {
-            builder = builder1.postProcess(postProcess);
-        } else {
-            builder = (Builder<T,V>)builder1;
-        }
-        if (ready != null) builder.readiness(ready);
-        
-        return builder.build();
-    }
-
-    public static <T> T waitInTaskForAttributeReady(Entity source, 
AttributeSensor<T> sensor, Predicate<? super T> ready) {
-        return waitInTaskForAttributeReady(source, sensor, ready, 
ImmutableList.<AttributeAndSensorCondition<?>>of());
-    }
-
-    public static <T> T waitInTaskForAttributeReady(final Entity source, final 
AttributeSensor<T> sensor, Predicate<? super T> ready, 
List<AttributeAndSensorCondition<?>> abortConditions) {
-        String blockingDetails = "Waiting for ready from "+source+" "+sensor+" 
(subscription)";
-        return waitInTaskForAttributeReady(source, sensor, ready, 
abortConditions, blockingDetails);
-    }
-    
-    // TODO would be nice to have an easy semantics for whenServiceUp (cf 
DynamicWebAppClusterImpl.whenServiceUp)
-    
-    public static <T> T waitInTaskForAttributeReady(final Entity source, final 
AttributeSensor<T> sensor, Predicate<? super T> ready, 
List<AttributeAndSensorCondition<?>> abortConditions, String blockingDetails) {
-        return new WaitInTaskForAttributeReady<T,T>(source, sensor, ready, 
abortConditions, blockingDetails).call();
-    }
-    
-    protected static class WaitInTaskForAttributeReady<T,V> implements 
Callable<V> {
-
-        /* This is a change since before Oct 2014. Previously it would 
continue to poll,
-         * (maybe finding a different error) if the target entity becomes 
unmanaged. 
-         * Now it actively checks unmanaged by default, and still throws 
although it might 
-         * now find a different problem. */
-        private final static boolean DEFAULT_IGNORE_UNMANAGED = false;
-        
-        protected final Entity source;
-        protected final AttributeSensor<T> sensor;
-        protected final Predicate<? super T> ready;
-        protected final List<AttributeAndSensorCondition<?>> 
abortSensorConditions;
-        protected final String blockingDetails;
-        protected final Function<? super T,? extends V> postProcess;
-        protected final Duration timeout;
-        protected final Maybe<V> onTimeout;
-        protected final boolean ignoreUnmanaged;
-        protected final Maybe<V> onUnmanaged;
-        // TODO onError Continue / Throw / Return(V)
-        
-        protected WaitInTaskForAttributeReady(Builder<T, V> builder) {
-            this.source = builder.source;
-            this.sensor = builder.sensor;
-            this.ready = builder.readiness;
-            this.abortSensorConditions = builder.abortSensorConditions;
-            this.blockingDetails = builder.blockingDetails;
-            this.postProcess = builder.postProcess;
-            this.timeout = builder.timeout;
-            this.onTimeout = builder.onTimeout;
-            this.ignoreUnmanaged = builder.ignoreUnmanaged;
-            this.onUnmanaged = builder.onUnmanaged;
-        }
-        
-        private WaitInTaskForAttributeReady(Entity source, AttributeSensor<T> 
sensor, Predicate<? super T> ready,
-                List<AttributeAndSensorCondition<?>> abortConditions, String 
blockingDetails) {
-            this.source = source;
-            this.sensor = sensor;
-            this.ready = ready;
-            this.abortSensorConditions = abortConditions;
-            this.blockingDetails = blockingDetails;
-            
-            this.timeout = Duration.PRACTICALLY_FOREVER;
-            this.onTimeout = Maybe.absent();
-            this.ignoreUnmanaged = DEFAULT_IGNORE_UNMANAGED;
-            this.onUnmanaged = Maybe.absent();
-            this.postProcess = null;
-        }
-
-        @SuppressWarnings("unchecked")
-        protected V postProcess(T value) {
-            if (this.postProcess!=null) return postProcess.apply(value);
-            // if no post-processing assume the types are correct
-            return (V) value;
-        }
-        
-        protected boolean ready(T value) {
-            if (ready!=null) return ready.apply(value);
-            return GroovyJavaMethods.truth(value);
-        }
-        
-        @SuppressWarnings({ "rawtypes", "unchecked" })
-        @Override
-        public V call() {
-            T value = source.getAttribute(sensor);
-
-            // return immediately if either the ready predicate or the abort 
conditions hold
-            if (ready(value)) return postProcess(value);
-
-            final List<Exception> abortionExceptions = 
Lists.newCopyOnWriteArrayList();
-            long start = System.currentTimeMillis();
-            
-            for (AttributeAndSensorCondition abortCondition : 
abortSensorConditions) {
-                Object abortValue = 
abortCondition.source.getAttribute(abortCondition.sensor);
-                if (abortCondition.predicate.apply(abortValue)) {
-                    abortionExceptions.add(new Exception("Abort due to 
"+abortCondition.source+" -> "+abortCondition.sensor));
-                }
-            }
-            if (abortionExceptions.size() > 0) {
-                throw new CompoundRuntimeException("Aborted waiting for ready 
from "+source+" "+sensor, abortionExceptions);
-            }
-
-            TaskInternal<?> current = (TaskInternal<?>) Tasks.current();
-            if (current == null) throw new IllegalStateException("Should only 
be invoked in a running task");
-            Entity entity = BrooklynTaskTags.getTargetOrContextEntity(current);
-            if (entity == null) throw new IllegalStateException("Should only 
be invoked in a running task with an entity tag; "+
-                current+" has no entity tag 
("+current.getStatusDetail(false)+")");
-            
-            final LinkedList<T> publishedValues = new LinkedList<T>();
-            final Semaphore semaphore = new Semaphore(0); // could use 
Exchanger
-            SubscriptionHandle subscription = null;
-            List<SubscriptionHandle> abortSubscriptions = Lists.newArrayList();
-            
-            try {
-                subscription = 
((EntityInternal)entity).getSubscriptionContext().subscribe(source, sensor, new 
SensorEventListener<T>() {
-                    @Override public void onEvent(SensorEvent<T> event) {
-                        synchronized (publishedValues) { 
publishedValues.add(event.getValue()); }
-                        semaphore.release();
-                    }});
-                for (final AttributeAndSensorCondition abortCondition : 
abortSensorConditions) {
-                    
abortSubscriptions.add(((EntityInternal)entity).getSubscriptionContext().subscribe(abortCondition.source,
 abortCondition.sensor, new SensorEventListener<Object>() {
-                        @Override public void onEvent(SensorEvent<Object> 
event) {
-                            if 
(abortCondition.predicate.apply(event.getValue())) {
-                                abortionExceptions.add(new Exception("Abort 
due to "+abortCondition.source+" -> "+abortCondition.sensor));
-                                semaphore.release();
-                            }
-                        }}));
-                    Object abortValue = 
abortCondition.source.getAttribute(abortCondition.sensor);
-                    if (abortCondition.predicate.apply(abortValue)) {
-                        abortionExceptions.add(new Exception("Abort due to 
"+abortCondition.source+" -> "+abortCondition.sensor));
-                    }
-                }
-                if (abortionExceptions.size() > 0) {
-                    throw new CompoundRuntimeException("Aborted waiting for 
ready from "+source+" "+sensor, abortionExceptions);
-                }
-
-                CountdownTimer timer = timeout!=null ? 
timeout.countdownTimer() : null;
-                Duration maxPeriod = ValueResolver.PRETTY_QUICK_WAIT;
-                Duration nextPeriod = ValueResolver.REAL_QUICK_PERIOD;
-                while (true) {
-                    // check the source on initial run (could be done outside 
the loop) 
-                    // and also (optionally) on each iteration in case it is 
more recent 
-                    value = source.getAttribute(sensor);
-                    if (ready(value)) break;
-
-                    if (timer!=null) {
-                        if 
(timer.getDurationRemaining().isShorterThan(nextPeriod)) {
-                            nextPeriod = timer.getDurationRemaining();
-                        }
-                        if (timer.isExpired()) {
-                            if (onTimeout.isPresent()) return onTimeout.get();
-                            throw new RuntimeTimeoutException("Unsatisfied 
after "+Duration.sinceUtc(start));
-                        }
-                    }
-
-                    String prevBlockingDetails = 
current.setBlockingDetails(blockingDetails);
-                    try {
-                        if (semaphore.tryAcquire(nextPeriod.toMilliseconds(), 
TimeUnit.MILLISECONDS)) {
-                            // immediately release so we are available for the 
next check
-                            semaphore.release();
-                            // if other permits have been made available (e.g. 
multiple notifications) drain them all as no point running multiple times
-                            semaphore.drainPermits();
-                        }
-                    } finally {
-                        current.setBlockingDetails(prevBlockingDetails);
-                    }
-
-                    // check any subscribed values which have come in first
-                    while (true) {
-                        synchronized (publishedValues) {
-                            if (publishedValues.isEmpty()) break;
-                            value = publishedValues.pop(); 
-                        }
-                        if (ready(value)) break;
-                    }
-
-                    // if unmanaged then ignore the other abort conditions
-                    if (!ignoreUnmanaged && 
Entities.isNoLongerManaged(entity)) {
-                        if (onUnmanaged.isPresent()) return onUnmanaged.get();
-                        throw new NotManagedException(entity);                 
       
-                    }
-                    
-                    if (abortionExceptions.size() > 0) {
-                        throw new CompoundRuntimeException("Aborted waiting 
for ready from "+source+" "+sensor, abortionExceptions);
-                    }
-
-                    nextPeriod = nextPeriod.times(2).upperBound(maxPeriod);
-                }
-                if (LOG.isDebugEnabled()) LOG.debug("Attribute-ready for {} in 
entity {}", sensor, source);
-                return postProcess(value);
-            } catch (InterruptedException e) {
-                throw Exceptions.propagate(e);
-            } finally {
-                if (subscription != null) {
-                    
((EntityInternal)entity).getSubscriptionContext().unsubscribe(subscription);
-                }
-                for (SubscriptionHandle handle : abortSubscriptions) {
-                    
((EntityInternal)entity).getSubscriptionContext().unsubscribe(handle);
-                }
-            }
-        }
-    }
-    
-    /**
-     * Returns a {@link Task} which blocks until the given job returns, then 
returns the value of that job.
-     * 
-     * @deprecated since 0.7; code will be moved into test utilities
-     */
-    @Deprecated
-    public static <T> Task<T> whenDone(Callable<T> job) {
-        return new BasicTask<T>(MutableMap.of("tag", "whenDone", 
"displayName", "waiting for job"), job);
-    }
-
-    /**
-     * Returns a {@link Task} which waits for the result of first parameter, 
then applies the function in the second
-     * parameter to it, returning that result.
-     *
-     * Particular useful in Entity configuration where config will block until 
Tasks have completed,
-     * allowing for example an {@link #attributeWhenReady(Entity, 
AttributeSensor, Predicate)} expression to be
-     * passed in the first argument then transformed by the function in the 
second argument to generate
-     * the value that is used for the configuration
-     */
-    public static <U,T> Task<T> transform(final Task<U> task, final 
Function<U,T> transformer) {
-        return transform(MutableMap.of("displayName", "transforming "+task), 
task, transformer);
-    }
- 
-    /** @see #transform(Task, Function) */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public static <U,T> Task<T> transform(Task<U> task, Closure transformer) {
-        return transform(task, 
GroovyJavaMethods.functionFromClosure(transformer));
-    }
-    
-    /** @see #transform(Task, Function) */
-    @SuppressWarnings({ "rawtypes" })
-    public static <U,T> Task<T> transform(final Map flags, final 
TaskAdaptable<U> task, final Function<U,T> transformer) {
-        return new BasicTask<T>(flags, new Callable<T>() {
-            public T call() throws Exception {
-                if (!task.asTask().isSubmitted()) {
-                    
BasicExecutionContext.getCurrentExecutionContext().submit(task);
-                } 
-                return transformer.apply(task.asTask().get());
-            }});        
-    }
-     
-    /** Returns a task which waits for multiple other tasks (submitting if 
necessary)
-     * and performs arbitrary computation over the List of results.
-     * @see #transform(Task, Function) but note argument order is reversed 
(counterintuitive) to allow for varargs */
-    public static <U,T> Task<T> transformMultiple(Function<List<U>,T> 
transformer, @SuppressWarnings("unchecked") TaskAdaptable<U> ...tasks) {
-        return transformMultiple(MutableMap.of("displayName", "transforming 
multiple"), transformer, tasks);
-    }
-
-    /** @see #transformMultiple(Function, TaskAdaptable...) */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public static <U,T> Task<T> transformMultiple(Closure transformer, 
TaskAdaptable<U> ...tasks) {
-        return 
transformMultiple(GroovyJavaMethods.functionFromClosure(transformer), tasks);
-    }
-
-    /** @see #transformMultiple(Function, TaskAdaptable...) */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public static <U,T> Task<T> transformMultiple(Map flags, Closure 
transformer, TaskAdaptable<U> ...tasks) {
-        return transformMultiple(flags, 
GroovyJavaMethods.functionFromClosure(transformer), tasks);
-    }
-    
-    /** @see #transformMultiple(Function, TaskAdaptable...) */
-    @SuppressWarnings({ "rawtypes" })
-    public static <U,T> Task<T> transformMultiple(Map flags, final 
Function<List<U>,T> transformer, @SuppressWarnings("unchecked") 
TaskAdaptable<U> ...tasks) {
-        return transformMultiple(flags, transformer, Arrays.asList(tasks));
-    }
-    @SuppressWarnings({ "rawtypes" })
-    public static <U,T> Task<T> transformMultiple(Map flags, final 
Function<List<U>,T> transformer, Collection<? extends TaskAdaptable<U>> tasks) {
-        if (tasks.size()==1) {
-            return transform(flags, Iterables.getOnlyElement(tasks), new 
Function<U,T>() {
-                @Override
-                @Nullable
-                public T apply(@Nullable U input) {
-                    return transformer.apply(ImmutableList.of(input));
-                }
-            });
-        }
-        return transform(flags, new ParallelTask<U>(tasks), transformer);
-    }
-
-
-    /** Method which returns a Future containing a string formatted using 
String.format,
-     * where the arguments can be normal objects or tasks;
-     * tasks will be waited on (submitted if necessary) and their results 
substituted in the call
-     * to String.format.
-     * <p>
-     * Example:
-     * <pre>
-     * {@code
-     *   setConfig(URL, DependentConfiguration.formatString("%s:%s", 
-     *           DependentConfiguration.attributeWhenReady(target, 
Target.HOSTNAME),
-     *           DependentConfiguration.attributeWhenReady(target, 
Target.PORT) ) );
-     * }
-     * </pre>
-     */
-    @SuppressWarnings("unchecked")
-    public static Task<String> formatString(final String spec, final Object 
...args) {
-        List<TaskAdaptable<Object>> taskArgs = Lists.newArrayList();
-        for (Object arg: args) {
-            if (arg instanceof TaskAdaptable) 
taskArgs.add((TaskAdaptable<Object>)arg);
-            else if (arg instanceof TaskFactory) taskArgs.add( 
((TaskFactory<TaskAdaptable<Object>>)arg).newTask() );
-        }
-            
-        return transformMultiple(
-            MutableMap.<String,String>of("displayName", "formatting '"+spec+"' 
with "+taskArgs.size()+" task"+(taskArgs.size()!=1?"s":"")), 
-                new Function<List<Object>, String>() {
-            @Override public String apply(List<Object> input) {
-                Iterator<?> tri = input.iterator();
-                Object[] vv = new Object[args.length];
-                int i=0;
-                for (Object arg : args) {
-                    if (arg instanceof TaskAdaptable || arg instanceof 
TaskFactory) vv[i] = tri.next();
-                    else if (arg instanceof DeferredSupplier) vv[i] = 
((DeferredSupplier<?>) arg).get();
-                    else vv[i] = arg;
-                    i++;
-                }
-                return String.format(spec, vv);
-            }},
-            taskArgs);
-    }
-
-    /** returns a task for parallel execution returning a list of values for 
the given sensor for the given entity list, 
-     * optionally when the values satisfy a given readiness predicate 
(defaulting to groovy truth if not supplied) */
-    public static <T> Task<List<T>> listAttributesWhenReady(AttributeSensor<T> 
sensor, Iterable<Entity> entities) {
-        return listAttributesWhenReady(sensor, entities, 
GroovyJavaMethods.truthPredicate());
-    }
-    
-    public static <T> Task<List<T>> listAttributesWhenReady(AttributeSensor<T> 
sensor, Iterable<Entity> entities, Closure<Boolean> readiness) {
-        Predicate<Object> readinessPredicate = (readiness != null) ? 
GroovyJavaMethods.<Object>predicateFromClosure(readiness) : 
GroovyJavaMethods.truthPredicate();
-        return listAttributesWhenReady(sensor, entities, readinessPredicate);
-    }
-    
-    /** returns a task for parallel execution returning a list of values of 
the given sensor list on the given entity, 
-     * optionally when the values satisfy a given readiness predicate 
(defaulting to groovy truth if not supplied) */    
-    public static <T> Task<List<T>> listAttributesWhenReady(final 
AttributeSensor<T> sensor, Iterable<Entity> entities, Predicate<? super T> 
readiness) {
-        if (readiness == null) readiness = GroovyJavaMethods.truthPredicate();
-        return builder().attributeWhenReadyFromMultiple(entities, sensor, 
readiness).build();
-    }
-
-    /** @see #waitForTask(Task, Entity, String) */
-    public static <T> T waitForTask(Task<T> t, Entity context) throws 
InterruptedException {
-        return waitForTask(t, context, null);
-    }
-    
-    /** blocks until the given task completes, submitting if necessary, 
returning the result of that task;
-     * optional contextMessage is available in status if this is running in a 
task
-     */
-    @SuppressWarnings("unchecked")
-    public static <T> T waitForTask(Task<T> t, Entity context, String 
contextMessage) throws InterruptedException {
-        try {
-            return (T) Tasks.resolveValue(t, Object.class, 
((EntityInternal)context).getExecutionContext(), contextMessage);
-        } catch (ExecutionException e) {
-            throw Throwables.propagate(e);
-        }
-    }
-    
-    public static class AttributeAndSensorCondition<T> {
-        protected final Entity source;
-        protected final AttributeSensor<T> sensor;
-        protected final Predicate<? super T> predicate;
-        
-        public AttributeAndSensorCondition(Entity source, AttributeSensor<T> 
sensor, Predicate<? super T> predicate) {
-            this.source = checkNotNull(source, "source");
-            this.sensor = checkNotNull(sensor, "sensor");
-            this.predicate = checkNotNull(predicate, "predicate");
-        }
-    }
-    
-    public static ProtoBuilder builder() {
-        return new ProtoBuilder();
-    }
-    
-    /**
-     * Builder for producing variants of attributeWhenReady.
-     */
-    @Beta
-    public static class ProtoBuilder {
-        /**
-         * Will wait for the attribute on the given entity.
-         * If that entity reports {@link Lifecycle#ON_FIRE} for its {@link 
Attributes#SERVICE_STATE} then it will abort. 
-         */
-        public <T2> Builder<T2,T2> attributeWhenReady(Entity source, 
AttributeSensor<T2> sensor) {
-            return new Builder<T2,T2>(source, sensor).abortIfOnFire();
-        }
-
-        /**
-         * Will wait for the attribute on the given entity, not aborting when 
it goes {@link Lifecycle#ON_FIRE}.
-         */
-        public <T2> Builder<T2,T2> attributeWhenReadyAllowingOnFire(Entity 
source, AttributeSensor<T2> sensor) {
-            return new Builder<T2,T2>(source, sensor);
-        }
-
-        /** Constructs a builder for task for parallel execution returning a 
list of values of the given sensor list on the given entity, 
-         * optionally when the values satisfy a given readiness predicate 
(defaulting to groovy truth if not supplied) */ 
-        @Beta
-        public <T> MultiBuilder<T, T, List<T>> 
attributeWhenReadyFromMultiple(Iterable<? extends Entity> sources, 
AttributeSensor<T> sensor) {
-            return attributeWhenReadyFromMultiple(sources, sensor, 
GroovyJavaMethods.truthPredicate());
-        }
-        /** As {@link #attributeWhenReadyFromMultiple(Iterable, 
AttributeSensor)} with an explicit readiness test. */
-        @Beta
-        public <T> MultiBuilder<T, T, List<T>> 
attributeWhenReadyFromMultiple(Iterable<? extends Entity> sources, 
AttributeSensor<T> sensor, Predicate<? super T> readiness) {
-            return new MultiBuilder<T, T, List<T>>(sources, sensor, readiness);
-        }
-    }
-
-    /**
-     * Builder for producing variants of attributeWhenReady.
-     */
-    public static class Builder<T,V> {
-        protected Entity source;
-        protected AttributeSensor<T> sensor;
-        protected Predicate<? super T> readiness;
-        protected Function<? super T, ? extends V> postProcess;
-        protected List<AttributeAndSensorCondition<?>> abortSensorConditions = 
Lists.newArrayList();
-        protected String blockingDetails;
-        protected Duration timeout;
-        protected Maybe<V> onTimeout;
-        protected  boolean ignoreUnmanaged = 
WaitInTaskForAttributeReady.DEFAULT_IGNORE_UNMANAGED;
-        protected Maybe<V> onUnmanaged;
-
-        protected Builder(Entity source, AttributeSensor<T> sensor) {
-            this.source = source;
-            this.sensor = sensor;
-        }
-        
-        /**
-         * Will wait for the attribute on the given entity.
-         * If that entity report {@link Lifecycle#ON_FIRE} for its {@link 
Attributes#SERVICE_STATE_ACTUAL} then it will abort.
-         * @deprecated since 0.7.0 use {@link 
DependentConfiguration#builder()} then {@link 
ProtoBuilder#attributeWhenReady(Entity, AttributeSensor)} then {@link 
#abortIfOnFire()} 
-         */
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        public <T2> Builder<T2,T2> attributeWhenReady(Entity source, 
AttributeSensor<T2> sensor) {
-            this.source = checkNotNull(source, "source");
-            this.sensor = (AttributeSensor) checkNotNull(sensor, "sensor");
-            abortIfOnFire();
-            return (Builder<T2, T2>) this;
-        }
-        public Builder<T,V> readiness(Closure<Boolean> val) {
-            this.readiness = 
GroovyJavaMethods.predicateFromClosure(checkNotNull(val, "val"));
-            return this;
-        }
-        public Builder<T,V> readiness(Predicate<? super T> val) {
-            this.readiness = checkNotNull(val, "ready");
-            return this;
-        }
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        public <V2> Builder<T,V2> postProcess(Closure<V2> val) {
-            this.postProcess = (Function) 
GroovyJavaMethods.<T,V2>functionFromClosure(checkNotNull(val, "postProcess"));
-            return (Builder<T,V2>) this;
-        }
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        public <V2> Builder<T,V2> postProcess(final Function<? super T, V2>  
val) {
-            this.postProcess = (Function) checkNotNull(val, "postProcess");
-            return (Builder<T,V2>) this;
-        }
-        public <T2> Builder<T,V> abortIf(Entity source, AttributeSensor<T2> 
sensor) {
-            return abortIf(source, sensor, GroovyJavaMethods.truthPredicate());
-        }
-        public <T2> Builder<T,V> abortIf(Entity source, AttributeSensor<T2> 
sensor, Predicate<? super T2> predicate) {
-            abortSensorConditions.add(new 
AttributeAndSensorCondition<T2>(source, sensor, predicate));
-            return this;
-        }
-        public Builder<T,V> abortIfOnFire() {
-            abortIf(source, Attributes.SERVICE_STATE_ACTUAL, 
Predicates.equalTo(Lifecycle.ON_FIRE));
-            return this;
-        }
-        public Builder<T,V> blockingDetails(String val) {
-            blockingDetails = val;
-            return this;
-        }
-        /** specifies an optional timeout; by default it waits forever, or 
until unmanaged or other abort condition */
-        public Builder<T,V> timeout(Duration val) {
-            timeout = val;
-            return this;
-        }
-        public Builder<T,V> onTimeoutReturn(V val) {
-            onTimeout = Maybe.of(val);
-            return this;
-        }
-        public Builder<T,V> onTimeoutThrow() {
-            onTimeout = Maybe.<V>absent();
-            return this;
-        }
-        public Builder<T,V> onUnmanagedReturn(V val) {
-            onUnmanaged = Maybe.of(val);
-            return this;
-        }
-        public Builder<T,V> onUnmanagedThrow() {
-            onUnmanaged = Maybe.<V>absent();
-            return this;
-        }
-        /** @since 0.7.0 included in case old behaviour of not checking 
whether the entity is managed is required
-         * (I can't see why it is; polling will likely give errors, once it is 
unmanaged this will never completed,
-         * and before management the current code will continue, so long as 
there are no other errors) */ @Deprecated
-        public Builder<T,V> onUnmanagedContinue() {
-            ignoreUnmanaged = true;
-            return this;
-        }
-        /** take advantage of the fact that this builder can build multiple 
times, allowing subclasses 
-         * to change the source along the way */
-        protected Builder<T,V> source(Entity source) {
-            this.source = source;
-            return this;
-        }
-        /** as {@link #source(Entity)} */
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        protected Builder<T,V> sensor(AttributeSensor<? extends T> sensor) {
-            this.sensor = (AttributeSensor) sensor;
-            return this;
-        }
-        public Task<V> build() {
-            validate();
-            
-            return Tasks.<V>builder().dynamic(false)
-                .name("waiting on "+sensor.getName())
-                .description("Waiting on sensor "+sensor.getName()+" from 
"+source)
-                .tag("attributeWhenReady")
-                .body(new WaitInTaskForAttributeReady<T,V>(this))
-                .build();
-        }
-        
-        public V runNow() {
-            validate();
-            return new WaitInTaskForAttributeReady<T,V>(this).call();
-        }
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        private void validate() {
-            checkNotNull(source, "Entity source");
-            checkNotNull(sensor, "Sensor");
-            if (readiness == null) readiness = 
GroovyJavaMethods.truthPredicate();
-            if (postProcess == null) postProcess = (Function) 
Functions.identity();
-        }
-    }
-
-    /**
-     * Builder for producing variants of attributeWhenReady.
-     */
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @Beta
-    public static class MultiBuilder<T, V, V2> {
-        protected final String name;
-        protected final String descriptionBase;
-        protected final Builder<T,V> builder;
-        // if desired, the use of this multiSource could allow different 
conditions; 
-        // but probably an easier API just for the caller to build the 
parallel task  
-        protected final List<AttributeAndSensorCondition<?>> multiSource = 
Lists.newArrayList();
-        protected Function<? super List<V>, V2> postProcessFromMultiple;
-        
-        /** returns a task for parallel execution returning a list of values 
of the given sensor list on the given entity, 
-         * optionally when the values satisfy a given readiness predicate 
(defaulting to groovy truth if not supplied) */ 
-        @Beta
-        protected MultiBuilder(Iterable<? extends Entity> sources, 
AttributeSensor<T> sensor) {
-            this(sources, sensor, GroovyJavaMethods.truthPredicate());
-        }
-        @Beta
-        protected MultiBuilder(Iterable<? extends Entity> sources, 
AttributeSensor<T> sensor, Predicate<? super T> readiness) {
-            builder = new Builder<T,V>(null, sensor);
-            builder.readiness(readiness);
-            
-            for (Entity s : checkNotNull(sources, "sources")) {
-                multiSource.add(new AttributeAndSensorCondition<T>(s, sensor, 
readiness));
-            }
-            this.name = "waiting on "+sensor.getName();
-            this.descriptionBase = "waiting on "+sensor.getName()+" "+readiness
-                +" from "+Iterables.size(sources)+" 
entit"+Strings.ies(sources);
-        }
-        
-        /** Apply post-processing to the entire list of results */
-        public <V2b> MultiBuilder<T, V, V2b> postProcessFromMultiple(final 
Function<? super List<V>, V2b> val) {
-            this.postProcessFromMultiple = (Function) checkNotNull(val, 
"postProcessFromMulitple");
-            return (MultiBuilder<T,V, V2b>) this;
-        }
-        /** Apply post-processing to the entire list of results 
-         * See {@link CollectionFunctionals#all(Predicate)} and {@link 
CollectionFunctionals#quorum(org.apache.brooklyn.util.collections.QuorumCheck, 
Predicate)
-         * which allow useful arguments. */
-        public MultiBuilder<T, V, Boolean> postProcessFromMultiple(final 
Predicate<? super List<V>> val) {
-            return postProcessFromMultiple(Functions.forPredicate(val));
-        }
-        
-        public <V1> MultiBuilder<T, V1, V2> postProcess(Closure<V1> val) {
-            builder.postProcess(val);
-            return (MultiBuilder<T, V1, V2>) this;
-        }
-        public <V1> MultiBuilder<T, V1, V2> postProcess(final Function<? super 
T, V1>  val) {
-            builder.postProcess(val);
-            return (MultiBuilder<T, V1, V2>) this;
-        }
-        public <T2> MultiBuilder<T, V, V2> abortIf(Entity source, 
AttributeSensor<T2> sensor) {
-            builder.abortIf(source, sensor);
-            return this;
-        }
-        public <T2> MultiBuilder<T, V, V2> abortIf(Entity source, 
AttributeSensor<T2> sensor, Predicate<? super T2> predicate) {
-            builder.abortIf(source, sensor, predicate);
-            return this;
-        }
-        public MultiBuilder<T, V, V2> abortIfOnFire() {
-            builder.abortIfOnFire();
-            return this;
-        }
-        public MultiBuilder<T, V, V2> blockingDetails(String val) {
-            builder.blockingDetails(val);
-            return this;
-        }
-        public MultiBuilder<T, V, V2> timeout(Duration val) {
-            builder.timeout(val);
-            return this;
-        }
-        public MultiBuilder<T, V, V2> onTimeoutReturn(V val) {
-            builder.onTimeoutReturn(val);
-            return this;
-        }
-        public MultiBuilder<T, V, V2> onTimeoutThrow() {
-            builder.onTimeoutThrow();
-            return this;
-        }
-        public MultiBuilder<T, V, V2> onUnmanagedReturn(V val) {
-            builder.onUnmanagedReturn(val);
-            return this;
-        }
-        public MultiBuilder<T, V, V2> onUnmanagedThrow() {
-            builder.onUnmanagedThrow();
-            return this;
-        }
-        
-        public Task<V2> build() {
-            List<Task<V>> tasks = MutableList.of();
-            for (AttributeAndSensorCondition<?> source: multiSource) {
-                builder.source(source.source);
-                builder.sensor((AttributeSensor)source.sensor);
-                builder.readiness((Predicate)source.predicate);
-                tasks.add(builder.build());
-            }
-            final Task<List<V>> parallelTask = 
Tasks.<List<V>>builder().parallel(true).addAll(tasks)
-                .name(name)
-                .description(descriptionBase+
-                    (builder.timeout!=null ? ", timeout "+builder.timeout : 
""))
-                .build();
-            
-            if (postProcessFromMultiple == null) {
-                // V2 should be the right type in normal operations
-                return (Task<V2>) parallelTask;
-            } else {
-                return 
Tasks.<V2>builder().name(name).description(descriptionBase)
-                    .tag("attributeWhenReady")
-                    .body(new Callable<V2>() {
-                        @Override public V2 call() throws Exception {
-                            List<V> prePostProgress = 
DynamicTasks.queue(parallelTask).get();
-                            return DynamicTasks.queue(
-                                
Tasks.<V2>builder().name("post-processing").description("Applying 
"+postProcessFromMultiple)
-                                    
.body(Functionals.callable(postProcessFromMultiple, prePostProgress))
-                                    .build()).get();
-                        }
-                    })
-                    .build();
-            }
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java 
b/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
deleted file mode 100644
index 6b9c780..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
+++ /dev/null
@@ -1,96 +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.sensor.core;
-
-import java.net.URI;
-
-import net.minidev.json.JSONObject;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.effector.AddSensor;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Functions;
-import com.google.common.base.Supplier;
-
-/**
- * Configurable {@link org.apache.brooklyn.api.entity.EntityInitializer} which 
adds an HTTP sensor feed to retrieve the
- * {@link JSONObject} from a JSON response in order to populate the sensor 
with the data at the {@code jsonPath}.
- *
- * @see SshCommandSensor
- * @see JmxAttributeSensor
- */
-@Beta
-public final class HttpRequestSensor<T> extends AddSensor<T> {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(HttpRequestSensor.class);
-
-    public static final ConfigKey<String> SENSOR_URI = 
ConfigKeys.newStringConfigKey("uri", "HTTP URI to poll for JSON");
-    public static final ConfigKey<String> JSON_PATH = 
ConfigKeys.newStringConfigKey("jsonPath", "JSON path to select in HTTP 
response; default $", "$");
-    public static final ConfigKey<String> USERNAME = 
ConfigKeys.newStringConfigKey("username", "Username for HTTP request, if 
required");
-    public static final ConfigKey<String> PASSWORD = 
ConfigKeys.newStringConfigKey("password", "Password for HTTP request, if 
required");
-
-    protected final Supplier<URI> uri;
-    protected final String jsonPath;
-    protected final String username;
-    protected final String password;
-
-    public HttpRequestSensor(final ConfigBag params) {
-        super(params);
-
-        uri = new Supplier<URI>() {
-            @Override
-            public URI get() {
-                return URI.create(params.get(SENSOR_URI));
-            }
-        };
-        jsonPath = params.get(JSON_PATH);
-        username = params.get(USERNAME);
-        password = params.get(PASSWORD);
-    }
-
-    @Override
-    public void apply(final EntityLocal entity) {
-        super.apply(entity);
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Adding HTTP JSON sensor {} to {}", name, entity);
-        }
-
-        HttpPollConfig<T> pollConfig = new HttpPollConfig<T>(sensor)
-                .checkSuccess(HttpValueFunctions.responseCodeEquals(200))
-                .onFailureOrException(Functions.constant((T) null))
-                
.onSuccess(HttpValueFunctions.<T>jsonContentsFromPath(jsonPath))
-                .period(period);
-
-        HttpFeed.builder().entity(entity)
-                .baseUri(uri)
-                .credentialsIfNotNull(username, password)
-                .poll(pollConfig)
-                .build();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
 
b/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
deleted file mode 100644
index e269966..0000000
--- 
a/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.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 org.apache.brooklyn.sensor.core;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-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.location.PortRange;
-import org.apache.brooklyn.api.location.PortSupplier;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
-import org.apache.brooklyn.core.internal.BrooklynInitialization;
-import org.apache.brooklyn.core.location.Locations;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-
-/**
- * A {@link Sensor} describing a port on a system,
- * with a {@link ConfigKey} which can be configured with a port range
- * (either a number e.g. 80, or a string e.g. "80" or "8080-8089" or even "80, 
8080-8089, 8800+", or a list of these).
- * <p>
- * To convert at runtime a single port is chosen, respecting the entity.
- */
-public class PortAttributeSensorAndConfigKey extends 
AttributeSensorAndConfigKey<PortRange,Integer> {
-
-    private static final long serialVersionUID = 4680651022807491321L;
-
-    public static final Logger LOG = 
LoggerFactory.getLogger(PortAttributeSensorAndConfigKey.class);
-
-    static { BrooklynInitialization.initAll(); }
-
-    public PortAttributeSensorAndConfigKey(String name) {
-        this(name, name, null);
-    }
-    public PortAttributeSensorAndConfigKey(String name, String description) {
-        this(name, description, null);
-    }
-    public PortAttributeSensorAndConfigKey(String name, String description, 
Object defaultValue) {
-        super(PortRange.class, Integer.class, name, description, defaultValue);
-    }
-    public PortAttributeSensorAndConfigKey(PortAttributeSensorAndConfigKey 
orig, Object defaultValue) {
-        super(orig, TypeCoercions.coerce(defaultValue, PortRange.class));
-    }
-    @Override
-    protected Integer convertConfigToSensor(PortRange value, Entity entity) {
-        if (value==null) return null;
-        Collection<? extends Location> locations = entity.getLocations();
-        if (!locations.isEmpty()) {
-            Maybe<? extends Location> lo = 
Locations.findUniqueMachineLocation(locations);
-            if (!lo.isPresent()) {
-                // Try a unique location which isn't a machine provisioner
-                Iterator<? extends Location> li = Iterables.filter(locations,
-                        
Predicates.not(Predicates.instanceOf(MachineProvisioningLocation.class))).iterator();
-                if (li.hasNext()) lo = Maybe.of(li.next());
-                if (li.hasNext()) lo = Maybe.absent();
-            }
-            // Fall back to selecting the single location
-            if (!lo.isPresent() && locations.size() == 1) {
-                lo = Maybe.of(locations.iterator().next());
-            }
-            if (LOG.isTraceEnabled()) {
-                LOG.trace("Convert config to sensor for {} found locations: 
{}. Selected: {}", new Object[] {entity, locations, lo});
-            }
-            if (lo.isPresent()) {
-                Location l = lo.get();
-                Optional<Boolean> locationRunning = 
Optional.fromNullable(l.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START_IF_RUNNING));
-                Optional<Boolean> entityRunning = 
Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START_IF_RUNNING));
-                Optional<Boolean> locationInstalled = 
Optional.fromNullable(l.getConfig(BrooklynConfigKeys.SKIP_ENTITY_INSTALLATION));
-                Optional<Boolean> entityInstalled = 
Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_INSTALLATION));
-                Optional<Boolean> entityStarted = 
Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START));
-                boolean skipCheck = 
locationRunning.or(entityRunning).or(locationInstalled).or(entityInstalled).or(entityStarted).or(false);
-                if (l instanceof PortSupplier) {
-                    int p = ((PortSupplier) l).obtainPort(value);
-                    if (p != -1) {
-                        LOG.debug("{}: choosing port {} for {}", new Object[] 
{ entity, p, getName() });
-                        return p;
-                    }
-                    // If we are not skipping install or already started, fail 
now
-                    if (!skipCheck) {
-                        int rangeSize = Iterables.size(value);
-                        if (rangeSize == 0) {
-                            LOG.warn("{}: no port available for {} (empty 
range {})", new Object[] { entity, getName(), value });
-                        } else if (rangeSize == 1) {
-                            Integer pp = value.iterator().next();
-                            if (pp > 1024) {
-                                LOG.warn("{}: port {} not available for {}", 
new Object[] { entity, pp, getName() });
-                            } else {
-                                LOG.warn("{}: port {} not available for {} 
(root may be required?)", new Object[] { entity, pp, getName() });
-                            }
-                        } else {
-                            LOG.warn("{}: no port available for {} (tried 
range {})", new Object[] { entity, getName(), value });
-                        }
-                        return null; // Definitively, no ports available
-                    }
-                }
-                // Ports may be available, we just can't tell from the location
-                Integer v = (value.isEmpty() ? null : value.iterator().next());
-                LOG.debug("{}: choosing port {} (unconfirmed) for {}", new 
Object[] { entity, v, getName() });
-                return v;
-            } else {
-                LOG.warn("{}: ports not applicable, or not yet applicable, 
because has multiple locations {}; ignoring ", new Object[] { entity, 
locations, getName() });
-            }
-        } else {
-            LOG.warn("{}: ports not applicable, or not yet applicable, bacause 
has no locations; ignoring {}", entity, getName());
-        }
-        return null;
-    }
-
-    @Override
-    protected Integer convertConfigToSensor(PortRange value, ManagementContext 
managementContext) {
-        LOG.warn("ports not applicable, because given managementContext rather 
than entity; ignoring {}", getName());
-        return null;
-    }
-}

Reply via email to