/**
  * Merges another metadata registry into this metadata registry. Both registries are locked during
  * this time, first this registry and then the other registry. Do not attempt to do a.merge(b) and
  * b.merge(a) in separate threads at the same time or a deadlock may occur.
  */
 public synchronized MetadataRegistry merge(MetadataRegistry other) {
   synchronized (other) {
     for (Map.Entry<RootKey, AttributeMetadataRegistryBuilder> entry :
         other.attributes.entrySet()) {
       RootKey key = entry.getKey();
       AttributeMetadataRegistryBuilder builder = attributes.get(key);
       if (builder == null) {
         builder = new AttributeMetadataRegistryBuilder(this);
         attributes.put(key, builder);
       }
       builder.merge(entry.getValue());
     }
     for (Map.Entry<RootKey, ElementMetadataRegistryBuilder> entry : other.elements.entrySet()) {
       RootKey key = entry.getKey();
       ElementMetadataRegistryBuilder builder = elements.get(key);
       if (builder == null) {
         builder = new ElementMetadataRegistryBuilder(this);
         elements.put(key, builder);
       }
       builder.merge(entry.getValue());
     }
   }
   return this;
 }