docs: public TypeDefinitionRegistry merge(TypeDefinitionRegistry typeRegistry) throws SchemaProblem {
          List<GraphQLError> errors = new ArrayList<>();
  
          Map<String, TypeDefinition> tempTypes = new LinkedHashMap<>();
          typeRegistry.types.values().forEach(newEntry -> {
              Optional<GraphQLError> defined = define(this.types, tempTypes, newEntry);
              defined.ifPresent(errors::add);
          });
  
          Map<String, DirectiveDefinition> tempDirectiveDefs = new LinkedHashMap<>();
          typeRegistry.directiveDefinitions.values().forEach(newEntry -> {
              Optional<GraphQLError> defined = define(this.directiveDefinitions, tempDirectiveDefs, newEntry);
              defined.ifPresent(errors::add);
          });
  
          Map<String, ScalarTypeDefinition> tempScalarTypes = new LinkedHashMap<>();
          typeRegistry.scalarTypes.values().forEach(newEntry -> define(this.scalarTypes, tempScalarTypes, newEntry).ifPresent(errors::add));
  
          if (typeRegistry.schema != null && this.schema != null) {
              errors.add(new SchemaRedefinitionError(this.schema, typeRegistry.schema));
          }
  
          if (!errors.isEmpty()) {
              throw new SchemaProblem(errors);
          }
  
          if (this.schema == null) {
              // ensure schema is not overwritten by merge
              this.schema = typeRegistry.schema;
          }
  
          // ok commit to the merge
          this.types.putAll(tempTypes);
          this.scalarTypes.putAll(tempScalarTypes);
          this.directiveDefinitions.putAll(tempDirectiveDefs);
          //
          // merge type extensions since they can be redefined by design
          typeRegistry.objectTypeExtensions.forEach((key, value) -> {
              List<ObjectTypeExtensionDefinition> currentList = this.objectTypeExtensions
                      .computeIfAbsent(key, k -> new ArrayList<>());
              currentList.addAll(value);
          });
          typeRegistry.interfaceTypeExtensions.forEach((key, value) -> {
              List<InterfaceTypeExtensionDefinition> currentList = this.interfaceTypeExtensions
                      .computeIfAbsent(key, k -> new ArrayList<>());
              currentList.addAll(value);
          });
          typeRegistry.unionTypeExtensions.forEach((key, value) -> {
              List<UnionTypeExtensionDefinition> currentList = this.unionTypeExtensions
                      .computeIfAbsent(key, k -> new ArrayList<>());
              currentList.addAll(value);
          });
          typeRegistry.enumTypeExtensions.forEach((key, value) -> {
              List<EnumTypeExtensionDefinition> currentList = this.enumTypeExtensions
                      .computeIfAbsent(key, k -> new ArrayList<>());
              currentList.addAll(value);
          });
          typeRegistry.scalarTypeExtensions.forEach((key, value) -> {
              List<ScalarTypeExtensionDefinition> currentList = this.scalarTypeExtensions
                      .computeIfAbsent(key, k -> new ArrayList<>());
              currentList.addAll(value);
          });
          typeRegistry.inputObjectTypeExtensions.forEach((key, value) -> {
              List<InputObjectTypeExtensionDefinition> currentList = this.inputObjectTypeExtensions
                      .computeIfAbsent(key, k -> new ArrayList<>());
              currentList.addAll(value);
          });
  
          return this;
      }