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

[3/4] incubator-brooklyn git commit: This closes #833

This closes #833


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

Branch: refs/heads/master
Commit: f9b357d716e28067eed4af3c691b22921a54d296
Parents: 4d0bbce e1a2d66
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Tue Aug 18 02:28:19 2015 -0400
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Tue Aug 18 02:28:19 2015 -0400

----------------------------------------------------------------------
 .../brooklyn/basic/AbstractBrooklynObject.java  | 249 ----------------
 .../brooklyn/basic/BasicConfigurableObject.java | 120 --------
 .../brooklyn/basic/BrooklynDynamicType.java     | 284 -------------------
 .../brooklyn/basic/BrooklynObjectInternal.java  | 104 -------
 .../brooklyn/basic/BrooklynTypeSnapshot.java    | 102 -------
 .../main/java/brooklyn/basic/BrooklynTypes.java | 132 ---------
 .../basic/internal/ApiObjectsFactoryImpl.java   |  42 ---
 .../enricher/basic/EnricherDynamicType.java     |   2 +-
 .../enricher/basic/EnricherTypeSnapshot.java    |   2 +-
 .../brooklyn/entity/basic/AbstractEntity.java   |   2 +-
 .../java/brooklyn/entity/basic/Entities.java    |   2 +-
 .../entity/basic/EntityDynamicType.java         |   2 +-
 .../brooklyn/entity/basic/EntityInternal.java   |   2 +-
 .../entity/basic/EntityTypeSnapshot.java        |   2 +-
 .../java/brooklyn/entity/basic/EntityTypes.java |   2 +-
 .../AbstractBrooklynObjectRebindSupport.java    |   2 +-
 .../rebind/ActivePartialRebindIteration.java    |   2 +-
 .../rebind/ImmediateDeltaChangeListener.java    |   2 +-
 .../rebind/PeriodicDeltaChangeListener.java     |   2 +-
 .../brooklyn/entity/rebind/RebindIteration.java |   4 +-
 .../entity/rebind/dto/BasicEntityMemento.java   |   3 +-
 .../entity/rebind/dto/MementosGenerators.java   |   2 +-
 .../persister/BrooklynPersistenceUtils.java     |   2 +-
 .../brooklyn/basic/AbstractBrooklynObject.java  | 249 ++++++++++++++++
 .../brooklyn/basic/BasicConfigurableObject.java | 120 ++++++++
 .../brooklyn/basic/BrooklynDynamicType.java     | 284 +++++++++++++++++++
 .../brooklyn/basic/BrooklynObjectInternal.java  | 104 +++++++
 .../brooklyn/basic/BrooklynTypeSnapshot.java    | 102 +++++++
 .../apache/brooklyn/basic/BrooklynTypes.java    | 132 +++++++++
 .../basic/internal/ApiObjectsFactoryImpl.java   |  42 +++
 .../catalog/internal/BasicBrooklynCatalog.java  |   2 +-
 .../core/catalog/internal/CatalogItemDo.java    |   2 +-
 .../internal/CatalogItemDtoAbstract.java        |   2 +-
 .../core/catalog/internal/CatalogUtils.java     |   2 +-
 .../catalog/internal/CatalogXmlSerializer.java  |   4 +-
 .../policy/basic/AbstractEntityAdjunct.java     |   4 +-
 .../core/policy/basic/PolicyDynamicType.java    |   2 +-
 .../core/policy/basic/PolicyTypeSnapshot.java   |   2 +-
 .../location/basic/AbstractLocation.java        |   2 +-
 .../location/basic/LocationDynamicType.java     |   2 +-
 .../location/basic/LocationInternal.java        |   2 +-
 .../location/basic/LocationTypeSnapshot.java    |   2 +-
 ...pi.basic.internal.ApiObjectsFactoryInterface |   2 +-
 .../CatalogOsgiVersionMoreEntityTest.java       |   2 +-
 .../main/java/org/apache/brooklyn/cli/Main.java |  13 +-
 .../brooklyn/cli/lister/ItemDescriptors.java    |   4 +-
 .../SoftlayerObtainPrivateLiveTest.java         |   2 +-
 .../rest/resources/PolicyConfigResource.java    |   2 +-
 .../rest/transform/CatalogTransformer.java      |   2 +-
 .../rest/util/BrooklynRestResourceUtils.java    |   2 +-
 50 files changed, 1074 insertions(+), 1084 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/basic/Entities.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/basic/EntityInternal.java
index 36e6907,f7fa53f..d9967d1
--- a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
@@@ -33,10 -33,10 +33,10 @@@ import org.apache.brooklyn.api.manageme
  import org.apache.brooklyn.api.management.SubscriptionContext;
  import org.apache.brooklyn.api.mementos.EntityMemento;
  import org.apache.brooklyn.core.management.internal.EntityManagementSupport;
 +import org.apache.brooklyn.core.util.config.ConfigBag;
  
