introduce BrooklynTypeRegistry and start migrating Catalog to it

remove some of the deprecated Catalog methods, and change many lookups to 
catalog to lookup in the type registry.

NEXT - immediate low-hanging fruit:
* move the TypeReg classes to where they belong
* finish changing lookups in catalog so all reads go through registry
  (but writes still go to catalog)

NEXT - provide new features:
* add TypeReg for Beans, so types can be registered (at least by brooklyn 
startup code) for relationships, tasks, etc
* new TypeReg REST API, including allowing completion proposals for yaml
* new PlanToSpecTransformer API, and use the TypeImplementation.kind to pick 
the transformer to use, so we don't try the stupid 
attempt-load-with-any-transformer

NEXT - clean up:
* persist registered types and REST API and addToCatalog allows defining new 
(e.g. new relationships)
* get rid of catalog, or at least deprecate it and make all *writes* to 
TypeRegistry, and it stores things
* optionally, allow interim/multiple TypeRegistry instances to be used when 
loading catalogs or to resolve deep blueprints


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

Branch: refs/heads/master
Commit: dc968f9d0dab816df6f6993399f0a84ce5e8810c
Parents: 4585e2c
Author: Alex Heneveld <[email protected]>
Authored: Thu Oct 29 22:28:14 2015 +0000
Committer: Alex Heneveld <[email protected]>
Committed: Fri Oct 30 02:54:07 2015 +0000

----------------------------------------------------------------------
 .../brooklyn/api/catalog/BrooklynCatalog.java   |  45 ++--
 .../brooklyn/api/catalog/CatalogItem.java       |   9 +-
 .../apache/brooklyn/api/mgmt/EntityManager.java |   2 +-
 .../brooklyn/api/mgmt/ManagementContext.java    |   4 +
 .../api/typereg/BrooklynTypeRegistry.java       |  55 +++++
 .../brooklyn/api/typereg/OsgiBundleWithUrl.java |  36 +++
 .../brooklyn/api/typereg/RegisteredType.java    |  55 +++++
 .../catalog/internal/BasicBrooklynCatalog.java  |  71 +-----
 .../core/catalog/internal/CatalogBundleDto.java |   5 +-
 .../internal/CatalogItemDtoAbstract.java        |   2 +-
 .../core/catalog/internal/CatalogUtils.java     |  22 +-
 .../core/entity/factory/ApplicationBuilder.java |   7 +-
 .../OsgiBrooklynClassLoadingContext.java        |   8 +-
 .../brooklyn/core/mgmt/ha/OsgiManager.java      |  47 ++--
 .../internal/AbstractManagementContext.java     |   9 +
 .../core/mgmt/internal/LocalEntityManager.java  |   1 +
 .../mgmt/internal/ManagementTransitionMode.java |   2 +-
 .../NonDeploymentManagementContext.java         |  12 +-
 .../core/mgmt/rebind/RebindIteration.java       |   2 +-
 .../core/typereg/BasicBrooklynTypeRegistry.java | 122 ++++++++++
 .../core/typereg/BasicOsgiBundleWithUrl.java    | 101 ++++++++
 .../core/typereg/RegisteredTypePredicates.java  | 180 ++++++++++++++
 .../brooklyn/core/typereg/RegisteredTypes.java  | 183 ++++++++++++++
 .../apache/brooklyn/util/core/osgi/Osgis.java   |   2 +-
 .../core/catalog/internal/CatalogDtoTest.java   |   6 +-
 .../core/catalog/internal/CatalogScanTest.java  |   3 +-
 .../catalog/internal/CatalogVersioningTest.java |   2 +-
 .../core/mgmt/rebind/RebindTestFixture.java     |   2 +-
 .../BrooklynAssemblyTemplateInstantiator.java   |   9 +-
 .../BrooklynComponentTemplateResolver.java      |  24 +-
 .../BrooklynEntityDecorationResolver.java       |  30 +--
 .../spi/creation/CampToSpecTransformer.java     |  17 +-
 .../brooklyn/catalog/CatalogYamlCombiTest.java  |  14 +-
 .../brooklyn/catalog/CatalogYamlEntityTest.java |  39 +--
 .../catalog/CatalogYamlLocationTest.java        |  27 +-
 .../brooklyn/test/lite/CampYamlLiteTest.java    |  20 +-
 .../test/lite/TestAppAssemblyInstantiator.java  |   1 -
 .../rest/util/BrooklynRestResourceUtils.java    | 244 +++++++++----------
 .../brooklyn/rest/util/WebResourceUtils.java    |   2 +-
 .../rest/resources/ApplicationResourceTest.java |  11 +-
 .../rest/resources/DescendantsTest.java         |  15 +-
 .../rest/resources/ScriptResourceTest.java      |  12 +-
 .../rest/resources/UsageResourceTest.java       |   9 +-
 43 files changed, 1079 insertions(+), 390 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java
