private void checkSpecTypeIsValid(String type, Class<? extends BrooklynObject> subType) {
   if (RegisteredTypes.validate(
           mgmt().getTypeRegistry().get(type), RegisteredTypeLoadingContexts.spec(subType))
       == null) {
     try {
       brooklyn().getCatalogClassLoader().loadClass(type);
     } catch (ClassNotFoundException e) {
       log.debug("Class not found for type '" + type + "'; reporting 404", e);
       throw WebResourceUtils.notFound("Undefined type '%s'", type);
     }
     log.info(
         JavaClassNames.simpleClassName(subType)
             + " type '{}' not defined in catalog but is on classpath; continuing",
         type);
   }
 }
  @SuppressWarnings({"unchecked"})
  @Override
  public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(
      CatalogItem<T, SpecT> item, Set<String> encounteredTypes) {
    // Ignore old-style java type catalog items - there is a different (deprecated) transformer for
    // that
    if (item.getPlanYaml() == null) {
      throw new PlanNotRecognizedException("Old style catalog item " + item + " not supported.");
    }
    if (encounteredTypes.contains(item.getSymbolicName())) {
      throw new IllegalStateException(
          "Already encountered types "
              + encounteredTypes
              + " must not contain catalog item being resolver "
              + item.getSymbolicName());
    }

    // Not really clear what should happen to the top-level attributes, ignored until a good use
    // case appears.
    return (SpecT)
        CampResolver.createSpecFromFull(
            mgmt, RegisteredTypes.of(item), item.getCatalogItemJavaType(), encounteredTypes, null);
  }