/**
   * Here is what we do to deal with whitelisted children: 1) Find each transform(parent, child,
   * context)-> whitelisted children 2) Find composite(parent, child, context)-> all children. 3)
   * For each child element not in the whitelist -> hide the child element.
   */
  private void whitelistElements() {

    for (Map.Entry<RootKey, ElementMetadataRegistryBuilder> rootEntry : elements.entrySet()) {
      ElementMetadataRegistryBuilder builder = rootEntry.getValue();
      Map<TransformKey, Set<ElementKey<?, ?>>> whitelistMap = Maps.newLinkedHashMap();

      Map<TransformKey, ElementCreatorImpl> creators = builder.getCreators();

      for (Map.Entry<TransformKey, ElementCreatorImpl> entry : creators.entrySet()) {
        TransformKey key = entry.getKey();
        ElementCreatorImpl element = entry.getValue();
        if (element.getElementWhitelist() != null) {
          whitelistMap.put(key, element.getElementWhitelist());
        }
      }

      for (Map.Entry<TransformKey, Set<ElementKey<?, ?>>> whitelistEntry :
          whitelistMap.entrySet()) {
        TransformKey key = whitelistEntry.getKey();
        Set<ElementKey<?, ?>> whitelist = whitelistEntry.getValue();
        Set<QName> whitelistNames = Sets.newHashSet();
        for (ElementKey<?, ?> whitelistKey : whitelist) {
          whitelistNames.add(whitelistKey.getId());
        }

        Set<ElementKey<?, ?>> allChildren = Sets.newHashSet();
        for (Map.Entry<TransformKey, ElementCreatorImpl> entry : creators.entrySet()) {

          if (entry.getKey().matches(key)) {
            allChildren.addAll(entry.getValue().getElementSet());
          }
        }

        if (!allChildren.containsAll(whitelist)) {
          Set<ElementKey<?, ?>> missing = Sets.newHashSet(whitelist);
          missing.removeAll(allChildren);
          throw new IllegalStateException(
              "Missing children!  Whitelist specified "
                  + missing
                  + " but did not find those child elements.");
        }

        for (ElementKey<?, ?> child : allChildren) {
          if (!whitelistNames.contains(child.getId())) {
            ElementKey<?, ?> parent = (ElementKey<?, ?>) key.getKey();
            build(parent, child, key.getContext()).setVisible(false);
          }
        }
      }
    }
  }
 /**
  * Registers the metadata for an element key. This will call the "registerMetadata" method on the
  * {@link Element} subclass that the key refers to, if it refers to a subclass. If it refers to
  * Element directly it will just build the key.
  *
  * @throws IllegalArgumentException if the element type does not support a registration method.
  */
 public MetadataRegistry register(ElementKey<?, ?> key) {
   if (key != null) {
     Class<? extends Element> elementType = key.getElementType();
     if (Element.class == elementType) {
       build(key);
     } else {
       registerClass(elementType);
     }
   }
   return this;
 }