@Override
 public List<String> getFlavorNames(String themePageName) {
   if (pageReg != null) {
     PageDescriptor themePage = pageReg.getPage(themePageName);
     if (themePage != null) {
       List<String> flavors = new ArrayList<String>();
       List<String> localFlavors = themePage.getFlavors();
       if (localFlavors != null) {
         flavors.addAll(localFlavors);
       }
       // add flavors from theme for all pages
       PageDescriptor forAllPage = pageReg.getConfigurationApplyingToAll();
       if (forAllPage != null) {
         localFlavors = forAllPage.getFlavors();
         if (localFlavors != null) {
           flavors.addAll(localFlavors);
         }
       }
       // add default flavor if it's not listed there
       String defaultFlavor = themePage.getDefaultFlavor();
       if (defaultFlavor != null) {
         if (!flavors.contains(defaultFlavor)) {
           flavors.add(0, defaultFlavor);
         }
       }
       return flavors;
     }
   }
   return null;
 }
 @Override
 public void unregisterContribution(
     Object contribution, String extensionPoint, ComponentInstance contributor) {
   if (contribution instanceof FlavorDescriptor) {
     FlavorDescriptor flavor = (FlavorDescriptor) contribution;
     flavorReg.removeContribution(flavor);
   } else if (contribution instanceof Resource) {
     Resource resource = (Resource) contribution;
     unregisterResource(resource);
   } else if (contribution instanceof SimpleStyle) {
     SimpleStyle style = (SimpleStyle) contribution;
     unregisterResource(getResourceFromStyle(style));
   } else if (contribution instanceof PageDescriptor) {
     PageDescriptor page = (PageDescriptor) contribution;
     if (page.hasResources() && !Framework.getRuntime().isShuttingDown()) {
       WebResourceManager wrm = Framework.getService(WebResourceManager.class);
       wrm.unregisterResourceBundle(page.getComputedResourceBundle());
     }
     pageReg.removeContribution(page);
   } else if (contribution instanceof NegotiationDescriptor) {
     NegotiationDescriptor neg = (NegotiationDescriptor) contribution;
     negReg.removeContribution(neg);
   } else {
     log.error(
         String.format(
             "Unknown contribution to the theme " + "styling service, extension point '%s': '%s",
             extensionPoint, contribution));
   }
 }
 @Override
 public String getDefaultFlavorName(String themePageName) {
   if (pageReg != null) {
     PageDescriptor themePage = pageReg.getPage(themePageName);
     if (themePage != null) {
       return themePage.getDefaultFlavor();
     }
   }
   return null;
 }
 protected void mergePage(PageDescriptor page, PageDescriptor globalPage) {
   if (page != null && globalPage != null) {
     // merge with global resources
     PageDescriptor clone = globalPage.clone();
     clone.setAppendFlavors(true);
     clone.setAppendResources(true);
     clone.setAppendStyles(true);
     page.merge(clone);
   }
 }
 @Override
 public void registerContribution(
     Object contribution, String extensionPoint, ComponentInstance contributor) {
   if (contribution instanceof FlavorDescriptor) {
     FlavorDescriptor flavor = (FlavorDescriptor) contribution;
     log.info(String.format("Register flavor '%s'", flavor.getName()));
     registerFlavor(flavor, contributor.getContext());
     log.info(String.format("Done registering flavor '%s'", flavor.getName()));
   } else if (contribution instanceof SimpleStyle) {
     SimpleStyle style = (SimpleStyle) contribution;
     log.info(String.format("Register style '%s'", style.getName()));
     String message =
         String.format(
             "Style '%s' on component %s should now be contributed to extension "
                 + "point '%s': a compatibility registration was performed but it may not be "
                 + "accurate. Note that the 'flavor' processor should be used with this resource.",
             style.getName(), contributor.getName(), WR_EX);
     DeprecationLogger.log(message, "7.4");
     Framework.getRuntime().getWarnings().add(message);
     ResourceDescriptor resource = getResourceFromStyle(style);
     registerResource(resource, contributor.getContext());
     log.info(String.format("Done registering style '%s'", style.getName()));
   } else if (contribution instanceof PageDescriptor) {
     PageDescriptor page = (PageDescriptor) contribution;
     log.info(String.format("Register page '%s'", page.getName()));
     if (page.hasResources()) {
       // automatically register a bundle for page resources
       WebResourceManager wrm = Framework.getService(WebResourceManager.class);
       wrm.registerResourceBundle(page.getComputedResourceBundle());
     }
     pageReg.addContribution(page);
     log.info(String.format("Done registering page '%s'", page.getName()));
   } else if (contribution instanceof ResourceDescriptor) {
     ResourceDescriptor resource = (ResourceDescriptor) contribution;
     log.info(String.format("Register resource '%s'", resource.getName()));
     String message =
         String.format(
             "Resource '%s' on component %s should now be contributed to extension "
                 + "point '%s': a compatibility registration was performed but it may not be accurate.",
             resource.getName(), contributor.getName(), WR_EX);
     DeprecationLogger.log(message, "7.4");
     Framework.getRuntime().getWarnings().add(message);
     // ensure path is absolute, consider that resource is in the war, and if not, user will have
     // to declare it
     // directly to the WRM endpoint
     String path = resource.getPath();
     if (path != null && !path.startsWith("/")) {
       resource.setUri("/" + path);
     }
     registerResource(resource, contributor.getContext());
     log.info(String.format("Done registering resource '%s'", resource.getName()));
   } else if (contribution instanceof NegotiationDescriptor) {
     NegotiationDescriptor neg = (NegotiationDescriptor) contribution;
     log.info(String.format("Register negotiation for '%s'", neg.getTarget()));
     negReg.addContribution(neg);
     log.info(String.format("Done registering negotiation for '%s'", neg.getTarget()));
   } else {
     log.error(
         String.format(
             "Unknown contribution to the theme " + "styling service, extension point '%s': '%s",
             extensionPoint, contribution));
   }
 }