/**
  * Returns the leading whitespace of a string.
  *
  * @param text The String to check.
  * @return The leading whitespace.
  */
 public static String getLeadingWhitespace(String text) {
   int count = 0;
   int len = text.length();
   while (count < len && RSyntaxUtilities.isWhitespace(text.charAt(count))) {
     count++;
   }
   return text.substring(0, count);
 }
  public static int getMatchingBracketPosition(RSyntaxTextArea textArea) {

    try {

      // Actually position just BEFORE caret.
      int caretPosition = textArea.getCaretPosition() - 1;
      if (caretPosition > -1) {

        // Some variables that will be used later.
        Token token;
        Element map;
        int curLine;
        Element line;
        int start, end;
        RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument();
        char bracket = doc.charAt(caretPosition);

        // First, see if the previous char was a bracket
        // ('{', '}', '(', ')', '[', ']').
        // If it was, then make sure this bracket isn't sitting in
        // the middle of a comment or string.  If it isn't, then
        // initialize some stuff so we can continue on.
        char bracketMatch;
        boolean goForward;
        switch (bracket) {
          case '{':
          case '(':
          case '[':

            // Ensure this bracket isn't in a comment.
            map = doc.getDefaultRootElement();
            curLine = map.getElementIndex(caretPosition);
            line = map.getElement(curLine);
            start = line.getStartOffset();
            end = line.getEndOffset();
            token = doc.getTokenListForLine(curLine);
            token = RSyntaxUtilities.getTokenAtOffset(token, caretPosition);
            // All brackets are always returned as "separators."
            if (token.type != Token.SEPARATOR) {
              return -1;
            }
            bracketMatch = bracket == '{' ? '}' : (bracket == '(' ? ')' : ']');
            goForward = true;
            break;

          case '}':
          case ')':
          case ']':

            // Ensure this bracket isn't in a comment.
            map = doc.getDefaultRootElement();
            curLine = map.getElementIndex(caretPosition);
            line = map.getElement(curLine);
            start = line.getStartOffset();
            end = line.getEndOffset();
            token = doc.getTokenListForLine(curLine);
            token = RSyntaxUtilities.getTokenAtOffset(token, caretPosition);
            // All brackets are always returned as "separators."
            if (token.type != Token.SEPARATOR) {
              return -1;
            }
            bracketMatch = bracket == '}' ? '{' : (bracket == ')' ? '(' : '[');
            goForward = false;
            break;

          default:
            return -1;
        }

        if (goForward) {

          int lastLine = map.getElementCount();

          // Start just after the found bracket since we're sure
          // we're not in a comment.
          start = caretPosition + 1;
          int numEmbedded = 0;
          boolean haveTokenList = false;

          while (true) {

            doc.getText(start, end - start, charSegment);
            int segOffset = charSegment.offset;

            for (int i = segOffset; i < segOffset + charSegment.count; i++) {

              char ch = charSegment.array[i];

              if (ch == bracket) {
                if (haveTokenList == false) {
                  token = doc.getTokenListForLine(curLine);
                  haveTokenList = true;
                }
                int offset = start + (i - segOffset);
                token = RSyntaxUtilities.getTokenAtOffset(token, offset);
                if (token.type == Token.SEPARATOR) numEmbedded++;
              } else if (ch == bracketMatch) {
                if (haveTokenList == false) {
                  token = doc.getTokenListForLine(curLine);
                  haveTokenList = true;
                }
                int offset = start + (i - segOffset);
                token = RSyntaxUtilities.getTokenAtOffset(token, offset);
                if (token.type == Token.SEPARATOR) {
                  if (numEmbedded == 0) return offset;
                  numEmbedded--;
                }
              }
            } // End of for (int i=segOffset; i<segOffset+charSegment.count; i++).

            // Bail out if we've gone through all lines and
            // haven't found the match.
            if (++curLine == lastLine) return -1;

            // Otherwise, go through the next line.
            haveTokenList = false;
            line = map.getElement(curLine);
            start = line.getStartOffset();
            end = line.getEndOffset();
          } // End of while (true).

        } // End of if (goForward).

        // Otherwise, we're going backward through the file
        // (since we found '}', ')' or ']').
        else { // goForward==false

          // End just before the found bracket since we're sure
          // we're not in a comment.
          end = caretPosition; // - 1;
          int numEmbedded = 0;
          boolean haveTokenList = false;
          Token t2;

          while (true) {

            doc.getText(start, end - start, charSegment);
            int segOffset = charSegment.offset;
            int iStart = segOffset + charSegment.count - 1;

            for (int i = iStart; i >= segOffset; i--) {

              char ch = charSegment.array[i];

              if (ch == bracket) {
                if (haveTokenList == false) {
                  token = doc.getTokenListForLine(curLine);
                  haveTokenList = true;
                }
                int offset = start + (i - segOffset);
                t2 = RSyntaxUtilities.getTokenAtOffset(token, offset);
                if (t2.type == Token.SEPARATOR) numEmbedded++;
              } else if (ch == bracketMatch) {
                if (haveTokenList == false) {
                  token = doc.getTokenListForLine(curLine);
                  haveTokenList = true;
                }
                int offset = start + (i - segOffset);
                t2 = RSyntaxUtilities.getTokenAtOffset(token, offset);
                if (t2.type == Token.SEPARATOR) {
                  if (numEmbedded == 0) return offset;
                  numEmbedded--;
                }
              }
            } // End of for (int i=segOffset; i<segOffset+charSegment.count; i++).

            // Bail out if we've gone through all lines and
            // haven't found the match.
            if (--curLine == -1) return -1;

            // Otherwise, get ready for going through the
            // next line.
            haveTokenList = false;
            line = map.getElement(curLine);
            start = line.getStartOffset();
            end = line.getEndOffset();
          } // End of while (true).
        } // End of else.
      } // End of if (caretPosition>-1).

    } catch (BadLocationException ble) {
      // Shouldn't ever happen.
      ble.printStackTrace();
    }

    // Something went wrong...
    return -1;
  }