You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/02/01 18:51:07 UTC

[25/51] [abbrv] [partial] brooklyn-server git commit: move subdir from incubator up a level as it is promoted to its own repo (first non-incubator commit!)

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
deleted file mode 100644
index 41a0a9c..0000000
--- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ /dev/null
@@ -1,1073 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.catalog.BrooklynCatalog;
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
-import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
-import org.apache.brooklyn.core.catalog.CatalogPredicates;
-import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
-import org.apache.brooklyn.core.location.BasicLocationRegistry;
-import org.apache.brooklyn.core.mgmt.internal.CampYamlParser;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.typereg.BrooklynTypePlanTransformer;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.collections.MutableSet;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.javalang.AggregateClassLoader;
-import org.apache.brooklyn.util.javalang.LoadedClassLoader;
-import org.apache.brooklyn.util.text.Strings;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-import org.apache.brooklyn.util.yaml.Yamls;
-import org.apache.brooklyn.util.yaml.Yamls.YamlExtract;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.yaml.snakeyaml.Yaml;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSortedSet;
-import com.google.common.collect.Iterables;
-
-/* TODO the complex tree-structured catalogs are only useful when we are relying on those separate catalog classloaders
- * to isolate classpaths. with osgi everything is just put into the "manual additions" catalog. */
-public class BasicBrooklynCatalog implements BrooklynCatalog {
-    public static final String POLICIES_KEY = "brooklyn.policies";
-    public static final String LOCATIONS_KEY = "brooklyn.locations";
-    public static final String NO_VERSION = "0.0.0.SNAPSHOT";
-
-    private static final Logger log = LoggerFactory.getLogger(BasicBrooklynCatalog.class);
-
-    public static class BrooklynLoaderTracker {
-        public static final ThreadLocal<BrooklynClassLoadingContext> loader = new ThreadLocal<BrooklynClassLoadingContext>();
-        
-        public static void setLoader(BrooklynClassLoadingContext val) {
-            loader.set(val);
-        }
-        
-        // TODO Stack, for recursive calls?
-        public static void unsetLoader(BrooklynClassLoadingContext val) {
-            loader.set(null);
-        }
-        
-        public static BrooklynClassLoadingContext getLoader() {
-            return loader.get();
-        }
-    }
-
-    private final ManagementContext mgmt;
-    private CatalogDo catalog;
-    private volatile CatalogDo manualAdditionsCatalog;
-    private volatile LoadedClassLoader manualAdditionsClasses;
-    private final AggregateClassLoader rootClassLoader = AggregateClassLoader.newInstanceWithNoLoaders();
-
-    public BasicBrooklynCatalog(ManagementContext mgmt) {
-        this(mgmt, CatalogDto.newNamedInstance("empty catalog", "empty catalog", "empty catalog, expected to be reset later"));
-    }
-
-    public BasicBrooklynCatalog(ManagementContext mgmt, CatalogDto dto) {
-        this.mgmt = checkNotNull(mgmt, "managementContext");
-        this.catalog = new CatalogDo(mgmt, dto);
-    }
-
-    public boolean blockIfNotLoaded(Duration timeout) {
-        try {
-            return getCatalog().blockIfNotLoaded(timeout);
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-    
-    public void reset(CatalogDto dto) {
-        reset(dto, true);
-    }
-
-    public void reset(CatalogDto dto, boolean failOnLoadError) {
-        // Unregister all existing persisted items.
-        for (CatalogItem<?, ?> toRemove : getCatalogItems()) {
-            if (log.isTraceEnabled()) {
-                log.trace("Scheduling item for persistence removal: {}", toRemove.getId());
-            }
-            mgmt.getRebindManager().getChangeListener().onUnmanaged(toRemove);
-        }
-        CatalogDo catalog = new CatalogDo(mgmt, dto);
-        CatalogUtils.logDebugOrTraceIfRebinding(log, "Resetting "+this+" catalog to "+dto);
-        catalog.load(mgmt, null, failOnLoadError);
-        CatalogUtils.logDebugOrTraceIfRebinding(log, "Reloaded catalog for "+this+", now switching");
-        this.catalog = catalog;
-        resetRootClassLoader();
-        this.manualAdditionsCatalog = null;
-
-        // Inject management context into and persist all the new entries.
-        for (CatalogItem<?, ?> entry : getCatalogItems()) {
-            boolean setManagementContext = false;
-            if (entry instanceof CatalogItemDo) {
-                CatalogItemDo<?, ?> cid = CatalogItemDo.class.cast(entry);
-                if (cid.getDto() instanceof CatalogItemDtoAbstract) {
-                    CatalogItemDtoAbstract<?, ?> cdto = CatalogItemDtoAbstract.class.cast(cid.getDto());
-                    if (cdto.getManagementContext() == null) {
-                        cdto.setManagementContext((ManagementContextInternal) mgmt);
-                    }
-                    setManagementContext = true;
-                }
-            }
-            if (!setManagementContext) {
-                log.warn("Can't set management context on entry with unexpected type in catalog. type={}, " +
-                        "expected={}", entry, CatalogItemDo.class);
-            }
-            if (log.isTraceEnabled()) {
-                log.trace("Scheduling item for persistence addition: {}", entry.getId());
-            }
-            mgmt.getRebindManager().getChangeListener().onManaged(entry);
-        }
-
-    }
-
-    /**
-     * Resets the catalog to the given entries
-     */
-    @Override
-    public void reset(Collection<CatalogItem<?, ?>> entries) {
-        CatalogDto newDto = CatalogDto.newDtoFromCatalogItems(entries, "explicit-catalog-reset");
-        reset(newDto);
-    }
-    
-    public CatalogDo getCatalog() {
-        return catalog;
-    }
-
-    protected CatalogItemDo<?,?> getCatalogItemDo(String symbolicName, String version) {
-        String fixedVersionId = getFixedVersionId(symbolicName, version);
-        if (fixedVersionId == null) {
-            //no items with symbolicName exist
-            return null;
-        }
-
-        return catalog.getIdCache().get( CatalogUtils.getVersionedId(symbolicName, fixedVersionId) );
-    }
-    
-    private String getFixedVersionId(String symbolicName, String version) {
-        if (version!=null && !DEFAULT_VERSION.equals(version)) {
-            return version;
-        } else {
-            return getBestVersion(symbolicName);
-        }
-    }
-
-    /** returns best version, as defined by {@link BrooklynCatalog#getCatalogItem(String, String)} */
-    private String getBestVersion(String symbolicName) {
-        Iterable<CatalogItem<Object, Object>> versions = getCatalogItems(Predicates.and(
-                CatalogPredicates.disabled(false),
-                CatalogPredicates.symbolicName(Predicates.equalTo(symbolicName))));
-        Collection<CatalogItem<Object, Object>> orderedVersions = sortVersionsDesc(versions);
-        if (!orderedVersions.isEmpty()) {
-            return orderedVersions.iterator().next().getVersion();
-        } else {
-            return null;
-        }
-    }
-
-    private <T,SpecT> Collection<CatalogItem<T,SpecT>> sortVersionsDesc(Iterable<CatalogItem<T,SpecT>> versions) {
-        return ImmutableSortedSet.orderedBy(CatalogItemComparator.<T,SpecT>getInstance()).addAll(versions).build();
-    }
-
-    @Override
-    public CatalogItem<?,?> getCatalogItem(String symbolicName, String version) {
-        if (symbolicName == null) return null;
-        checkNotNull(version, "version");
-        CatalogItemDo<?, ?> itemDo = getCatalogItemDo(symbolicName, version);
-        if (itemDo == null) return null;
-        return itemDo.getDto();
-    }
-    
-    @Override
-    public void deleteCatalogItem(String symbolicName, String version) {
-        log.debug("Deleting manual catalog item from "+mgmt+": "+symbolicName + ":" + version);
-        checkNotNull(symbolicName, "id");
-        checkNotNull(version, "version");
-        if (DEFAULT_VERSION.equals(version)) {
-            throw new IllegalStateException("Deleting items with unspecified version (argument DEFAULT_VERSION) not supported.");
-        }
-        CatalogItem<?, ?> item = getCatalogItem(symbolicName, version);
-        CatalogItemDtoAbstract<?,?> itemDto = getAbstractCatalogItem(item);
-        if (itemDto == null) {
-            throw new NoSuchElementException("No catalog item found with id "+symbolicName);
-        }
-        if (manualAdditionsCatalog==null) loadManualAdditionsCatalog();
-        manualAdditionsCatalog.deleteEntry(itemDto);
-        
-        // Ensure the cache is de-populated
-        getCatalog().deleteEntry(itemDto);
-
-        // And indicate to the management context that it should be removed.
-        if (log.isTraceEnabled()) {
-            log.trace("Scheduling item for persistence removal: {}", itemDto.getId());
-        }
-        if (itemDto.getCatalogItemType() == CatalogItemType.LOCATION) {
-            @SuppressWarnings("unchecked")
-            CatalogItem<Location,LocationSpec<?>> locationItem = (CatalogItem<Location, LocationSpec<?>>) itemDto;
-            ((BasicLocationRegistry)mgmt.getLocationRegistry()).removeDefinedLocation(locationItem);
-        }
-        mgmt.getRebindManager().getChangeListener().onUnmanaged(itemDto);
-
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public <T,SpecT> CatalogItem<T,SpecT> getCatalogItem(Class<T> type, String id, String version) {
-        if (id==null || version==null) return null;
-        CatalogItem<?,?> result = getCatalogItem(id, version);
-        if (result==null) return null;
-        if (type==null || type.isAssignableFrom(result.getCatalogItemJavaType())) 
-            return (CatalogItem<T,SpecT>)result;
-        return null;
-    }
-
-    @Override
-    public void persist(CatalogItem<?, ?> catalogItem) {
-        checkArgument(getCatalogItem(catalogItem.getSymbolicName(), catalogItem.getVersion()) != null, "Unknown catalog item %s", catalogItem);
-        mgmt.getRebindManager().getChangeListener().onChanged(catalogItem);
-    }
-    
-    @Override
-    public ClassLoader getRootClassLoader() {
-        if (rootClassLoader.isEmpty() && catalog!=null) {
-            resetRootClassLoader();
-        }
-        return rootClassLoader;
-    }
-
-    private void resetRootClassLoader() {
-        rootClassLoader.reset(ImmutableList.of(catalog.getRootClassLoader()));
-    }
-
-    /**
-     * Loads this catalog. No effect if already loaded.
-     */
-    public void load() {
-        log.debug("Loading catalog for " + mgmt);
-        getCatalog().load(mgmt, null);
-        if (log.isDebugEnabled()) {
-            log.debug("Loaded catalog for " + mgmt + ": " + catalog + "; search classpath is " + catalog.getRootClassLoader());
-        }
-    }
-
-    @Override
-    public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createSpec(CatalogItem<T, SpecT> item) {
-        if (item == null) return null;
-        @SuppressWarnings("unchecked")
-        CatalogItemDo<T,SpecT> loadedItem = (CatalogItemDo<T, SpecT>) getCatalogItemDo(item.getSymbolicName(), item.getVersion());
-        if (loadedItem == null) throw new RuntimeException(item+" not in catalog; cannot create spec");
-        if (loadedItem.getSpecType()==null) return null;
-
-        SpecT spec = internalCreateSpecLegacy(mgmt, loadedItem, MutableSet.<String>of(), true);
-        if (spec != null) {
-            return spec;
-        }
-
-        throw new IllegalStateException("No known mechanism to create instance of "+item);
-    }
-    
-    /** @deprecated since introduction in 0.9.0, only used for backwards compatibility, can be removed any time;
-     * uses the type-creation info on the item.
-     * deprecated transformers must be included by routines which don't use {@link BrooklynTypePlanTransformer} instances;
-     * otherwise deprecated transformers should be excluded. (deprecation is taken as equivalent to having a new-style transformer.) */
-    @Deprecated 
-    public static <T,SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT internalCreateSpecLegacy(ManagementContext mgmt, final CatalogItem<T, SpecT> item, final Set<String> encounteredTypes, boolean includeDeprecatedTransformers) {
-        // deprecated lookup
-        if (encounteredTypes.contains(item.getSymbolicName())) {
-            throw new IllegalStateException("Type being resolved '"+item.getSymbolicName()+"' has already been encountered in " + encounteredTypes + "; recursive cycle detected");
-        }
-        Maybe<SpecT> specMaybe = org.apache.brooklyn.core.plan.PlanToSpecFactory.attemptWithLoaders(mgmt, includeDeprecatedTransformers, new Function<org.apache.brooklyn.core.plan.PlanToSpecTransformer, SpecT>() {
-            @Override
-            public SpecT apply(org.apache.brooklyn.core.plan.PlanToSpecTransformer input) {
-                return input.createCatalogSpec(item, encounteredTypes);
-            }
-        });
-        return specMaybe.get();
-    }
-
-    @Deprecated /** @deprecated since 0.7.0 only used by other deprecated items */ 
-    private <T,SpecT> CatalogItemDtoAbstract<T,SpecT> getAbstractCatalogItem(CatalogItem<T,SpecT> item) {
-        while (item instanceof CatalogItemDo) item = ((CatalogItemDo<T,SpecT>)item).itemDto;
-        if (item==null) return null;
-        if (item instanceof CatalogItemDtoAbstract) return (CatalogItemDtoAbstract<T,SpecT>) item;
-        throw new IllegalStateException("Cannot unwrap catalog item '"+item+"' (type "+item.getClass()+") to restore DTO");
-    }
-    
-    @SuppressWarnings("unchecked")
-    private static <T> Maybe<T> getFirstAs(Map<?,?> map, Class<T> type, String firstKey, String ...otherKeys) {
-        if (map==null) return Maybe.absent("No map available");
-        String foundKey = null;
-        Object value = null;
-        if (map.containsKey(firstKey)) foundKey = firstKey;
-        else for (String key: otherKeys) {
-            if (map.containsKey(key)) {
-                foundKey = key;
-                break;
-            }
-        }
-        if (foundKey==null) return Maybe.absent("Missing entry '"+firstKey+"'");
-        value = map.get(foundKey);
-        if (type.equals(String.class) && Number.class.isInstance(value)) value = value.toString();
-        if (!type.isInstance(value)) 
-            throw new IllegalArgumentException("Entry for '"+firstKey+"' should be of type "+type+", not "+value.getClass());
-        return Maybe.of((T)value);
-    }
-    
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    private Maybe<Map<?,?>> getFirstAsMap(Map<?,?> map, String firstKey, String ...otherKeys) {
-        return (Maybe<Map<?,?>>)(Maybe) getFirstAs(map, Map.class, firstKey, otherKeys);
-    }
-
-    private List<CatalogItemDtoAbstract<?,?>> collectCatalogItems(String yaml) {
-        Map<?,?> itemDef = Yamls.getAs(Yamls.parseAll(yaml), Map.class);
-        Map<?,?> catalogMetadata = getFirstAsMap(itemDef, "brooklyn.catalog").orNull();
-        if (catalogMetadata==null)
-            log.warn("No `brooklyn.catalog` supplied in catalog request; using legacy mode for "+itemDef);
-        catalogMetadata = MutableMap.copyOf(catalogMetadata);
-
-        List<CatalogItemDtoAbstract<?, ?>> result = MutableList.of();
-        
-        collectCatalogItems(Yamls.getTextOfYamlAtPath(yaml, "brooklyn.catalog").getMatchedYamlTextOrWarn(), 
-            catalogMetadata, result, null);
-        
-        itemDef.remove("brooklyn.catalog");
-        catalogMetadata.remove("item");
-        catalogMetadata.remove("items");
-        if (!itemDef.isEmpty()) {
-            log.debug("Reading brooklyn.catalog peer keys as item ('top-level syntax')");
-            Map<String,?> rootItem = MutableMap.of("item", itemDef);
-            String rootItemYaml = yaml;
-            YamlExtract yamlExtract = Yamls.getTextOfYamlAtPath(rootItemYaml, "brooklyn.catalog");
-            String match = yamlExtract.withOriginalIndentation(true).withKeyIncluded(true).getMatchedYamlTextOrWarn();
-            if (match!=null) {
-                if (rootItemYaml.startsWith(match)) rootItemYaml = Strings.removeFromStart(rootItemYaml, match);
-                else rootItemYaml = Strings.replaceAllNonRegex(rootItemYaml, "\n"+match, "");
-            }
-            collectCatalogItems("item:\n"+makeAsIndentedObject(rootItemYaml), rootItem, result, catalogMetadata);
-        }
-        
-        return result;
-    }
-
-    @SuppressWarnings("unchecked")
-    private void collectCatalogItems(String sourceYaml, Map<?,?> itemMetadata, List<CatalogItemDtoAbstract<?, ?>> result, Map<?,?> parentMetadata) {
-
-        if (sourceYaml==null) sourceYaml = new Yaml().dump(itemMetadata);
-
-        Map<?, ?> itemMetadataWithoutItemDef = MutableMap.builder()
-                .putAll(itemMetadata)
-                .remove("item")
-                .remove("items")
-                .build();
-        
-        // Parse CAMP-YAML DSL in item metadata (but not in item or items - those will be parsed only when used). 
-        CampYamlParser parser = mgmt.getConfig().getConfig(CampYamlParser.YAML_PARSER_KEY);
-        if (parser != null) {
-            itemMetadataWithoutItemDef = parser.parse((Map<String, Object>) itemMetadataWithoutItemDef);
-            try {
-                itemMetadataWithoutItemDef = (Map<String, Object>) Tasks.resolveDeepValue(itemMetadataWithoutItemDef, Object.class, mgmt.getServerExecutionContext());
-            } catch (Exception e) {
-                throw Exceptions.propagate(e);
-            }
-            
-        } else {
-            log.info("No Camp-YAML parser regsitered for parsing catalog item DSL; skipping DSL-parsing");
-        }
-
-        Map<Object,Object> catalogMetadata = MutableMap.<Object, Object>builder()
-                .putAll(parentMetadata)
-                .putAll(itemMetadataWithoutItemDef)
-                .putIfNotNull("item", itemMetadata.get("item"))
-                .putIfNotNull("items", itemMetadata.get("items"))
-                .build();
-
-        // brooklyn.libraries we treat specially, to append the list, with the child's list preferred in classloading order
-        // `libraries` is supported in some places as a legacy syntax; it should always be `brooklyn.libraries` for new apps
-        // TODO in 0.8.0 require brooklyn.libraries, don't allow "libraries" on its own
-        List<?> librariesNew = MutableList.copyOf(getFirstAs(itemMetadataWithoutItemDef, List.class, "brooklyn.libraries", "libraries").orNull());
-        Collection<CatalogBundle> libraryBundlesNew = CatalogItemDtoAbstract.parseLibraries(librariesNew);
-
-        List<?> librariesCombined = MutableList.copyOf(librariesNew)
-            .appendAll(getFirstAs(parentMetadata, List.class, "brooklyn.libraries", "libraries").orNull());
-        if (!librariesCombined.isEmpty())
-            catalogMetadata.put("brooklyn.libraries", librariesCombined);
-        Collection<CatalogBundle> libraryBundles = CatalogItemDtoAbstract.parseLibraries(librariesCombined);
-
-        // TODO as this may take a while if downloading, the REST call should be async
-        // (this load is required for the scan below and I think also for yaml resolution)
-        CatalogUtils.installLibraries(mgmt, libraryBundlesNew);
-
-        Boolean scanJavaAnnotations = getFirstAs(itemMetadataWithoutItemDef, Boolean.class, "scanJavaAnnotations", "scan_java_annotations").orNull();
-        if (scanJavaAnnotations==null || !scanJavaAnnotations) {
-            // don't scan
-        } else {
-            // scan for annotations: if libraries here, scan them; if inherited libraries error; else scan classpath
-            if (!libraryBundlesNew.isEmpty()) {
-                result.addAll(scanAnnotationsFromBundles(mgmt, libraryBundlesNew, catalogMetadata));
-            } else if (libraryBundles.isEmpty()) {
-                result.addAll(scanAnnotationsFromLocal(mgmt, catalogMetadata));
-            } else {
-                throw new IllegalStateException("Cannot scan catalog node no local bundles, and with inherited bundles we will not scan the classpath");
-            }
-        }
-        
-        Object items = catalogMetadata.remove("items");
-        Object item = catalogMetadata.remove("item");
-
-        if (items!=null) {
-            int count = 0;
-            for (Map<?,?> i: ((List<Map<?,?>>)items)) {
-                collectCatalogItems(Yamls.getTextOfYamlAtPath(sourceYaml, "items", count).getMatchedYamlTextOrWarn(),
-                        i, result, catalogMetadata);
-                count++;
-            }
-        }
-        
-        if (item==null) return;
-
-        // now look at the actual item, first correcting the sourceYaml and interpreting the catalog metadata
-        String itemYaml = Yamls.getTextOfYamlAtPath(sourceYaml, "item").getMatchedYamlTextOrWarn();
-        if (itemYaml!=null) sourceYaml = itemYaml;
-        else sourceYaml = new Yaml().dump(item);
-        
-        CatalogItemType itemType = TypeCoercions.coerce(getFirstAs(catalogMetadata, Object.class, "itemType", "item_type").orNull(), CatalogItemType.class);
-
-        String id = getFirstAs(catalogMetadata, String.class, "id").orNull();
-        String version = getFirstAs(catalogMetadata, String.class, "version").orNull();
-        String symbolicName = getFirstAs(catalogMetadata, String.class, "symbolicName").orNull();
-        String displayName = getFirstAs(catalogMetadata, String.class, "displayName").orNull();
-        String name = getFirstAs(catalogMetadata, String.class, "name").orNull();
-
-        if ((Strings.isNonBlank(id) || Strings.isNonBlank(symbolicName)) && 
-                Strings.isNonBlank(displayName) &&
-                Strings.isNonBlank(name) && !name.equals(displayName)) {
-            log.warn("Name property will be ignored due to the existence of displayName and at least one of id, symbolicName");
-        }
-
-        PlanInterpreterGuessingType planInterpreter = new PlanInterpreterGuessingType(null, item, sourceYaml, itemType, libraryBundles, result).reconstruct();
-        if (!planInterpreter.isResolved()) {
-            throw Exceptions.create("Could not resolve item"
-                + (Strings.isNonBlank(id) ? " '"+id+"'" : Strings.isNonBlank(symbolicName) ? " '"+symbolicName+"'" : Strings.isNonBlank(name) ? " '"+name+"'" : "")
-                // better not to show yaml, takes up lots of space, and with multiple plan transformers there might be multiple errors; 
-                // some of the errors themselves may reproduce it
-                // (ideally in future we'll be able to return typed errors with caret position of error)
-//                + ":\n"+sourceYaml
-                , planInterpreter.getErrors());
-        }
-        itemType = planInterpreter.getCatalogItemType();
-        Map<?, ?> itemAsMap = planInterpreter.getItem();
-        // the "plan yaml" includes the services: ... or brooklyn.policies: ... outer key,
-        // as opposed to the rawer { type: xxx } map without that outer key which is valid as item input
-        // TODO this plan yaml is needed for subsequent reconstruction; would be nicer if it weren't! 
-
-        // if symname not set, infer from: id, then name, then item id, then item name
-        if (Strings.isBlank(symbolicName)) {
-            if (Strings.isNonBlank(id)) {
-                if (CatalogUtils.looksLikeVersionedId(id)) {
-                    symbolicName = CatalogUtils.getSymbolicNameFromVersionedId(id);
-                } else {
-                    symbolicName = id;
-                }
-            } else if (Strings.isNonBlank(name)) {
-                if (CatalogUtils.looksLikeVersionedId(name)) {
-                    symbolicName = CatalogUtils.getSymbolicNameFromVersionedId(name);
-                } else {
-                    symbolicName = name;
-                }
-            } else {
-                symbolicName = setFromItemIfUnset(symbolicName, itemAsMap, "id");
-                symbolicName = setFromItemIfUnset(symbolicName, itemAsMap, "name");
-                // TODO we should let the plan transformer give us this
-                symbolicName = setFromItemIfUnset(symbolicName, itemAsMap, "template_name");
-                if (Strings.isBlank(symbolicName)) {
-                    log.error("Can't infer catalog item symbolicName from the following plan:\n" + sourceYaml);
-                    throw new IllegalStateException("Can't infer catalog item symbolicName from catalog item metadata");
-                }
-            }
-        }
-
-        // if version not set, infer from: id, then from name, then item version
-        if (CatalogUtils.looksLikeVersionedId(id)) {
-            String versionFromId = CatalogUtils.getVersionFromVersionedId(id);
-            if (versionFromId != null && Strings.isNonBlank(version) && !versionFromId.equals(version)) {
-                throw new IllegalArgumentException("Discrepency between version set in id " + versionFromId + " and version property " + version);
-            }
-            version = versionFromId;
-        }
-        if (Strings.isBlank(version)) {
-            if (CatalogUtils.looksLikeVersionedId(name)) {
-                version = CatalogUtils.getVersionFromVersionedId(name);
-            } else if (Strings.isBlank(version)) {
-                version = setFromItemIfUnset(version, itemAsMap, "version");
-                version = setFromItemIfUnset(version, itemAsMap, "template_version");
-                if (version==null) {
-                    log.warn("No version specified for catalog item " + symbolicName + ". Using default value.");
-                    version = null;
-                }
-            }
-        }
-        
-        // if not set, ID can come from symname:version, failing that, from the plan.id, failing that from the sym name
-        if (Strings.isBlank(id)) {
-            // let ID be inferred, especially from name, to support style where only "name" is specified, with inline version
-            if (Strings.isNonBlank(symbolicName) && Strings.isNonBlank(version)) {
-                id = symbolicName + ":" + version;
-            }
-            id = setFromItemIfUnset(id, itemAsMap, "id");
-            if (Strings.isBlank(id)) {
-                if (Strings.isNonBlank(symbolicName)) {
-                    id = symbolicName;
-                } else {
-                    log.error("Can't infer catalog item id from the following plan:\n" + sourceYaml);
-                    throw new IllegalStateException("Can't infer catalog item id from catalog item metadata");
-                }
-            }
-        }
-
-        if (Strings.isBlank(displayName)) {
-            if (Strings.isNonBlank(name)) displayName = name;
-            displayName = setFromItemIfUnset(displayName, itemAsMap, "name");
-        }
-
-        String description = getFirstAs(catalogMetadata, String.class, "description").orNull();
-        description = setFromItemIfUnset(description, itemAsMap, "description");
-
-        // icon.url is discouraged, but kept for legacy compatibility; should deprecate this
-        final String catalogIconUrl = getFirstAs(catalogMetadata, String.class, "iconUrl", "icon_url", "icon.url").orNull();
-
-        final String deprecated = getFirstAs(catalogMetadata, String.class, "deprecated").orNull();
-        final Boolean catalogDeprecated = Boolean.valueOf(deprecated);
-
-        // run again now that we know the ID
-        planInterpreter = new PlanInterpreterGuessingType(id, item, sourceYaml, itemType, libraryBundles, result).reconstruct();
-        if (!planInterpreter.isResolved()) {
-            throw new IllegalStateException("Could not resolve plan once id and itemType are known (recursive reference?): "+sourceYaml);
-        }
-        String sourcePlanYaml = planInterpreter.getPlanYaml();
-
-        CatalogItemDtoAbstract<?, ?> dto = createItemBuilder(itemType, symbolicName, version)
-            .libraries(libraryBundles)
-            .displayName(displayName)
-            .description(description)
-            .deprecated(catalogDeprecated)
-            .iconUrl(catalogIconUrl)
-            .plan(sourcePlanYaml)
-            .build();
-
-        dto.setManagementContext((ManagementContextInternal) mgmt);
-        result.add(dto);
-    }
-
-    private String setFromItemIfUnset(String oldValue, Map<?,?> item, String fieldAttr) {
-        if (Strings.isNonBlank(oldValue)) return oldValue;
-        if (item!=null) {
-            Object newValue = item.get(fieldAttr);
-            if (newValue instanceof String && Strings.isNonBlank((String)newValue)) 
-                return (String)newValue;
-        }
-        return oldValue;
-    }
-
-    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromLocal(ManagementContext mgmt, Map<?, ?> catalogMetadata) {
-        CatalogDto dto = CatalogDto.newNamedInstance("Local Scanned Catalog", "All annotated Brooklyn entities detected in the classpath", "scanning-local-classpath");
-        return scanAnnotationsInternal(mgmt, new CatalogDo(dto), catalogMetadata);
-    }
-    
-    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsFromBundles(ManagementContext mgmt, Collection<CatalogBundle> libraries, Map<?, ?> catalogMetadata) {
-        CatalogDto dto = CatalogDto.newNamedInstance("Bundles Scanned Catalog", "All annotated Brooklyn entities detected in bundles", "scanning-bundles-classpath-"+libraries.hashCode());
-        List<String> urls = MutableList.of();
-        for (CatalogBundle b: libraries) {
-            // TODO currently does not support pre-installed bundles identified by name:version 
-            // (ie where URL not supplied)
-            if (Strings.isNonBlank(b.getUrl())) {
-                urls.add(b.getUrl());
-            }
-        }
-        
-        if (urls.isEmpty()) {
-            log.warn("No bundles to scan: scanJavaAnnotations currently only applies to OSGi bundles provided by URL"); 
-            return MutableList.of();
-        }
-        
-        CatalogDo subCatalog = new CatalogDo(dto);
-        subCatalog.addToClasspath(urls.toArray(new String[0]));
-        return scanAnnotationsInternal(mgmt, subCatalog, catalogMetadata);
-    }
-    
-    private Collection<CatalogItemDtoAbstract<?, ?>> scanAnnotationsInternal(ManagementContext mgmt, CatalogDo subCatalog, Map<?, ?> catalogMetadata) {
-        // TODO this does java-scanning only;
-        // the call when scanning bundles should use the CatalogItem instead and use OSGi when loading for scanning
-        // (or another scanning mechanism).  see comments on CatalogClasspathDo.load
-        subCatalog.mgmt = mgmt;
-        subCatalog.setClasspathScanForEntities(CatalogScanningModes.ANNOTATIONS);
-        subCatalog.load();
-        // TODO apply metadata?  (extract YAML from the items returned)
-        // also see doc .../catalog/index.md which says we might not apply metadata
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-        Collection<CatalogItemDtoAbstract<?, ?>> result = (Collection<CatalogItemDtoAbstract<?, ?>>)(Collection)Collections2.transform(
-                (Collection<CatalogItemDo<Object,Object>>)(Collection)subCatalog.getIdCache().values(), 
-                itemDoToDtoAddingSelectedMetadataDuringScan(catalogMetadata));
-        return result;
-    }
-
-    private class PlanInterpreterGuessingType {
-
-        final String id;
-        final Map<?,?> item;
-        final String itemYaml;
-        final Collection<CatalogBundle> libraryBundles;
-        final List<CatalogItemDtoAbstract<?, ?>> itemsDefinedSoFar;
-        
-        CatalogItemType catalogItemType;
-        String planYaml;
-        boolean resolved = false;
-        List<Exception> errors = MutableList.of();
-        List<Exception> entityErrors = MutableList.of();
-        
-        public PlanInterpreterGuessingType(@Nullable String id, Object item, String itemYaml, @Nullable CatalogItemType optionalCiType, 
-                Collection<CatalogBundle> libraryBundles, List<CatalogItemDtoAbstract<?,?>> itemsDefinedSoFar) {
-            // ID is useful to prevent recursive references (possibly only supported for entities?)
-            this.id = id;
-            
-            if (item instanceof String) {
-                // if just a string supplied, wrap as map
-                this.item = MutableMap.of("type", item);
-                this.itemYaml = "type:\n"+makeAsIndentedObject(itemYaml);                
-            } else {
-                this.item = (Map<?,?>)item;
-                this.itemYaml = itemYaml;
-            }
-            this.catalogItemType = optionalCiType;
-            this.libraryBundles = libraryBundles;
-            this.itemsDefinedSoFar = itemsDefinedSoFar;
-        }
-
-        public PlanInterpreterGuessingType reconstruct() {
-            if (catalogItemType==CatalogItemType.TEMPLATE) {
-                // template *must* be explicitly defined, and if so, none of the other calls apply
-                attemptType(null, CatalogItemType.TEMPLATE);
-                
-            } else {
-                attemptType(null, CatalogItemType.ENTITY);
-
-                attemptType("services", CatalogItemType.ENTITY);
-                attemptType(POLICIES_KEY, CatalogItemType.POLICY);
-                attemptType(LOCATIONS_KEY, CatalogItemType.LOCATION);
-            }
-            
-            if (!resolved && catalogItemType==CatalogItemType.TEMPLATE) {
-                // anything goes, for an explicit template, because we can't easily recurse into the types
-                planYaml = itemYaml;
-                resolved = true;
-            }
-            
-            return this;
-        }
-
-        public boolean isResolved() { return resolved; }
-        
-        /** Returns potentially useful errors encountered while guessing types. 
-         * May only be available where the type is known. */
-        public List<Exception> getErrors() {
-            if (errors.isEmpty()) return entityErrors;
-            return errors;
-        }
-        
-        public CatalogItemType getCatalogItemType() {
-            return catalogItemType; 
-        }
-        
-        public String getPlanYaml() {
-            return planYaml;
-        }
-        
-        private boolean attemptType(String key, CatalogItemType candidateCiType) {
-            if (resolved) return false;
-            if (catalogItemType!=null && catalogItemType!=candidateCiType) return false;
-            
-            final String candidateYaml;
-            if (key==null) candidateYaml = itemYaml;
-            else {
-                if (item.containsKey(key))
-                    candidateYaml = itemYaml;
-                else
-                    candidateYaml = key + ":\n" + makeAsIndentedList(itemYaml);
-            }
-            // first look in collected items, if a key is given
-            String type = (String) item.get("type");
-            String version = null;
-            if (CatalogUtils.looksLikeVersionedId(type)) {
-                version = CatalogUtils.getVersionFromVersionedId(type);
-                type = CatalogUtils.getSymbolicNameFromVersionedId(type);
-            }
-            if (type!=null && key!=null) {
-                for (CatalogItemDtoAbstract<?,?> candidate: itemsDefinedSoFar) {
-                    if (candidateCiType == candidate.getCatalogItemType() &&
-                            (type.equals(candidate.getSymbolicName()) || type.equals(candidate.getId()))) {
-                        if (version==null || version.equals(candidate.getVersion())) {
-                            // matched - exit
-                            catalogItemType = candidateCiType;
-                            planYaml = candidateYaml;
-                            resolved = true;
-                            return true;
-                        }
-                    }
-                }
-            }
-            
-            // then try parsing plan - this will use loader
-            try {
-                @SuppressWarnings("rawtypes")
-                CatalogItem itemToAttempt = createItemBuilder(candidateCiType, getIdWithRandomDefault(), DEFAULT_VERSION)
-                    .plan(candidateYaml)
-                    .libraries(libraryBundles)
-                    .build();
-                @SuppressWarnings("unchecked")
-                AbstractBrooklynObjectSpec<?, ?> spec = internalCreateSpecLegacy(mgmt, itemToAttempt, MutableSet.<String>of(), true);
-                if (spec!=null) {
-                    catalogItemType = candidateCiType;
-                    planYaml = candidateYaml;
-                    resolved = true;
-                }
-                return true;
-            } catch (Exception e) {
-                Exceptions.propagateIfFatal(e);
-                // record the error if we have reason to expect this guess to succeed
-                if (item.containsKey("services") && (candidateCiType==CatalogItemType.ENTITY || candidateCiType==CatalogItemType.TEMPLATE)) {
-                    // explicit services supplied, so plan should have been parseable for an entity or a a service
-                    errors.add(e);
-                } else if (catalogItemType!=null && key!=null) {
-                    // explicit itemType supplied, so plan should be parseable in the cases where we're given a key
-                    // (when we're not given a key, the previous block should apply)
-                    errors.add(e);
-                } else {
-                    // all other cases, the error is probably due to us not getting the type right, probably ignore it
-                    // but cache it if we've checked entity, we'll use that as fallback errors
-                    if (candidateCiType==CatalogItemType.ENTITY) {
-                        entityErrors.add(e);
-                    }
-                    if (log.isTraceEnabled())
-                        log.trace("Guessing type of plan, it looks like it isn't "+candidateCiType+"/"+key+": "+e);
-                }
-            }
-            
-            // finally try parsing a cut-down plan, in case there is a nested reference to a newly defined catalog item
-            if (type!=null && key!=null) {
-                try {
-                    String cutDownYaml = key + ":\n" + makeAsIndentedList("type: "+type);
-                    @SuppressWarnings("rawtypes")
-                    CatalogItem itemToAttempt = createItemBuilder(candidateCiType, getIdWithRandomDefault(), DEFAULT_VERSION)
-                            .plan(cutDownYaml)
-                            .libraries(libraryBundles)
-                            .build();
-                    @SuppressWarnings("unchecked")
-                    AbstractBrooklynObjectSpec<?, ?> cutdownSpec = internalCreateSpecLegacy(mgmt, itemToAttempt, MutableSet.<String>of(), true);
-                    if (cutdownSpec!=null) {
-                        catalogItemType = candidateCiType;
-                        planYaml = candidateYaml;
-                        resolved = true;
-                    }
-                    return true;
-                } catch (Exception e) {
-                    Exceptions.propagateIfFatal(e);
-                }
-            }
-            // FIXME we should lookup type in the catalog on its own, then infer the type from that,
-            // and give proper errors (right now e.g. if there are no transformers then we bail out 
-            // with very little information)
-            
-            return false;
-        }
-
-        private String getIdWithRandomDefault() {
-            return id != null ? id : Strings.makeRandomId(10);
-        }
-        public Map<?,?> getItem() {
-            return item;
-        }
-    }
-    
-    private String makeAsIndentedList(String yaml) {
-        String[] lines = yaml.split("\n");
-        lines[0] = "- "+lines[0];
-        for (int i=1; i<lines.length; i++)
-            lines[i] = "  " + lines[i];
-        return Strings.join(lines, "\n");
-    }
-
-    private String makeAsIndentedObject(String yaml) {
-        String[] lines = yaml.split("\n");
-        for (int i=0; i<lines.length; i++)
-            lines[i] = "  " + lines[i];
-        return Strings.join(lines, "\n");
-    }
-
-    static CatalogItemBuilder<?> createItemBuilder(CatalogItemType itemType, String symbolicName, String version) {
-        return CatalogItemBuilder.newItem(itemType, symbolicName, version);
-    }
-
-    // these kept as their logic may prove useful; Apr 2015
-//    private boolean isApplicationSpec(EntitySpec<?> spec) {
-//        return !Boolean.TRUE.equals(spec.getConfig().get(EntityManagementUtils.WRAPPER_APP_MARKER));
-//    }
-//
-//    private boolean isEntityPlan(DeploymentPlan plan) {
-//        return plan!=null && !plan.getServices().isEmpty() || !plan.getArtifacts().isEmpty();
-//    }
-//    
-//    private boolean isPolicyPlan(DeploymentPlan plan) {
-//        return !isEntityPlan(plan) && plan.getCustomAttributes().containsKey(POLICIES_KEY);
-//    }
-//
-//    private boolean isLocationPlan(DeploymentPlan plan) {
-//        return !isEntityPlan(plan) && plan.getCustomAttributes().containsKey(LOCATIONS_KEY);
-//    }
-
-    //------------------------
-    
-    @Override
-    public CatalogItem<?,?> addItem(String yaml) {
-        return addItem(yaml, false);
-    }
-
-    @Override
-    public List<? extends CatalogItem<?,?>> addItems(String yaml) {
-        return addItems(yaml, false);
-    }
-
-    @Override
-    public CatalogItem<?,?> addItem(String yaml, boolean forceUpdate) {
-        return Iterables.getOnlyElement(addItems(yaml, forceUpdate));
-    }
-    
-    @Override
-    public List<? extends CatalogItem<?,?>> addItems(String yaml, boolean forceUpdate) {
-        log.debug("Adding manual catalog item to "+mgmt+": "+yaml);
-        checkNotNull(yaml, "yaml");
-        List<CatalogItemDtoAbstract<?, ?>> result = collectCatalogItems(yaml);
-
-        // do this at the end for atomic updates; if there are intra-yaml references, we handle them specially
-        for (CatalogItemDtoAbstract<?, ?> item: result) {
-            addItemDto(item, forceUpdate);
-        }
-        return result;
-    }
-    
-    private CatalogItem<?,?> addItemDto(CatalogItemDtoAbstract<?, ?> itemDto, boolean forceUpdate) {
-        CatalogItem<?, ?> existingDto = checkItemAllowedAndIfSoReturnAnyDuplicate(itemDto, true, forceUpdate);
-        if (existingDto!=null) {
-            // it's a duplicate, and not forced, just return it
-            log.trace("Using existing duplicate for catalog item {}", itemDto.getId());
-            return existingDto;
-        }
-
-        if (manualAdditionsCatalog==null) loadManualAdditionsCatalog();
-        manualAdditionsCatalog.addEntry(itemDto);
-
-        // Ensure the cache is populated and it is persisted by the management context
-        getCatalog().addEntry(itemDto);
-
-        // Request that the management context persist the item.
-        if (log.isTraceEnabled()) {
-            log.trace("Scheduling item for persistence addition: {}", itemDto.getId());
-        }
-        if (itemDto.getCatalogItemType() == CatalogItemType.LOCATION) {
-            @SuppressWarnings("unchecked")
-            CatalogItem<Location,LocationSpec<?>> locationItem = (CatalogItem<Location, LocationSpec<?>>) itemDto;
-            ((BasicLocationRegistry)mgmt.getLocationRegistry()).updateDefinedLocation(locationItem);
-        }
-        mgmt.getRebindManager().getChangeListener().onManaged(itemDto);
-
-        return itemDto;
-    }
-
-    /** returns item DTO if item is an allowed duplicate, or null if it should be added (there is no duplicate), 
-     * throwing if item cannot be added */
-    private CatalogItem<?, ?> checkItemAllowedAndIfSoReturnAnyDuplicate(CatalogItem<?,?> itemDto, boolean allowDuplicates, boolean forceUpdate) {
-        if (forceUpdate) return null;
-        CatalogItemDo<?, ?> existingItem = getCatalogItemDo(itemDto.getSymbolicName(), itemDto.getVersion());
-        if (existingItem == null) return null;
-        // check if they are equal
-        CatalogItem<?, ?> existingDto = existingItem.getDto();
-        if (existingDto.equals(itemDto)) {
-            if (allowDuplicates) return existingItem;
-            throw new IllegalStateException("Updating existing catalog entries, even with the same content, is forbidden: " +
-                    itemDto.getSymbolicName() + ":" + itemDto.getVersion() + ". Use forceUpdate argument to override.");
-        } else {
-            throw new IllegalStateException("Updating existing catalog entries is forbidden: " +
-                    itemDto.getSymbolicName() + ":" + itemDto.getVersion() + ". Use forceUpdate argument to override.");
-        }
-    }
-
-    @Override @Deprecated /** @deprecated see super */
-    public void addItem(CatalogItem<?,?> item) {
-        //assume forceUpdate for backwards compatibility
-        log.debug("Adding manual catalog item to "+mgmt+": "+item);
-        checkNotNull(item, "item");
-        CatalogUtils.installLibraries(mgmt, item.getLibraries());
-        if (manualAdditionsCatalog==null) loadManualAdditionsCatalog();
-        manualAdditionsCatalog.addEntry(getAbstractCatalogItem(item));
-    }
-
-    @Override @Deprecated /** @deprecated see super */
-    public CatalogItem<?,?> addItem(Class<?> type) {
-        //assume forceUpdate for backwards compatibility
-        log.debug("Adding manual catalog item to "+mgmt+": "+type);
-        checkNotNull(type, "type");
-        if (manualAdditionsCatalog==null) loadManualAdditionsCatalog();
-        manualAdditionsClasses.addClass(type);
-        return manualAdditionsCatalog.classpath.addCatalogEntry(type);
-    }
-
-    private synchronized void loadManualAdditionsCatalog() {
-        if (manualAdditionsCatalog!=null) return;
-        CatalogDto manualAdditionsCatalogDto = CatalogDto.newNamedInstance(
-                "Manual Catalog Additions", "User-additions to the catalog while Brooklyn is running, " +
-                "created "+Time.makeDateString(),
-                "manual-additions");
-        CatalogDo manualAdditionsCatalog = catalog.addCatalog(manualAdditionsCatalogDto);
-        if (manualAdditionsCatalog==null) {
-            // not hard to support, but slightly messy -- probably have to use ID's to retrieve the loaded instance
-            // for now block once, then retry
-            log.warn("Blocking until catalog is loaded before changing it");
-            boolean loaded = blockIfNotLoaded(Duration.TEN_SECONDS);
-            if (!loaded)
-                log.warn("Catalog still not loaded after delay; subsequent operations may fail");
-            manualAdditionsCatalog = catalog.addCatalog(manualAdditionsCatalogDto);
-            if (manualAdditionsCatalog==null) {
-                throw new UnsupportedOperationException("Catalogs cannot be added until the base catalog is loaded, and catalog is taking a while to load!");
-            }
-        }
-        
-        log.debug("Creating manual additions catalog for "+mgmt+": "+manualAdditionsCatalog);
-        manualAdditionsClasses = new LoadedClassLoader();
-        ((AggregateClassLoader)manualAdditionsCatalog.classpath.getLocalClassLoader()).addFirst(manualAdditionsClasses);
-        
-        // expose when we're all done
-        this.manualAdditionsCatalog = manualAdditionsCatalog;
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @Override
-    public <T,SpecT> Iterable<CatalogItem<T,SpecT>> getCatalogItems() {
-        if (!getCatalog().isLoaded()) {
-            // some callers use this to force the catalog to load (maybe when starting as hot_backup without a catalog ?)
-            log.debug("Forcing catalog load on access of catalog items");
-            load();
-        }
-        return ImmutableList.copyOf((Iterable)catalog.getIdCache().values());
-    }
-    
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    @Override
-    public <T,SpecT> Iterable<CatalogItem<T,SpecT>> getCatalogItems(Predicate<? super CatalogItem<T,SpecT>> filter) {
-        Iterable<CatalogItemDo<T,SpecT>> filtered = Iterables.filter((Iterable)catalog.getIdCache().values(), (Predicate<CatalogItem<T,SpecT>>)(Predicate) filter);
-        return Iterables.transform(filtered, BasicBrooklynCatalog.<T,SpecT>itemDoToDto());
-    }
-
-    private static <T,SpecT> Function<CatalogItemDo<T,SpecT>, CatalogItem<T,SpecT>> itemDoToDto() {
-        return new Function<CatalogItemDo<T,SpecT>, CatalogItem<T,SpecT>>() {
-            @Override
-            public CatalogItem<T,SpecT> apply(@Nullable CatalogItemDo<T,SpecT> item) {
-                if (item==null) return null;
-                return item.getDto();
-            }
-        };
-    }
-    
-    private static <T,SpecT> Function<CatalogItemDo<T, SpecT>, CatalogItem<T,SpecT>> itemDoToDtoAddingSelectedMetadataDuringScan(final Map<?, ?> catalogMetadata) {
-        return new Function<CatalogItemDo<T,SpecT>, CatalogItem<T,SpecT>>() {
-            @Override
-            public CatalogItem<T,SpecT> apply(@Nullable CatalogItemDo<T,SpecT> item) {
-                if (item==null) return null;
-                CatalogItemDtoAbstract<T, SpecT> dto = (CatalogItemDtoAbstract<T, SpecT>) item.getDto();
-
-                // when scanning we only allow version and libraries to be overwritten
-                
-                String version = getFirstAs(catalogMetadata, String.class, "version").orNull();
-                if (Strings.isNonBlank(version)) dto.setVersion(version);
-                
-                Object librariesCombined = catalogMetadata.get("brooklyn.libraries");
-                if (librariesCombined instanceof Collection) {
-                    // will be set by scan -- slightly longwinded way to retrieve, but scanning for osgi needs an overhaul in any case
-                    Collection<CatalogBundle> libraryBundles = CatalogItemDtoAbstract.parseLibraries((Collection<?>) librariesCombined);
-                    dto.setLibraries(libraryBundles);
-                }
-                // replace java type with plan yaml -- needed for libraries / catalog item to be picked up,
-                // but probably useful to transition away from javaType altogether
-                dto.setSymbolicName(dto.getJavaType());
-                switch (dto.getCatalogItemType()) {
-                    case TEMPLATE:
-                    case ENTITY:
-                        dto.setPlanYaml("services: [{ type: "+dto.getJavaType()+" }]");
-                        break;
-                    case POLICY:
-                        dto.setPlanYaml(POLICIES_KEY + ": [{ type: "+dto.getJavaType()+" }]");
-                        break;
-                    case LOCATION:
-                        dto.setPlanYaml(LOCATIONS_KEY + ": [{ type: "+dto.getJavaType()+" }]");
-                        break;
-                }
-                dto.setJavaType(null);
-
-                return dto;
-            }
-        };
-    }
-
-    transient CatalogXmlSerializer serializer;
-    
-    public String toXmlString() {
-        if (serializer==null) loadSerializer();
-        return serializer.toString(catalog.dto);
-    }
-    
-    private synchronized void loadSerializer() {
-        if (serializer==null) 
-            serializer = new CatalogXmlSerializer();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleConverter.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleConverter.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleConverter.java
deleted file mode 100644
index 79b39c3..0000000
--- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleConverter.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import com.thoughtworks.xstream.converters.Converter;
-import com.thoughtworks.xstream.converters.MarshallingContext;
-import com.thoughtworks.xstream.converters.UnmarshallingContext;
-import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
-import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
-import com.thoughtworks.xstream.io.HierarchicalStreamReader;
-import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
-import com.thoughtworks.xstream.mapper.Mapper;
-
-
-/**
- *  Convert old-style catalog.xml file formats to the latest version.
- *  The code is needed only during transition to the new version, can be removed after a while.
- */
-@Deprecated
-public class CatalogBundleConverter implements Converter {
-
-    private ReflectionConverter delegateConverter;
-
-    public CatalogBundleConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
-        this.delegateConverter = new ReflectionConverter(mapper, reflectionProvider);
-    }
-
-    @Override
-    public boolean canConvert(@SuppressWarnings("rawtypes") Class type) {
-        return type == CatalogBundleDto.class;
-    }
-
-    @Override
-    public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
-        context.convertAnother(source, delegateConverter);
-    }
-
-    @Override
-    public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
-        if (reader.hasMoreChildren()) {
-            return context.convertAnother(context.currentObject(), CatalogBundleDto.class, delegateConverter);
-        } else {
-            return new CatalogBundleDto(null, null, reader.getValue());
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java
deleted file mode 100644
index d3ce7ac..0000000
--- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
-
-public class CatalogBundleDto implements CatalogBundle {
-    private String symbolicName;
-    private String version;
-    private String url;
-
-    public CatalogBundleDto() {}
-
-    public CatalogBundleDto(String name, String version, String url) {
-        if (name == null && version == null) {
-            Preconditions.checkNotNull(url, "url to an OSGi bundle is required");
-        } else {
-            Preconditions.checkNotNull(name, "both name and version are required");
-            Preconditions.checkNotNull(version, "both name and version are required");
-        }
-
-        this.symbolicName = name;
-        this.version = version;
-        this.url = url;
-    }
-
-    @Override
-    public boolean isNameResolved() {
-        return symbolicName != null && version != null;
-    }
-    
-    @Override
-    public boolean isNamed() { return isNameResolved(); }
-
-    @Override
-    public String getSymbolicName() {
-        return symbolicName;
-    }
-
-    @Override
-    public String getVersion() {
-        return version;
-    }
-
-    @Override
-    public String getUrl() {
-        return url;
-    }
-
-    @Override
-    public String toString() {
-        return Objects.toStringHelper(this)
-                .add("symbolicName", symbolicName)
-                .add("version", version)
-                .add("url", url)
-                .toString();
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(symbolicName, version, url);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        CatalogBundleDto other = (CatalogBundleDto) obj;
-        if (!Objects.equal(symbolicName, other.symbolicName)) return false;
-        if (!Objects.equal(version, other.version)) return false;
-        if (!Objects.equal(url, other.url)) return false;
-        return true;
-    }
-    
-    
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
deleted file mode 100644
index d183c7e..0000000
--- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDo.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.catalog.Catalog;
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.entity.Application;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.policy.Policy;
-import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
-import org.apache.brooklyn.core.mgmt.BrooklynTags;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.util.core.ResourceUtils;
-import org.apache.brooklyn.util.core.javalang.ReflectionScanner;
-import org.apache.brooklyn.util.core.javalang.UrlClassLoader;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.javalang.AggregateClassLoader;
-import org.apache.brooklyn.util.os.Os;
-import org.apache.brooklyn.util.stream.Streams;
-import org.apache.brooklyn.util.text.Strings;
-import org.apache.brooklyn.util.time.Time;
-import org.apache.commons.lang3.ClassUtils;
-import org.reflections.util.ClasspathHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.Iterables;
-
-public class CatalogClasspathDo {
-
-    public static enum CatalogScanningModes {
-        /** the classpath is not scanned; 
-         * for any catalog which is presented over the internet this is recommended (to prevent loading) and is the default; 
-         * (you should explicitly list the items to include; it may be useful to autogenerate it by using a local catalog
-         * scanning with ANNOTATIONS, viwing that by running mgmt.getCatalog().toXmlString(),
-         * then editing the resulting XML (e.g. setting the classpath and removing the scan attribute) */
-        NONE, 
-        
-        /** types in the classpath are scanned for annotations indicating inclusion in the catalog ({@link Catalog});
-         * this is the default if no catalog is supplied, scanning the local classpath */
-        ANNOTATIONS,
-        
-        @Beta
-        /** all catalog-friendly types are included, 
-         * even if not annotated for inclusion in the catalog; useful for quick hacking,
-         * or a classpath (and possibly in future a regex, if added) which is known to have only good things in it;
-         * however the precise semantics of what is included is subject to change,
-         * and it is strongly recommended to use the {@link Catalog} annotation and scan for annotations 
-         * <p>
-         * a catalog-friendly type is currently defined as:
-         * any concrete non-anonymous (and not a non-static inner) class implementing Entity or Policy;
-         * and additionally for entities and applications, an interface with the {@link ImplementedBy} annotation;
-         * note that this means classes done "properly" with both an interface and an implementation
-         * will be included twice, once as interface and once as implementation;
-         * this guarantees inclusion of anything previously included (implementations; 
-         * and this will be removed from catalog in future likely),
-         * plus things now done properly (which will become the only way in the future)
-         **/
-        TYPES
-    }
-    
-    private static final Logger log = LoggerFactory.getLogger(CatalogClasspathDo.class);
-    
-    private final CatalogDo catalog;
-    private final CatalogClasspathDto classpath;
-    private final CatalogScanningModes scanMode;
-    
-    boolean isLoaded = false;
-    private URL[] urls;
-    
-    private final AggregateClassLoader classloader = AggregateClassLoader.newInstanceWithNoLoaders();
-    private volatile boolean classloaderLoaded = false;
-
-    public CatalogClasspathDo(CatalogDo catalog) {
-        this.catalog = Preconditions.checkNotNull(catalog, "catalog");
-        this.classpath = catalog.dto.classpath;
-        this.scanMode = (classpath != null) ? classpath.scan : null;
-    }
-    
-    /** causes all scanning-based classpaths to scan the classpaths
-    * (but does _not_ load all JARs) */
-    // TODO this does a Java scan; we also need an OSGi scan which uses the OSGi classloaders when loading for scanning and resolving dependencies 
-    synchronized void load() {
-        if (classpath == null || isLoaded) return;
-
-        if (classpath.getEntries() == null) {
-            urls = new URL[0];
-        } else {
-            urls = new URL[classpath.getEntries().size()];
-            for (int i=0; i<urls.length; i++) {
-                try {
-                    String u = classpath.getEntries().get(i);
-                    if (u.startsWith("classpath:")) {
-                        // special support for classpath: url's
-                        // TODO put convenience in ResourceUtils for extracting to a normal url
-                        // (or see below)
-                        InputStream uin = ResourceUtils.create(this).getResourceFromUrl(u);
-                        File f = Os.newTempFile("brooklyn-catalog-"+u, null);
-                        FileOutputStream fout = new FileOutputStream(f);
-                        try {
-                            Streams.copy(uin, fout);
-                        } finally {
-                            Streams.closeQuietly(fout);
-                            Streams.closeQuietly(uin);
-                        }
-                        u = f.toURI().toString();
-                    }
-                    urls[i] = new URL(u);
-                    
-                    // TODO potential disk leak above as we have no way to know when the temp file can be removed earlier than server shutdown;
-                    // a better way to handle this is to supply a stream handler (but URLConnection is a little bit hard to work with):
-//                    urls[i] = new URL(null, classpath.getEntries().get(i)   // (handy construtor for reparsing urls, without splitting into uri first)
-//                        , new URLStreamHandler() {
-//                            @Override
-//                            protected URLConnection openConnection(URL u) throws IOException {
-//                                new ResourceUtils(null). ???
-//                            }
-//                        });
-                } catch (Exception e) {
-                    Exceptions.propagateIfFatal(e);
-                    log.error("Error loading URL "+classpath.getEntries().get(i)+" in definition of catalog "+catalog+"; skipping definition");
-                    throw Exceptions.propagate(e);
-                }
-            }
-        }
-        
-        // prefix is supported (but not really used yet) --
-        // seems to have _better_ URL-discovery with prefixes 
-        // (might also offer regex ? but that is post-load filter as opposed to native optimisation)
-        String prefix = null;
-
-        if (scanMode==null || scanMode==CatalogScanningModes.NONE)
-            return;
-        
-        Stopwatch timer = Stopwatch.createStarted();
-        ReflectionScanner scanner = null;
-        if (!catalog.isLocal()) {
-            log.warn("Scanning not supported for remote catalogs; ignoring scan request in "+catalog);
-        } else if (classpath.getEntries() == null || classpath.getEntries().isEmpty()) {
-            // scan default classpath:
-            ClassLoader baseCL = null;
-            Iterable<URL> baseCP = null;
-            if (catalog.mgmt instanceof ManagementContextInternal) {
-                baseCL = ((ManagementContextInternal)catalog.mgmt).getBaseClassLoader();
-                baseCP = ((ManagementContextInternal)catalog.mgmt).getBaseClassPathForScanning();
-            }
-            scanner = new ReflectionScanner(baseCP, prefix, baseCL, catalog.getRootClassLoader());
-            if (scanner.getSubTypesOf(Entity.class).isEmpty()) {
-                try {
-                    ((ManagementContextInternal)catalog.mgmt).setBaseClassPathForScanning(ClasspathHelper.forJavaClassPath());
-                    log.debug("Catalog scan of default classloader returned nothing; reverting to java.class.path");
-                    baseCP = sanitizeCP(((ManagementContextInternal) catalog.mgmt).getBaseClassPathForScanning());
-                    scanner = new ReflectionScanner(baseCP, prefix, baseCL, catalog.getRootClassLoader());
-                } catch (Exception e) {
-                    log.info("Catalog scan is empty, and unable to use java.class.path (base classpath is "+baseCP+"): "+e);
-                    Exceptions.propagateIfFatal(e);
-                }
-            }
-        } else {
-            // scan specified jars:
-            scanner = new ReflectionScanner(urls==null || urls.length==0 ? null : Arrays.asList(urls), prefix, getLocalClassLoader());
-        }
-        
-        if (scanner!=null) {
-            int count = 0, countApps = 0;
-            if (scanMode==CatalogScanningModes.ANNOTATIONS) {
-                Set<Class<?>> catalogClasses = scanner.getTypesAnnotatedWith(Catalog.class);
-                for (Class<?> c: catalogClasses) {
-                    try {
-                        CatalogItem<?,?> item = addCatalogEntry(c);
-                        count++;
-                        if (CatalogTemplateItemDto.class.isInstance(item)) countApps++;
-                    } catch (Exception e) {
-                        log.warn("Failed to add catalog entry for "+c+"; continuing scan...", e);
-                    }
-                }
-            } else if (scanMode==CatalogScanningModes.TYPES) {
-                Iterable<Class<?>> entities = this.excludeInvalidClasses(
-                        Iterables.concat(scanner.getSubTypesOf(Entity.class),
-                                // not sure why we have to look for sub-types of Application, 
-                                // they should be picked up as sub-types of Entity, but in maven builds (only!)
-                                // they are not -- i presume a bug in scanner
-                                scanner.getSubTypesOf(Application.class), 
-                                scanner.getSubTypesOf(ApplicationBuilder.class)));
-                for (Class<?> c: entities) {
-                    if (Application.class.isAssignableFrom(c) || ApplicationBuilder.class.isAssignableFrom(c)) {
-                        addCatalogEntry(new CatalogTemplateItemDto(), c);
-                        countApps++;
-                    } else {
-                        addCatalogEntry(new CatalogEntityItemDto(), c);
-                    }
-                    count++;
-                }
-                Iterable<Class<? extends Policy>> policies = this.excludeInvalidClasses(scanner.getSubTypesOf(Policy.class));
-                for (Class<?> c: policies) {
-                    addCatalogEntry(new CatalogPolicyItemDto(), c);
-                    count++;
-                }
-                
-                Iterable<Class<? extends Location>> locations = this.excludeInvalidClasses(scanner.getSubTypesOf(Location.class));
-                for (Class<?> c: locations) {
-                    addCatalogEntry(new CatalogLocationItemDto(), c);
-                    count++;
-                }
-            } else {
-                throw new IllegalStateException("Unsupported catalog scan mode "+scanMode+" for "+this);
-            }
-            log.debug("Catalog '"+catalog.dto.name+"' classpath scan completed: loaded "+
-                    count+" item"+Strings.s(count)+" ("+countApps+" app"+Strings.s(countApps)+") in "+Time.makeTimeStringRounded(timer));
-        }
-        
-        isLoaded = true;
-    }
-
-    private Iterable<URL> sanitizeCP(Iterable<URL> baseClassPathForScanning) {
-        /*
-        If Brooklyn is being run via apache daemon[1], and the classpath contains the contents of an empty folder,
-        (e.g. xxx:lib/patch/*:xxx) the classpath will be incorrectly expanded to include a zero-length string
-        (e.g. xxx::xxx), which is then interpreted by {@link org.reflections.Reflections#scan} as the root of the
-        file system. See [2], line 90+. This needs to be removed, lest we attempt to scan the entire filesystem
-
-        [1]: http://commons.apache.org/proper/commons-daemon/
-        [2]: http://svn.apache.org/viewvc/commons/proper/daemon/trunk/src/native/unix/native/arguments.c?view=markup&pathrev=1196468
-         */
-        Iterables.removeIf(baseClassPathForScanning, new Predicate<URL>() {
-            @Override
-            public boolean apply(@Nullable URL url) {
-                return Strings.isEmpty(url.getFile()) || "/".equals(url.getFile());
-            }
-        });
-        return baseClassPathForScanning;
-    }
-
-    /** removes inner classes (non-static nesteds) and others; 
-     * bear in mind named ones will be hard to instantiate without the outer class instance) */
-    private <T> Iterable<Class<? extends T>> excludeInvalidClasses(Iterable<Class<? extends T>> input) {
-        Predicate<Class<? extends T>> f = new Predicate<Class<? extends T>>() {
-            @Override
-            public boolean apply(@Nullable Class<? extends T> input) {
-                if (input==null) return false;
-                if (input.isLocalClass() || input.isAnonymousClass()) return false;
-                if (Modifier.isAbstract(input.getModifiers())) {
-                    if (input.getAnnotation(ImplementedBy.class)==null)
-                        return false;
-                }
-                // non-abstract top-level classes are okay
-                if (!input.isMemberClass()) return true;
-                if (!Modifier.isStatic(input.getModifiers())) return false;
-                // nested classes only okay if static
-                return true;
-            }
-        };
-        return Iterables.filter(input, f);
-    }
-
-    /** augments the given item with annotations and class data for the given class, then adds to catalog
-     * @deprecated since 0.7.0 the classpath DO is replaced by libraries */
-    @Deprecated
-    public CatalogItem<?,?> addCatalogEntry(Class<?> c) {
-        if (Application.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogTemplateItemDto(), c);
-        if (ApplicationBuilder.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogTemplateItemDto(), c);
-        if (Entity.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogEntityItemDto(), c);
-        if (Policy.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogPolicyItemDto(), c);
-        if (Location.class.isAssignableFrom(c)) return addCatalogEntry(new CatalogLocationItemDto(), c);
-        throw new IllegalStateException("Cannot add "+c+" to catalog: unsupported type "+c.getName());
-    }
-    
-    /** augments the given item with annotations and class data for the given class, then adds to catalog 
-     * @deprecated since 0.7.0 the classpath DO is replaced by libraries */
-    @Deprecated
-    public CatalogItem<?,?> addCatalogEntry(CatalogItemDtoAbstract<?,?> item, Class<?> c) {
-        Catalog catalogAnnotation = c.getAnnotation(Catalog.class);
-        item.setSymbolicName(c.getName());
-        item.setJavaType(c.getName());
-        item.setDisplayName(firstNonEmpty(c.getSimpleName(), c.getName()));
-        if (catalogAnnotation!=null) {
-            item.setDisplayName(firstNonEmpty(catalogAnnotation.name(), item.getDisplayName()));
-            item.setDescription(firstNonEmpty(catalogAnnotation.description()));
-            item.setIconUrl(firstNonEmpty(catalogAnnotation.iconUrl()));
-        }
-        if (item instanceof CatalogEntityItemDto || item instanceof CatalogTemplateItemDto) {
-            item.tags().addTag(BrooklynTags.newTraitsTag(ClassUtils.getAllInterfaces(c)));
-        }
-        if (log.isTraceEnabled())
-            log.trace("adding to catalog: "+c+" (from catalog "+catalog+")");
-        catalog.addEntry(item);
-        return item;
-    }
-
-    private static String firstNonEmpty(String ...candidates) {
-        for (String c: candidates)
-            if (c!=null && !c.isEmpty()) return c;
-        return null;
-    }
-
-    /** returns classloader for the entries specified here */
-    public ClassLoader getLocalClassLoader() {
-        if (!classloaderLoaded) loadLocalClassLoader();
-        return classloader;
-    }
-
-    protected synchronized void loadLocalClassLoader() {
-        if (classloaderLoaded) return;
-        if (urls==null) return;
-        classloader.addFirst(new UrlClassLoader(urls));
-        classloaderLoaded = true;
-        return;
-    }
-
-    /** adds the given URL as something this classloader will load
-     * (however no scanning is done) */
-    public void addToClasspath(URL u, boolean updateDto) {
-        if (updateDto) classpath.getEntries().add(u.toExternalForm());
-        addToClasspath(new UrlClassLoader(u));
-    }
-
-    /** adds the given URL as something this classloader will load
-     * (however no scanning is done).
-     * <p>
-     * the DTO will _not_ be updated. */
-    public void addToClasspath(ClassLoader loader) {
-        classloader.addFirst(loader);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d03f254b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDto.java
----------------------------------------------------------------------
diff --git a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDto.java b/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDto.java
deleted file mode 100644
index 5779a4e..0000000
--- a/brooklyn-server/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogClasspathDto.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.brooklyn.core.catalog.internal;
-
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.brooklyn.core.catalog.internal.CatalogClasspathDo.CatalogScanningModes;
-
-public class CatalogClasspathDto {
-    
-    /** whether/what to scan; defaults to 'none' */
-    CatalogScanningModes scan;
-    private List<String> entries;
-    
-    public synchronized void addEntry(String url) {
-        if (entries==null)
-            entries = new CopyOnWriteArrayList<String>();
-        
-        entries.add(url);
-    }
-
-    public synchronized List<String> getEntries() {
-        return entries;
-    }
-    
-}