docs: private void addTarget(
      Object key,
      String topic,
      String selectorString,
      SelectorDomain domain,
      Resolver resolver,
      MatchTarget target,
      Selector inputSelector,
      Map<String, Object> selectorProperties)
      throws InvalidTopicSyntaxException,
             SIDiscriminatorSyntaxException,
             QuerySyntaxException,
             MatchingException
    {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.entry(tc,
                    "addTarget",
                    new Object[]{key,
                                 topic,
                                 selectorString,
                                 domain,
                                 resolver,
                                 target});
  
      _syntaxChecker.checkTopicSyntax(topic);
      Selector selectorTree = _matching.createTopicLikeOperator(_rootId, topic);
      Transformer transformer = Matching.getTransformer();
      // get single instance of Transformer
      if (selectorString != null && selectorString.trim().length() != 0)
      {
        try
        {
          // Synchronization block to protect the parser object from being reset
          // whilst in use.
          synchronized (this)
          {
            Selector parsed;
            if (inputSelector == null)
            {
              MatchParser parser = null;
              if(domain.equals(SelectorDomain.JMS))
              {
                // Drive the parser
                _sibParser = _matching.primeMatchParser(_sibParser,
                                                   selectorString,
                                                   SelectorDomain.JMS.toInt());
                parser = _sibParser;
              }
              else if(domain.equals(SelectorDomain.SIMESSAGE))
              {
                // Drive the parser
                _sibParser = _matching.primeMatchParser(_sibParser,
                                                   selectorString,
                                                   SelectorDomain.SIMESSAGE.toInt());
                parser = _sibParser;
              }
              else // In the XPath1.0 case we use the default resolver
              {
                // Drive the parser
                _xpathParser = _matching.primeMatchParser(_xpathParser,
                                                   selectorString,
                                                   SelectorDomain.XPATH1.toInt());
  
                // The selector expression may incorporate namespace prefix mappings, so we
                // handle those here.
                if(selectorProperties != null)
                {
                  Map<String, String> prefixMappings = null;
                  prefixMappings = (Map<String, String>)selectorProperties.get("namespacePrefixMappings");
                  if(prefixMappings != null)
                  {
                    XPath10Parser xpParser = (XPath10Parser)_xpathParser;
                    xpParser.setNamespaceMappings(prefixMappings);
                  }
                }
                parser = _xpathParser;
              }
  
              // We're ready to parse the selector
              if(disableXPathOptimizer && domain.equals(SelectorDomain.XPATH1))
              {
                // In this special case we'll disable the MatchSpace XPath
                // optimizations and process XPath expressions as whole entities.
                XPath10Parser xpParser = (XPath10Parser)parser;
  
                // The selector expression may incorporate namespace prefix mappings, so we
                // handle those here.
                if(selectorProperties != null)
                {
                  Map<String, String> prefixMappings = null;
                  prefixMappings = (Map<String, String>)selectorProperties.get("namespacePrefixMappings");
                  if(prefixMappings != null)
                  {
                    xpParser.setNamespaceMappings(prefixMappings);
                  }
                }
  
                parsed = xpParser.parseWholeSelector(selectorString);
              }
              else
              {
                // Parse in the usual manner
                parsed = parser.getSelector(selectorString);
              }
  
              if (parsed.getType() == Selector.INVALID)
              {
                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                  SibTr.exit(tc, "addTarget", "QuerySyntaxException");
  
                throw new QuerySyntaxException(selectorString);
              }
              if (resolver == null)
                resolver = _defaultResolver;
              parsed = transformer.resolve(parsed, resolver, _positionAssigner);
              if (parsed.getType() == Selector.INVALID)
              {
                if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                  SibTr.exit(tc, "addTarget", "QuerySyntaxException");
  
                throw new QuerySyntaxException(selectorString);
              }
            }
            else
            {
              parsed = inputSelector;
            }
  
            selectorTree =
              _matching.createOperator(Selector.AND, selectorTree, parsed);
          }
        }
        catch (RuntimeException e)
        {
          // No FFDC code needed
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(tc, "addTarget", "QuerySyntaxException");
          throw new QuerySyntaxException(e.getMessage());
        }
      }
  
      // Dont do DNF transformation in XPATH Case.
      Conjunction[] expr = null;
      if(domain != null && domain.equals(SelectorDomain.XPATH1))
        expr = transformer.organizeTests(selectorTree);
      else
        expr = transformer.organizeTests(transformer.DNF(selectorTree));
  
      if (expr == null)
        expr = new Conjunction[] { null };
  
      MatchTarget[] targ = new MatchTarget[expr.length];
  
      for (int i = 0; i < targ.length; i++)
      {
        targ[i] = (i == 0) ? target : target.duplicate();
        _matchSpace.addTarget(expr[i], targ[i]);
      }
  
      // Add to the HashMap, with synch, there may be other accessors
      synchronized(_targets)
      {
        // If this is a subscription, then we need to modify
        // the monitoring state.
        if(target instanceof MonitoredConsumer)
        {
          _consumerMonitoring.addConsumer(key,
                                        topic,
                                        selectorString,
                                        target,
                                        isWildCarded(topic));
        }
  
        // Now add the target to the _targets table
        _targets.put(key, new Target(expr, targ));
      }
  
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(tc, "addTarget");
    }