docs: private String[] splitOnNonEscapedChar(String inputStr, char splitChar, int expectedPartCount) {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc, "splitOnNonEscapedChar", new Object[]{inputStr, splitChar, expectedPartCount});
  
      String[] parts = null;
      List<String> partsList = null;
  
      // Index variable along the length of the string
      int startPoint = 0;
      int tokenStart = 0;
      int splitCharIndex = 0;
  
      // Used to keep track of how many parts we have found
      int partCount = 0;
  
      // Implement manual splitting here.
  
      // Loop through searching for unescaped splitter characters until we reach the end of the string
      // or the requested number of pieces.
      while ((splitCharIndex != -1) && (partCount != (expectedPartCount-1))) {
        splitCharIndex = inputStr.indexOf(splitChar, startPoint);
  
        // We only have work to do here if a splitter char was found and it was not escaped.
        if ((splitCharIndex != -1) && !charIsEscaped(inputStr, splitCharIndex)) {
          // Found a non-escaped splitter character
  
          // Set the first part of the string.
          String nextPart = inputStr.substring(tokenStart, splitCharIndex);
  
          // If we have not yet initialized the storage then do so now.
          if (expectedPartCount >= 2) {
            if (parts == null) parts = new String[expectedPartCount];
            parts[partCount] = nextPart;
          }
          else {
            // Variable storage mechanism.
            if (partsList == null) partsList = new ArrayList<String>(5);
            partsList.add(nextPart);
          }
  
          // Indicate that we have found a new part.
          partCount++;
  
          // Move up the start point appropriately
          startPoint = splitCharIndex+1;
          tokenStart = startPoint;
        }
  
        else {
          // If the splitter is escaped then we need to look further
          // down the string for the next one.
          startPoint = splitCharIndex+1;
          // implicit 'continue' on the while loop.
        }
  
      }
  
      // Get the last part of the token string here. Either we haven't found another splitter,
      // or we just need to pick up the last chunk (regardless of whether it contains further
      // splitters).
  
      String nextPart = inputStr.substring(tokenStart, inputStr.length());
  
      if (expectedPartCount >= 2) {
        if (parts == null) {
          // If we haven't found any splitters then just pass back the string itself.
          parts = new String[1];
        }
        // Either there weren't any splitter characters, or we found one at some point but
        // have subsequently run out of further ones to process - in any case we need to put
        // in the last part of the string.
        parts[partCount] = nextPart;
      }
      else {
        // Variable storage final step here.
        if (partsList == null) {
          // No parts found - special optimized path here.
          parts = new String[1];
          parts[0] = nextPart;
        }
        else {
          partsList.add(nextPart);
          // Conver the list back into a string[]
          parts = partsList.toArray(new String[] {});
        }
      }
  
      // Do a quick check to see whether we were unable to make up the requested number of elements in
      // the array (in which case it is too big and needs resizing). This should hopefully be a minority
      // case.
      if ((parts[parts.length-1] == null)) {
        // There are one or more empty spaces at the end of the array.
        // Find the last element that doesn't have real data in it and trim the array appropriately.
        // In observations the last element can be empty string, so the partCount isn't any good to us here.
        int lastValidEntry = 0;
        while ((parts[lastValidEntry] != null) && (!"".equals(parts[lastValidEntry]))) {
          lastValidEntry++;
        }
        String[] tempParts = new String[lastValidEntry];
        System.arraycopy(parts, 0, tempParts, 0, lastValidEntry);
        parts = tempParts;
      }
  
      // Slightly unconventional way of ensuring that the content of the array is properly traced rather than just
      // the array object code (tr.exit will call toString on each of the parts of the array)
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "splitOnNonEscapedChar",  parts);
      return parts;
    }