docs: @Override
      public void merge(WebServiceRef webServiceRef, Class<?> instanceClass, Member member) throws InjectionException {
  
          mergeWSRInfo(webServiceRef, instanceClass, member);
  
          // The former value should override the later one, i.e. the settings in DD should override the ones in annotation,
          // but we prefer the subclass.
          Class<?> annoType = webServiceRef.type();
          if (!annoType.getName().equals(Object.class.getName())) {
              Class<?> existingType = loadClass(wsrInfo.getServiceRefTypeClassName());
  
              if (!existingType.getName().equals(Object.class.getName())) {
                  //prefer the subclass
                  if (existingType.isAssignableFrom(annoType)) {
                      wsrInfo.setServiceRefTypeClassName(annoType.getName());
                  } else if (annoType.isAssignableFrom(existingType)) {
                      wsrInfo.setServiceRefTypeClassName(existingType.getName());
                  } else { // conflict
                      String msgKey;
                      Object[] inserts;
                      if (member != null) {
                          msgKey = "error.service.ref.type.mismatch.for.member";
                          inserts = new Object[] { wsrInfo.getJndiName(), member.getName(), member.getDeclaringClass().getName(),
                                                  annoType.getName(), existingType.getName() };
                      } else {
                          msgKey = "error.service.ref.type.mismatch.for.class";
                          inserts = new Object[] { wsrInfo.getJndiName(), annoType.getName(), existingType.getName() };
                      }
                      Tr.error(tc, msgKey, inserts);
                      throw new InjectionException(Tr.formatMessage(tc, msgKey, inserts));
                  }
              } else {
                  wsrInfo.setServiceRefTypeClassName(annoType.getName());
              }
          }
  
          Class<?> annoValue = webServiceRef.value();
          if (!annoValue.getName().equals(Service.class.getName())) {
              Class<?> existingValue = loadClass(wsrInfo.getServiceInterfaceClassName());
  
              if (!existingValue.getName().equals(Service.class.getName())) {
                  //prefer the subclass
                  if (existingValue.isAssignableFrom(annoValue)) {
                      wsrInfo.setServiceInterfaceClassName(annoValue.getName());
                  } else if (annoValue.isAssignableFrom(existingValue)) {
                      wsrInfo.setServiceInterfaceClassName(existingValue.getName());
                  } else { // conflict
                      String msgKey;
                      Object[] inserts;
                      if (member != null) {
                          msgKey = "error.service.interface.mismatch.for.member";
                          inserts = new Object[] { wsrInfo.getJndiName(), member.getName(), member.getDeclaringClass().getName(), annoValue.getName(),
                                                  existingValue.getName() };
                      } else {
                          msgKey = "error.service.interface.mismatch.for.class";
                          inserts = new Object[] { wsrInfo.getJndiName(), annoValue.getName(), existingValue.getName() };
                      }
                      Tr.error(tc, msgKey, inserts);
                      throw new InjectionException(Tr.formatMessage(tc, msgKey, inserts));
                  }
              } else {
                  wsrInfo.setServiceInterfaceClassName(annoValue.getName());
              }
          }
  
          // Validate and set value and type
          if (member == null) {
              validateAndSetClassLevelWebServiceRef(instanceClass);
          } else {
              // If the wsrInfo service ref type hasn't been set, the infer it from the member.
              validateAndSetMemberLevelWebServiceRef(member);
          }
  
          // now check the WSDL locations
          if (webServiceRef.wsdlLocation() != null && !webServiceRef.wsdlLocation().isEmpty()) {
              processExistingWSDL(webServiceRef.wsdlLocation(), member);
          }
  
          // now check to see if there was an @HandlerChain annotation on this member
          HandlerChain handlerChainInstance = null;
          if (member == null) {
              handlerChainInstance = instanceClass.getAnnotation(HandlerChain.class);
          } else if (member instanceof Field) {
              Field field = (Field) member;
              handlerChainInstance = field.getAnnotation(HandlerChain.class);
          } else if (member instanceof Method) {
              Method method = (Method) member;
              handlerChainInstance = method.getAnnotation(HandlerChain.class);
          }
          if (handlerChainInstance != null) {
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, "@HandlerChain annotation found with @WebServiceRef annotation, jndiName: " + webServiceRef.name());
              }
              wsrInfo.setHandlerChainDeclaringClassName(instanceClass.getName());
              wsrInfo.setHandlerChainAnnotation(handlerChainInstance);
          }
  
      }