code: public String buildAddTopicExpression(
      String destName,
      String discriminator) throws SIDiscriminatorSyntaxException
    {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.entry(
          tc,
          "buildAddTopicExpression",
          new Object[] { destName, discriminator });
  
      String combo = null;
  
      if (discriminator == null)
        combo =
          destName
            + MatchSpace.SUBTOPIC_DOUBLE_SEPARATOR_STOP_STRING;
      else if (discriminator.trim().length() == 0)
        combo =
          destName;
      else if (discriminator.startsWith(MatchSpace.SUBTOPIC_DOUBLE_SEPARATOR_STRING))
        combo =
          destName
            + discriminator;
      else if (discriminator.startsWith(""+MatchSpace.SUBTOPIC_SEPARATOR_CHAR))
      {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
          SibTr.exit(tc, "buildAddTopicExpression", "SISelectorSyntaxException");
  
        throw new SIDiscriminatorSyntaxException(
          nls.getFormattedMessage(
            "INVALID_TOPIC_ERROR_CWSIP0372",
            new Object[] { discriminator },
            null));
      }
      else
        combo =
          destName
            + MatchSpace.SUBTOPIC_SEPARATOR_CHAR
            + discriminator;
  
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
        SibTr.exit(tc, "buildAddTopicExpression", combo);
  
      return combo;
    }
docs: Concatenates topicspace and a topic expression with a level separator between.
  
  Null topics are treated as wildcarded topics at the root level so the
  combination topic becomes topicSpace//.
  Empty topics are treated as a subscription to the root level so becomes
  topicSpace/
  Topics that begin // need to be treated as topicSpace//
  Topics that begin / are rejected
  
  @param topicSpace  The topicspace name
  @param discriminator  The topic
  
  @exception SIDiscriminatorSyntaxException If the topic starts with a leading /