----------------------------------------------------------------------
diff --git 
a/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java 
b/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java
index 0bc0dfe..da850d7 100644
--- a/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java
+++ b/api/src/main/java/org/apache/brooklyn/api/catalog/BrooklynCatalog.java
@@ -23,41 +23,30 @@ import java.util.NoSuchElementException;
 
 import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Predicate;
 
 public interface BrooklynCatalog {
+    /** 
+     * Version set in catalog when creator does not supply a version, to mean 
a low priority item;
+     * and used when requesting to indicate the best version.
+     * (See {@link #getCatalogItem(String, String)} for discussion of the best 
version.)
+     */
     static String DEFAULT_VERSION = "0.0.0_DEFAULT_VERSION";
 
-    /** @return The item with the given {@link CatalogItem#getSymbolicName()
-     * symbolicName}, or null if not found.
-     * @deprecated since 0.7.0 use {@link #getCatalogItem(String, String)};
-     * or see also CatalogUtils getCatalogItemOptionalVersion */
-    @Deprecated
-    CatalogItem<?,?> getCatalogItem(String symbolicName);
-
-    /** @return The item with the given {@link CatalogItem#getSymbolicName()
-     * symbolicName}, or null if not found. */
+    /** @return The item matching the given given 
+     * {@link CatalogItem#getSymbolicName() symbolicName} 
+     * and optionally {@link CatalogItem#getVersion()},
+     * taking the best version if the version is {@link #DEFAULT_VERSION} or 
null,
+     * returning null if no matches are found. */
     CatalogItem<?,?> getCatalogItem(String symbolicName, String version);
 
-    /** @return Deletes the item with the given
-     *  {@link CatalogItem#getSymbolicName() symbolicName}
-     * @throws NoSuchElementException if not found
-     * @deprecated since 0.7.0 use {@link #deleteCatalogItem(String, String)} 
*/
-    @Deprecated
-    void deleteCatalogItem(String symbolicName);
-
     /** @return Deletes the item with the given {@link 
CatalogItem#getSymbolicName()
      * symbolicName} and version
      * @throws NoSuchElementException if not found */
     void deleteCatalogItem(String symbolicName, String version);
 
     /** variant of {@link #getCatalogItem(String, String)} which checks (and 
casts) type for convenience
-     * (returns null if type does not match)
-     * @deprecated since 0.7.0 use {@link #getCatalogItem(Class<T>, String, 
String)} */
-    @Deprecated
-    <T,SpecT> CatalogItem<T,SpecT> getCatalogItem(Class<T> type, String 
symbolicName);
-
-    /** variant of {@link #getCatalogItem(String, String)} which checks (and 
casts) type for convenience
      * (returns null if type does not match) */
     <T,SpecT> CatalogItem<T,SpecT> getCatalogItem(Class<T> type, String 
symbolicName, String version);
 
@@ -80,14 +69,8 @@ public interface BrooklynCatalog {
     // TODO this should be cached on the item and renamed getSpec(...), else 
we re-create it too often (every time catalog is listed)
     <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT 
createSpec(CatalogItem<T, SpecT> item);
     
-    /** throws exceptions if any problems 
-     * @deprecated since 0.7.0 use {@link #createSpec(CatalogItem)} */
-    @Deprecated
-    <T,SpecT> Class<? extends T> loadClass(CatalogItem<T,SpecT> item);
-    /** @deprecated since 0.7.0 use {@link #createSpec(CatalogItem)} */
-    @Deprecated
-    <T> Class<? extends T> loadClassByType(String typeName, Class<T> 
typeClass);
     /** @deprecated since 0.7.0 use {@link #createSpec(CatalogItem)} */
+    // used in one place in BRRU with warnings added in 0.9.0. remove after 
0.9. 
     CatalogItem<?,?> getCatalogItemForType(String typeName);
 
     /**
@@ -150,9 +133,11 @@ public interface BrooklynCatalog {
      * so it is recommended to edit the 'manual' catalog DTO if using it to
      * generate a catalog, either adding the appropriate classpath URL or 
removing this entry.
      *
-     * @deprecated since 0.7.0 Construct catalogs with OSGi bundles instead
+     * @deprecated since 0.7.0 Construct catalogs with OSGi bundles instead.
+     * This is used in a handful of tests which should be rewritten to refer 
to OSGi bundles.
      */
     @Deprecated
+    @VisibleForTesting
     CatalogItem<?,?> addItem(Class<?> clazz);
 
     void reset(Collection<CatalogItem<?, ?>> entries);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java 
b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
index bf806aa..5d9b5ee 100644
--- a/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
+++ b/api/src/main/java/org/apache/brooklyn/api/catalog/CatalogItem.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
 import org.apache.brooklyn.api.mgmt.rebind.Rebindable;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.CatalogItemMemento;
 import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
 
 import com.google.common.annotations.Beta;
 
@@ -39,12 +40,8 @@ public interface CatalogItem<T,SpecT> extends 
BrooklynObject, Rebindable {
         LOCATION;
     }
     
-    public static interface CatalogBundle {
-        public String getSymbolicName();
-        public String getVersion();
-        public String getUrl();
-
-        /** @return true if the bundle reference contains both name and 
version*/
+    public static interface CatalogBundle extends OsgiBundleWithUrl {
+        /** @deprecated since 0.9.0, use {@link #isFullDetailKnown()} */
         public boolean isNamed();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/api/src/main/java/org/apache/brooklyn/api/mgmt/EntityManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/EntityManager.java 
b/api/src/main/java/org/apache/brooklyn/api/mgmt/EntityManager.java
index d423c76..fe66a5b 100644
--- a/api/src/main/java/org/apache/brooklyn/api/mgmt/EntityManager.java
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/EntityManager.java
@@ -48,7 +48,7 @@ public interface EntityManager {
     EntityTypeRegistry getEntityTypeRegistry();
     
     /**
-     * Creates a new (unmanaged) entity.
+     * Creates a new entity. Management is started immediately (by this 
method).
      * 
      * @param spec
      * @return A proxy to the created entity (rather than the actual entity 
itself).

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java
----------------------------------------------------------------------
diff --git 
a/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java 
b/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java
index f809fb2..cabadee 100644
--- a/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java
+++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java
@@ -34,6 +34,7 @@ import 
org.apache.brooklyn.api.mgmt.entitlement.EntitlementManager;
 import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityManager;
 import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
 import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
 import org.apache.brooklyn.config.StringConfigMap;
 import org.apache.brooklyn.util.guava.Maybe;
 
@@ -206,6 +207,9 @@ public interface ManagementContext {
     /** Record of configured Brooklyn entities (and templates and policies) 
which can be loaded */
     BrooklynCatalog getCatalog();
 
+    /** Record of configured classes which can be loaded */
+    BrooklynTypeRegistry getTypeRegistry();
+    
     /** Returns the class loader to be used to load items. 
      * Temporary routine while catalog supports classloader-based and 
OSGi-based classloading. */
     @Beta

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git 
a/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java 
b/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
new file mode 100644
index 0000000..25f07ab
--- /dev/null
+++ 
b/api/src/main/java/org/apache/brooklyn/api/typereg/BrooklynTypeRegistry.java
@@ -0,0 +1,55 @@
+/*
+ * 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.api.typereg;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+
+import com.google.common.base.Predicate;
+
+
+public interface BrooklynTypeRegistry {
+
+    public enum RegisteredTypeKind {
+        /** a registered type which will create an {@link 
AbstractBrooklynObjectSpec} (e.g. {@link EntitySpec}) 
+         * for the type registered (e.g. the {@link Entity} instance) */
+        SPEC,
+        // TODO
+//        BEAN 
+        
+        // NB: additional kinds should have the Visitor in RegisteredTypes 
updated
+    }
+    
+    Iterable<RegisteredType> getAll();
+    Iterable<RegisteredType> getAll(Predicate<? super RegisteredType> 
alwaysTrue);
+    
+    RegisteredType get(String symbolicNameWithOptionalVersion, @Nullable 
RegisteredTypeKind kind, @Nullable Class<?> requiredSupertype);
+    RegisteredType get(String symbolicName, String version, @Nullable 
RegisteredTypeKind kind, @Nullable Class<?> requiredSupertype);
+    RegisteredType get(String symbolicName, String version);
+
+    @SuppressWarnings("rawtypes")
+    <T extends AbstractBrooklynObjectSpec> T createSpec(RegisteredType type, 
@Nullable Class<T> specKind);
+    
+    // TODO when we support beans
+//    <T> T createBean(RegisteredType type, Class<T> superType);
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/api/src/main/java/org/apache/brooklyn/api/typereg/OsgiBundleWithUrl.java
----------------------------------------------------------------------
diff --git 
a/api/src/main/java/org/apache/brooklyn/api/typereg/OsgiBundleWithUrl.java 
b/api/src/main/java/org/apache/brooklyn/api/typereg/OsgiBundleWithUrl.java
new file mode 100644
index 0000000..ec3ef40
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/typereg/OsgiBundleWithUrl.java
@@ -0,0 +1,36 @@
+/*
+ * 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.api.typereg;
+
+import com.google.common.annotations.Beta;
+
+@Beta
+public interface OsgiBundleWithUrl {
+    
+    public String getSymbolicName();
+    public String getVersion();
+    
+    /** where this bundle can be downloaded; typically required unless we are 
guaranteed the bundle will be manually installed */
+    public String getUrl();
+    
+    /** @return true if we have a name and version for this bundle;
+     * false if not, e.g. if we only know the URL and we haven't loaded it yet 
*/
+    public boolean isFullDetailKnown();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
----------------------------------------------------------------------
diff --git 
a/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java 
b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
new file mode 100644
index 0000000..5158c34
--- /dev/null
+++ b/api/src/main/java/org/apache/brooklyn/api/typereg/RegisteredType.java
@@ -0,0 +1,55 @@
+/*
+ * 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.api.typereg;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.objs.Identifiable;
+
+public interface RegisteredType extends Identifiable {
+    
+    @Override
+    String getId();
+    
+    String getSymbolicName();
+    String getVersion();
+
+    Collection<OsgiBundleWithUrl> getLibraries();
+
+    String getDisplayName();
+    String getDescription();
+    String getIconUrl();
+
+    /** @return the java type or a supertype thereof that this registered type 
represents.
+     * <p>
+     * For beans, this is the type that the {@link BrooklynTypeRegistry} will 
create. 
+     * For specs, this is what the spec that will be created points at 
+     * (e.g. the concrete {@link Entity}, not the {@link EntitySpec});
+     * <p>
+     * In some cases this may return an interface or a super-type of what will 
actually be created, 
+     * such as if the concrete type is private and callers should know only 
about a particular public interface,
+     * or if precise type details are unavailable and all that is known at 
creation is some higher level interface/supertype
+     * (e.g. this may return {@link Entity} even though the spec points at a 
specific subclass,
+     * for instance because the YAML has not yet been parsed or OSGi bundles 
downloaded). 
+     */
+    Class<?> getJavaType();
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index 9850eca..ce168b6 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -185,14 +185,15 @@ public class BasicBrooklynCatalog implements 
BrooklynCatalog {
     }
     
     private String getFixedVersionId(String symbolicName, String version) {
-        if (!DEFAULT_VERSION.equals(version)) {
+        if (version!=null && !DEFAULT_VERSION.equals(version)) {
             return version;
         } else {
-            return getDefaultVersion(symbolicName);
+            return getBestVersion(symbolicName);
         }
     }
 
-    private String getDefaultVersion(String 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))));
@@ -209,12 +210,6 @@ public class BasicBrooklynCatalog implements 
BrooklynCatalog {
     }
 
     @Override
-    @Deprecated
-    public CatalogItem<?,?> getCatalogItem(String symbolicName) {
-        return getCatalogItem(symbolicName, DEFAULT_VERSION);
-    }
-    
-    @Override
     public CatalogItem<?,?> getCatalogItem(String symbolicName, String 
version) {
         if (symbolicName == null) return null;
         checkNotNull(version, "version");
@@ -224,14 +219,6 @@ public class BasicBrooklynCatalog implements 
BrooklynCatalog {
     }
     
     @Override
-    @Deprecated
-    public void deleteCatalogItem(String id) {
-        //Delete only if installed through the
-        //deprecated methods. Don't support DEFAULT_VERSION for delete.
-        deleteCatalogItem(id, NO_VERSION);
-    }
-
-    @Override
     public void deleteCatalogItem(String symbolicName, String version) {
         log.debug("Deleting manual catalog item from "+mgmt+": "+symbolicName 
+ ":" + version);
         checkNotNull(symbolicName, "id");
@@ -263,12 +250,6 @@ public class BasicBrooklynCatalog implements 
BrooklynCatalog {
 
     }
 
-    @Override
-    @Deprecated
-    public <T,SpecT> CatalogItem<T,SpecT> getCatalogItem(Class<T> type, String 
id) {
-        return getCatalogItem(type, id, DEFAULT_VERSION);
-    }
-    
     @SuppressWarnings("unchecked")
     @Override
     public <T,SpecT> CatalogItem<T,SpecT> getCatalogItem(Class<T> type, String 
id, String version) {
@@ -315,46 +296,16 @@ public class BasicBrooklynCatalog implements 
BrooklynCatalog {
         @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");
-        Class<SpecT> specType = loadedItem.getSpecType();
-        if (specType==null) return null;
+        if (loadedItem.getSpecType()==null) return null;
 
-        if (loadedItem.getPlanYaml() != null) {
-            SpecT yamlSpec = EntityManagementUtils.createCatalogSpec(mgmt, 
loadedItem);
-            if (yamlSpec != null) {
-                return yamlSpec;
-            }
+        SpecT spec = EntityManagementUtils.createCatalogSpec(mgmt, loadedItem);
+        if (spec != null) {
+            return spec;
         }
 
         throw new IllegalStateException("No known mechanism to create instance 
of "+item);
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    /** @deprecated since 0.7.0 use {@link #createSpec(CatalogItem)} */
-    @Deprecated
-    public <T,SpecT> Class<? extends T> loadClass(CatalogItem<T,SpecT> item) {
-        if (log.isDebugEnabled())
-            log.debug("Loading class for catalog item " + item);
-        checkNotNull(item);
-        CatalogItemDo<?,?> loadedItem = 
getCatalogItemDo(item.getSymbolicName(), item.getVersion());
-        if (loadedItem==null) throw new NoSuchElementException("Unable to load 
'"+item.getId()+"' to instantiate it");
-        return (Class<? extends T>) loadedItem.getJavaClass();
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Override
-    /** @deprecated since 0.7.0 use {@link #createSpec(CatalogItem)} */
-    @Deprecated
-    public <T> Class<? extends T> loadClassByType(String typeName, Class<T> 
typeClass) {
-        final CatalogItem<?,?> resultI = getCatalogItemForType(typeName);
-
-        if (resultI == null) {
-            throw new NoSuchElementException("Unable to find catalog item for 
type "+typeName);
-        }
-
-        return (Class<? extends T>) loadClass(resultI);
-    }
-
     @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;
@@ -507,13 +458,13 @@ public class BasicBrooklynCatalog implements 
BrooklynCatalog {
         if (Strings.isBlank(symbolicName)) {
             if (Strings.isNonBlank(id)) {
                 if (CatalogUtils.looksLikeVersionedId(id)) {
-                    symbolicName = CatalogUtils.getIdFromVersionedId(id);
+                    symbolicName = 
CatalogUtils.getSymbolicNameFromVersionedId(id);
                 } else {
                     symbolicName = id;
                 }
             } else if (Strings.isNonBlank(name)) {
                 if (CatalogUtils.looksLikeVersionedId(name)) {
-                    symbolicName = CatalogUtils.getIdFromVersionedId(name);
+                    symbolicName = 
CatalogUtils.getSymbolicNameFromVersionedId(name);
                 } else {
                     symbolicName = name;
                 }
@@ -741,7 +692,7 @@ public class BasicBrooklynCatalog implements 
BrooklynCatalog {
             String version = null;
             if (CatalogUtils.looksLikeVersionedId(type)) {
                 version = CatalogUtils.getVersionFromVersionedId(type);
-                type = CatalogUtils.getIdFromVersionedId(type);
+                type = CatalogUtils.getSymbolicNameFromVersionedId(type);
             }
             if (type!=null && key!=null) {
                 for (CatalogItemDtoAbstract<?,?> candidate: itemsDefinedSoFar) 
{

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java
 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java
index 60472ae..51a4757 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java
@@ -44,9 +44,12 @@ public class CatalogBundleDto implements CatalogBundle {
     }
 
     @Override
-    public boolean isNamed() {
+    public boolean isFullDetailKnown() {
         return symbolicName != null && version != null;
     }
+    
+    @Override
+    public boolean isNamed() { return isFullDetailKnown(); }
 
     @Override
     public String getSymbolicName() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
index 6262508..414b3e6 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java
@@ -411,7 +411,7 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> 
extends AbstractBrooklynO
                     url = inlineRef;
                 } else if (CatalogUtils.looksLikeVersionedId(inlineRef)) {
                     //looks like a name+version ref
-                    name = CatalogUtils.getIdFromVersionedId(inlineRef);
+                    name = 
CatalogUtils.getSymbolicNameFromVersionedId(inlineRef);
                     version = 
CatalogUtils.getVersionFromVersionedId(inlineRef);
                     url = null;
                 } else {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
index 1da2957..4561046 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
@@ -22,14 +22,14 @@ import java.util.Collection;
 
 import javax.annotation.Nullable;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 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.entity.Entity;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
 import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
+import org.apache.brooklyn.api.typereg.RegisteredType;
 import org.apache.brooklyn.core.BrooklynLogging;
 import 
org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.BrooklynLoaderTracker;
 import org.apache.brooklyn.core.entity.EntityInternal;
@@ -44,6 +44,8 @@ import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Joiner;
@@ -63,6 +65,10 @@ public class CatalogUtils {
         return newClassLoadingContext(mgmt, item.getId(), item.getLibraries());
     }
     
+    public static BrooklynClassLoadingContext 
newClassLoadingContext(ManagementContext mgmt, RegisteredType item) {
+        return newClassLoadingContext(mgmt, item.getId(), item.getLibraries());
+    }
+    
     public static BrooklynClassLoadingContext getClassLoadingContext(Entity 
entity) {
         ManagementContext mgmt = 
((EntityInternal)entity).getManagementContext();
         String catId = entity.getCatalogItemId();
@@ -75,7 +81,7 @@ public class CatalogUtils {
         return newClassLoadingContext(mgmt, cat);
     }
 
-    public static BrooklynClassLoadingContext newClassLoadingContext(@Nullable 
ManagementContext mgmt, String catalogItemId, Collection<CatalogBundle> 
libraries) {
+    public static BrooklynClassLoadingContext newClassLoadingContext(@Nullable 
ManagementContext mgmt, String catalogItemId, Collection<? extends 
OsgiBundleWithUrl> libraries) {
         BrooklynClassLoadingContextSequential result = new 
BrooklynClassLoadingContextSequential(mgmt);
 
         if (libraries!=null && !libraries.isEmpty()) {
@@ -193,7 +199,13 @@ public class CatalogUtils {
         return true;
     }
 
+    /** @deprecated since 0.9.0 use {@link 
#getSymbolicNameFromVersionedId(String)} */
+    @Deprecated
     public static String getIdFromVersionedId(String versionedId) {
+        return getSymbolicNameFromVersionedId(versionedId);
+    }
+    
+    public static String getSymbolicNameFromVersionedId(String versionedId) {
         if (versionedId == null) return null;
         int versionDelimiterPos = versionedId.lastIndexOf(VERSION_DELIMITER);
         if (versionDelimiterPos != -1) {
@@ -224,7 +236,7 @@ public class CatalogUtils {
     public static CatalogItem<?, ?> 
getCatalogItemOptionalVersion(ManagementContext mgmt, String versionedId) {
         if (versionedId == null) return null;
         if (looksLikeVersionedId(versionedId)) {
-            String id = getIdFromVersionedId(versionedId);
+            String id = getSymbolicNameFromVersionedId(versionedId);
             String version = getVersionFromVersionedId(versionedId);
             return mgmt.getCatalog().getCatalogItem(id, version);
         } else {
@@ -240,7 +252,7 @@ public class CatalogUtils {
 
     public static <T,SpecT> CatalogItem<T, SpecT> 
getCatalogItemOptionalVersion(ManagementContext mgmt, Class<T> type, String 
versionedId) {
         if (looksLikeVersionedId(versionedId)) {
-            String id = getIdFromVersionedId(versionedId);
+            String id = getSymbolicNameFromVersionedId(versionedId);
             String version = getVersionFromVersionedId(versionedId);
             return mgmt.getCatalog().getCatalogItem(type, id, version);
         } else {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/entity/factory/ApplicationBuilder.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/entity/factory/ApplicationBuilder.java
 
b/core/src/main/java/org/apache/brooklyn/core/entity/factory/ApplicationBuilder.java
index 2d3ee08..f8167a0 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/entity/factory/ApplicationBuilder.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/entity/factory/ApplicationBuilder.java
@@ -88,11 +88,7 @@ public abstract class ApplicationBuilder {
     }
 
     @SuppressWarnings("unchecked")
-    @Beta
-    /** @deprecated since 0.7.0 the management context should normally be 
passed in;
-     * for TestApplication also see 
TestApplication.Factory.newManagedInstanceForTests() */ 
-    @Deprecated
-    public static <T extends StartableApplication> T 
newManagedApp(EntitySpec<T> spec) {
+    private static <T extends StartableApplication> T 
newManagedApp(EntitySpec<T> spec) {
         return (T) new ApplicationBuilder(spec) {
             @Override protected void doBuild() {
             }
@@ -109,6 +105,7 @@ public abstract class ApplicationBuilder {
         }
     }
 
+    /** @deprecated class can be removed; users of this convenience method can 
now simply do mgmt.getEntityManager().createEntity(spec) */ 
     @SuppressWarnings("unchecked")
     @Beta
     public static <T extends StartableApplication> T 
newManagedApp(EntitySpec<T> spec, ManagementContext managementContext) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/OsgiBrooklynClassLoadingContext.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/OsgiBrooklynClassLoadingContext.java
 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/OsgiBrooklynClassLoadingContext.java
index fa12aa2..74f3de1 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/OsgiBrooklynClassLoadingContext.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/classloading/OsgiBrooklynClassLoadingContext.java
@@ -23,8 +23,8 @@ import java.util.Collection;
 import java.util.Collections;
 
 import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
 import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
 import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
 import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
@@ -37,16 +37,16 @@ public class OsgiBrooklynClassLoadingContext extends 
AbstractBrooklynClassLoadin
 
     private final String catalogItemId;
     private boolean hasBundles = false;
-    private transient Collection<CatalogBundle> _bundles;
+    private transient Collection<? extends OsgiBundleWithUrl> _bundles;
 
-    public OsgiBrooklynClassLoadingContext(ManagementContext mgmt, String 
catalogItemId, Collection<CatalogBundle> bundles) {
+    public OsgiBrooklynClassLoadingContext(ManagementContext mgmt, String 
catalogItemId, Collection<? extends OsgiBundleWithUrl> bundles) {
         super(mgmt);
         this._bundles = bundles;
         this.hasBundles = bundles!=null && !bundles.isEmpty();
         this.catalogItemId = catalogItemId;
     }
 
-    public Collection<CatalogBundle> getBundles() {
+    public Collection<? extends OsgiBundleWithUrl> getBundles() {
         if (_bundles!=null || !hasBundles) return _bundles;
         CatalogItem<?, ?> cat = 
CatalogUtils.getCatalogItemOptionalVersion(mgmt, catalogItemId);
         if (cat==null) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
index 2afb17c..e906e3a 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
@@ -29,12 +29,9 @@ import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.osgi.framework.Bundle;
-import org.osgi.framework.launch.Framework;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
 import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.BrooklynVersion;
 import org.apache.brooklyn.core.server.BrooklynServerConfig;
@@ -50,9 +47,13 @@ import org.apache.brooklyn.util.os.Os.DeletionResult;
 import org.apache.brooklyn.util.repeat.Repeater;
 import org.apache.brooklyn.util.text.Strings;
 import org.apache.brooklyn.util.time.Duration;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.launch.Framework;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 
 public class OsgiManager {
 
@@ -170,20 +171,20 @@ public class OsgiManager {
     }
 
     public static boolean isBundleNameEqualOrAbsent(CatalogBundle bundle, 
Bundle b) {
-        return !bundle.isNamed() ||
+        return !bundle.isFullDetailKnown() ||
                 (bundle.getSymbolicName().equals(b.getSymbolicName()) &&
                 bundle.getVersion().equals(b.getVersion().toString()));
     }
 
-    public <T> Maybe<Class<T>> tryResolveClass(String type, CatalogBundle... 
catalogBundles) {
-        return tryResolveClass(type, Arrays.asList(catalogBundles));
+    public <T> Maybe<Class<T>> tryResolveClass(String type, 
OsgiBundleWithUrl... osgiBundles) {
+        return tryResolveClass(type, Arrays.asList(osgiBundles));
     }
-    public <T> Maybe<Class<T>> tryResolveClass(String type, 
Iterable<CatalogBundle> catalogBundles) {
-        Map<CatalogBundle,Throwable> bundleProblems = MutableMap.of();
+    public <T> Maybe<Class<T>> tryResolveClass(String type, Iterable<? extends 
OsgiBundleWithUrl> osgiBundles) {
+        Map<OsgiBundleWithUrl,Throwable> bundleProblems = MutableMap.of();
         Set<String> extraMessages = MutableSet.of();
-        for (CatalogBundle catalogBundle: catalogBundles) {
+        for (OsgiBundleWithUrl osgiBundle: osgiBundles) {
             try {
-                Maybe<Bundle> bundle = findBundle(catalogBundle);
+                Maybe<Bundle> bundle = findBundle(osgiBundle);
                 if (bundle.isPresent()) {
                     Bundle b = bundle.get();
                     Class<T> clazz;
@@ -200,13 +201,13 @@ public class OsgiManager {
                     }
                     return Maybe.of(clazz);
                 } else {
-                    bundleProblems.put(catalogBundle, 
((Maybe.Absent<?>)bundle).getException());
+                    bundleProblems.put(osgiBundle, 
((Maybe.Absent<?>)bundle).getException());
                 }
                 
             } catch (Exception e) {
                 // should come from classloading now; name formatting or 
missing bundle errors will be caught above 
                 Exceptions.propagateIfFatal(e);
-                bundleProblems.put(catalogBundle, e);
+                bundleProblems.put(osgiBundle, e);
 
                 Throwable cause = e.getCause();
                 if (cause != null && cause.getMessage().contains("Unresolved 
constraint in bundle")) {
@@ -217,7 +218,7 @@ public class OsgiManager {
                         extraMessages.add("Your development environment may 
not have created necessary files. Doing a maven build then retrying may fix the 
issue.");
                     }
                     if (!extraMessages.isEmpty()) 
log.warn(Strings.join(extraMessages, " "));
-                    log.warn("Unresolved constraint resolving OSGi bundle 
"+catalogBundle+" to load "+type+": "+cause.getMessage());
+                    log.warn("Unresolved constraint resolving OSGi bundle 
"+osgiBundle+" to load "+type+": "+cause.getMessage());
                     if (log.isDebugEnabled()) log.debug("Trace for OSGi 
resolution failure", e);
                 }
             }
@@ -235,7 +236,7 @@ public class OsgiManager {
         }
     }
 
-    public Maybe<Bundle> findBundle(CatalogBundle catalogBundle) {
+    public Maybe<Bundle> findBundle(OsgiBundleWithUrl catalogBundle) {
         //Either fail at install time when the user supplied name:version is 
different
         //from the one reported from the bundle
         //or
@@ -256,10 +257,10 @@ public class OsgiManager {
     /**
      * Iterates through catalogBundles until one contains a resource with the 
given name.
      */
-    public URL getResource(String name, Iterable<CatalogBundle> 
catalogBundles) {
-        for (CatalogBundle catalogBundle: catalogBundles) {
+    public URL getResource(String name, Iterable<? extends OsgiBundleWithUrl> 
osgiBundles) {
+        for (OsgiBundleWithUrl osgiBundle: osgiBundles) {
             try {
-                Maybe<Bundle> bundle = findBundle(catalogBundle);
+                Maybe<Bundle> bundle = findBundle(osgiBundle);
                 if (bundle.isPresent()) {
                     URL result = bundle.get().getResource(name);
                     if (result!=null) return result;
@@ -272,11 +273,11 @@ public class OsgiManager {
     }
 
     /**
-     * @return An iterable of all resources matching name in catalogBundles.
+     * @return URL's to all resources matching the given name (using {@link 
Bundle#getResources(String)} in the referenced osgi bundles.
      */
-    public Iterable<URL> getResources(String name, Iterable<CatalogBundle> 
catalogBundles) {
-        List<URL> resources = Lists.newArrayList();
-        for (CatalogBundle catalogBundle : catalogBundles) {
+    public Iterable<URL> getResources(String name, Iterable<? extends 
OsgiBundleWithUrl> osgiBundles) {
+        Set<URL> resources = Sets.newLinkedHashSet();
+        for (OsgiBundleWithUrl catalogBundle : osgiBundles) {
             try {
                 Maybe<Bundle> bundle = findBundle(catalogBundle);
                 if (bundle.isPresent()) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
index 01b507f..284b357 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java
@@ -48,6 +48,7 @@ import 
org.apache.brooklyn.api.mgmt.entitlement.EntitlementManager;
 import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityManager;
 import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
 import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
 import org.apache.brooklyn.config.StringConfigMap;
 import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
 import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
@@ -69,6 +70,7 @@ import 
org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContex
 import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
 import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
 import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl;
+import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry;
 import org.apache.brooklyn.util.collections.MutableList;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.ResourceUtils;
@@ -151,6 +153,7 @@ public abstract class AbstractManagementContext implements 
ManagementContextInte
     protected BrooklynProperties configMap;
     protected BasicLocationRegistry locationRegistry;
     protected final BasicBrooklynCatalog catalog;
+    protected final BrooklynTypeRegistry typeRegistry;
     protected ClassLoader baseClassLoader;
     protected Iterable<URL> baseClassPathForScanning;
 
@@ -189,6 +192,7 @@ public abstract class AbstractManagementContext implements 
ManagementContextInte
         DataGrid datagrid = datagridFactory.newDataGrid(this);
 
         this.catalog = new BasicBrooklynCatalog(this);
+        this.typeRegistry = new BasicBrooklynTypeRegistry(this);
         
         this.storage = new BrooklynStorageImpl(datagrid);
         this.rebindManager = new RebindManagerImpl(this); // TODO leaking 
"this" reference; yuck
@@ -385,6 +389,11 @@ public abstract class AbstractManagementContext implements 
ManagementContextInte
     }
     
     @Override
+    public BrooklynTypeRegistry getTypeRegistry() {
+        return typeRegistry;
+    }
+    
+    @Override
     public ClassLoader getCatalogClassLoader() {
         // catalog does not have to be initialized
         return catalog.getRootClassLoader();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java
 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java
index 7d3b705..aaa12d5 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalEntityManager.java
@@ -394,6 +394,7 @@ public class LocalEntityManager implements 
EntityManagerInternal {
 
     @Override
     public void unmanage(final Entity e) {
+        // TODO don't want to guess; should we inspect state of e ?  or maybe 
it doesn't matter ?
         unmanage(e, 
ManagementTransitionMode.guessing(BrooklynObjectManagementMode.MANAGED_PRIMARY, 
BrooklynObjectManagementMode.NONEXISTENT));
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementTransitionMode.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementTransitionMode.java
 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementTransitionMode.java
index f076c3a..08f111b 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementTransitionMode.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/ManagementTransitionMode.java
@@ -44,7 +44,7 @@ public class ManagementTransitionMode {
         return new 
ManagementTransitionMode(Preconditions.checkNotNull(modeBefore, "modeBefore"), 
Preconditions.checkNotNull(modeAfter, "modeAfter"));
     }
 
-    @Deprecated /** @deprecated marking places where we aren't sure */
+    @Deprecated /** @deprecated since 0.9.0 - used to mark places where we 
aren't sure, remove once we are satisfied */
     public static ManagementTransitionMode 
guessing(BrooklynObjectManagementMode modeBefore, BrooklynObjectManagementMode 
modeAfter) {
         return transitioning(modeBefore, modeAfter);
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
index 5223cf8..68172bb 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java
@@ -29,8 +29,6 @@ import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.effector.Effector;
 import org.apache.brooklyn.api.entity.Application;
@@ -59,12 +57,12 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData;
 import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
 import org.apache.brooklyn.config.StringConfigMap;
 import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
 import org.apache.brooklyn.core.entity.AbstractEntity;
 import org.apache.brooklyn.core.internal.BrooklynProperties;
 import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
-import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
 import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
 import org.apache.brooklyn.core.mgmt.usage.UsageManager;
 import org.apache.brooklyn.core.objs.proxy.InternalEntityFactory;
@@ -72,6 +70,8 @@ import 
org.apache.brooklyn.core.objs.proxy.InternalLocationFactory;
 import org.apache.brooklyn.core.objs.proxy.InternalPolicyFactory;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Objects;
 
@@ -329,6 +329,12 @@ public class NonDeploymentManagementContext implements 
ManagementContextInternal
         checkInitialManagementContextReal();
         return initialManagementContext.getCatalog();
     }
+
+    @Override
+    public BrooklynTypeRegistry getTypeRegistry() {
+        checkInitialManagementContextReal();
+        return initialManagementContext.getTypeRegistry();
+    }
     
     @Override
     public ClassLoader getCatalogClassLoader() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
index 7b00ff8..2279e8c 100644
--- 
a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
+++ 
b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
@@ -932,7 +932,7 @@ public abstract class RebindIteration {
                         // This is a dangling reference to the catalog item 
(which will have been logged by lookupCatalogItem).
                         // Try loading as any version.
                         if (CatalogUtils.looksLikeVersionedId(catalogItemId)) {
-                            String symbolicName = 
CatalogUtils.getIdFromVersionedId(catalogItemId);
+                            String symbolicName = 
CatalogUtils.getSymbolicNameFromVersionedId(catalogItemId);
                             catalogItem = 
rebindContext.lookup().lookupCatalogItem(symbolicName);
                             
                             if (catalogItem != null) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
 
b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
new file mode 100644
index 0000000..3d418e4
--- /dev/null
+++ 
b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
@@ -0,0 +1,122 @@
+/*
+ * 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.typereg;
+
+import org.apache.brooklyn.api.catalog.BrooklynCatalog;
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.internal.AbstractBrooklynObjectSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
+import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
+import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.typereg.RegisteredTypes.JavaTypeImplementation;
+import org.apache.brooklyn.core.typereg.RegisteredTypes.RegisteredSpecType;
+import org.apache.brooklyn.core.typereg.RegisteredTypes.TypeImplementation;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
+
+    @SuppressWarnings("unused")
+    private static final Logger log = 
LoggerFactory.getLogger(BasicBrooklynTypeRegistry.class);
+    
+    private ManagementContext mgmt;
+
+    public BasicBrooklynTypeRegistry(ManagementContext mgmt) {
+        this.mgmt = mgmt;
+    }
+    
+    private static final Function<CatalogItem<?,?>,RegisteredType> CI_TO_RT = 
new Function<CatalogItem<?,?>, RegisteredType>() {
+        @Override
+        public RegisteredType apply(CatalogItem<?, ?> item) {
+            if (item==null) return null;
+            TypeImplementation impl = null;
+            if (item.getPlanYaml()!=null) {
+                impl = new TypeImplementation(null, item.getPlanYaml());
+            }
+            if (item.getJavaType()!=null) {
+                impl = new JavaTypeImplementation(item.getJavaType());
+            }
+            if (impl!=null) {
+                RegisteredSpecType type = new 
RegisteredSpecType(item.getSymbolicName(), item.getVersion(),
+                    item.getCatalogItemJavaType(), impl);
+                type.bundles = 
MutableList.<OsgiBundleWithUrl>copyOf(item.getLibraries());
+                type.displayName = item.getDisplayName();
+                type.description = item.getDescription();
+                type.iconUrl = item.getIconUrl();
+                
+                // TODO
+                // disabled, deprecated
+                // javaType, specType, registeredTypeName ...
+                // tags ?
+                return type;
+            }
+            throw new IllegalStateException("Unsupported catalog item "+item+" 
when trying to create RegisteredType");
+        }
+    };
+    
+    public Iterable<RegisteredType> getAll() {
+        return getAll(Predicates.alwaysTrue());
+    }
+    
+    @Override
+    public Iterable<RegisteredType> getAll(Predicate<? super RegisteredType> 
filter) {
+        return 
Iterables.filter(Iterables.transform(mgmt.getCatalog().getCatalogItems(), 
CI_TO_RT), filter);
+    }
+
+    @Override
+    public RegisteredType get(String symbolicNameWithOptionalVersion, 
RegisteredTypeKind kind, Class<?> parentClass) {
+        if 
(CatalogUtils.looksLikeVersionedId(symbolicNameWithOptionalVersion)) {
+            String id = 
CatalogUtils.getSymbolicNameFromVersionedId(symbolicNameWithOptionalVersion);
+            String version = 
CatalogUtils.getVersionFromVersionedId(symbolicNameWithOptionalVersion);
+            return get(id, version, kind, parentClass);
+        } else {
+            return get(symbolicNameWithOptionalVersion, 
BrooklynCatalog.DEFAULT_VERSION, kind, parentClass);
+        }
+    }
+
+    @Override
+    public RegisteredType get(String symbolicName, String version, 
RegisteredTypeKind kind, Class<?> parentClass) {
+        return CI_TO_RT.apply( mgmt.getCatalog().getCatalogItem(symbolicName, 
version) );
+    }
+
+    @Override
+    public RegisteredType get(String symbolicName, String version) {
+        return get(symbolicName, version, null, null);
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Override
+    public <T extends AbstractBrooklynObjectSpec> T createSpec(RegisteredType 
type, Class<T> specKind) {
+        if (!(type instanceof RegisteredSpecType)) { 
+            throw new IllegalStateException("Cannot create spec from type 
"+type);
+        }
+        
+        CatalogItem item = 
mgmt.getCatalog().getCatalogItem(type.getSymbolicName(), type.getVersion());
+        return (T) mgmt.getCatalog().createSpec(item);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/typereg/BasicOsgiBundleWithUrl.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicOsgiBundleWithUrl.java
 
b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicOsgiBundleWithUrl.java
new file mode 100644
index 0000000..c21ca98
--- /dev/null
+++ 
b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicOsgiBundleWithUrl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.typereg;
+
+import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle;
+import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+
+public class BasicOsgiBundleWithUrl implements CatalogBundle, 
OsgiBundleWithUrl {
+    private String symbolicName;
+    private String version;
+    private String url;
+
+    // for deserializing (not sure if needed?)
+    @SuppressWarnings("unused")
+    private BasicOsgiBundleWithUrl() {}
+
+    public BasicOsgiBundleWithUrl(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 isFullDetailKnown() {
+        return symbolicName != null && version != null;
+    }
+    
+    @Override
+    @Deprecated //see super
+    public boolean isNamed() {
+        return isFullDetailKnown();
+    }
+
+    @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;
+        OsgiBundleWithUrl other = (OsgiBundleWithUrl) obj;
+        if (!Objects.equal(symbolicName, other.getSymbolicName())) return 
false;
+        if (!Objects.equal(version, other.getVersion())) return false;
+        if (!Objects.equal(url, other.getUrl())) return false;
+        return true;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
 
b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
new file mode 100644
index 0000000..7c719f2
--- /dev/null
+++ 
b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypePredicates.java
@@ -0,0 +1,180 @@
+/*
+ * 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.typereg;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Application;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+
+public class RegisteredTypePredicates {
+
+//    public static Predicate<RegisteredType> deprecated(final boolean 
deprecated) {
+//        return new DeprecatedEqualTo(deprecated);
+//    }
+//
+//    private static class DeprecatedEqualTo implements 
Predicate<RegisteredType> {
+//        private final boolean deprecated;
+//        
+//        public DeprecatedEqualTo(boolean deprecated) {
+//            this.deprecated = deprecated;
+//        }
+//        @Override
+//        public boolean apply(@Nullable RegisteredType item) {
+//            return (item != null) && item.isDeprecated() == deprecated;
+//        }
+//    }
+//
+//    public static Predicate<RegisteredType> disabled(boolean disabled) {
+//        return new DisabledEqualTo(disabled);
+//    }
+//
+//    private static class DisabledEqualTo implements 
Predicate<RegisteredType> {
+//        private final boolean disabled;
+//        
+//        public DisabledEqualTo(boolean disabled) {
+//            this.disabled = disabled;
+//        }
+//        @Override
+//        public boolean apply(@Nullable RegisteredType item) {
+//            return (item != null) && item.isDisabled() == disabled;
+//        }
+//    }
+
+    @SuppressWarnings("unused")
+    private static final Function<RegisteredType,String> 
ID_OF_ITEM_TRANSFORMER_ANONYMOUS = new Function<RegisteredType, String>() {
+        @Override @Nullable
+        public String apply(@Nullable RegisteredType input) {
+            if (input==null) return null;
+            return input.getId();
+        }
+    };
+
+    public static final Function<RegisteredType,String> ID_OF_ITEM_TRANSFORMER 
= new IdOfItemTransformer();
+    
+    private static class IdOfItemTransformer implements 
Function<RegisteredType,String> {
+        @Override @Nullable
+        public String apply(@Nullable RegisteredType input) {
+            if (input==null) return null;
+            return input.getId();
+        }
+    };
+
+    public static Predicate<RegisteredType> displayName(final Predicate<? 
super String> filter) {
+        return new DisplayNameMatches(filter);
+    }
+
+    private static class DisplayNameMatches implements 
Predicate<RegisteredType> {
+        private final Predicate<? super String> filter;
+        
+        public DisplayNameMatches(Predicate<? super String> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable RegisteredType item) {
+            return (item != null) && filter.apply(item.getDisplayName());
+        }
+    }
+
+    public static Predicate<RegisteredType> symbolicName(final Predicate<? 
super String> filter) {
+        return new SymbolicNameMatches(filter);
+    }
+    
+    private static class SymbolicNameMatches implements 
Predicate<RegisteredType> {
+        private final Predicate<? super String> filter;
+        
+        public SymbolicNameMatches(Predicate<? super String> filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable RegisteredType item) {
+            return (item != null) && filter.apply(item.getSymbolicName());
+        }
+    }
+
+    public static <T> Predicate<RegisteredType> javaType(final 
Predicate<Class<T>> filter) {
+        return new JavaTypeMatches(filter);
+    }
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public static Predicate<RegisteredType> javaTypeAssignableFrom(final 
Class<?> filter) {
+        return javaType((Predicate)Predicates.assignableFrom(filter));
+    }
+    
+    private static class JavaTypeMatches implements Predicate<RegisteredType> {
+        private final Predicate<Class<?>> filter;
+        
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        private <T> JavaTypeMatches(Predicate filter) {
+            this.filter = filter;
+        }
+        @Override
+        public boolean apply(@Nullable RegisteredType item) {
+            if (item==null) return false;
+            return (item != null) && filter.apply(item.getJavaType());
+        }
+    }
+
+    public static final Predicate<RegisteredType> IS_APPLICATION = 
javaTypeAssignableFrom(Application.class);
+    public static final Predicate<RegisteredType> IS_ENTITY = 
javaTypeAssignableFrom(Entity.class);
+    public static final Predicate<RegisteredType> IS_LOCATION = 
javaTypeAssignableFrom(Location.class);
+    public static final Predicate<RegisteredType> IS_POLICY = 
javaTypeAssignableFrom(Policy.class);
+
+    public static Predicate<RegisteredType> entitledToSee(final 
ManagementContext mgmt) {
+        return new EntitledToSee(mgmt);
+    }
+    
+    private static class EntitledToSee implements Predicate<RegisteredType> {
+        private final ManagementContext mgmt;
+        
+        public EntitledToSee(ManagementContext mgmt) {
+            this.mgmt = mgmt;
+        }
+        @Override
+        public boolean apply(@Nullable RegisteredType item) {
+            return (item != null) && 
+                    Entitlements.isEntitled(mgmt.getEntitlementManager(), 
Entitlements.SEE_CATALOG_ITEM, item.getId());
+        }
+    }
+ 
+//    public static Predicate<RegisteredType> isBestVersion(final 
ManagementContext mgmt) {
+//        return new IsBestVersion(mgmt);
+//    }
+//    
+//    private static class IsBestVersion implements Predicate<RegisteredType> {
+//        private final ManagementContext mgmt;
+//        
+//        public IsBestVersion(ManagementContext mgmt) {
+//            this.mgmt = mgmt;
+//        }
+//        @Override
+//        public boolean apply(@Nullable RegisteredType item) {
+//            return CatalogUtils.isBestVersion(mgmt, item);
+//        }
+//    }
+    
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java 
b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
new file mode 100644
index 0000000..0668d0a
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
@@ -0,0 +1,183 @@
+/*
+ * 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.typereg;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl;
+import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind;
+import org.apache.brooklyn.core.plan.PlanToSpecTransformer;
+
+import com.google.common.annotations.Beta;
+
+public class RegisteredTypes {
+
+    /** Visitor adapter which can be used to ensure all kinds are supported */
+    public static abstract class RegisteredTypeKindVisitor<T> {
+        public T visit(RegisteredType type) {
+            if (type==null) throw new NullPointerException("Registered type 
must not be null");
+            if (type instanceof RegisteredSpecType) {
+                visitSpec((RegisteredSpecType)type);
+            }
+            throw new IllegalStateException("Unexpected registered type: 
"+type.getClass());
+        }
+
+        protected abstract T visitSpec(RegisteredSpecType type);
+        
+        // TODO beans, others
+    }
+    
+    public static RegisteredTypeKind getKindOf(RegisteredType type) {
+        return new RegisteredTypeKindVisitor<RegisteredTypeKind>() {
+            @Override protected RegisteredTypeKind 
visitSpec(RegisteredSpecType type) { return RegisteredTypeKind.SPEC; }
+        }.visit(type);
+    }
+    
+    public abstract static class AbstractRegisteredType implements 
RegisteredType {
+
+        final String symbolicName;
+        final String version;
+        
+        List<OsgiBundleWithUrl> bundles;
+        String displayName;
+        String description;
+        String iconUrl;
+
+        // TODO ensure this is re-populated on rebind
+        transient Class<?> javaType;
+        
+        public AbstractRegisteredType(String symbolicName, String version, 
Class<?> javaType) {
+            this.symbolicName = symbolicName;
+            this.version = version;
+            this.javaType = javaType;
+        }
+
+        @Override
+        public String getId() {
+            return symbolicName + (version!=null ? ":"+version : "");
+        }
+
+        @Override
+        public String getSymbolicName() {
+            return symbolicName;
+        }
+
+        @Override
+        public String getVersion() {
+            return version;
+        }
+        
+        @Override
+        public Collection<OsgiBundleWithUrl> getLibraries() {
+            return bundles;
+        }
+
+        @Override
+        public String getDisplayName() {
+            return displayName;
+        }
+
+        @Override
+        public String getDescription() {
+            return description;
+        }
+
+        @Override
+        public String getIconUrl() {
+            return iconUrl;
+        }
+        
+        @Override
+        public Class<?> getJavaType() {
+            return javaType;
+        }
+    }
+
+    // TODO
+//    public static class RegisteredBeanType extends AbstractRegisteredType {
+//        
+//    }
+    
+    public static class RegisteredSpecType extends AbstractRegisteredType {
+
+        private TypeImplementation impl;
+        
+        public RegisteredSpecType(String symbolicName, String version, 
Class<?> javaType, TypeImplementation impl) {
+            super(symbolicName, version, javaType);
+            this.impl = impl;
+        }
+
+        public TypeImplementation getImplementation() {
+            return impl;
+        }
+    }
+
+    public static class TypeImplementation {
+        final String kind;
+        final Object data;
+        
+        public TypeImplementation(String kind, Object data) {
+            super();
+            this.kind = kind;
+            this.data = data;
+        }
+
+        /** details of the implementation, if known;
+         * this may be null if the relevant {@link PlanToSpecTransformer} was 
not declared when created,
+         * but in general we should look to determine the kind as early as 
possible and use that
+         * to retrieve the appropriate such transformer.
+         */
+        public String getKind() {
+            return kind;
+        }
+        
+        public Object getData() {
+            return data;
+        }
+    }
+    
+    public static class JavaTypeImplementation extends TypeImplementation {
+        public static final String KIND = "java";
+        public JavaTypeImplementation(String javaType) {
+            super(KIND, javaType);
+        }
+        public String getJavaType() { return (String)getData(); }
+    }
+    
+//    // TODO remove, unless we want it
+//    public static class CampYamlTypeImplementation extends 
TypeImplementation {
+//        public static final String KIND = "camp";
+//        public CampYamlTypeImplementation(String javaType) {
+//            super(KIND, javaType);
+//        }
+//        public String getCampYaml() { return (String)getData(); }
+//    }
+
+    /** returns the implementation data for a spec if it is a string (e.g. 
plan yaml or java class name); else false */
+    @Beta
+    public static String getImplementationDataStringForSpec(RegisteredType 
item) {
+        if (!(item instanceof RegisteredSpecType)) return null;
+        Object data = ((RegisteredSpecType)item).getImplementation().getData();
+        if (data instanceof String) return (String) data;
+        return null;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java 
b/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
index 006604d..9b94f57 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/osgi/Osgis.java
@@ -133,7 +133,7 @@ public class Osgis {
         }
 
         public BundleFinder bundle(CatalogBundle bundle) {
-            if (bundle.isNamed()) {
+            if (bundle.isFullDetailKnown()) {
                 symbolicName(bundle.getSymbolicName());
                 version(bundle.getVersion());
             }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoTest.java
 
b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoTest.java
index 0b72c90..dc3662c 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogDtoTest.java
@@ -147,11 +147,11 @@ public class CatalogDtoTest {
         String version = "0.1.2";
         String versionedId = CatalogUtils.getVersionedId(id, version);
         
-        Assert.assertNull(CatalogUtils.getIdFromVersionedId(null));
+        Assert.assertNull(CatalogUtils.getSymbolicNameFromVersionedId(null));
         Assert.assertNull(CatalogUtils.getVersionFromVersionedId(null));
-        Assert.assertNull(CatalogUtils.getIdFromVersionedId(id));
+        Assert.assertNull(CatalogUtils.getSymbolicNameFromVersionedId(id));
         Assert.assertNull(CatalogUtils.getVersionFromVersionedId(version));
-        Assert.assertEquals(CatalogUtils.getIdFromVersionedId(versionedId), 
id);
+        
Assert.assertEquals(CatalogUtils.getSymbolicNameFromVersionedId(versionedId), 
id);
         
Assert.assertEquals(CatalogUtils.getVersionFromVersionedId(versionedId), 
version);
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogScanTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogScanTest.java
 
b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogScanTest.java
index 7a4fecb..da5ca53 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogScanTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogScanTest.java
@@ -121,7 +121,8 @@ public class CatalogScanTest {
         
         Assert.assertEquals(s1.getDescription(), "Some silly app test");
         
-        Class<? extends Application> app = c.loadClass(s1);
+        @SuppressWarnings({ "unchecked", "rawtypes" })
+        Class<?> app = c.createSpec((CatalogItem)s1).getType();
         Assert.assertEquals(MySillyAppTemplate.class, app);
         
         String xml = ((BasicBrooklynCatalog)c).toXmlString();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
 
b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
index e7eeba9..0ca2171 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/CatalogVersioningTest.java
@@ -71,7 +71,7 @@ public class CatalogVersioningTest {
             Assert.assertFalse(CatalogUtils.looksLikeVersionedId(versionedId));
         } else {
             Assert.assertTrue(CatalogUtils.looksLikeVersionedId(versionedId));
-            
Assert.assertEquals(CatalogUtils.getIdFromVersionedId(versionedId), id);
+            
Assert.assertEquals(CatalogUtils.getSymbolicNameFromVersionedId(versionedId), 
id);
             
Assert.assertEquals(CatalogUtils.getVersionFromVersionedId(versionedId), 
version);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
----------------------------------------------------------------------
diff --git 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
index c9acdf3..921ea9e 100644
--- 
a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
+++ 
b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindTestFixture.java
@@ -289,7 +289,7 @@ public abstract class RebindTestFixture<T extends 
StartableApplication> {
         assertEquals(actualIds.size(), 
Iterables.size(actual.getCatalogItems()), "id keyset size != size of catalog. 
Are there duplicates in the catalog?");
         assertEquals(actualIds, expectedIds);
         for (String versionedId : actualIds) {
-            String id = CatalogUtils.getIdFromVersionedId(versionedId);
+            String id = 
CatalogUtils.getSymbolicNameFromVersionedId(versionedId);
             String version = 
CatalogUtils.getVersionFromVersionedId(versionedId);
             assertCatalogItemsEqual(actual.getCatalogItem(id, version), 
expected.getCatalogItem(id, version));
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/dc968f9d/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
----------------------------------------------------------------------
diff --git 
a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
 
b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
index 1876e99..3368df2 100644
--- 
a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
+++ 
b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/BrooklynAssemblyTemplateInstantiator.java
@@ -32,7 +32,6 @@ import org.apache.brooklyn.camp.spi.AssemblyTemplate;
 import org.apache.brooklyn.camp.spi.AssemblyTemplate.Builder;
 import org.apache.brooklyn.camp.spi.PlatformComponentTemplate;
 import org.apache.brooklyn.camp.spi.collection.ResolvableLink;
-import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
 import org.apache.brooklyn.core.mgmt.EntityManagementUtils.CreationResult;
 import org.apache.brooklyn.core.mgmt.HasBrooklynManagementContext;
@@ -74,8 +73,8 @@ public class BrooklynAssemblyTemplateInstantiator implements 
AssemblyTemplateSpe
     public List<EntitySpec<?>> createServiceSpecs(
             AssemblyTemplate template,
             CampPlatform platform, BrooklynClassLoadingContext itemLoader,
-            Set<String> encounteredCatalogTypes) {
-        return buildTemplateServicesAsSpecs(itemLoader, template, platform, 
encounteredCatalogTypes);
+            Set<String> encounteredRegisteredTypeIds) {
+        return buildTemplateServicesAsSpecs(itemLoader, template, platform, 
encounteredRegisteredTypeIds);
     }
 
     @Override
@@ -125,13 +124,13 @@ public class BrooklynAssemblyTemplateInstantiator 
implements AssemblyTemplateSpe
         return EntityManagementUtils.canPromoteWrappedApplication(app);
     }
 
-    private List<EntitySpec<?>> 
buildTemplateServicesAsSpecs(BrooklynClassLoadingContext loader, 
AssemblyTemplate template, CampPlatform platform, Set<String> 
encounteredCatalogTypes) {
+    private List<EntitySpec<?>> 
buildTemplateServicesAsSpecs(BrooklynClassLoadingContext loader, 
AssemblyTemplate template, CampPlatform platform, Set<String> 
encounteredRegisteredTypeIds) {
         List<EntitySpec<?>> result = Lists.newArrayList();
 
         for (ResolvableLink<PlatformComponentTemplate> ctl: 
template.getPlatformComponentTemplates().links()) {
             PlatformComponentTemplate appChildComponentTemplate = 
ctl.resolve();
             BrooklynComponentTemplateResolver entityResolver = 
BrooklynComponentTemplateResolver.Factory.newInstance(loader, 
appChildComponentTemplate);
-            EntitySpec<?> spec = 
entityResolver.resolveSpec(encounteredCatalogTypes);
+            EntitySpec<?> spec = 
entityResolver.resolveSpec(encounteredRegisteredTypeIds);
             result.add(spec);
         }
         return result;

Reply via email to