private Fold findOpenFoldClosestTo(Point p) {

    Fold fold = null;

    RSyntaxTextArea rsta = (RSyntaxTextArea) textArea;
    if (rsta.isCodeFoldingEnabled()) { // Should always be true
      int offs = rsta.viewToModel(p); // TODO: Optimize me
      if (offs > -1) {
        try {
          int line = rsta.getLineOfOffset(offs);
          int origLine = line;
          FoldManager fm = rsta.getFoldManager();
          do {
            fold = fm.getFoldForLine(line);
          } while (fold == null && line-- >= 0);
          if (fold != null && !fold.containsOrStartsOnLine(origLine)) {
            // Found closest fold, but doesn't actually contain line
            fold = null;
          }
        } catch (BadLocationException ble) {
          ble.printStackTrace(); // Never happens
        }
      }
    }

    return fold;
  }
  /**
   * Overridden to show the content of a collapsed fold on mouse-overs.
   *
   * @param e The mouse location.
   */
  public String getToolTipText(MouseEvent e) {

    String text = null;

    RSyntaxTextArea rsta = (RSyntaxTextArea) textArea;
    if (rsta.isCodeFoldingEnabled()) {
      FoldManager fm = rsta.getFoldManager();
      int pos = rsta.viewToModel(new Point(0, e.getY()));
      if (pos >= 0) { // Not -1
        int line = 0;
        try {
          line = rsta.getLineOfOffset(pos);
        } catch (BadLocationException ble) {
          ble.printStackTrace(); // Never happens
          return null;
        }
        Fold fold = fm.getFoldForLine(line);
        if (fold != null && fold.isCollapsed()) {

          int endLine = fold.getEndLine();
          if (fold.getLineCount() > 25) { // Not too big
            endLine = fold.getStartLine() + 25;
          }

          StringBuffer sb = new StringBuffer("<html><nobr>");
          while (line <= endLine && line < rsta.getLineCount()) { // Sanity
            Token t = rsta.getTokenListForLine(line);
            while (t != null && t.isPaintable()) {
              t.appendHTMLRepresentation(sb, rsta, true, true);
              t = t.getNextToken();
            }
            sb.append("<br>");
            line++;
          }

          text = sb.toString();
        }
      }
    }

    return text;
  }