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:25 UTC

[2/4] incubator-brooklyn git commit: [BROOKLYN-162] Renaming package brooklyn.basic at ./core

[BROOKLYN-162] Renaming package brooklyn.basic at ./core


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

Branch: refs/heads/master
Commit: e1a2d6686ed007077ef32876c15a74db1738f16f
Parents: 5ef0b61
Author: Ivana Yovcheva <iv...@gmail.com>
Authored: Mon Aug 17 15:54:46 2015 +0300
Committer: Ivana Yovcheva <iv...@gmail.com>
Committed: Mon Aug 17 15:54:46 2015 +0300

----------------------------------------------------------------------
 .../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 +-
 .../policy/basic/AbstractEntityAdjunct.java     |   4 +-
 .../policy/basic/PolicyDynamicType.java         |   2 +-
 .../policy/basic/PolicyTypeSnapshot.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  |   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, 1072 insertions(+), 1084 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java b/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
deleted file mode 100644
index c990ed9..0000000
--- a/core/src/main/java/brooklyn/basic/AbstractBrooklynObject.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.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.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/e1a2d668/core/src/main/java/brooklyn/basic/BasicConfigurableObject.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BasicConfigurableObject.java b/core/src/main/java/brooklyn/basic/BasicConfigurableObject.java
deleted file mode 100644
index d02f1bd..0000000
--- a/core/src/main/java/brooklyn/basic/BasicConfigurableObject.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.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 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/e1a2d668/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java b/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
deleted file mode 100644
index dbf8bbc..0000000
--- a/core/src/main/java/brooklyn/basic/BrooklynDynamicType.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.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.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/e1a2d668/core/src/main/java/brooklyn/basic/BrooklynObjectInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynObjectInternal.java b/core/src/main/java/brooklyn/basic/BrooklynObjectInternal.java
deleted file mode 100644
index 038013f..0000000
--- a/core/src/main/java/brooklyn/basic/BrooklynObjectInternal.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.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 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/e1a2d668/core/src/main/java/brooklyn/basic/BrooklynTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypeSnapshot.java b/core/src/main/java/brooklyn/basic/BrooklynTypeSnapshot.java
deleted file mode 100644
index 1d0ba73..0000000
--- a/core/src/main/java/brooklyn/basic/BrooklynTypeSnapshot.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.basic;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.basic.BrooklynType;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.util.text.Strings;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public class BrooklynTypeSnapshot implements BrooklynType {
-    private static final long serialVersionUID = 4670930188951106009L;
-    
-    private final String name;
-    private transient volatile String simpleName;
-    private final Map<String, ConfigKey<?>> configKeys;
-    private final Set<ConfigKey<?>> configKeysSet;
-
-    protected BrooklynTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
-        this.name = name;
-        this.configKeys = ImmutableMap.copyOf(configKeys);
-        this.configKeysSet = ImmutableSet.copyOf(this.configKeys.values());
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-    
-    private String toSimpleName(String name) {
-        String simpleName = name.substring(name.lastIndexOf(".")+1);
-        if (Strings.isBlank(simpleName)) simpleName = name.trim();
-        return Strings.makeValidFilename(simpleName);
-    }
-
-    @Override
-    public String getSimpleName() {
-        String sn = simpleName;
-        if (sn==null) {
-            sn = toSimpleName(getName());
-            simpleName = sn;
-        }
-        return sn;
-    }
-    
-    @Override
-    public Set<ConfigKey<?>> getConfigKeys() {
-        return configKeysSet;
-    }
-    
-    @Override
-    public ConfigKey<?> getConfigKey(String name) {
-        return configKeys.get(name);
-    }
-    
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(name, configKeys);
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (!(obj instanceof BrooklynTypeSnapshot)) return false;
-        BrooklynTypeSnapshot o = (BrooklynTypeSnapshot) obj;
-        
-        return Objects.equal(name, o.name) && Objects.equal(configKeys, o.configKeys);
-    }
-    
-    @Override
-    public String toString() {
-        return toStringHelper().toString();
-    }
-    
-    protected ToStringHelper toStringHelper() {
-        return Objects.toStringHelper(name)
-                .add("configKeys", configKeys);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/basic/BrooklynTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/BrooklynTypes.java b/core/src/main/java/brooklyn/basic/BrooklynTypes.java
deleted file mode 100644
index 64dbcd0..0000000
--- a/core/src/main/java/brooklyn/basic/BrooklynTypes.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.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 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/e1a2d668/core/src/main/java/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/basic/internal/ApiObjectsFactoryImpl.java b/core/src/main/java/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
deleted file mode 100644
index 8e0f5a4..0000000
--- a/core/src/main/java/brooklyn/basic/internal/ApiObjectsFactoryImpl.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.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 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/e1a2d668/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java b/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java
index 0604941..1645a23 100644
--- a/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java
+++ b/core/src/main/java/brooklyn/enricher/basic/EnricherDynamicType.java
@@ -21,7 +21,7 @@ package brooklyn.enricher.basic;
 import org.apache.brooklyn.api.policy.Enricher;
 import org.apache.brooklyn.api.policy.EnricherType;
 
-import brooklyn.basic.BrooklynDynamicType;
+import org.apache.brooklyn.basic.BrooklynDynamicType;
 
 public class EnricherDynamicType extends BrooklynDynamicType<Enricher, AbstractEnricher> {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java b/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java
index a8d240d..547831a 100644
--- a/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java
+++ b/core/src/main/java/brooklyn/enricher/basic/EnricherTypeSnapshot.java
@@ -22,7 +22,7 @@ import java.util.Map;
 
 import org.apache.brooklyn.api.policy.EnricherType;
 
-import brooklyn.basic.BrooklynTypeSnapshot;
+import org.apache.brooklyn.basic.BrooklynTypeSnapshot;
 import brooklyn.config.ConfigKey;
 
 public class EnricherTypeSnapshot extends BrooklynTypeSnapshot implements EnricherType {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
index 1d21a7e..ee429b2 100644
--- a/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
+++ b/core/src/main/java/brooklyn/entity/basic/AbstractEntity.java
@@ -64,7 +64,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.basic.AbstractBrooklynObject;
+import org.apache.brooklyn.basic.AbstractBrooklynObject;
 import brooklyn.config.BrooklynLogging;
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/basic/Entities.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/Entities.java b/core/src/main/java/brooklyn/entity/basic/Entities.java
index c768726..00aabd7 100644
--- a/core/src/main/java/brooklyn/entity/basic/Entities.java
+++ b/core/src/main/java/brooklyn/entity/basic/Entities.java
@@ -67,7 +67,7 @@ import org.apache.brooklyn.core.management.internal.NonDeploymentManagementConte
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.basic.BrooklynObjectInternal;
+import org.apache.brooklyn.basic.BrooklynObjectInternal;
 import brooklyn.config.BrooklynProperties;
 import brooklyn.config.ConfigKey;
 import brooklyn.config.ConfigKey.HasConfigKey;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java b/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
index 6477485..794fdaf 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
@@ -33,7 +33,7 @@ import org.apache.brooklyn.api.event.Sensor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.basic.BrooklynDynamicType;
+import org.apache.brooklyn.basic.BrooklynDynamicType;
 import brooklyn.config.ConfigKey.HasConfigKey;
 import brooklyn.entity.effector.EffectorAndBody;
 import brooklyn.entity.effector.EffectorBody;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java b/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
index 085079f..f7fa53f 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityInternal.java
@@ -34,7 +34,7 @@ import org.apache.brooklyn.api.management.SubscriptionContext;
 import org.apache.brooklyn.api.mementos.EntityMemento;
 import org.apache.brooklyn.core.management.internal.EntityManagementSupport;
 
-import brooklyn.basic.BrooklynObjectInternal;
+import org.apache.brooklyn.basic.BrooklynObjectInternal;
 import brooklyn.config.ConfigKey;
 import brooklyn.util.config.ConfigBag;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java b/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java
index ab6b239..dddecf6 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityTypeSnapshot.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.api.entity.EntityType;
 import org.apache.brooklyn.api.entity.ParameterType;
 import org.apache.brooklyn.api.event.Sensor;
 
-import brooklyn.basic.BrooklynTypeSnapshot;
+import org.apache.brooklyn.basic.BrooklynTypeSnapshot;
 import brooklyn.config.ConfigKey;
 import brooklyn.util.guava.Maybe;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/basic/EntityTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityTypes.java b/core/src/main/java/brooklyn/entity/basic/EntityTypes.java
index 9970538..77620f8 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityTypes.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityTypes.java
@@ -18,7 +18,7 @@
  */
 package brooklyn.entity.basic;
 
-import brooklyn.basic.BrooklynTypes;
+import org.apache.brooklyn.basic.BrooklynTypes;
 
 /**
  * @deprecated since 0.7.0; use {@link BrooklynTypes}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
index 19a6cd6..f3eca47 100644
--- a/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
+++ b/core/src/main/java/brooklyn/entity/rebind/AbstractBrooklynObjectRebindSupport.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.api.policy.EntityAdjunct;
 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;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/rebind/ActivePartialRebindIteration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/ActivePartialRebindIteration.java b/core/src/main/java/brooklyn/entity/rebind/ActivePartialRebindIteration.java
index c1d2576..f0a0d25 100644
--- a/core/src/main/java/brooklyn/entity/rebind/ActivePartialRebindIteration.java
+++ b/core/src/main/java/brooklyn/entity/rebind/ActivePartialRebindIteration.java
@@ -37,7 +37,7 @@ import org.apache.brooklyn.api.mementos.BrooklynMementoRawData.Builder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.basic.BrooklynObjectInternal;
+import org.apache.brooklyn.basic.BrooklynObjectInternal;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.rebind.persister.BrooklynMementoPersisterToObjectStore;
 import brooklyn.entity.rebind.persister.PersistenceActivityMetrics;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
index 5a0a97a..bb1241e 100644
--- a/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/ImmediateDeltaChangeListener.java
@@ -21,7 +21,7 @@ package brooklyn.entity.rebind;
 import java.util.Collection;
 import java.util.Map;
 
-import brooklyn.basic.BrooklynObjectInternal;
+import org.apache.brooklyn.basic.BrooklynObjectInternal;
 
 import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.catalog.CatalogItem;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
index d204ecc..6e1e09f 100644
--- a/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
+++ b/core/src/main/java/brooklyn/entity/rebind/PeriodicDeltaChangeListener.java
@@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.basic.BrooklynObjectInternal;
+import org.apache.brooklyn.basic.BrooklynObjectInternal;
 
 import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.catalog.CatalogItem;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
index 1164fff..f2ddfb2 100644
--- a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
+++ b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java
@@ -33,8 +33,8 @@ import java.util.concurrent.atomic.AtomicInteger;
 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 org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.catalog.BrooklynCatalog;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java b/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
index 2e80444..204148d 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/BasicEntityMemento.java
@@ -35,11 +35,10 @@ import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.basic.BrooklynTypes;
+import org.apache.brooklyn.basic.BrooklynTypes;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Sanitizer;
 import brooklyn.event.basic.Sensors;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
index dbe6e26..5399159 100644
--- a/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/brooklyn/entity/rebind/dto/MementosGenerators.java
@@ -25,7 +25,7 @@ import java.lang.reflect.Proxy;
 import java.util.Map;
 import java.util.Set;
 
-import brooklyn.basic.BrooklynTypes;
+import org.apache.brooklyn.basic.BrooklynTypes;
 
 import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.catalog.CatalogItem;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
index 68074e9..63945c3 100644
--- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
+++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynPersistenceUtils.java
@@ -23,7 +23,7 @@ import java.util.List;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import brooklyn.basic.BrooklynObjectInternal;
+import org.apache.brooklyn.basic.BrooklynObjectInternal;
 
 import org.apache.brooklyn.api.basic.BrooklynObject;
 import org.apache.brooklyn.api.catalog.CatalogItem;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
index ab303a0..96be1af 100644
--- a/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
+++ b/core/src/main/java/brooklyn/policy/basic/AbstractEntityAdjunct.java
@@ -44,8 +44,8 @@ import org.apache.brooklyn.core.management.internal.SubscriptionTracker;
 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;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java b/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java
index b6d3c6d..98e334a 100644
--- a/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java
+++ b/core/src/main/java/brooklyn/policy/basic/PolicyDynamicType.java
@@ -21,7 +21,7 @@ package brooklyn.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> {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java b/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java
index b6d2f33..66f8194 100644
--- a/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java
+++ b/core/src/main/java/brooklyn/policy/basic/PolicyTypeSnapshot.java
@@ -22,7 +22,7 @@ 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 {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e1a2d668/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java b/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
new file mode 100644
index 0000000..260c91b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/basic/AbstractBrooklynObject.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.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.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/e1a2d668/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java b/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
new file mode 100644
index 0000000..f376d74
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/basic/BasicConfigurableObject.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.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 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);
+        }
+    }
+}