- import brooklyn.basic.BrooklynObjectInternal;
+ import org.apache.brooklyn.basic.BrooklynObjectInternal;
  import brooklyn.config.ConfigKey;
 -import brooklyn.util.config.ConfigBag;
  
  import com.google.common.annotations.Beta;
  

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
----------------------------------------------------------------------
diff --cc core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
index 000a651,f3eca47..aed26d4
--- a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
@@@ -26,8 -25,9 +26,8 @@@ import org.apache.brooklyn.core.policy.
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
- import brooklyn.basic.AbstractBrooklynObject;
+ import org.apache.brooklyn.basic.AbstractBrooklynObject;
  import brooklyn.entity.rebind.dto.MementosGenerators;
 -import brooklyn.policy.basic.AbstractEntityAdjunct.AdjunctTagSupport;
  import brooklyn.util.text.Strings;
  
  public abstract class AbstractBrooklynObjectRebindSupport<T extends Memento> implements RebindSupport<T> {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
index 0000000,260c91b..4515492
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
@@@ -1,0 -1,249 +1,249 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  * KIND, either express or implied.  See the License for the
+  * specific language governing permissions and limitations
+  * under the License.
+  */
+ package org.apache.brooklyn.basic;
+ 
+ import java.util.Collections;
+ import java.util.Map;
+ import java.util.Set;
+ 
+ import org.apache.brooklyn.api.basic.internal.ApiObjectsFactory;
+ import org.apache.brooklyn.api.management.ManagementContext;
+ import org.apache.brooklyn.core.management.internal.ManagementContextInternal;
++import org.apache.brooklyn.core.util.config.ConfigBag;
++import org.apache.brooklyn.core.util.flags.SetFromFlag;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ import brooklyn.entity.basic.AbstractEntity;
+ import brooklyn.entity.proxying.InternalFactory;
+ import brooklyn.entity.rebind.RebindManagerImpl;
 -import brooklyn.util.config.ConfigBag;
 -import brooklyn.util.flags.SetFromFlag;
+ import brooklyn.util.text.Identifiers;
+ 
+ import com.google.common.collect.ImmutableSet;
+ import com.google.common.collect.Iterables;
+ import com.google.common.collect.Maps;
+ import com.google.common.collect.Sets;
+ 
+ public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
+ 
+     private static final Logger log = LoggerFactory.getLogger(AbstractBrooklynObject.class);
+ 
+     private boolean _legacyConstruction;
+     private boolean hasWarnedOfNoManagementContextWhenPersistRequested;
+ 
+     @SetFromFlag(value = "id")
+     private String id = Identifiers.makeRandomId(8);
+ 
+     private String catalogItemId;
+ 
+     /** subclasses should synchronize on this for all access */
+     @SetFromFlag(value = "tags")
+     private final Set<Object> tags = Sets.newLinkedHashSet();
+ 
+     private volatile ManagementContext managementContext;
+ 
+     public abstract void setDisplayName(String newName);
+ 
+     public AbstractBrooklynObject() {
+         this(Maps.newLinkedHashMap());
+     }
+ 
+     public AbstractBrooklynObject(Map<?, ?> properties) {
+         _legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
+ 
+         if (!_legacyConstruction && properties != null && !properties.isEmpty()) {
+             log.warn("Forcing use of deprecated old-style construction for {} because properties were " +
+                             "specified ({}); instead use specs (e.g. LocationSpec, EntitySpec, etc)",
+                     getClass().getName(), properties);
+             if (log.isDebugEnabled())
+                 log.debug("Source of use of old-style construction", new Throwable("Source of use of old-style construction"));
+             _legacyConstruction = true;
+         }
+ 
+         catalogItemId = ApiObjectsFactory.get().getCatalogItemIdFromContext();
+ 
+         // rely on sub-class to call configure(properties), because otherwise its fields will not have been initialised
+     }
+ 
+     /**
+      * See {@link #configure(Map)}
+      *
+      * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+      */
+     @Deprecated
+     protected AbstractBrooklynObject configure() {
+         return configure(Collections.emptyMap());
+     }
+ 
+     /**
+      * Will set fields from flags, and put the remaining ones into the 'leftovers' map.
+      * For some types, you can find unused config via {@link ConfigBag#getUnusedConfig()}.
+      * <p>
+      * To be overridden by AbstractEntity, AbstractLoation, AbstractPolicy, AbstractEnricher, etc.
+      * <p>
+      * But should not be overridden by specific entity types. If you do, the entity may break in
+      * subsequent releases. Also note that if you require fields to be initialized you must do that
+      * in this method. You must *not* rely on field initializers because they may not run until *after*
+      * this method (this method is invoked by the constructor in this class, so initializers
+      * in subclasses will not have run when this overridden method is invoked.)
+      *
+      * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
+      */
+     @Deprecated
+     protected abstract AbstractBrooklynObject configure(Map<?, ?> flags);
+ 
+     protected boolean isLegacyConstruction() {
+         return _legacyConstruction;
+     }
+ 
+     /**
+      * Called by framework (in new-style instances where spec was used) after configuring etc,
+      * but before a reference to this instance is shared.
+      * <p>
+      * To preserve backwards compatibility for if the instance is constructed directly, one
+      * can call the code below, but that means it will be called after references to this
+      * policy have been shared with other entities.
+      * <pre>
+      * {@code
+      * if (isLegacyConstruction()) {
+      *     init();
+      * }
+      * }
+      * </pre>
+      */
+     public void init() {
+         // no-op
+     }
+ 
+     /**
+      * Called by framework on rebind (in new-style instances):
+      * <ul>
+      * <li> after configuring, but
+      * <li> before the instance is managed, and
+      * <li> before adjuncts are attached to entities, and
+      * <li> before a reference to an object is shared.
+      * </ul>
+      * Note that {@link #init()} will not be called on rebind.
+      * <p>
+      * If you need to intercept behaviour <i>after</i> adjuncts are attached,
+      * consider {@link AbstractEntity#onManagementStarting()} 
+      * (but probably worth raising a discussion on the mailing list!)
+      */
+     public void rebind() {
+         // no-op
+     }
+ 
+     public void setManagementContext(ManagementContextInternal managementContext) {
+         this.managementContext = managementContext;
+     }
+ 
+     public ManagementContext getManagementContext() {
+         return managementContext;
+     }
+ 
+     protected boolean isRebinding() {
+         return RebindManagerImpl.RebindTracker.isRebinding();
+     }
+ 
+     protected void requestPersist() {
+         if (getManagementContext() != null) {
+             getManagementContext().getRebindManager().getChangeListener().onChanged(this);
+         } else {
+             // Might be nice to log this at debug but it gets hit a lot of times as locations
+             // are created and destroyed for the API. It also might not be an error - the
+             // management context might be null if the object is being recreated by persistence.
+             if (log.isTraceEnabled() && !hasWarnedOfNoManagementContextWhenPersistRequested) {
+                 log.trace("Cannot fulfil request to persist {} because it has no management context. " +
+                         "This warning will not be logged for this object again.", this);
+                 hasWarnedOfNoManagementContextWhenPersistRequested = true;
+             }
+         }
+     }
+ 
+     @Override
+     public String getId() {
+         return id;
+     }
+ 
+     @Override
+     public void setCatalogItemId(String id) {
+         this.catalogItemId = id;
+     }
+ 
+     @Override
+     public String getCatalogItemId() {
+         return catalogItemId;
+     }
+ 
+     protected void onTagsChanged() {
+         requestPersist();
+     }
+ 
+     @Override
+     public TagSupport tags() {
+         return new BasicTagSupport();
+     }
+ 
+     protected class BasicTagSupport implements TagSupport {
+         @Override
+         public Set<Object> getTags() {
+             synchronized (tags) {
+                 return ImmutableSet.copyOf(tags);
+             }
+         }
+ 
+         @Override
+         public boolean containsTag(Object tag) {
+             synchronized (tags) {
+                 return tags.contains(tag);
+             }
+         }
+ 
+         @Override
+         public boolean addTag(Object tag) {
+             boolean result;
+             synchronized (tags) {
+                 result = tags.add(tag);
+             }
+             onTagsChanged();
+             return result;
+         }
+ 
+         @Override
+         public boolean addTags(Iterable<?> newTags) {
+             boolean result;
+             synchronized (tags) {
+                 result = Iterables.addAll(tags, newTags);
+             }
+             onTagsChanged();
+             return result;
+         }
+ 
+         @Override
+         public boolean removeTag(Object tag) {
+             boolean result;
+             synchronized (tags) {
+                 result = tags.remove(tag);
+             }
+             onTagsChanged();
+             return result;
+         }
+     }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
index 0000000,f376d74..f79b1d7
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
@@@ -1,0 -1,120 +1,120 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  * KIND, either express or implied.  See the License for the
+  * specific language governing permissions and limitations
+  * under the License.
+  */
+ package org.apache.brooklyn.basic;
+ 
+ import org.apache.brooklyn.api.entity.trait.Configurable;
+ import org.apache.brooklyn.api.entity.trait.Identifiable;
+ import org.apache.brooklyn.api.management.ManagementContext;
+ import org.apache.brooklyn.api.management.Task;
+ import org.apache.brooklyn.core.management.ManagementContextInjectable;
++import org.apache.brooklyn.core.util.config.ConfigBag;
++import org.apache.brooklyn.core.util.flags.SetFromFlag;
+ 
+ import brooklyn.camp.brooklyn.api.HasBrooklynManagementContext;
+ import brooklyn.config.ConfigKey;
+ import brooklyn.config.ConfigKey.HasConfigKey;
+ import brooklyn.config.ConfigMap;
 -import brooklyn.util.config.ConfigBag;
 -import brooklyn.util.flags.SetFromFlag;
+ import brooklyn.util.text.Identifiers;
+ 
+ /**
+  * A parent class for ancilliary objects that do not require the full heavy lifting of {@link AbstractBrooklynObject}
+  * or similar, but wish to use {@link ConfigKey} and {@link Configurable} in their construction, via the
+  * {@code $brooklyn:object} method of the CAMP DSL.
+  * <p>
+  * Type coercion of values will occur when the {@link ConfigMap} is accessed, but resolving of {@link Task tasks} and other
+  * deferred operations are assumed to have occurred prior to calling {@link #setConfig(ConfigKey, Object)} i.e. at
+  * object construction.
+  */
+ public class BasicConfigurableObject implements Configurable, Identifiable, ManagementContextInjectable, HasBrooklynManagementContext {
+ 
+     @SetFromFlag("id")
+     private String id = Identifiers.makeRandomId(8);
+ 
+     private volatile ManagementContext managementContext;
+     private BasicConfigurationSupport config;
+     
+     public BasicConfigurableObject() {
+         config = new BasicConfigurationSupport();
+     }
+ 
+     @Override
+     public void injectManagementContext(ManagementContext managementContext) {
+         this.managementContext = managementContext;
+     }
+ 
+     public ManagementContext getBrooklynManagementContext() {
+         return managementContext;
+     }
+ 
+     @Override
+     public String getId() {
+         return id;
+     }
+ 
+     @Override
+     public ConfigurationSupport config() {
+         return config;
+     }
+ 
+     @Override
+     @Deprecated
+     public <T> T setConfig(ConfigKey<T> key, T value) {
+         return config().set(key, value);
+     }
+ 
+     public <T> T getConfig(ConfigKey<T> key) {
+         return config().get(key);
+     }
+ 
+     private static class BasicConfigurationSupport implements ConfigurationSupport {
+         private final ConfigBag config = ConfigBag.newInstance();
+ 
+         @Override
+         public <T> T get(ConfigKey<T> key) {
+             return config.get(key);
+         }
+ 
+         @Override
+         public <T> T get(HasConfigKey<T> key) {
+             return get(key.getConfigKey());
+         }
+ 
+         @Override
+         public <T> T set(ConfigKey<T> key, T val) {
+             T old = config.get(key);
+             config.configure(key, val);
+             return old;
+         }
+ 
+         @Override
+         public <T> T set(HasConfigKey<T> key, T val) {
+             return set(key.getConfigKey(), val);
+         }
+ 
+         @Override
+         public <T> T set(ConfigKey<T> key, Task<T> val) {
+             throw new UnsupportedOperationException();
+         }
+ 
+         @Override
+         public <T> T set(HasConfigKey<T> key, Task<T> val) {
+             return set(key.getConfigKey(), val);
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/BrooklynDynamicType.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/BrooklynDynamicType.java
index 0000000,368b035..f6a8893
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/BrooklynDynamicType.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/BrooklynDynamicType.java
@@@ -1,0 -1,284 +1,284 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES 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.basic;
+ 
+ import static com.google.common.base.Preconditions.checkNotNull;
+ 
+ import java.lang.reflect.Field;
+ import java.lang.reflect.Modifier;
+ import java.util.ArrayList;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.LinkedHashMap;
+ import java.util.LinkedHashSet;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.atomic.AtomicBoolean;
+ 
+ import org.apache.brooklyn.api.basic.BrooklynObject;
+ import org.apache.brooklyn.api.basic.BrooklynType;
++import org.apache.brooklyn.core.util.flags.FlagUtils;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ import brooklyn.config.ConfigKey;
+ import brooklyn.config.ConfigKey.HasConfigKey;
+ import brooklyn.event.basic.BasicConfigKey.BasicConfigKeyOverwriting;
 -import brooklyn.util.flags.FlagUtils;
+ import brooklyn.util.javalang.Reflections;
+ import brooklyn.util.text.Strings;
+ 
+ import com.google.common.base.Joiner;
+ import com.google.common.base.Objects;
+ import com.google.common.collect.ArrayListMultimap;
+ import com.google.common.collect.ListMultimap;
+ import com.google.common.collect.Lists;
+ 
+ /**
+  * This is the actual type of a brooklyn object instance at runtime,
+  * which can change from the static {@link BrooklynType}, and can change over time;
+  * for this reason it does *not* implement BrooklynType, but 
+  * callers can call {@link #getSnapshot()} to get a snapshot such instance.  
+  */
+ public abstract class BrooklynDynamicType<T extends BrooklynObject, AbstractT extends AbstractBrooklynObject> {
+ 
+     private static final Logger LOG = LoggerFactory.getLogger(BrooklynDynamicType.class);
+ 
+     protected final Class<? extends T> brooklynClass;
+     protected final AbstractT instance;
+     protected volatile String name;
+     
+     /** 
+      * Map of config keys (and their fields) on this instance, by name.
+      */
+     protected final Map<String,FieldAndValue<ConfigKey<?>>> configKeys = new ConcurrentHashMap<String, FieldAndValue<ConfigKey<?>>>();
+ 
+     private volatile BrooklynTypeSnapshot snapshot;
+     private final AtomicBoolean snapshotValid = new AtomicBoolean(false);
+ 
+     @SuppressWarnings("unchecked")
+     public BrooklynDynamicType(AbstractT instance) {
+         this((Class<? extends T>) instance.getClass(), instance);
+     }
+     public BrooklynDynamicType(Class<? extends T> clazz) {
+         this(clazz, null);
+     }
+     protected BrooklynDynamicType(Class<? extends T> clazz, AbstractT instance) {
+         this.brooklynClass = checkNotNull(clazz, "brooklyn class");
+         this.instance = instance;
+         // NB: official name is usually injected later, e.g. from AbstractEntity.setManagementContext
+         this.name = (clazz.getCanonicalName() == null) ? clazz.getName() : clazz.getCanonicalName();
+         
+         buildConfigKeys(clazz, null, configKeys);
+         if (LOG.isTraceEnabled())
+             LOG.trace("Entity {} config keys: {}", (instance==null ? clazz.getName() : instance.getId()), Joiner.on(", ").join(configKeys.keySet()));
+     }
+     
+     protected abstract BrooklynTypeSnapshot newSnapshot();
+ 
+     protected void invalidateSnapshot() {
+         snapshotValid.set(false);
+     }
+ 
+     public void setName(String name) {
+         if (Strings.isBlank(name)) {
+             throw new IllegalArgumentException("Invalid name "+(name == null ? "null" : "'"+name+"'")+"; name must be non-empty and not just white space");
+         }
+         this.name = name;
+         invalidateSnapshot();
+     }
+     
+     public synchronized BrooklynType getSnapshot() {
+         return refreshSnapshot();
+     }
+     
+     public Class<? extends T> getBrooklynClass() {
+         return brooklynClass;
+     }
+     
+     // --------------------------------------------------
+     
+     /**
+      * ConfigKeys available on this entity.
+      */
+     public Map<String,ConfigKey<?>> getConfigKeys() {
+         return Collections.unmodifiableMap(value(configKeys));
+     }
+ 
+     /**
+      * ConfigKeys available on this entity.
+      */
+     public ConfigKey<?> getConfigKey(String keyName) { 
+         return value(configKeys.get(keyName)); 
+     }
+ 
+     /** field where a config key is defined, for use getting annotations. note annotations are not inherited. */
+     public Field getConfigKeyField(String keyName) { 
+         return field(configKeys.get(keyName)); 
+     }
+ 
+     protected BrooklynTypeSnapshot refreshSnapshot() {
+         if (snapshotValid.compareAndSet(false, true)) {
+             snapshot = newSnapshot();
+         }
+         return snapshot;
+     }
+ 
+     /**
+      * Finds the config keys defined on the entity's class, statics and optionally any non-static (discouraged).
+      * Prefers keys which overwrite other keys, and prefers keys which are lower in the hierarchy;
+      * logs warnings if there are two conflicting keys which don't have an overwriting relationship.
+      */
+     protected static void buildConfigKeys(Class<? extends BrooklynObject> clazz, AbstractBrooklynObject optionalInstance, 
+             Map<String, FieldAndValue<ConfigKey<?>>> configKeys) {
+         ListMultimap<String,FieldAndValue<ConfigKey<?>>> configKeysAll = 
+                 ArrayListMultimap.<String, FieldAndValue<ConfigKey<?>>>create();
+         
+         for (Field f : FlagUtils.getAllFields(clazz)) {
+             boolean isConfigKey = ConfigKey.class.isAssignableFrom(f.getType());
+             if (!isConfigKey) {
+                 if (!HasConfigKey.class.isAssignableFrom(f.getType())) {
+                     // neither ConfigKey nor HasConfigKey
+                     continue;
+                 }
+             }
+             if (!Modifier.isStatic(f.getModifiers())) {
+                 // require it to be static or we have an instance
+                 LOG.warn("Discouraged use of non-static config key "+f+" defined in " + (optionalInstance!=null ? optionalInstance : clazz));
+                 if (optionalInstance==null) continue;
+             }
+             try {
+                 Object v = f.get(optionalInstance);
+ 
+                 if (v == null) {
+                     LOG.warn("no value defined for config key field (skipping): "+f);
+                 } else {
+                     ConfigKey<?> k = isConfigKey ? (ConfigKey<?>) v : ((HasConfigKey<?>) v).getConfigKey();
+                     configKeysAll.put(k.getName(), new FieldAndValue<ConfigKey<?>>(f, k));
+                 }
+             } catch (IllegalAccessException e) {
+                 LOG.warn("cannot access config key (skipping): "+f);
+             }
+         }
+         LinkedHashSet<String> keys = new LinkedHashSet<String>(configKeysAll.keys());
+         for (String kn: keys) {
+             List<FieldAndValue<ConfigKey<?>>> kk = Lists.newArrayList(configKeysAll.get(kn));
+             if (kk.size()>1) {
+                 // remove anything which extends another value in the list
+                 for (FieldAndValue<ConfigKey<?>> k: kk) {
+                     ConfigKey<?> key = value(k);
+                     if (key instanceof BasicConfigKeyOverwriting) {                            
+                         ConfigKey<?> parent = ((BasicConfigKeyOverwriting<?>)key).getParentKey();
+                         // find and remove the parent from consideration
+                         for (FieldAndValue<ConfigKey<?>> k2: kk) {
+                             if (value(k2) == parent)
+                                 configKeysAll.remove(kn, k2);
+                         }
+                     }
+                 }
+                 kk = Lists.newArrayList(configKeysAll.get(kn));
+             }
+             // multiple keys, not overwriting; if their values are the same then we don't mind
+             FieldAndValue<ConfigKey<?>> best = null;
+             for (FieldAndValue<ConfigKey<?>> k: kk) {
+                 if (best==null) {
+                     best=k;
+                 } else {
+                     Field lower = Reflections.inferSubbestField(k.field, best.field);
+                     ConfigKey<? extends Object> lowerV = lower==null ? null : lower.equals(k.field) ? k.value : best.value;
+                     if (best.value == k.value) {
+                         // same value doesn't matter which we take (but take lower if there is one)
+                         if (LOG.isTraceEnabled()) 
+                             LOG.trace("multiple definitions for config key {} on {}; same value {}; " +
+                                     "from {} and {}, preferring {}", 
+                                     new Object[] {
+                                     best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+                                     best.value.getDefaultValue(),
+                                     k.field, best.field, lower});
+                         best = new FieldAndValue<ConfigKey<?>>(lower!=null ? lower : best.field, best.value);
+                     } else if (lower!=null) {
+                         // different value, but one clearly lower (in type hierarchy)
+                         if (LOG.isTraceEnabled()) 
+                             LOG.trace("multiple definitions for config key {} on {}; " +
+                                     "from {} and {}, preferring lower {}, value {}", 
+                                     new Object[] {
+                                     best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+                                     k.field, best.field, lower,
+                                     lowerV.getDefaultValue() });
+                         best = new FieldAndValue<ConfigKey<?>>(lower, lowerV);
+                     } else {
+                         // different value, neither one lower than another in hierarchy
+                         LOG.warn("multiple ambiguous definitions for config key {} on {}; " +
+                                 "from {} and {}, values {} and {}; " +
+                                 "keeping latter (arbitrarily)", 
+                                 new Object[] {
+                                 best.value.getName(), optionalInstance!=null ? optionalInstance : clazz,
+                                 k.field, best.field, 
+                                 k.value.getDefaultValue(), best.value.getDefaultValue() });
+                         // (no change)
+                     }
+                 }
+             }
+             if (best==null) {
+                 // shouldn't happen
+                 LOG.error("Error - no matching config key from "+kk+" in class "+clazz+", even though had config key name "+kn);
+                 continue;
+             } else {
+                 configKeys.put(best.value.getName(), best);
+             }
+         }
+     }
+     
+     protected static class FieldAndValue<V> {
+         public final Field field;
+         public final V value;
+         public FieldAndValue(Field field, V value) {
+             this.field = field;
+             this.value = value;
+         }
+         @Override
+         public String toString() {
+             return Objects.toStringHelper(this).add("field", field).add("value", value).toString();
+         }
+     }
+     
+     protected static <V> V value(FieldAndValue<V> fv) {
+         if (fv==null) return null;
+         return fv.value;
+     }
+     
+     protected static Field field(FieldAndValue<?> fv) {
+         if (fv==null) return null;
+         return fv.field;
+     }
+ 
+     protected static <V> Collection<V> value(Collection<FieldAndValue<V>> fvs) {
+         List<V> result = new ArrayList<V>();
+         for (FieldAndValue<V> fv: fvs) result.add(value(fv));
+         return result;
+     }
+ 
+     protected static <K,V> Map<K,V> value(Map<K,FieldAndValue<V>> fvs) {
+         Map<K,V> result = new LinkedHashMap<K,V>();
+         for (K key: fvs.keySet())
+             result.put(key, value(fvs.get(key)));
+         return result;
+     }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/BrooklynObjectInternal.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/BrooklynObjectInternal.java
index 0000000,8109b78..eacb1e1
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/BrooklynObjectInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/BrooklynObjectInternal.java
@@@ -1,0 -1,104 +1,104 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES 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.basic;
+ 
+ import java.util.Map;
+ 
+ import org.apache.brooklyn.api.basic.BrooklynObject;
+ import org.apache.brooklyn.api.entity.rebind.RebindSupport;
+ import org.apache.brooklyn.api.entity.rebind.Rebindable;
+ import org.apache.brooklyn.api.entity.trait.Configurable;
++import org.apache.brooklyn.core.util.config.ConfigBag;
+ 
+ import brooklyn.config.ConfigKey;
+ import brooklyn.config.ConfigKey.HasConfigKey;
 -import brooklyn.util.config.ConfigBag;
+ import brooklyn.util.guava.Maybe;
+ 
+ import com.google.common.annotations.Beta;
+ 
+ public interface BrooklynObjectInternal extends BrooklynObject, Rebindable {
+     
+     void setCatalogItemId(String id);
+     
+     @SuppressWarnings("rawtypes")  // subclasses typically apply stronger typing
+     RebindSupport getRebindSupport();
+     
+     ConfigurationSupportInternal config();
+ 
+     @Beta
+     public interface ConfigurationSupportInternal extends Configurable.ConfigurationSupport {
+         
+         /**
+          * Returns a read-only view of all the config key/value pairs on this entity, backed by a string-based map, 
+          * including config names that did not match anything on this entity.
+          * 
+          * TODO This method gives no information about which config is inherited versus local;
+          * this means {@link ConfigKey#getInheritance()} cannot be respected. This is an unsolvable problem
+          * for "config names that did not match anything on this entity". Therefore consider using
+          * alternative getters.
+          */
+         @Beta
+         ConfigBag getBag();
+         
+         /**
+          * Returns a read-only view of the local (i.e. not inherited) config key/value pairs on this entity, 
+          * backed by a string-based map, including config names that did not match anything on this entity.
+          */
+         @Beta
+         ConfigBag getLocalBag();
+         
+         /**
+          * Returns the uncoerced value for this config key, if available, not taking any default.
+          * If there is no local value and there is an explicit inherited value, will return the inherited.
+          */
+         @Beta
+         Maybe<Object> getRaw(ConfigKey<?> key);
+ 
+         /**
+          * @see {@link #getConfigRaw(ConfigKey)}
+          */
+         @Beta
+         Maybe<Object> getRaw(HasConfigKey<?> key);
+ 
+         /**
+          * Returns the uncoerced value for this config key, if available,
+          * not following any inheritance chains and not taking any default.
+          */
+         @Beta
+         Maybe<Object> getLocalRaw(ConfigKey<?> key);
+ 
+         /**
+          * @see {@link #getLocalConfigRaw(ConfigKey)}
+          */
+         @Beta
+         Maybe<Object> getLocalRaw(HasConfigKey<?> key);
+ 
+         @Beta
+         void addToLocalBag(Map<String, ?> vals);
+ 
+         @Beta
+         void removeFromLocalBag(String key);
+ 
+         @Beta
+         void refreshInheritedConfig();
+         
+         @Beta
+         void refreshInheritedConfigOfChildren();
+     }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/BrooklynTypes.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/BrooklynTypes.java
index 0000000,f64c8f9..d199686
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/BrooklynTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/BrooklynTypes.java
@@@ -1,0 -1,132 +1,132 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES 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.basic;
+ 
+ import java.util.Map;
+ 
+ import org.apache.brooklyn.api.basic.BrooklynObject;
+ import org.apache.brooklyn.api.entity.Entity;
+ import org.apache.brooklyn.api.event.Sensor;
+ import org.apache.brooklyn.api.location.Location;
+ import org.apache.brooklyn.api.policy.Enricher;
+ import org.apache.brooklyn.api.policy.Policy;
++import org.apache.brooklyn.core.policy.basic.PolicyDynamicType;
+ 
+ import brooklyn.config.ConfigKey;
+ import brooklyn.enricher.basic.EnricherDynamicType;
+ import brooklyn.entity.basic.EntityDynamicType;
 -import brooklyn.policy.basic.PolicyDynamicType;
+ import brooklyn.util.exceptions.Exceptions;
+ 
+ import com.google.common.collect.Maps;
+ 
+ public class BrooklynTypes {
+ 
+     private static class ImmutableEntityType extends EntityDynamicType {
+         public ImmutableEntityType(Class<? extends Entity> clazz) {
+             super(clazz);
+         }
+         @Override
+         public void setName(String name) {
+             throw new UnsupportedOperationException();
+         }
+         @Override
+         public void addSensor(Sensor<?> newSensor) {
+             throw new UnsupportedOperationException();
+         }
+         @Override
+         public void addSensorIfAbsent(Sensor<?> newSensor) {
+             throw new UnsupportedOperationException();
+         }
+         @Override
+         public Sensor<?> addSensorIfAbsentWithoutPublishing(Sensor<?> newSensor) {
+             throw new UnsupportedOperationException();
+         }
+         @Override
+         public void addSensors(Iterable<? extends Sensor<?>> newSensors) {
+             throw new UnsupportedOperationException();
+         }
+         @Override
+         public boolean removeSensor(Sensor<?> sensor) {
+             throw new UnsupportedOperationException();
+         }
+         @Override
+         public Sensor<?> removeSensor(String sensorName) {
+             throw new UnsupportedOperationException();
+         }
+     }
+     
+     @SuppressWarnings("rawtypes")
+     private static final Map<Class,BrooklynDynamicType<?,?>> cache = Maps.newConcurrentMap();
+     
+     public static EntityDynamicType getDefinedEntityType(Class<? extends Entity> entityClass) {
+         return (EntityDynamicType) BrooklynTypes.getDefinedBrooklynType(entityClass);
+     }
+ 
+     public static BrooklynDynamicType<?,?> getDefinedBrooklynType(Class<? extends BrooklynObject> brooklynClass) {
+         BrooklynDynamicType<?,?> t = cache.get(brooklynClass);
+         if (t!=null) return t;
+         return loadDefinedBrooklynType(brooklynClass);
+     }
+ 
+     @SuppressWarnings("unchecked")
+     private static synchronized BrooklynDynamicType<?,?> loadDefinedBrooklynType(Class<? extends BrooklynObject> brooklynClass) {
+         BrooklynDynamicType<?,?> type = cache.get(brooklynClass);
+         if (type != null) return type;
+         
+         if (Entity.class.isAssignableFrom(brooklynClass)) {
+             type = new ImmutableEntityType((Class<? extends Entity>)brooklynClass);
+         } else if (Location.class.isAssignableFrom(brooklynClass)) {
+             type = new ImmutableEntityType((Class<? extends Entity>)brooklynClass);
+         } else if (Policy.class.isAssignableFrom(brooklynClass)) {
+             type = new PolicyDynamicType((Class<? extends Policy>)brooklynClass); // TODO immutable?
+         } else if (Enricher.class.isAssignableFrom(brooklynClass)) {
+             type = new EnricherDynamicType((Class<? extends Enricher>)brooklynClass); // TODO immutable?
+         } else {
+             throw new IllegalStateException("Invalid brooklyn type "+brooklynClass);
+         }
+         cache.put(brooklynClass, type);
+         return type;
+     }
+ 
+     public static Map<String, ConfigKey<?>> getDefinedConfigKeys(Class<? extends BrooklynObject> brooklynClass) {
+         return getDefinedBrooklynType(brooklynClass).getConfigKeys();
+     }
+     
+     @SuppressWarnings("unchecked")
+     public static Map<String, ConfigKey<?>> getDefinedConfigKeys(String brooklynTypeName) {
+         try {
+             return getDefinedConfigKeys((Class<? extends BrooklynObject>) Class.forName(brooklynTypeName));
+         } catch (ClassNotFoundException e) {
+             throw Exceptions.propagate(e);
+         }
+     }
+     
+     public static Map<String, Sensor<?>> getDefinedSensors(Class<? extends Entity> entityClass) {
+         return getDefinedEntityType(entityClass).getSensors();
+     }
+     
+     @SuppressWarnings("unchecked")
+     public static Map<String, Sensor<?>> getDefinedSensors(String entityTypeName) {
+         try {
+             return getDefinedSensors((Class<? extends Entity>) Class.forName(entityTypeName));
+         } catch (ClassNotFoundException e) {
+             throw Exceptions.propagate(e);
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
index 0000000,d200a3c..a51ee39
mode 000000,100644..100644
--- a/core/src/main/java/org/apache/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
@@@ -1,0 -1,42 +1,42 @@@
+ /*
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  *     http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  * KIND, either express or implied.  See the License for the
+  * specific language governing permissions and limitations
+  * under the License.
+  */
+ package org.apache.brooklyn.basic.internal;
+ 
+ import org.apache.brooklyn.api.basic.internal.ApiObjectsFactoryInterface;
+ import org.apache.brooklyn.api.entity.Entity;
+ import org.apache.brooklyn.api.management.Task;
++import org.apache.brooklyn.core.util.task.Tasks;
+ 
+ import brooklyn.entity.basic.BrooklynTaskTags;
 -import brooklyn.util.task.Tasks;
+ 
+ public class ApiObjectsFactoryImpl implements ApiObjectsFactoryInterface {
+ 
+     @Override
+     public String getCatalogItemIdFromContext() {
+         Task<?> currentTask = Tasks.current();
+         if (currentTask != null) {
+             Entity contextEntity = BrooklynTaskTags.getContextEntity(currentTask);
+             if (contextEntity != null) {
+                 return contextEntity.getCatalogItemId();
+             }
+         }
+         return null;
+     }
+ 
+ }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogXmlSerializer.java
index 836cac3,ede8bde..49462e2
--- 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 +24,12 @@@ 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 org.apache.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/f9b357d7/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java
index eda106f,0000000..f5c36aa
mode 100644,000000..100644
--- a/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/org/apache/brooklyn/core/policy/basic/AbstractEntityAdjunct.java
@@@ -1,510 -1,0 +1,510 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing,
 + * software distributed under the License is distributed on an
 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 + * KIND, either express or implied.  See the License for the
 + * specific language governing permissions and limitations
 + * under the License.
 + */
 +package org.apache.brooklyn.core.policy.basic;
 +
 +import static brooklyn.util.GroovyJavaMethods.truth;
 +import static com.google.common.base.Preconditions.checkState;
 +
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.Iterator;
 +import java.util.Map;
 +import java.util.Set;
 +import java.util.concurrent.atomic.AtomicBoolean;
 +
 +import org.apache.brooklyn.api.entity.Entity;
 +import org.apache.brooklyn.api.entity.Group;
 +import org.apache.brooklyn.api.entity.basic.EntityLocal;
 +import org.apache.brooklyn.api.entity.trait.Configurable;
 +import org.apache.brooklyn.api.event.AttributeSensor;
 +import org.apache.brooklyn.api.event.Sensor;
 +import org.apache.brooklyn.api.event.SensorEventListener;
 +import org.apache.brooklyn.api.management.ExecutionContext;
 +import org.apache.brooklyn.api.management.SubscriptionContext;
 +import org.apache.brooklyn.api.management.SubscriptionHandle;
 +import org.apache.brooklyn.api.management.Task;
 +import org.apache.brooklyn.api.policy.EntityAdjunct;
 +import org.apache.brooklyn.core.management.internal.SubscriptionTracker;
 +import org.apache.brooklyn.core.util.config.ConfigBag;
 +import org.apache.brooklyn.core.util.flags.FlagUtils;
 +import org.apache.brooklyn.core.util.flags.SetFromFlag;
 +import org.apache.brooklyn.core.util.flags.TypeCoercions;
 +import org.slf4j.Logger;
 +import org.slf4j.LoggerFactory;
 +
- import brooklyn.basic.AbstractBrooklynObject;
- import brooklyn.basic.BrooklynObjectInternal;
++import org.apache.brooklyn.basic.AbstractBrooklynObject;
++import org.apache.brooklyn.basic.BrooklynObjectInternal;
 +import brooklyn.config.ConfigKey;
 +import brooklyn.config.ConfigKey.HasConfigKey;
 +import brooklyn.config.ConfigMap;
 +import brooklyn.enricher.basic.AbstractEnricher;
 +import brooklyn.entity.basic.ConfigKeys;
 +import brooklyn.entity.basic.Entities;
 +import brooklyn.entity.basic.EntityInternal;
 +import brooklyn.util.guava.Maybe;
 +import brooklyn.util.text.Strings;
 +
 +import com.google.common.annotations.Beta;
 +import com.google.common.base.Objects;
 +import com.google.common.base.Preconditions;
 +import com.google.common.collect.ImmutableSet;
 +import com.google.common.collect.Maps;
 +
 +
 +/**
 + * Common functionality for policies and enrichers
 + */
 +public abstract class AbstractEntityAdjunct extends AbstractBrooklynObject implements BrooklynObjectInternal, EntityAdjunct, Configurable {
 +    private static final Logger log = LoggerFactory.getLogger(AbstractEntityAdjunct.class);
 +
 +    private boolean _legacyNoConstructionInit;
 +
 +    /**
 +     * @deprecated since 0.7.0; leftover properties are put into config, since when coming from yaml this is normal.
 +     */
 +    @Deprecated
 +    protected Map<String,Object> leftoverProperties = Maps.newLinkedHashMap();
 +
 +    protected transient ExecutionContext execution;
 +
 +    private final BasicConfigurationSupport config = new BasicConfigurationSupport();
 +    
 +    /**
 +     * The config values of this entity. Updating this map should be done
 +     * via {@link #config()}.
 +     * 
 +     * @deprecated since 0.7.0; use {@link #config()} instead; this field may be made private or deleted in a future release.
 +     */
 +    @Deprecated
 +    protected final ConfigMapImpl configsInternal = new ConfigMapImpl(this);
 +
 +    /**
 +     * @deprecated since 0.7.0; use {@link #getAdjunctType()} instead; this field may be made private or deleted in a future release.
 +     */
 +    @Deprecated
 +    protected final AdjunctType adjunctType = new AdjunctType(this);
 +
 +    @SetFromFlag
 +    protected String name;
 +    
 +    protected transient EntityLocal entity;
 +    
 +    /** not for direct access; refer to as 'subscriptionTracker' via getter so that it is initialized */
 +    protected transient SubscriptionTracker _subscriptionTracker;
 +    
 +    private AtomicBoolean destroyed = new AtomicBoolean(false);
 +    
 +    @SetFromFlag(value="uniqueTag")
 +    protected String uniqueTag;
 +
 +    public AbstractEntityAdjunct() {
 +        this(Collections.emptyMap());
 +    }
 +    
 +    public AbstractEntityAdjunct(@SuppressWarnings("rawtypes") Map properties) {
 +        super(properties);
 +        _legacyNoConstructionInit = (properties != null) && Boolean.TRUE.equals(properties.get("noConstructionInit"));
 +        
 +        if (isLegacyConstruction()) {
 +            AbstractBrooklynObject checkWeGetThis = configure(properties);
 +            assert this.equals(checkWeGetThis) : this+" configure method does not return itself; returns "+checkWeGetThis+" instead of "+this;
 +
 +            boolean deferConstructionChecks = (properties.containsKey("deferConstructionChecks") && TypeCoercions.coerce(properties.get("deferConstructionChecks"), Boolean.class));
 +            if (!deferConstructionChecks) {
 +                FlagUtils.checkRequiredFields(this);
 +            }
 +        }
 +    }
 +
 +    /**
 +     * @deprecated since 0.7.0; only used for legacy brooklyn types where constructor is called directly
 +     */
 +    @Override
 +    @Deprecated
 +    @SuppressWarnings({ "unchecked", "rawtypes" })
 +    public AbstractEntityAdjunct configure(Map flags) {
 +        // TODO only set on first time through
 +        boolean isFirstTime = true;
 +        
 +        // allow config keys, and fields, to be set from these flags if they have a SetFromFlag annotation
 +        // or if the value is a config key
 +        for (Iterator<Map.Entry> iter = flags.entrySet().iterator(); iter.hasNext();) {
 +            Map.Entry entry = iter.next();
 +            if (entry.getKey() instanceof ConfigKey) {
 +                ConfigKey key = (ConfigKey)entry.getKey();
 +                if (adjunctType.getConfigKeys().contains(key)) {
 +                    setConfig(key, entry.getValue());
 +                } else {
 +                    log.warn("Unknown configuration key {} for policy {}; ignoring", key, this);
 +                    iter.remove();
 +                }
 +            }
 +        }
 +
 +        ConfigBag bag = new ConfigBag().putAll(flags);
 +        FlagUtils.setFieldsFromFlags(this, bag, isFirstTime);
 +        FlagUtils.setAllConfigKeys(this, bag, false);
 +        leftoverProperties.putAll(bag.getUnusedConfig());
 +
 +        //replace properties _contents_ with leftovers so subclasses see leftovers only
 +        flags.clear();
 +        flags.putAll(leftoverProperties);
 +        leftoverProperties = flags;
 +        
 +        if (!truth(name) && flags.containsKey("displayName")) {
 +            //TODO inconsistent with entity and location, where name is legacy and displayName is encouraged!
 +            //'displayName' is a legacy way to refer to a policy's name
 +            Preconditions.checkArgument(flags.get("displayName") instanceof CharSequence, "'displayName' property should be a string");
 +            setDisplayName(flags.remove("displayName").toString());
 +        }
 +        
 +        // set leftover flags should as config items; particularly useful when these have come from a brooklyn.config map 
 +        for (Object flag: flags.keySet()) {
 +            ConfigKey<Object> key = ConfigKeys.newConfigKey(Object.class, Strings.toString(flag));
 +            if (config().getRaw(key).isPresent()) {
 +                log.warn("Config '"+flag+"' on "+this+" conflicts with key already set; ignoring");
 +            } else {
 +                config().set(key, flags.get(flag));
 +            }
 +        }
 +        
 +        return this;
 +    }
 +    
 +    /**
 +     * Used for legacy-style policies/enrichers on rebind, to indicate that init() should not be called.
 +     * Will likely be deleted in a future release; should not be called apart from by framework code.
 +     */
 +    @Beta
 +    protected boolean isLegacyNoConstructionInit() {
 +        return _legacyNoConstructionInit;
 +    }
 +
 +    @Override
 +    public ConfigurationSupportInternal config() {
 +        return config;
 +    }
 +
 +    private class BasicConfigurationSupport implements ConfigurationSupportInternal {
 +
 +        @Override
 +        public <T> T get(ConfigKey<T> key) {
 +            return configsInternal.getConfig(key);
 +        }
 +
 +        @Override
 +        public <T> T get(HasConfigKey<T> key) {
 +            return get(key.getConfigKey());
 +        }
 +
 +        @SuppressWarnings("unchecked")
 +        @Override
 +        public <T> T set(ConfigKey<T> key, T val) {
 +            if (entity != null && isRunning()) {
 +                doReconfigureConfig(key, val);
 +            }
 +            T result = (T) configsInternal.setConfig(key, val);
 +            onChanged();
 +            return result;
 +        }
 +
 +        @Override
 +        public <T> T set(HasConfigKey<T> key, T val) {
 +            return setConfig(key.getConfigKey(), val);
 +        }
 +
 +        @SuppressWarnings("unchecked")
 +        @Override
 +        public <T> T set(ConfigKey<T> key, Task<T> val) {
 +            if (entity != null && isRunning()) {
 +                // TODO Support for AbstractEntityAdjunct
 +                throw new UnsupportedOperationException();
 +            }
 +            T result = (T) configsInternal.setConfig(key, val);
 +            onChanged();
 +            return result;
 +        }
 +
 +        @Override
 +        public <T> T set(HasConfigKey<T> key, Task<T> val) {
 +            return set(key.getConfigKey(), val);
 +        }
 +
 +        @Override
 +        public ConfigBag getBag() {
 +            return getLocalBag();
 +        }
 +
 +        @Override
 +        public ConfigBag getLocalBag() {
 +            return ConfigBag.newInstance(configsInternal.getAllConfig());
 +        }
 +
 +        @Override
 +        public Maybe<Object> getRaw(ConfigKey<?> key) {
 +            return configsInternal.getConfigRaw(key, true);
 +        }
 +
 +        @Override
 +        public Maybe<Object> getRaw(HasConfigKey<?> key) {
 +            return getRaw(key.getConfigKey());
 +        }
 +
 +        @Override
 +        public Maybe<Object> getLocalRaw(ConfigKey<?> key) {
 +            return configsInternal.getConfigRaw(key, false);
 +        }
 +
 +        @Override
 +        public Maybe<Object> getLocalRaw(HasConfigKey<?> key) {
 +            return getLocalRaw(key.getConfigKey());
 +        }
 +
 +        @Override
 +        public void addToLocalBag(Map<String, ?> vals) {
 +            configsInternal.addToLocalBag(vals);
 +        }
 +        
 +        @Override
 +        public void removeFromLocalBag(String key) {
 +            configsInternal.removeFromLocalBag(key);
 +        }
 +        
 +        @Override
 +        public void refreshInheritedConfig() {
 +            // no-op for location
 +        }
 +        
 +        @Override
 +        public void refreshInheritedConfigOfChildren() {
 +            // no-op for location
 +        }
 +    }
 +
 +    public <T> T getConfig(ConfigKey<T> key) {
 +        return config().get(key);
 +    }
 +    
 +    protected <K> K getRequiredConfig(ConfigKey<K> key) {
 +        K result = config().get(key);
 +        if (result==null) 
 +            throw new NullPointerException("Value required for '"+key.getName()+"' in "+this);
 +        return result;
 +    }
 +
 +    @Override
 +    @Deprecated
 +    public <T> T setConfig(ConfigKey<T> key, T val) {
 +        return config().set(key, val);
 +    }
 +    
 +    // TODO make immutable
 +    /** for inspection only */
 +    @Beta
 +    @Deprecated
 +    public ConfigMap getConfigMap() {
 +        return configsInternal;
 +    }
 +    
 +    /**
 +     * Invoked whenever a config change is applied after management is started.
 +     * Default implementation throws an exception to disallow the change. 
 +     * Can be overridden to return (allowing the change) or to make other changes 
 +     * (if necessary), and of course it can do this selectively and call the super to disallow any others. */
 +    protected <T> void doReconfigureConfig(ConfigKey<T> key, T val) {
 +        throw new UnsupportedOperationException("reconfiguring "+key+" unsupported for "+this);
 +    }
 +    
 +    @Override
 +    protected void onTagsChanged() {
 +        onChanged();
 +    }
 +    
 +    protected abstract void onChanged();
 +    
 +    protected AdjunctType getAdjunctType() {
 +        return adjunctType;
 +    }
 +    
 +    @Override
 +    public String getDisplayName() {
 +        if (name!=null && name.length()>0) return name;
 +        return getClass().getCanonicalName();
 +    }
 +    
 +    public void setDisplayName(String name) {
 +        this.name = name;
 +    }
 +
 +    public void setEntity(EntityLocal entity) {
 +        if (destroyed.get()) throw new IllegalStateException("Cannot set entity on a destroyed entity adjunct");
 +        this.entity = entity;
 +        if (entity!=null && getCatalogItemId() == null) {
 +            setCatalogItemId(entity.getCatalogItemId());
 +        }
 +    }
 +    
 +    /** @deprecated since 0.7.0 only {@link AbstractEnricher} has emit convenience */
 +    protected <T> void emit(Sensor<T> sensor, Object val) {
 +        checkState(entity != null, "entity must first be set");
 +        if (val == Entities.UNCHANGED) {
 +            return;
 +        }
 +        if (val == Entities.REMOVE) {
 +            ((EntityInternal)entity).removeAttribute((AttributeSensor<T>) sensor);
 +            return;
 +        }
 +        
 +        T newVal = TypeCoercions.coerce(val, sensor.getTypeToken());
 +        if (sensor instanceof AttributeSensor) {
 +            entity.setAttribute((AttributeSensor<T>)sensor, newVal);
 +        } else { 
 +            entity.emit(sensor, newVal);
 +        }
 +    }
 +
 +    protected synchronized SubscriptionTracker getSubscriptionTracker() {
 +        if (_subscriptionTracker!=null) return _subscriptionTracker;
 +        if (entity==null) return null;
 +        _subscriptionTracker = new SubscriptionTracker(((EntityInternal)entity).getManagementSupport().getSubscriptionContext());
 +        return _subscriptionTracker;
 +    }
 +    
 +    /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */
 +    protected <T> SubscriptionHandle subscribe(Entity producer, Sensor<T> sensor, SensorEventListener<? super T> listener) {
 +        if (!checkCanSubscribe()) return null;
 +        return getSubscriptionTracker().subscribe(producer, sensor, listener);
 +    }
 +
 +    /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */
 +    protected <T> SubscriptionHandle subscribeToMembers(Group producerGroup, Sensor<T> sensor, SensorEventListener<? super T> listener) {
 +        if (!checkCanSubscribe(producerGroup)) return null;
 +        return getSubscriptionTracker().subscribeToMembers(producerGroup, sensor, listener);
 +    }
 +
 +    /** @see SubscriptionContext#subscribe(Entity, Sensor, SensorEventListener) */
 +    protected <T> SubscriptionHandle subscribeToChildren(Entity producerParent, Sensor<T> sensor, SensorEventListener<? super T> listener) {
 +        if (!checkCanSubscribe(producerParent)) return null;
 +        return getSubscriptionTracker().subscribeToChildren(producerParent, sensor, listener);
 +    }
 +
 +    /** @deprecated since 0.7.0 use {@link #checkCanSubscribe(Entity)} */
 +    @Deprecated
 +    protected boolean check(Entity requiredEntity) {
 +        return checkCanSubscribe(requiredEntity);
 +    }
 +    /** returns false if deleted, throws exception if invalid state, otherwise true.
 +     * okay if entity is not yet managed (but not if entity is no longer managed). */
 +    protected boolean checkCanSubscribe(Entity producer) {
 +        if (destroyed.get()) return false;
 +        if (producer==null) throw new IllegalStateException(this+" given a null target for subscription");
 +        if (entity==null) throw new IllegalStateException(this+" cannot subscribe to "+producer+" because it is not associated to an entity");
 +        if (((EntityInternal)entity).getManagementSupport().isNoLongerManaged()) throw new IllegalStateException(this+" cannot subscribe to "+producer+" because the associated entity "+entity+" is no longer managed");
 +        return true;
 +    }
 +    protected boolean checkCanSubscribe() {
 +        if (destroyed.get()) return false;
 +        if (entity==null) throw new IllegalStateException(this+" cannot subscribe because it is not associated to an entity");
 +        if (((EntityInternal)entity).getManagementSupport().isNoLongerManaged()) throw new IllegalStateException(this+" cannot subscribe because the associated entity "+entity+" is no longer managed");
 +        return true;
 +    }
 +        
 +    /**
 +     * Unsubscribes the given producer.
 +     *
 +     * @see SubscriptionContext#unsubscribe(SubscriptionHandle)
 +     */
 +    protected boolean unsubscribe(Entity producer) {
 +        if (destroyed.get()) return false;
 +        return getSubscriptionTracker().unsubscribe(producer);
 +    }
 +
 +    /**
 +    * Unsubscribes the given producer.
 +    *
 +    * @see SubscriptionContext#unsubscribe(SubscriptionHandle)
 +    */
 +   protected boolean unsubscribe(Entity producer, SubscriptionHandle handle) {
 +       if (destroyed.get()) return false;
 +       return getSubscriptionTracker().unsubscribe(producer, handle);
 +   }
 +
 +    /**
 +    * @return a list of all subscription handles
 +    */
 +    protected Collection<SubscriptionHandle> getAllSubscriptions() {
 +        SubscriptionTracker tracker = getSubscriptionTracker();
 +        return (tracker != null) ? tracker.getAllSubscriptions() : Collections.<SubscriptionHandle>emptyList();
 +    }
 +    
 +    /** 
 +     * Unsubscribes and clears all managed subscriptions; is called by the owning entity when a policy is removed
 +     * and should always be called by any subclasses overriding this method
 +     */
 +    public void destroy() {
 +        destroyed.set(true);
 +        SubscriptionTracker tracker = getSubscriptionTracker();
 +        if (tracker != null) tracker.unsubscribeAll();
 +    }
 +    
 +    @Override
 +    public boolean isDestroyed() {
 +        return destroyed.get();
 +    }
 +    
 +    @Override
 +    public boolean isRunning() {
 +        return !isDestroyed();
 +    }
 +
 +    @Override
 +    public String getUniqueTag() {
 +        return uniqueTag;
 +    }
 +
 +    public TagSupport tags() {
 +        return new AdjunctTagSupport();
 +    }
 +
 +    public class AdjunctTagSupport extends BasicTagSupport {
 +        @Override
 +        public Set<Object> getTags() {
 +            ImmutableSet.Builder<Object> rb = ImmutableSet.builder().addAll(super.getTags());
 +            if (getUniqueTag()!=null) rb.add(getUniqueTag());
 +            return rb.build();
 +        }
 +        public String getUniqueTag() {
 +            return AbstractEntityAdjunct.this.getUniqueTag();
 +        }
 +        public void setUniqueTag(String uniqueTag) {
 +            AbstractEntityAdjunct.this.uniqueTag = uniqueTag;
 +        }
 +    }
 +
 +    @Override
 +    public String toString() {
 +        return Objects.toStringHelper(getClass()).omitNullValues()
 +                .add("name", name)
 +                .add("uniqueTag", uniqueTag)
 +                .add("running", isRunning())
 +                .add("entity", entity)
 +                .add("id", getId())
 +                .toString();
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyDynamicType.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyDynamicType.java
index 315d03d,0000000..a98aead
mode 100644,000000..100644
--- a/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyDynamicType.java
+++ b/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyDynamicType.java
@@@ -1,44 -1,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.policy.basic;
 +
 +import org.apache.brooklyn.api.policy.Policy;
 +import org.apache.brooklyn.api.policy.PolicyType;
 +
- import brooklyn.basic.BrooklynDynamicType;
++import org.apache.brooklyn.basic.BrooklynDynamicType;
 +
 +public class PolicyDynamicType extends BrooklynDynamicType<Policy, AbstractPolicy> {
 +
 +    public PolicyDynamicType(Class<? extends Policy> type) {
 +        super(type);
 +    }
 +    
 +    public PolicyDynamicType(AbstractPolicy policy) {
 +        super(policy);
 +    }
 +    
 +    public PolicyType getSnapshot() {
 +        return (PolicyType) super.getSnapshot();
 +    }
 +
 +    @Override
 +    protected PolicyTypeSnapshot newSnapshot() {
 +        return new PolicyTypeSnapshot(name, value(configKeys));
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyTypeSnapshot.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyTypeSnapshot.java
index 0e655b6,0000000..6604350
mode 100644,000000..100644
--- a/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyTypeSnapshot.java
+++ b/core/src/main/java/org/apache/brooklyn/core/policy/basic/PolicyTypeSnapshot.java
@@@ -1,40 -1,0 +1,40 @@@
 +/*
 + * Licensed to the Apache Software Foundation (ASF) under one
 + * or more contributor license agreements.  See the NOTICE file
 + * distributed with this work for additional information
 + * regarding copyright ownership.  The ASF licenses this file
 + * to you under the Apache License, Version 2.0 (the
 + * "License"); you may not use this file except in compliance
 + * with the License.  You may obtain a copy of the License at
 + *
 + *     http://www.apache.org/licenses/LICENSE-2.0
 + *
 + * Unless required by applicable law or agreed to in writing,
 + * software distributed under the License is distributed on an
 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 + * KIND, either express or implied.  See the License for the
 + * specific language governing permissions and limitations
 + * under the License.
 + */
 +package org.apache.brooklyn.core.policy.basic;
 +
 +import java.util.Map;
 +
 +import org.apache.brooklyn.api.policy.PolicyType;
 +
- import brooklyn.basic.BrooklynTypeSnapshot;
++import org.apache.brooklyn.basic.BrooklynTypeSnapshot;
 +import brooklyn.config.ConfigKey;
 +
 +public class PolicyTypeSnapshot extends BrooklynTypeSnapshot implements PolicyType {
 +    private static final long serialVersionUID = 4670930188951106009L;
 +    
 +    PolicyTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
 +        super(name, configKeys);
 +    }
 +
 +    @Override
 +    public boolean equals(Object obj) {
 +        if (this == obj) return true;
 +        return (obj instanceof PolicyTypeSnapshot) && super.equals(obj);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/location/basic/AbstractLocation.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
----------------------------------------------------------------------
diff --cc core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
index 4a444c7,0082b9a..5d2e18e
--- a/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
+++ b/core/src/main/java/org/apache/brooklyn/location/basic/LocationInternal.java
@@@ -24,9 -24,8 +24,9 @@@ import org.apache.brooklyn.api.entity.r
  import org.apache.brooklyn.api.location.Location;
  import org.apache.brooklyn.api.management.ManagementContext;
  import org.apache.brooklyn.api.mementos.LocationMemento;
 +import org.apache.brooklyn.core.util.config.ConfigBag;
  
- import brooklyn.basic.BrooklynObjectInternal;
+ import org.apache.brooklyn.basic.BrooklynObjectInternal;
  import brooklyn.config.ConfigInheritance;
  import brooklyn.config.ConfigKey;
  import brooklyn.entity.basic.ConfigKeys;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
----------------------------------------------------------------------
diff --cc usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
index 95c10a1,8cce298..7293abf
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/Main.java
@@@ -66,19 -65,8 +65,9 @@@ import org.apache.brooklyn.cli.CloudExp
  import org.apache.brooklyn.cli.CloudExplorer.ComputeListInstancesCommand;
  import org.apache.brooklyn.cli.CloudExplorer.ComputeTerminateInstancesCommand;
  import org.apache.brooklyn.cli.ItemLister.ListAllCommand;
- import org.apache.brooklyn.cli.CloudExplorer.BlobstoreGetBlobCommand;
- import org.apache.brooklyn.cli.CloudExplorer.BlobstoreListContainerCommand;
- import org.apache.brooklyn.cli.CloudExplorer.BlobstoreListContainersCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeDefaultTemplateCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeGetImageCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeListHardwareProfilesCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeListImagesCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeListInstancesCommand;
- import org.apache.brooklyn.cli.CloudExplorer.ComputeTerminateInstancesCommand;
- import org.apache.brooklyn.cli.ItemLister.ListAllCommand;
  import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
  import org.apache.brooklyn.core.management.ha.OsgiManager;
 +import org.apache.brooklyn.core.util.ResourceUtils;
  
  import brooklyn.entity.basic.AbstractApplication;
  import brooklyn.entity.basic.AbstractEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/qa/src/test/java/org/apache/brooklyn/qa/brooklynnode/SoftlayerObtainPrivateLiveTest.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/PolicyConfigResource.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f9b357d7/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------