docs: public void addInjectionTarget(Class<?> injectionType,
                                     String targetName,
                                     String targetClassName)
                      throws InjectionException
      {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
          if (isTraceOn && tc.isEntryEnabled())
              Tr.entry(tc, "addInjectionTarget : " + injectionType +
                           ", " + targetName + ", " + targetClassName);
  
          // F743-32443 - For federated client modules, we don't have a classloader,
          // so we need to defer target resolution until the client process is
          // running.  Save away the target names until they can be processed by
          // InjectionEngineImpl.processClientInjections.
          if (ivNameSpaceConfig.getOwningFlow() == ComponentNameSpaceConfiguration.ReferenceFlowKind.CLIENT &&
              ivNameSpaceConfig.getClassLoader() == null) // F743-32443
          {
              addInjectionTarget(new ClientInjectionTarget(targetClassName, targetName, this));
  
              if (isTraceOn && tc.isEntryEnabled())
                  Tr.exit(tc, "addInjectionTarget: added client injection target");
              return;
          }
  
          Field targetField = null;
          Method targetMethod = null;
          Class<?> injectionClass = loadClass(targetClassName); // d446474
          InjectionTarget injectionTarget = null;
  
          if (targetName != null &&
              targetClassName != null &&
              injectionClass != null)
          {
              // --------------------------------------------------------------------
              // First, try to locate the JavaBean property set method for the
              // specified target name. Per the EJB spec, the target name is the
              // JavaBean property name, and injection must be performed into the
              // corresponding set method if it exists.
              //
              // The following loop has been re-written to include looking for
              // type compatible set methods and to improve performance.      d648283
              // ---------------------------------------------------------------------
  
              Method primitiveMethod = null;
              List<Method> compatibleMethods = null;
              boolean isClient = ivNameSpaceConfig.isClientMain(injectionClass);
              String setMethodName = getMethodFromProperty(targetName);
              Class<?> primitiveClass = getPrimitiveClass(injectionType);
              List<Method> declaredMethods;
  
              try
              {
                  declaredMethods = getDeclaredSetMethods(injectionClass, isClient); // F743-32443
              } catch (LinkageError err) // RTC116577
              {
                  String message = Tr.formatMessage(tc,
                                                    "DECLARED_MEMBER_LINKAGE_ERROR_CWNEN0075E",
                                                    targetClassName,
                                                    setMethodName,
                                                    getJndiName(),
                                                    ivNameSpaceConfig.getDisplayName(),
                                                    ivNameSpaceConfig.getModuleName(),
                                                    ivNameSpaceConfig.getApplicationName(),
                                                    err.toString());
                  InjectionException ex = new InjectionException(message, err);
  
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                      Tr.debug(tc, "addInjectionTarget", ex);
                  throw ex;
              }
  
              for (Method method : declaredMethods)
              {
                  if (method.getName().equals(setMethodName))
                  {
                      Class<?>[] params = method.getParameterTypes();
                      if (params.length == 1)
                      {
                          // If the reference type was not defined in XML, then all
                          // methods with this name and 1 parameter are compatible. d667739.1
                          if (injectionType == null)
                          {
                              if (isTraceOn && tc.isDebugEnabled())
                                  Tr.debug(tc, "target method found (compatible) : " + method);
                              if (compatibleMethods == null) {
                                  compatibleMethods = new ArrayList<Method>();
                              }
                              compatibleMethods.add(method);
                              continue;
                          }
  
                          Class<?> param = params[0];
  
                          // First, look for the set method with specific type parameter;
                          // if found, then this is the one to use, done looking
                          if (param == injectionType)
                          {
                              if (isTraceOn && tc.isDebugEnabled())
                                  Tr.debug(tc, "target method found (specific) : " + method);
                              targetMethod = method;
                              break;
                          }
  
                          // Next, look for the set method with primitive version of type;
                          // if found, keep looking for one with specific match (above).
                          if (param == primitiveClass)
                          {
                              if (isTraceOn && tc.isDebugEnabled())
                                  Tr.debug(tc, "target method found (primitive) : " + method);
                              primitiveMethod = method;
                          }
  
                          // Finally, look for a type compatible match;          d648283
                          // if found, keep looking for more specific match (above).
                          else if (param.isAssignableFrom(injectionType))
                          {
                              if (isTraceOn && tc.isDebugEnabled())
                                  Tr.debug(tc, "target method found (compatible) : " + method);
                              if (compatibleMethods == null) {
                                  compatibleMethods = new ArrayList<Method>();
                              }
                              compatibleMethods.add(method);
                          }
                      }
                  }
              }
  
              // Now that the methods have been searched, use the one with the
              // most specific parameter type match.
              if (targetMethod == null)
              {
                  if (primitiveMethod != null)
                  {
                      targetMethod = primitiveMethod;
                  }
  
                  // Use a type compatible method if there is only one;
                  // otherwise, it is ambiguous.                               d648283
                  else if (compatibleMethods != null)
                  {
                      if (compatibleMethods.size() == 1)
                      {
                          targetMethod = compatibleMethods.get(0);
                      }
                      else
                      {
                          // More than one set method was found that is compatible
                          // with the injection type - unable to determine which
                          // one to use.                                         d648283
                          InjectionException iex = new InjectionException
                                          ("The " + targetName + " injection target property name for the " +
                                           getJndiName() + " reference is ambiguous in the " + targetClassName +
                                           " class.  The " + compatibleMethods.get(0) + " method and the " +
                                           compatibleMethods.get(1) + " method are both type compatible with the " +
                                           injectionType + " type.");
                          Tr.error(tc, "AMBIGUOUS_INJECTION_METHODS_CWNEN0061E",
                                   targetName, getJndiName(), targetClassName,
                                   compatibleMethods.get(0), compatibleMethods.get(1),
                                   injectionType);
                          throw iex;
                      }
                  }
              }
  
              if (targetMethod != null)
              {
                  // The method has been found, so looking for the field will be
                  // skipped (below)... however, don't bother creating the target
                  // if one already exists for this method.                    d648283
                  if (!containsTarget(targetMethod)) {
                      injectionTarget = createInjectionTarget(targetMethod,
                                                              this);
                  }
              }
  
              // --------------------------------------------------------------------
              // Second, if a set method could not be found, try to locate a field
              // with the JavaBean property name (i.e the specified target name).
              // ---------------------------------------------------------------------
  
              else
              {
                  // try to locate the target as field.
                  try
                  {
                      targetField = injectionClass.getDeclaredField(targetName);
                      Class<?> fieldClass = targetField.getType();
  
                      // <injection-target-class> and Field type consistency check
                      if (injectionType == null || // not specified          d667739.1
                          isClassesCompatible(fieldClass, injectionType))
                      {
                          if (isTraceOn && tc.isDebugEnabled())
                              Tr.debug(tc, "target field found (compatible) : " + targetField);
  
                          // The field has been found... however, don't bother creating
                          // the target if a one already exists for this field.  d648283
                          if (!containsTarget(targetField)) {
                              injectionTarget = new InjectionTargetField(targetField,
                                              this);
                          }
                      }
                      else
                      {
                          // This really should be an error, however this is the way
                          // the original code shipped, so changing this to an error
                          // could result in customer regressions.
                          String qualifiedTargetName = injectionClass.getName() + "." + targetName; // d668039
                          Tr.warning(tc, "FIELD_IS_DECLARED_DIFFERENT_THAN_THE_INECTION_TYPE_CWNEN0021W",
                                     qualifiedTargetName, fieldClass.getName(), injectionType.getName());
  
                          if (isValidationFailable()) // fail if enabled    F743-14449
                          {
                              throw new InjectionConfigurationException("The " + qualifiedTargetName +
                                                                        " field is declared as " + fieldClass.getName() +
                                                                        " but the requested injection type for the field is " +
                                                                        injectionType.getName() + ".");
                          }
                      }
                  } catch (NoSuchFieldException e)
                  {
                      FFDCFilter.processException(e, CLASS_NAME + ".addInjectionTarget",
                                                  "254", this, new Object[] { targetClassName, targetName });
  
                      // Unable to find either a set method or field, so log an error and
                      // fail indicating that neither could be found.
                      InjectionException iex = new InjectionException
                                      ("An injection target for the " + getJndiName() +
                                       " reference cannot be processed because neither the " +
                                       setMethodName + " method nor the " + targetName +
                                       " field exist on the " + targetClassName + " class.");
                      Tr.error(tc, "UNABLE_TO_FIND_THE_MEMBER_SPECIFIED_CWNEN0022E",
                               getJndiName(), setMethodName, targetName, targetClassName);
                      throw iex;
                  } catch (LinkageError err) // RTC116577
                  {
                      String message = Tr.formatMessage(tc,
                                                        "DECLARED_MEMBER_LINKAGE_ERROR_CWNEN0075E",
                                                        targetClassName,
                                                        targetName,
                                                        getJndiName(),
                                                        ivNameSpaceConfig.getDisplayName(),
                                                        ivNameSpaceConfig.getModuleName(),
                                                        ivNameSpaceConfig.getApplicationName(),
                                                        err.toString());
                      InjectionException ex = new InjectionException(message, err);
  
                      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
                          Tr.debug(tc, "addInjectionTarget", ex);
                      throw ex;
                  }
              }
          }
          else if (targetName != null ||
                   injectionType != null ||
                   injectionClass != null)
          {
              InjectionException iex;
              iex = new InjectionException("One or more of these argument(s) is null.  " + targetName + " targetName, " + injectionType + " injectionType, " + injectionClass
                                           + " injectionClass");
              Tr.error(tc, "INCORRECT_OR_NULL_INJECTION_TARGETS_SPECIFIED_CWNEN0023E", targetName, injectionType, injectionClass);
              throw iex;
          }
  
          // It may be normal at this point to not have an injection target. This
          // will occur if a target already exists for the field or method, or
          // the type of the field was not compatible with the injection type
          // (which should be an error, but historically has just been a warning.
          // If a target does exist, then finish setting it up and add it to the
          // list of targets associated with this binding.
          if (injectionTarget != null)
          {
              injectionTarget.setInjectionBinding(this);
              injectionTarget.ivFromXML = true; // d510950
  
              if (isTraceOn && tc.isDebugEnabled())
                  Tr.debug(tc, "adding injection target : " + injectionTarget);
  
              addInjectionTarget(injectionTarget);
          }
          else
          {
              if (isTraceOn && tc.isDebugEnabled())
                  Tr.debug(tc, "no injection target to add : duplicate or not compatible");
          }
  
          if (isTraceOn && tc.isEntryEnabled())
              Tr.exit(tc, "addInjectionTarget : " + ivInjectionTargets);
      }