docs: final boolean conflictsWith( NodeType primaryNodeType,
                                   NodeType[] mixinNodeTypes ) {
          Map<PropertyDefinitionId, JcrPropertyDefinition> props = new HashMap<PropertyDefinitionId, JcrPropertyDefinition>();
          /*
           * Need to have the same parent name for all PropertyDefinitionIds and NodeDefinitionIds as we're checking for conflicts on the definition name
           */
          final Name DEFAULT_NAME = this.name;
  
          for (JcrPropertyDefinition property : propertyDefinitions()) {
              /*
               * I'm trying really hard to reuse existing code, but it's a stretch in this case.  I don't care about the property
               * types or where they were declared... if more than one definition with the given name exists (not counting definitions
               * inherited from the same root definition), then there is a conflict.
               */
              PropertyDefinitionId pid = new PropertyDefinitionId(DEFAULT_NAME, property.name, PropertyType.UNDEFINED,
                                                                  property.isMultiple());
              props.put(pid, property);
          }
  
          /*
           * The specification does not mandate whether this should or should not be consider a conflict.  However, the Apache
           * TCK canRemoveMixin test cases assume that this will generate a conflict.
           */
          if (primaryNodeType.getName().equals(getName())) {
              // This node type has already been applied to the node
              return true;
          }
  
          for (JcrPropertyDefinition property : ((JcrNodeType)primaryNodeType).propertyDefinitions()) {
              PropertyDefinitionId pid = new PropertyDefinitionId(DEFAULT_NAME, property.name, PropertyType.UNDEFINED,
                                                                  property.isMultiple());
              JcrPropertyDefinition oldProp = props.put(pid, property);
              if (oldProp != null) {
                  String oldPropTypeName = oldProp.getDeclaringNodeType().getName();
                  String propTypeName = property.getDeclaringNodeType().getName();
                  if (!oldPropTypeName.equals(propTypeName)) {
                      // The two types conflict as both separately declare a property with the same name
                      return true;
                  }
              }
          }
  
          for (NodeType mixinNodeType : mixinNodeTypes) {
              /*
               * The specification does not mandate whether this should or should not be consider a conflict.  However, the Apache
               * TCK canRemoveMixin test cases assume that this will generate a conflict.
               */
              if (mixinNodeType.getName().equals(getName())) {
                  // This node type has already been applied to the node
                  return true;
              }
  
              for (JcrPropertyDefinition property : ((JcrNodeType)mixinNodeType).propertyDefinitions()) {
                  PropertyDefinitionId pid = new PropertyDefinitionId(DEFAULT_NAME, property.name, PropertyType.UNDEFINED,
                                                                      property.isMultiple());
                  JcrPropertyDefinition oldProp = props.put(pid, property);
                  if (oldProp != null) {
                      String oldPropTypeName = oldProp.getDeclaringNodeType().getName();
                      String propTypeName = property.getDeclaringNodeType().getName();
                      if (!oldPropTypeName.equals(propTypeName)) {
                          // The two types conflict as both separately declare a property with the same name
                          return true;
                      }
                  }
              }
          }
  
          Map<NodeDefinitionId, JcrNodeDefinition> childNodes = new HashMap<NodeDefinitionId, JcrNodeDefinition>();
  
          for (JcrNodeDefinition childNode : childNodeDefinitions()) {
              NodeDefinitionId nid = new NodeDefinitionId(DEFAULT_NAME, childNode.name, new Name[0]);
              childNodes.put(nid, childNode);
          }
  
          for (JcrNodeDefinition childNode : ((JcrNodeType)primaryNodeType).childNodeDefinitions()) {
              NodeDefinitionId nid = new NodeDefinitionId(DEFAULT_NAME, childNode.name, new Name[0]);
              JcrNodeDefinition oldNode = childNodes.put(nid, childNode);
              if (oldNode != null) {
                  String oldNodeTypeName = oldNode.getDeclaringNodeType().getName();
                  String childNodeTypeName = childNode.getDeclaringNodeType().getName();
                  if (!oldNodeTypeName.equals(childNodeTypeName)) {
                      // The two types conflict as both separately declare a child node with the same name
                      return true;
                  }
              }
          }
  
          for (NodeType mixinNodeType : mixinNodeTypes) {
              for (JcrNodeDefinition childNode : ((JcrNodeType)mixinNodeType).childNodeDefinitions()) {
                  NodeDefinitionId nid = new NodeDefinitionId(DEFAULT_NAME, childNode.name, new Name[0]);
                  JcrNodeDefinition oldNode = childNodes.put(nid, childNode);
                  if (oldNode != null) {
                      String oldNodeTypeName = oldNode.getDeclaringNodeType().getName();
                      String childNodeTypeName = childNode.getDeclaringNodeType().getName();
                      if (!oldNodeTypeName.equals(childNodeTypeName)) {
                          // The two types conflict as both separately declare a child node with the same name
                          return true;
                      }
                  }
              }
          }
  
          return false;
      }