public boolean isMatchedChar(char ch) {
   return fPairs.contains(ch);
 }
  private ParamRegion findEnclosingPeers(
      IDocument document,
      DocumentAccessor doc,
      int offset,
      int length,
      int lowerBoundary,
      int upperBoundary)
      throws BadLocationException {
    char[] pairs = fPairs.fPairs;
    /* Special ParamHelp added here */
    int cSeparators = 0;
    /* Special ParamHelp end here */

    int start;
    int end;
    if (length >= 0) {
      start = offset;
      end = offset + length;
    } else {
      end = offset;
      start = offset + length;
    }

    boolean lowerFound = false;
    boolean upperFound = false;
    int[][] counts = new int[pairs.length][2];
    char currChar = (start != document.getLength()) ? doc.getChar(start) : Character.MIN_VALUE;
    int pos1;
    int pos2;
    if (fPairs.isEndCharacter(currChar)) {
      pos1 = doc.getNextPosition(start, false);
      pos2 = start;
    }
    /* Special ParamHelp added here */
    else if (isSeparator(currChar)) {
      pos1 = doc.getNextPosition(start, false);
      pos2 = doc.getNextPosition(start, true);
    }
    /* Special ParamHelp end here */
    else {
      pos1 = start;
      pos2 = doc.getNextPosition(start, true);
    }

    while ((pos1 >= lowerBoundary && !lowerFound) || (pos2 < upperBoundary && !upperFound)) {
      for (int i = 0; i < counts.length; i++) {
        counts[i][0] = counts[i][1] = 0;
      }

      outer1:
      while (pos1 >= lowerBoundary && !lowerFound) {
        final char c = doc.getChar(pos1);
        int i = getCharacterIndex(c, document, pos1);
        if (i != -1 && doc.inPartition(pos1)) {
          if (i % 2 == 0) {
            counts[i / 2][0]--; // start
          } else {
            counts[i / 2][0]++; // end
          }
          for (int j = 0; j < counts.length; j++) {
            if (counts[j][0] == -1) {
              lowerFound = true;
              break outer1;
            }
          }
        }
        /* Special ParamHelp added here */
        else if (isSeparator(c)) {
          boolean nestedSeparator = false;
          for (int j = 0; j < counts.length; j++) {
            if (counts[j][0] != 0) {
              nestedSeparator = true;
            }
          }
          if (!nestedSeparator) cSeparators++;
        }
        /* Special ParamHelp end here */
        pos1 = doc.getNextPosition(pos1, false);
      }

      outer2:
      while (pos2 < upperBoundary && !upperFound) {
        final char c = doc.getChar(pos2);
        int i = getCharacterIndex(c, document, pos2);
        if (i != -1 && doc.inPartition(pos2)) {
          if (i % 2 == 0) {
            counts[i / 2][1]++; // start
          } else {
            counts[i / 2][1]--; // end
          }
          for (int j = 0; j < counts.length; j++) {
            if (counts[j][1] == -1 && counts[j][0] == -1) {
              upperFound = true;
              break outer2;
            }
          }
        }
        pos2 = doc.getNextPosition(pos2, true);
      }

      if (pos1 > start || pos2 < end - 1) {
        // match inside selection => discard
        pos1 = doc.getNextPosition(pos1, false);
        pos2 = doc.getNextPosition(pos2, true);
        lowerFound = false;
        upperFound = false;
      }
    }
    pos2++;
    if (pos1 < lowerBoundary || pos2 > upperBoundary) return null;
    ParamRegion ret = new ParamRegion();
    ret.region = new Region(pos1, pos2 - pos1);
    ret.paramSeparatorCount = cSeparators;
    return ret;
  }