text:
package mars.venus.editors.jeditsyntax;

   import mars.Globals;
   import mars.Settings;
   import mars.venus.editors.jeditsyntax.tokenmarker.*;
   import javax.swing.event.*;
   import javax.swing.text.*;
   import javax.swing.undo.*;
   import javax.swing.*;
   import java.awt.datatransfer.*;
   import java.awt.event.*;
   import java.awt.*;
   import java.util.Enumeration;
   import java.util.Vector;
   import java.util.ArrayList;

/**
 * jEdit's text area component. It is more suited for editing program
 * source code than JEditorPane, because it drops the unnecessary features
 * (images, variable-width lines, and so on) and adds a whole bunch of
 * useful goodies such as:
 *

 *
More flexible key binding scheme
 *
Supports macro recorders
 *
Rectangular selection
 *
Bracket highlighting
 *
Syntax highlighting
 *
Command repetition
 *
Block caret can be enabled
 *

 * It is also faster and doesn't have as many problems. It can be used
 * in other applications; the only other part of jEdit it depends on is
 * the syntax package.

 *
 * To use it in your app, treat it like any other component, for example:
 *
JEditTextArea ta = new JEditTextArea();
 * ta.setTokenMarker(new JavaTokenMarker());
 * ta.setText("public class Test {\n"
 *     + "    public static void main(String[] args) {\n"
 *     + "        System.out.println(\"Hello World\");\n"
 *     + "    }\n"
 *     + "}");

 *
 * @author Slava Pestov
 * @version $Id: JEditTextArea.java,v 1.36 1999/12/13 03:40:30 sp Exp $
 */
    public class JEditTextArea extends JComponent
   {
   /**
    * Adding components with this name to the text area will place
    * them left of the horizontal scroll bar. In jEdit, the status
    * bar is added this way.
    */
      public static String LEFT_OF_SCROLLBAR = "los";

    // Number of text lines moved for each click of the vertical scrollbar buttons.
      private static final int VERTICAL_SCROLLBAR_UNIT_INCREMENT_IN_LINES = 1;
    // Number of text lines moved for each "notch" of the mouse wheel scroller.
      private static final int LINES_PER_MOUSE_WHEEL_NOTCH = 3;

   /**
    * Creates a new JEditTextArea with the default settings.
    */
       public JEditTextArea(JComponent lineNumbers)
      {
         this(TextAreaDefaults.getDefaults(), lineNumbers);
      }

   /**
    * Creates a new JEditTextArea with the specified settings.
    * @param defaults The default settings
    */

      private JScrollBar lineNumbersVertical;//************************************

       public JEditTextArea(TextAreaDefaults defaults, JComponent lineNumbers)
      {
      // Enable the necessary events
         enableEvents(AWTEvent.KEY_EVENT_MASK);

      // Initialize some misc. stuff
         painter = new TextAreaPainter(this,defaults);
         documentHandler = new DocumentHandler();
         listenerList = new EventListenerList();
         caretEvent = new MutableCaretEvent();
         lineSegment = new Segment();
         bracketLine = bracketPosition = -1;
         blink = true;
         unredoing = false;

         JScrollPane lineNumberScroller = new JScrollPane(lineNumbers,
                       ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
                       ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
         lineNumberScroller.setBorder(new javax.swing.border.EmptyBorder(1,1,1,1));
         lineNumbersVertical = lineNumberScroller.getVerticalScrollBar();

      // Initialize the GUI
         JPanel lineNumbersPlusPainter = new JPanel(new BorderLayout());
         lineNumbersPlusPainter.add(painter, BorderLayout.CENTER);
         lineNumbersPlusPainter.add(lineNumberScroller, BorderLayout.WEST);
         setLayout(new ScrollLayout());
         add(CENTER, lineNumbersPlusPainter); //was: painter
         add(RIGHT,vertical = new JScrollBar(JScrollBar.VERTICAL));
         add(BOTTOM,horizontal = new JScrollBar(JScrollBar.HORIZONTAL));

      // Add some event listeners
         vertical.addAdjustmentListener(new AdjustHandler());
         horizontal.addAdjustmentListener(new AdjustHandler());
         painter.addComponentListener(new ComponentHandler());
         painter.addMouseListener(new MouseHandler());
         painter.addMouseMotionListener(new DragHandler());
         painter.addMouseWheelListener(new MouseWheelHandler()); // DPS 5-5-10
         addFocusListener(new FocusHandler());

      // Load the defaults
         setInputHandler(defaults.inputHandler);
         setDocument(defaults.document);
         editable = defaults.editable;
         caretVisible = defaults.caretVisible;
         caretBlinks = defaults.caretBlinks;
         caretBlinkRate = defaults.caretBlinkRate;
         electricScroll = defaults.electricScroll;

         popup = defaults.popup;

         caretTimer.setDelay(caretBlinkRate);

      	// Intercept keystrokes before focus manager gets them.  If in editing window,
      	// pass TAB keystrokes on to the key processor instead of letting focus
      	// manager use them for focus traversal.
      	// One can also accomplish this using: setFocusTraversalKeysEnabled(false);
      	// but that seems heavy-handed.
      	// DPS 12May2010
         KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(
                new KeyEventDispatcher() {
                   public boolean dispatchKeyEvent(KeyEvent e) {
                     if (JEditTextArea.this.isFocusOwner() && e.getKeyCode()==KeyEvent.VK_TAB &&  e.getModifiers()==0) {
                        processKeyEvent(e);
                        return true;
                     }
                     else {
                        return false;
                     }
                  }
               });

      // We don't seem to get the initial focus event?
         focusedComponent = this;
      }

   /**
    * Returns if this component can be traversed by pressing
    * the Tab key. This returns false.
    */
   //        public final boolean isManagingFocus()
   //       {
   //          return true;
   //       }

   /**
    * Returns the object responsible for painting this text area.
    */
       public final TextAreaPainter getPainter()
      {
         return painter;
      }

   /**
    * Returns the input handler.
    */
       public final InputHandler getInputHandler()
      {
         return inputHandler;
      }

   /**
    * Sets the input handler.
    * @param inputHandler The new input handler
    */
       public void setInputHandler(InputHandler inputHandler)
      {
         this.inputHandler = inputHandler;
      }

   /**
    * Returns true if the caret is blinking, false otherwise.
    */
       public final boolean isCaretBlinkEnabled()
      {
         return caretBlinks;
      }

   /**
    * Toggles caret blinking.
    * @param caretBlinks True if the caret should blink, false otherwise
    */
       public void setCaretBlinkEnabled(boolean caretBlinks)
      {
         this.caretBlinks = caretBlinks;
         if(!caretBlinks)
            blink = false;

         painter.invalidateSelectedLines();
      }

   /**
    * Returns true if the caret is visible, false otherwise.
    */
       public final boolean isCaretVisible()
      {
         return (!caretBlinks || blink) && caretVisible;
      }

   /**
    * Sets if the caret should be visible.
    * @param caretVisible True if the caret should be visible, false
    * otherwise
    */
       public void setCaretVisible(boolean caretVisible)
      {
         this.caretVisible = caretVisible;
         blink = true;

         painter.invalidateSelectedLines();
      }

   /**
    * Blinks the caret.
    */
       public final void blinkCaret()
      {
         if(caretBlinks)
         {
            blink = !blink;
            painter.invalidateSelectedLines();
         }
         else
            blink = true;
      }

   /**
    * Returns the number of lines from the top and button of the
    * text area that are always visible.
    */
       public final int getElectricScroll()
      {
         return electricScroll;
      }

   /**
    * Sets the number of lines from the top and bottom of the text
    * area that are always visible
    * @param electricScroll The number of lines always visible from
    * the top or bottom
    */
       public final void setElectricScroll(int electricScroll)
      {
         this.electricScroll = electricScroll;
      }

   /**
    * Updates the state of the scroll bars. This should be called
    * if the number of lines in the document changes, or when the
    * size of the text are changes.
    */
       public void updateScrollBars()
      {
         if(vertical != null && visibleLines != 0)
         {
            vertical.setValues(firstLine,visibleLines,0,getLineCount());
            vertical.setUnitIncrement(VERTICAL_SCROLLBAR_UNIT_INCREMENT_IN_LINES);
            vertical.setBlockIncrement(visibleLines);

         	// Editing area scrollbar has custom model that increments by number of text lines instead of
         	// number of pixels. The line number display uses a standard (but invisible) scrollbar based
         	// on pixels, so I need to adjust accordingly to keep it in synch with the editing area scrollbar.
         	// DPS 4-May-2010
            int height = painter.getFontMetrics(painter.getFont()).getHeight();
            lineNumbersVertical.setValues(firstLine*height, visibleLines*height,0,getLineCount()*height);
            lineNumbersVertical.setUnitIncrement(VERTICAL_SCROLLBAR_UNIT_INCREMENT_IN_LINES*height);
            lineNumbersVertical.setBlockIncrement(visibleLines*height);
         }

         int width = painter.getWidth();
         if(horizontal != null && width != 0)
         {
            horizontal.setValues(-horizontalOffset,width,0,width * 5);
            horizontal.setUnitIncrement(painter.getFontMetrics()
               .charWidth('w'));
            horizontal.setBlockIncrement(width / 2);
         }
      }

   /**
    * Returns the line displayed at the text area's origin.
    */
       public final int getFirstLine()
      {
         return firstLine;
      }

   /**
    * Sets the line displayed at the text area's origin and
    * updates the scroll bars.
    */
       public void setFirstLine(int firstLine)
      {
         if(firstLine == this.firstLine)
            return;
         int oldFirstLine = this.firstLine;
         this.firstLine = firstLine;
         updateScrollBars();
         painter.repaint();
      }

   /**
    * Returns the number of lines visible in this text area.
    */
       public final int getVisibleLines()
      {
         return visibleLines;
      }

   /**
    * Recalculates the number of visible lines. This should not
    * be called directly.
    */
       public final void recalculateVisibleLines()
      {
         if(painter == null)
            return;
         int height = painter.getHeight();
         int lineHeight = painter.getFontMetrics().getHeight();
         int oldVisibleLines = visibleLines;
         visibleLines = height / lineHeight;
         updateScrollBars();
      }

   /**
    * Returns the horizontal offset of drawn lines.
    */
       public final int getHorizontalOffset()
      {
         return horizontalOffset;
      }

   /**
    * Sets the horizontal offset of drawn lines. This can be used to
    * implement horizontal scrolling.
    * @param horizontalOffset offset The new horizontal offset
    */
       public void setHorizontalOffset(int horizontalOffset)
      {
         if(horizontalOffset == this.horizontalOffset)
            return;
         this.horizontalOffset = horizontalOffset;
         if(horizontalOffset != horizontal.getValue())
            updateScrollBars();
         painter.repaint();
      }

   /**
    * A fast way of changing both the first line and horizontal
    * offset.
    * @param firstLine The new first line
    * @param horizontalOffset The new horizontal offset
    * @return True if any of the values were changed, false otherwise
    */
       public boolean setOrigin(int firstLine, int horizontalOffset)
      {
         boolean changed = false;
         int oldFirstLine = this.firstLine;

         if(horizontalOffset != this.horizontalOffset)
         {
            this.horizontalOffset = horizontalOffset;
            changed = true;
         }

         if(firstLine != this.firstLine)
         {
            this.firstLine = firstLine;
            changed = true;
         }

         if(changed)
         {
            updateScrollBars();
            painter.repaint();
         }

         return changed;
      }

   /**
    * Ensures that the caret is visible by scrolling the text area if
    * necessary.
    * @return True if scrolling was actually performed, false if the
    * caret was already visible
    */
       public boolean scrollToCaret()
      {
         int line = getCaretLine();
         int lineStart = getLineStartOffset(line);
         int offset = Math.max(0,Math.min(getLineLength(line) - 1,
            getCaretPosition() - lineStart));

         return scrollTo(line,offset);
      }

   /**
    * Ensures that the specified line and offset is visible by scrolling
    * the text area if necessary.
    * @param line The line to scroll to
    * @param offset The offset in the line to scroll to
    * @return True if scrolling was actually performed, false if the
    * line and offset was already visible
    */
       public boolean scrollTo(int line, int offset)
      {
      // visibleLines == 0 before the component is realized
      // we can't do any proper scrolling then, so we have
      // this hack...
         if(visibleLines == 0)
         {
            setFirstLine(Math.max(0,line - electricScroll));
            return true;
         }

         int newFirstLine = firstLine;
         int newHorizontalOffset = horizontalOffset;

         if(line < firstLine + electricScroll)
         {
            newFirstLine = Math.max(0,line - electricScroll);
         }
         else if(line + electricScroll >= firstLine + visibleLines)
         {
            newFirstLine = (line - visibleLines) + electricScroll + 1;
            if(newFirstLine + visibleLines >= getLineCount())
               newFirstLine = getLineCount() - visibleLines;
            if(newFirstLine < 0)
               newFirstLine = 0;
         }

         int x = _offsetToX(line,offset);
         int width = painter.getFontMetrics().charWidth('w');

         if(x < 0)
         {
            newHorizontalOffset = Math.min(0,horizontalOffset
               - x + width + 5);
         }
         else if(x + width >= painter.getWidth())
         {
            newHorizontalOffset = horizontalOffset +
               (painter.getWidth() - x) - width - 5;
         }

         return setOrigin(newFirstLine,newHorizontalOffset);
      }

   /**
    * Converts a line index to a y co-ordinate.
    * @param line The line
    */
       public int lineToY(int line)
      {
         FontMetrics fm = painter.getFontMetrics();
         return (line - firstLine) * fm.getHeight()
            - (fm.getLeading() + fm.getMaxDescent());
      }

   /**
    * Converts a y co-ordinate to a line index.
    * @param y The y co-ordinate
    */
       public int yToLine(int y)
      {
         FontMetrics fm = painter.getFontMetrics();
         int height = fm.getHeight();
         return Math.max(0,Math.min(getLineCount() - 1,
            y / height + firstLine));
      }

   /**
    * Converts an offset in a line into an x co-ordinate. This is a
    * slow version that can be used any time.
    * @param line The line
    * @param offset The offset, from the start of the line
    */
       public final int offsetToX(int line, int offset)
      {
      // don't use cached tokens
         painter.currentLineTokens = null;
         return _offsetToX(line,offset);
      }

   /**
    * Converts an offset in a line into an x co-ordinate. This is a
    * fast version that should only be used if no changes were made
    * to the text since the last repaint.
    * @param line The line
    * @param offset The offset, from the start of the line
    */
       public int _offsetToX(int line, int offset)
      {
         TokenMarker tokenMarker = getTokenMarker();

      /* Use painter's cached info for speed */
         FontMetrics fm = painter.getFontMetrics();

         getLineText(line,lineSegment);

         int segmentOffset = lineSegment.offset;
         int x = horizontalOffset;

      /* If syntax coloring is disabled, do simple translation */
         if(tokenMarker == null)
         {
            lineSegment.count = offset;
            return x + Utilities.getTabbedTextWidth(lineSegment,
               fm,x,painter,0);
         }
         /* If syntax coloring is enabled, we have to do this because
         * tokens can vary in width */
         else
         {
            Token tokens;
            if(painter.currentLineIndex == line
            && painter.currentLineTokens != null)
               tokens = painter.currentLineTokens;
            else
            {
               painter.currentLineIndex = line;
               tokens = painter.currentLineTokens
                  = tokenMarker.markTokens(lineSegment,line);
            }

            Toolkit toolkit = painter.getToolkit();
            Font defaultFont = painter.getFont();
            SyntaxStyle[] styles = painter.getStyles();

            for(;;)
            {
               byte id = tokens.id;
               if(id == Token.END)
               {
                  return x;
               }

               if(id == Token.NULL)
                  fm = painter.getFontMetrics();
               else
                  fm = styles[id].getFontMetrics(defaultFont);

               int length = tokens.length;

               if(offset + segmentOffset < lineSegment.offset + length)
               {
                  lineSegment.count = offset - (lineSegment.offset - segmentOffset);
                  return x + Utilities.getTabbedTextWidth(
                     lineSegment,fm,x,painter,0);
               }
               else
               {
                  lineSegment.count = length;
                  x += Utilities.getTabbedTextWidth(
                     lineSegment,fm,x,painter,0);
                  lineSegment.offset += length;
               }
               tokens = tokens.next;
            }
         }
      }

   /**
    * Converts an x co-ordinate to an offset within a line.
    * @param line The line
    * @param x The x co-ordinate
    */
       public int xToOffset(int line, int x)
      {
         TokenMarker tokenMarker = getTokenMarker();

      /* Use painter's cached info for speed */
         FontMetrics fm = painter.getFontMetrics();

         getLineText(line,lineSegment);

         char[] segmentArray = lineSegment.array;
         int segmentOffset = lineSegment.offset;
         int segmentCount = lineSegment.count;

         int width = horizontalOffset;

         if(tokenMarker == null)
         {
            for(int i = 0; i < segmentCount; i++)
            {
               char c = segmentArray[i + segmentOffset];
               int charWidth;
               if(c == '\t')
                  charWidth = (int)painter.nextTabStop(width,i)
                     - width;
               else
                  charWidth = fm.charWidth(c);

               if(painter.isBlockCaretEnabled())
               {
                  if(x - charWidth <= width)
                     return i;
               }
               else
               {
                  if(x - charWidth / 2 <= width)
                     return i;
               }

               width += charWidth;
            }

            return segmentCount;
         }
         else
         {
            Token tokens;
            if(painter.currentLineIndex == line && painter
            .currentLineTokens != null)
               tokens = painter.currentLineTokens;
            else
            {
               painter.currentLineIndex = line;
               tokens = painter.currentLineTokens
                  = tokenMarker.markTokens(lineSegment,line);
            }

            int offset = 0;
            Toolkit toolkit = painter.getToolkit();
            Font defaultFont = painter.getFont();
            SyntaxStyle[] styles = painter.getStyles();

            for(;;)
            {
               byte id = tokens.id;
               if(id == Token.END)
                  return offset;

               if(id == Token.NULL)
                  fm = painter.getFontMetrics();
               else
                  fm = styles[id].getFontMetrics(defaultFont);

               int length = tokens.length;

               for(int i = 0; i < length; i++)
               {
                  char c = segmentArray[segmentOffset + offset + i];
                  int charWidth;
                  if(c == '\t')
                     charWidth = (int)painter.nextTabStop(width,offset + i)
                        - width;
                  else
                     charWidth = fm.charWidth(c);

                  if(painter.isBlockCaretEnabled())
                  {
                     if(x - charWidth <= width)
                        return offset + i;
                  }
                  else
                  {
                     if(x - charWidth / 2 <= width)
                        return offset + i;
                  }

                  width += charWidth;
               }

               offset += length;
               tokens = tokens.next;
            }
         }
      }

   /**
    * Converts a point to an offset, from the start of the text.
    * @param x The x co-ordinate of the point
    * @param y The y co-ordinate of the point
    */
       public int xyToOffset(int x, int y)
      {
         int line = yToLine(y);
         int start = getLineStartOffset(line);
         return start + xToOffset(line,x);
      }

   /**
    * Returns the document this text area is editing.
    */
       public final Document getDocument()
      {
         return document;
      }

   /**
    * Sets the document this text area is editing.
    * @param document The document
    */
       public void setDocument(SyntaxDocument document)
      {
         if(this.document == document)
            return;
         if(this.document != null)
            this.document.removeDocumentListener(documentHandler);
         this.document = document;

         document.addDocumentListener(documentHandler);

         select(0,0);
         updateScrollBars();
         painter.repaint();
      }

   /**
    * Returns the document's token marker. Equivalent to calling
    * getDocument().getTokenMarker().
    */
       public final TokenMarker getTokenMarker()
      {
         return document.getTokenMarker();
      }

   /**
    * Sets the document's token marker. Equivalent to caling
    * getDocument().setTokenMarker().
    * @param tokenMarker The token marker
    */
       public final void setTokenMarker(TokenMarker tokenMarker)
      {
         document.setTokenMarker(tokenMarker);
      }

   /**
    * Returns the length of the document. Equivalent to calling
    * getDocument().getLength().
    */
       public final int getDocumentLength()
      {
         return document.getLength();
      }

   /**
    * Returns the number of lines in the document.
    */
       public final int getLineCount()
      {
         return document.getDefaultRootElement().getElementCount();
      }

   /**
    * Returns the line containing the specified offset.
    * @param offset The offset
    */
       public final int getLineOfOffset(int offset)
      {
         return document.getDefaultRootElement().getElementIndex(offset);
      }

   /**
    * Returns the start offset of the specified line.
    * @param line The line
    * @return The start offset of the specified line, or -1 if the line is
    * invalid
    */
       public int getLineStartOffset(int line)
      {
         Element lineElement = document.getDefaultRootElement()
            .getElement(line);
         if(lineElement == null)
            return -1;
         else
            return lineElement.getStartOffset();
      }

   /**
    * Returns the end offset of the specified line.
    * @param line The line
    * @return The end offset of the specified line, or -1 if the line is
    * invalid.
    */
       public int getLineEndOffset(int line)
      {
         Element lineElement = document.getDefaultRootElement()
            .getElement(line);
         if(lineElement == null)
            return -1;
         else
            return lineElement.getEndOffset();
      }

   /**
    * Returns the length of the specified line.
    * @param line The line
    */
       public int getLineLength(int line)
      {
         Element lineElement = document.getDefaultRootElement()
            .getElement(line);
         if(lineElement == null)
            return -1;
         else
            return lineElement.getEndOffset()
               - lineElement.getStartOffset() - 1;
      }

   /**
    * Returns the entire text of this text area.
    */
       public String getText()
      {
         try
         {
            return document.getText(0,document.getLength());
         }
             catch(BadLocationException bl)
            {
               bl.printStackTrace();
               return null;
            }
      }

   /**
    * Sets the entire text of this text area.
    */
       public void setText(String text)
      {
         try
         {
            document.beginCompoundEdit();
            document.remove(0,document.getLength());
            document.insertString(0,text,null);
         }
             catch(BadLocationException bl)
            {
               bl.printStackTrace();
            }
         finally
         {
            document.endCompoundEdit();
         }
      }

   /**
    * Returns the specified substring of the document.
    * @param start The start offset
    * @param len The length of the substring
    * @return The substring, or null if the offsets are invalid
    */
       public final String getText(int start, int len)
      {
         try
         {
            return document.getText(start,len);
         }
             catch(BadLocationException bl)
            {
               bl.printStackTrace();
               return null;
            }
      }

   /**
    * Copies the specified substring of the document into a segment.
    * If the offsets are invalid, the segment will contain a null string.
    * @param start The start offset
    * @param len The length of the substring
    * @param segment The segment
    */
       public final void getText(int start, int len, Segment segment)
      {
         try
         {
            document.getText(start,len,segment);
         }
             catch(BadLocationException bl)
            {
               bl.printStackTrace();
               segment.offset = segment.count = 0;
            }
      }

   /**
    * Returns the text on the specified line.
    * @param lineIndex The line
    * @return The text, or null if the line is invalid
    */
       public final String getLineText(int lineIndex)
      {
         int start = getLineStartOffset(lineIndex);
         return getText(start,getLineEndOffset(lineIndex) - start - 1);
      }

   /**
    * Copies the text on the specified line into a segment. If the line
    * is invalid, the segment will contain a null string.
    * @param lineIndex The line
    */
       public final void getLineText(int lineIndex, Segment segment)
      {
         int start = getLineStartOffset(lineIndex);
         getText(start,getLineEndOffset(lineIndex) - start - 1,segment);
      }

   /**
    * Returns the selection start offset.
    */
       public final int getSelectionStart()
      {
         return selectionStart;
      }

   /**
    * Returns the offset where the selection starts on the specified
    * line.
    */
       public int getSelectionStart(int line)
      {
         if(line == selectionStartLine)
            return selectionStart;
         else if(rectSelect)
         {
            Element map = document.getDefaultRootElement();
            int start = selectionStart - map.getElement(selectionStartLine)
               .getStartOffset();

            Element lineElement = map.getElement(line);
            int lineStart = lineElement.getStartOffset();
            int lineEnd = lineElement.getEndOffset() - 1;
            return Math.min(lineEnd,lineStart + start);
         }
         else
            return getLineStartOffset(line);
      }

   /**
    * Returns the selection start line.
    */
       public final int getSelectionStartLine()
      {
         return selectionStartLine;
      }

   /**
    * Sets the selection start. The new selection will be the new
    * selection start and the old selection end.
    * @param selectionStart The selection start
    * @see #select(int,int)
    */
       public final void setSelectionStart(int selectionStart)
      {
         select(selectionStart,selectionEnd);
      }

   /**
    * Returns the selection end offset.
    */
       public final int getSelectionEnd()
      {
         return selectionEnd;
      }

   /**
    * Returns the offset where the selection ends on the specified
    * line.
    */
       public int getSelectionEnd(int line)
      {
         if(line == selectionEndLine)
            return selectionEnd;
         else if(rectSelect)
         {
            Element map = document.getDefaultRootElement();
            int end = selectionEnd - map.getElement(selectionEndLine)
               .getStartOffset();

            Element lineElement = map.getElement(line);
            int lineStart = lineElement.getStartOffset();
            int lineEnd = lineElement.getEndOffset() - 1;
            return Math.min(lineEnd,lineStart + end);
         }
         else
            return getLineEndOffset(line) - 1;
      }

   /**
    * Returns the selection end line.
    */
       public final int getSelectionEndLine()
      {
         return selectionEndLine;
      }

   /**
    * Sets the selection end. The new selection will be the old
    * selection start and the new selection end.
    * @param selectionEnd The selection end
    * @see #select(int,int)
    */
       public final void setSelectionEnd(int selectionEnd)
      {
         select(selectionStart,selectionEnd);
      }

   /**
    * Returns the caret position. This will either be the selection
    * start or the selection end, depending on which direction the
    * selection was made in.
    */
       public final int getCaretPosition()
      {
         return (biasLeft ? selectionStart : selectionEnd);
      }

   /**
    * Returns the caret line.
    */
       public final int getCaretLine()
      {
         return (biasLeft ? selectionStartLine : selectionEndLine);
      }

   /**
    * Returns the mark position. This will be the opposite selection
    * bound to the caret position.
    * @see #getCaretPosition()
    */
       public final int getMarkPosition()
      {
         return (biasLeft ? selectionEnd : selectionStart);
      }

   /**
    * Returns the mark line.
    */
       public final int getMarkLine()
      {
         return (biasLeft ? selectionEndLine : selectionStartLine);
      }

   /**
    * Sets the caret position. The new selection will consist of the
    * caret position only (hence no text will be selected)
    * @param caret The caret position
    * @see #select(int,int)
    */
       public final void setCaretPosition(int caret)
      {
         select(caret,caret);
      }

   /**
    * Selects all text in the document.
    */
       public final void selectAll()
      {
         select(0,getDocumentLength());
      }

   /**
    * Moves the mark to the caret position.
    */
       public final void selectNone()
      {
         select(getCaretPosition(),getCaretPosition());
      }

   /**
    * Selects from the start offset to the end offset. This is the
    * general selection method used by all other selecting methods.
    * The caret position will be start if start < end, and end
    * if end > start.
    * @param start The start offset
    * @param end The end offset
    */
       public void select(int start, int end)
      {
         int newStart, newEnd;
         boolean newBias;
         if(start <= end)
         {
            newStart = start;
            newEnd = end;
            newBias = false;
         }
         else
         {
            newStart = end;
            newEnd = start;
            newBias = true;
         }

         if(newStart < 0 || newEnd > getDocumentLength())
         {
            throw new IllegalArgumentException("Bounds out of"
               + " range: " + newStart + "," +
               newEnd);
         }

      // If the new position is the same as the old, we don't
      // do all this crap, however we still do the stuff at
      // the end (clearing magic position, scrolling)
         if(newStart != selectionStart || newEnd != selectionEnd
         || newBias != biasLeft)
         {
            int newStartLine = getLineOfOffset(newStart);
            int newEndLine = getLineOfOffset(newEnd);

            if(painter.isBracketHighlightEnabled())
            {
               if(bracketLine != -1)
                  painter.invalidateLine(bracketLine);
               updateBracketHighlight(end);
               if(bracketLine != -1)
                  painter.invalidateLine(bracketLine);
            }

            painter.invalidateLineRange(selectionStartLine,selectionEndLine);
            painter.invalidateLineRange(newStartLine,newEndLine);

            document.addUndoableEdit(new CaretUndo(
               selectionStart,selectionEnd));

            selectionStart = newStart;
            selectionEnd = newEnd;
            selectionStartLine = newStartLine;
            selectionEndLine = newEndLine;
            biasLeft = newBias;

            fireCaretEvent();
         }

      // When the user is typing, etc, we don't want the caret
      // to blink
         blink = true;
         caretTimer.restart();

      // Disable rectangle select if selection start = selection end
         if(selectionStart == selectionEnd)
            rectSelect = false;

      // Clear the `magic' caret position used by up/down
         magicCaret = -1;
         scrollToCaret();
      }

   /**
    * Returns the selected text, or null if no selection is active.
    */
       public final String getSelectedText()
      {
         if(selectionStart == selectionEnd)
            return null;

         if(rectSelect)
         {
         // Return each row of the selection on a new line

            Element map = document.getDefaultRootElement();

            int start = selectionStart - map.getElement(selectionStartLine)
               .getStartOffset();
            int end = selectionEnd - map.getElement(selectionEndLine)
               .getStartOffset();

         // Certain rectangles satisfy this condition...
            if(end < start)
            {
               int tmp = end;
               end = start;
               start = tmp;
            }

            StringBuffer buf = new StringBuffer();
            Segment seg = new Segment();

            for(int i = selectionStartLine; i <= selectionEndLine; i++)
            {
               Element lineElement = map.getElement(i);
               int lineStart = lineElement.getStartOffset();
               int lineEnd = lineElement.getEndOffset() - 1;
               int lineLen = lineEnd - lineStart;

               lineStart = Math.min(lineStart + start,lineEnd);
               lineLen = Math.min(end - start,lineEnd - lineStart);

               getText(lineStart,lineLen,seg);
               buf.append(seg.array,seg.offset,seg.count);

               if(i != selectionEndLine)
                  buf.append('\n');
            }

            return buf.toString();
         }
         else
         {
            return getText(selectionStart,
               selectionEnd - selectionStart);
         }
      }

   /**
    * Replaces the selection with the specified text.
    * @param selectedText The replacement text for the selection
    */
       public void setSelectedText(String selectedText)
      {
         if(!editable)
         {
            throw new InternalError("Text component"
               + " read only");
         }

         document.beginCompoundEdit();

         try
         {
            if(rectSelect)
            {
               Element map = document.getDefaultRootElement();

               int start = selectionStart - map.getElement(selectionStartLine)
                  .getStartOffset();
               int end = selectionEnd - map.getElement(selectionEndLine)
                  .getStartOffset();

            // Certain rectangles satisfy this condition...
               if(end < start)
               {
                  int tmp = end;
                  end = start;
                  start = tmp;
               }

               int lastNewline = 0;
               int currNewline = 0;

               for(int i = selectionStartLine; i <= selectionEndLine; i++)
               {
                  Element lineElement = map.getElement(i);
                  int lineStart = lineElement.getStartOffset();
                  int lineEnd = lineElement.getEndOffset() - 1;
                  int rectStart = Math.min(lineEnd,lineStart + start);

                  document.remove(rectStart,Math.min(lineEnd - rectStart,
                     end - start));

                  if(selectedText == null)
                     continue;

                  currNewline = selectedText.indexOf('\n',lastNewline);
                  if(currNewline == -1)
                     currNewline = selectedText.length();

                  document.insertString(rectStart,selectedText
                     .substring(lastNewline,currNewline),null);

                  lastNewline = Math.min(selectedText.length(),
                     currNewline + 1);
               }

               if(selectedText != null &&
               currNewline != selectedText.length())
               {
                  int offset = map.getElement(selectionEndLine)
                     .getEndOffset() - 1;
                  document.insertString(offset,"\n",null);
                  document.insertString(offset + 1,selectedText
                     .substring(currNewline + 1),null);
               }
            }
            else
            {
               document.remove(selectionStart,
                  selectionEnd - selectionStart);
               if(selectedText != null)
               {
                  document.insertString(selectionStart,
                     selectedText,null);
               }
            }
         }
             catch(BadLocationException bl)
            {
               bl.printStackTrace();
               throw new InternalError("Cannot replace"
                  + " selection");
            }
         // No matter what happends... stops us from leaving document
         // in a bad state
         finally
         {
            document.endCompoundEdit();
         }

         setCaretPosition(selectionEnd);
      }

   /**
    * Returns true if this text area is editable, false otherwise.
    */
       public final boolean isEditable()
      {
         return editable;
      }

   /**
    * Sets if this component is editable.
    * @param editable True if this text area should be editable,
    * false otherwise
    */
       public final void setEditable(boolean editable)
      {
         this.editable = editable;
      }

   /**
    * Returns the right click popup menu.
    */
       public final JPopupMenu getRightClickPopup()
      {
         return popup;
      }

   /**
    * Sets the right click popup menu.
    * @param popup The popup
    */
       public final void setRightClickPopup(JPopupMenu popup)
      {
         this.popup = popup;
      }

   /**
    * Returns the `magic' caret position. This can be used to preserve
    * the column position when moving up and down lines.
    */
       public final int getMagicCaretPosition()
      {
         return magicCaret;
      }

   /**
    * Sets the `magic' caret position. This can be used to preserve
    * the column position when moving up and down lines.
    * @param magicCaret The magic caret position
    */
       public final void setMagicCaretPosition(int magicCaret)
      {
         this.magicCaret = magicCaret;
      }

   /**
    * Similar to setSelectedText(), but overstrikes the
    * appropriate number of characters if overwrite mode is enabled.
    * @param str The string
    * @see #setSelectedText(String)
    * @see #isOverwriteEnabled()
    */
       public void overwriteSetSelectedText(String str)
      {
      // Don't overstrike if there is a selection
         if(!overwrite || selectionStart != selectionEnd)
         {
            setSelectedText(str);
            applySyntaxSensitiveHelp();
            return;
         }

      // Don't overstrike if we're on the end of
      // the line
         int caret = getCaretPosition();
         int caretLineEnd = getLineEndOffset(getCaretLine());
         if(caretLineEnd - caret <= str.length())
         {
            setSelectedText(str);
            applySyntaxSensitiveHelp();
            return;
         }

         document.beginCompoundEdit();

         try
         {
            document.remove(caret,str.length());
            document.insertString(caret,str,null);
         }
             catch(BadLocationException bl)
            {
               bl.printStackTrace();
            }
         finally
         {
            document.endCompoundEdit();
         }
         applySyntaxSensitiveHelp();

      }

      JPopupMenu popupMenu;

   /**
    * Returns true if overwrite mode is enabled, false otherwise.
    */
       public final boolean isOverwriteEnabled()
      {
         return overwrite;
      }

   /**
    * Sets if overwrite mode should be enabled.
    * @param overwrite True if overwrite mode should be enabled,
    * false otherwise.
    */
       public final void setOverwriteEnabled(boolean overwrite)
      {
         this.overwrite = overwrite;
         painter.invalidateSelectedLines();
      }

   /**
    * Returns true if the selection is rectangular, false otherwise.
    */
       public final boolean isSelectionRectangular()
      {
         return rectSelect;
      }

   /**
    * Sets if the selection should be rectangular.
    * @param overwrite True if the selection should be rectangular,
    * false otherwise.
    */
       public final void setSelectionRectangular(boolean rectSelect)
      {
         this.rectSelect = rectSelect;
         painter.invalidateSelectedLines();
      }

   /**
    * Returns the position of the highlighted bracket (the bracket
    * matching the one before the caret)
    */
       public final int getBracketPosition()
      {
         return bracketPosition;
      }

   /**
    * Returns the line of the highlighted bracket (the bracket
    * matching the one before the caret)
    */
       public final int getBracketLine()
      {
         return bracketLine;
      }

   /**
    * Adds a caret change listener to this text area.
    * @param listener The listener
    */
       public final void addCaretListener(CaretListener listener)
      {
         listenerList.add(CaretListener.class,listener);
      }

   /**
    * Removes a caret change listener from this text area.
    * @param listener The listener
    */
       public final void removeCaretListener(CaretListener listener)
      {
         listenerList.remove(CaretListener.class,listener);
      }

   /**
    * Deletes the selected text from the text area and places it
    * into the clipboard.
    */
       public void cut()
      {
         if(editable)
         {
            copy();
            setSelectedText("");
         }
      }

   /**
    * Places the selected text into the clipboard.
    */
       public void copy()
      {
         if(selectionStart != selectionEnd)
         {
            Clipboard clipboard = getToolkit().getSystemClipboard();

            String selection = getSelectedText();

            int repeatCount = inputHandler.getRepeatCount();
            StringBuffer buf = new StringBuffer();
            for(int i = 0; i < repeatCount; i++)
               buf.append(selection);

            clipboard.setContents(new StringSelection(buf.toString()),null);
         }
      }

   /**
    * Inserts the clipboard contents into the text.
    */
       public void paste()
      {
         if(editable)
         {
            Clipboard clipboard = getToolkit().getSystemClipboard();
            try
            {
            // The MacOS MRJ doesn't convert \r to \n,
            // so do it here
               String selection = ((String)clipboard
                  .getContents(this).getTransferData(
                  DataFlavor.stringFlavor))
                  .replace('\r','\n');

               int repeatCount = inputHandler.getRepeatCount();
               StringBuffer buf = new StringBuffer();
               for(int i = 0; i < repeatCount; i++)
                  buf.append(selection);
               selection = buf.toString();
               setSelectedText(selection);
            }
                catch(Exception e)
               {
                  getToolkit().beep();
                  System.err.println("Clipboard does not"
                     + " contain a string");
               }
         }
      }

   /**
    * Called by the AWT when this component is removed from it's parent.
    * This stops clears the currently focused component.
    */
       public void removeNotify()
      {
         super.removeNotify();
         if(focusedComponent == this)
            focusedComponent = null;
      }

   /**
    * Forwards key events directly to the input handler.
    * This is slightly faster than using a KeyListener
    * because some Swing overhead is avoided.
    */
       public void processKeyEvent(KeyEvent evt)
      {
         if(inputHandler == null)
            return;
         switch(evt.getID())
         {
            case KeyEvent.KEY_TYPED:
               inputHandler.keyTyped(evt);
               break;
            case KeyEvent.KEY_PRESSED:
               if (!checkPopupCompletion(evt)) {
                  inputHandler.keyPressed(evt);
               }
               checkPopupMenu(evt);
               break;
            case KeyEvent.KEY_RELEASED:
               inputHandler.keyReleased(evt);
               break;
         }
      }

   // protected members
      protected static String CENTER = "center";
      protected static String RIGHT = "right";
      protected static String BOTTOM = "bottom";

      protected static JEditTextArea focusedComponent;
      protected static Timer caretTimer;

      protected TextAreaPainter painter;

      protected JPopupMenu popup;

      protected EventListenerList listenerList;
      protected MutableCaretEvent caretEvent;

      protected boolean caretBlinks;
      protected boolean caretVisible;
      protected boolean blink;

      protected boolean editable;

      protected int caretBlinkRate;
      protected int firstLine;
      protected int visibleLines;
      protected int electricScroll;

      protected int horizontalOffset;

      protected JScrollBar vertical;
      protected JScrollBar horizontal;
      protected boolean scrollBarsInitialized;

      protected InputHandler inputHandler;
      protected SyntaxDocument document;
      protected DocumentHandler documentHandler;

      protected Segment lineSegment;

      protected int selectionStart;
      protected int selectionStartLine;
      protected int selectionEnd;
      protected int selectionEndLine;
      protected boolean biasLeft;

      protected int bracketPosition;
      protected int bracketLine;

      protected int magicCaret;
      protected boolean overwrite;
      protected boolean rectSelect;
      // "unredoing" is mode used by DocumentHandler's insertUpdate() and removeUpdate()
      // to pleasingly select the text and location of the undo.   DPS 3-May-2010
      protected boolean unredoing = false;

       protected void fireCaretEvent()
      {
         Object[] listeners = listenerList.getListenerList();
         for(int i = listeners.length - 2; i >= 0; i--)
         {
            if(listeners[i] == CaretListener.class)
            {
               ((CaretListener)listeners[i+1]).caretUpdate(caretEvent);
            }
         }
      }

       protected void updateBracketHighlight(int newCaretPosition)
      {
         if(newCaretPosition == 0)
         {
            bracketPosition = bracketLine = -1;
            return;
         }

         try
         {
            int offset = TextUtilities.findMatchingBracket(
               document,newCaretPosition - 1);
            if(offset != -1)
            {
               bracketLine = getLineOfOffset(offset);
               bracketPosition = offset - getLineStartOffset(bracketLine);
               return;
            }
         }
             catch(BadLocationException bl)
            {
               bl.printStackTrace();
            }

         bracketLine = bracketPosition = -1;
      }

       protected void documentChanged(DocumentEvent evt)
      {
         DocumentEvent.ElementChange ch = evt.getChange(
            document.getDefaultRootElement());

         int count;
         if(ch == null)
            count = 0;
         else
            count = ch.getChildrenAdded().length -
               ch.getChildrenRemoved().length;

         int line = getLineOfOffset(evt.getOffset());
         if(count == 0)
         {
            painter.invalidateLine(line);
         }
         // do magic stuff
         else if(line < firstLine)
         {
            setFirstLine(firstLine + count);
         }
         // end of magic stuff
         else
         {
            painter.invalidateLineRange(line,firstLine + visibleLines);
            updateScrollBars();
         }
      }

       class ScrollLayout implements LayoutManager
      {
          public void addLayoutComponent(String name, Component comp)
         {
            if(name.equals(CENTER))
               center = comp;
            else if(name.equals(RIGHT))
               right = comp;
            else if(name.equals(BOTTOM))
               bottom = comp;
            else if(name.equals(LEFT_OF_SCROLLBAR))
               leftOfScrollBar.addElement(comp);
         }

          public void removeLayoutComponent(Component comp)
         {
            if(center == comp)
               center = null;
            if(right == comp)
               right = null;
            if(bottom == comp)
               bottom = null;
            else
               leftOfScrollBar.removeElement(comp);
         }

          public Dimension preferredLayoutSize(Container parent)
         {
            Dimension dim = new Dimension();
            Insets insets = getInsets();
            dim.width = insets.left + insets.right;
            dim.height = insets.top + insets.bottom;

            Dimension centerPref = center.getPreferredSize();
            dim.width += centerPref.width;
            dim.height += centerPref.height;
            Dimension rightPref = right.getPreferredSize();
            dim.width += rightPref.width;
            Dimension bottomPref = bottom.getPreferredSize();
            dim.height += bottomPref.height;

            return dim;
         }

          public Dimension minimumLayoutSize(Container parent)
         {
            Dimension dim = new Dimension();
            Insets insets = getInsets();
            dim.width = insets.left + insets.right;
            dim.height = insets.top + insets.bottom;

            Dimension centerPref = center.getMinimumSize();
            dim.width += centerPref.width;
            dim.height += centerPref.height;
            Dimension rightPref = right.getMinimumSize();
            dim.width += rightPref.width;
            Dimension bottomPref = bottom.getMinimumSize();
            dim.height += bottomPref.height;

            return dim;
         }

          public void layoutContainer(Container parent)
         {
            Dimension size = parent.getSize();
            Insets insets = parent.getInsets();
            int itop = insets.top;
            int ileft = insets.left;
            int ibottom = insets.bottom;
            int iright = insets.right;

            int rightWidth = right.getPreferredSize().width;
            int bottomHeight = bottom.getPreferredSize().height;
            int centerWidth = size.width - rightWidth - ileft - iright;
            int centerHeight = size.height - bottomHeight - itop - ibottom;

            center.setBounds(
               ileft,
               itop,
               centerWidth,
               centerHeight);

            right.setBounds(
               ileft + centerWidth,
               itop,
               rightWidth,
               centerHeight);

         // Lay out all status components, in order
            Enumeration status = leftOfScrollBar.elements();
            while(status.hasMoreElements())
            {
               Component comp = (Component)status.nextElement();
               Dimension dim = comp.getPreferredSize();
               comp.setBounds(ileft,
                  itop + centerHeight,
                  dim.width,
                  bottomHeight);
               ileft += dim.width;
            }

            bottom.setBounds(
               ileft,
               itop + centerHeight,
               size.width - rightWidth - ileft - iright,
               bottomHeight);
         }

      // private members
         private Component center;
         private Component right;
         private Component bottom;
         private Vector leftOfScrollBar = new Vector();
      }

       static class CaretBlinker implements ActionListener
      {
          public void actionPerformed(ActionEvent evt)
         {
            if(focusedComponent != null
            && focusedComponent.hasFocus())
               focusedComponent.blinkCaret();
         }
      }

       class MutableCaretEvent extends CaretEvent
      {
          MutableCaretEvent()
         {
            super(JEditTextArea.this);
         }

          public int getDot()
         {
            return getCaretPosition();
         }

          public int getMark()
         {
            return getMarkPosition();
         }
      }

       class AdjustHandler implements AdjustmentListener
      {
          public void adjustmentValueChanged(final AdjustmentEvent evt)
         {
            if(!scrollBarsInitialized)
               return;

         // If this is not done, mousePressed events accumulate
         // and the result is that scrolling doesn't stop after
         // the mouse is released
            SwingUtilities.invokeLater(
                   new Runnable() {
                      public void run()
                     {
                        if(evt.getAdjustable() == vertical)
                           setFirstLine(vertical.getValue());
                        else
                           setHorizontalOffset(-horizontal.getValue());
                     }
                  });
         }
      }

       class ComponentHandler extends ComponentAdapter
      {
          public void componentResized(ComponentEvent evt)
         {
            recalculateVisibleLines();
            scrollBarsInitialized = true;
         }
      }

       class DocumentHandler implements DocumentListener
      {
          public void insertUpdate(DocumentEvent evt)
         {
            documentChanged(evt);

            int offset = evt.getOffset();
            int length = evt.getLength();

            // If event fired because of undo or redo, select inserted text. DPS 3-May-2010
            if (unredoing) {
               select(offset,offset+length);
               return;
            }

            int newStart;
            int newEnd;

            if(selectionStart > offset || (selectionStart
            == selectionEnd && selectionStart == offset))
               newStart = selectionStart + length;
            else
               newStart = selectionStart;

            if(selectionEnd >= offset)
               newEnd = selectionEnd + length;
            else
               newEnd = selectionEnd;
            select(newStart,newEnd);
         }

          public void removeUpdate(DocumentEvent evt)
         {
            documentChanged(evt);

            int offset = evt.getOffset();
            int length = evt.getLength();

            // If event fired because of undo or redo, move caret to position of removal. DPS 3-May-2010
            if (unredoing) {
               select(offset,offset);
               setCaretPosition(offset);
               return;
            }

            int newStart;
            int newEnd;

            if(selectionStart > offset)
            {
               if(selectionStart > offset + length)
                  newStart = selectionStart - length;
               else
                  newStart = offset;
            }
            else
               newStart = selectionStart;

            if(selectionEnd > offset)
            {
               if(selectionEnd > offset + length)
                  newEnd = selectionEnd - length;
               else
                  newEnd = offset;
            }
            else
               newEnd = selectionEnd;
            select(newStart,newEnd);
         }

          public void changedUpdate(DocumentEvent evt)
         {
         }
      }

       class DragHandler implements MouseMotionListener
      {
          public void mouseDragged(MouseEvent evt)
         {
            if(popup != null && popup.isVisible())
               return;

            setSelectionRectangular((evt.getModifiers()
               & InputEvent.CTRL_MASK) != 0);
            select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY()));
         }

          public void mouseMoved(MouseEvent evt) {}
      }

       class FocusHandler implements FocusListener
      {
          public void focusGained(FocusEvent evt)
         {
            setCaretVisible(true);
            focusedComponent = JEditTextArea.this;
         }

          public void focusLost(FocusEvent evt)
         {
            setCaretVisible(false);
            focusedComponent = null;
         }
      }

       // Added by DPS, 5-5-2010. Allows use of mouse wheel to scroll.
   	 // Scrolling as fast as I could, the most notches I could get in
   	 // one MouseWheelEvent was 3.  Normally it will be 1.  Nonetheless,
   	 // this will scroll up to the number in the event, subject to
   	 // scrollability of the text in its viewport.
       class MouseWheelHandler implements MouseWheelListener
      {
          public void mouseWheelMoved(MouseWheelEvent e) {
            int maxMotion = Math.abs(e.getWheelRotation()) * LINES_PER_MOUSE_WHEEL_NOTCH;
            if (e.getWheelRotation() < 0) {
               setFirstLine( getFirstLine() - Math.min(maxMotion, getFirstLine()) );
            }
            else {
               setFirstLine( getFirstLine() + (Math.min(maxMotion, Math.max(0,getLineCount()-(getFirstLine()+visibleLines)))));
            }
         }
      }

       class MouseHandler extends MouseAdapter
      {
          public void mousePressed(MouseEvent evt)
         {
            requestFocus();

         // Focus events not fired sometimes?
            setCaretVisible(true);
            focusedComponent = JEditTextArea.this;

            if((evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0
            && popup != null)
            {
               popup.show(painter,evt.getX(),evt.getY());
               return;
            }

            int line = yToLine(evt.getY());
            int offset = xToOffset(line,evt.getX());
            int dot = getLineStartOffset(line) + offset;

            switch(evt.getClickCount())
            {
               case 1:
                  doSingleClick(evt,line,offset,dot);
                  break;
               case 2:
               // It uses the bracket matching stuff, so
               // it can throw a BLE
                  try
                  {
                     doDoubleClick(evt,line,offset,dot);
                  }
                      catch(BadLocationException bl)
                     {
                        bl.printStackTrace();
                     }
                  break;
               case 3:
                  doTripleClick(evt,line,offset,dot);
                  break;
            }
         }

          private void doSingleClick(MouseEvent evt, int line,
          int offset, int dot)
         {
            if((evt.getModifiers() & InputEvent.SHIFT_MASK) != 0)
            {
               rectSelect = (evt.getModifiers() & InputEvent.CTRL_MASK) != 0;
               select(getMarkPosition(),dot);
            }
            else
               setCaretPosition(dot);
         }

          private void doDoubleClick(MouseEvent evt, int line,
          int offset, int dot) throws BadLocationException
         {
         // Ignore empty lines
            if(getLineLength(line) == 0)
               return;

            try
            {
               int bracket = TextUtilities.findMatchingBracket(
                  document,Math.max(0,dot - 1));
               if(bracket != -1)
               {
                  int mark = getMarkPosition();
               // Hack
                  if(bracket > mark)
                  {
                     bracket++;
                     mark--;
                  }
                  select(mark,bracket);
                  return;
               }
            }
                catch(BadLocationException bl)
               {
                  bl.printStackTrace();
               }

         // Ok, it's not a bracket... select the word
            String lineText = getLineText(line);
            char ch = lineText.charAt(Math.max(0,offset - 1));

            String noWordSep = (String)document.getProperty("noWordSep");
            if(noWordSep == null)
               noWordSep = "";

         // If the user clicked on a non-letter char,
         // we select the surrounding non-letters
            boolean selectNoLetter = (!Character
               .isLetterOrDigit(ch)
               && noWordSep.indexOf(ch) == -1);

            int wordStart = 0;

            for(int i = offset - 1; i >= 0; i--)
            {
               ch = lineText.charAt(i);
               if(selectNoLetter ^ (!Character
               .isLetterOrDigit(ch) &&
               noWordSep.indexOf(ch) == -1))
               {
                  wordStart = i + 1;
                  break;
               }
            }

            int wordEnd = lineText.length();
            for(int i = offset; i < lineText.length(); i++)
            {
               ch = lineText.charAt(i);
               if(selectNoLetter ^ (!Character
               .isLetterOrDigit(ch) &&
               noWordSep.indexOf(ch) == -1))
               {
                  wordEnd = i;
                  break;
               }
            }

            int lineStart = getLineStartOffset(line);
            select(lineStart + wordStart,lineStart + wordEnd);
         }

          private void doTripleClick(MouseEvent evt, int line,
          int offset, int dot)
         {
            select(getLineStartOffset(line),getLineEndOffset(line)-1);
         }
      }

       class CaretUndo extends AbstractUndoableEdit
      {
         private int start;
         private int end;

          CaretUndo(int start, int end)
         {
            this.start = start;
            this.end = end;
         }

          public boolean isSignificant()
         {
            return false;
         }

          public String getPresentationName()
         {
            return "caret move";
         }

          public void undo() throws CannotUndoException
         {
            super.undo();

            select(start,end);
         }

          public void redo() throws CannotRedoException
         {
            super.redo();

            select(start,end);
         }

          public boolean addEdit(UndoableEdit edit)
         {
            if(edit instanceof CaretUndo)
            {
               CaretUndo cedit = (CaretUndo)edit;
               start = cedit.start;
               end = cedit.end;
               cedit.die();

               return true;
            }
            else
               return false;
         }
      }

      /**
   	 *  Return any relevant tool tip text for token at specified position. Keyword match
   	 *  must be exact.  DPS 24-May-2010
   	 *  @param x x-coordinate of current position
   	 *  @param y y-coordinate of current position
   	 *  @return String containing appropriate tool tip text.  Possibly HTML-encoded.
   	 */
   	 // Is used for tool tip only (not popup menu)
       public String getSyntaxSensitiveToolTipText(int x, int y) {
         String result = null;
         int line = this.yToLine(y);
         ArrayList matches = getSyntaxSensitiveHelpAtLineOffset(line, this.xToOffset(line,x), true);
         if (matches == null) {
            return null;
         }
         int length = PopupHelpItem.maxExampleLength(matches) + 2;
         result = "";
         for (int i=0; i<matches.size(); i++) {
            PopupHelpItem match = (PopupHelpItem)matches.get(i);
            result += ((i==0)?"":"
") + "<tt>" + match.getExamplePaddedToLength(length).replaceAll(" "," ") + "</tt>" + match.getDescription();
         }
         return result + "";
      }

       /**
        * Constructs string for auto-indent feature.  Returns empty string
   	  * if auto-intent is disabled or if line has no leading white space.
   	  * Uses getLeadingWhiteSpace(). Is used by InputHandler when processing
   	  * key press for Enter key.   DPS 31-Dec-2010
   	  * @return String containing auto-indent characters to be inserted into text
   	  */
       public String getAutoIndent() {
         return (Globals.getSettings().getBooleanSetting(Settings.AUTO_INDENT)) ? getLeadingWhiteSpace() : "";
      }

       /**
        * Makes a copy of leading white space (tab or space) from the current line and
   	  * returns it.    DPS 31-Dec-2010
   	  * @return String containing leading white space of current line.  Empty string if none.
   	  */
       public String getLeadingWhiteSpace() {
         int line = getCaretLine();
         int lineLength = getLineLength(line);
         String indent = "";
         if (lineLength > 0) {
            String text = getText(getLineStartOffset(line), lineLength);
            for (int position = 0; position < text.length(); position++) {
               char character = text.charAt(position);
               if (character == '\t' || character == ' ') {
                  indent += character;
               }
               else {
                  break;
               }
            }
         }
         return indent;
      }

      //////////////////////////////////////////////////////////////////////////////////
      // Get relevant help information at specified position.  Returns ArrayList of
   	// PopupHelpItem with one per match, or null if no matches.
   	// The "exact" parameter is set depending on whether the match has to be
   	// exact or whether a prefix match will do.  The token "s" will not match
   	// any instruction names if exact is true, but will match "sw", "sh", etc
   	// if exact is false.  The former is helpful for mouse-movement-based tool
   	// tips (this is what you have).  The latter is helpful for caret-based tool
   	// tips (this is what you can do).
       private ArrayList getSyntaxSensitiveHelpAtLineOffset(int line, int offset, boolean exact) {
         ArrayList matches = null;
         TokenMarker tokenMarker = this.getTokenMarker();
         if (tokenMarker != null) {
            Segment lineSegment = new Segment();
            this.getLineText(line,lineSegment); // fill segment with info from this line
            Token tokens = tokenMarker.markTokens(lineSegment,line);
            Token tokenList = tokens;
            int tokenOffset = 0;
            Token tokenAtOffset = null;
         	// cool for following the tokens...
            //System.out.print("(JEditTextArea.java) Token Stream:");
            Token toke = tokens;
            for (;;) {
               //System.out.print(" "+toke.id+"("+toke.length+")");
               if (toke.id == Token.END)
                  break;
               toke = toke.next;
            }
            //System.out.println();

            for (;;) {
               byte id = tokens.id;
               if(id == Token.END)
                  break;
               int length = tokens.length;
               if (offset > tokenOffset && offset <= tokenOffset+length) {
                  tokenAtOffset = tokens;
                  break;
               }
               tokenOffset += length;
               tokens = tokens.next;
            }
            if (tokenAtOffset != null) {
               String tokenText = lineSegment.toString().substring(tokenOffset, tokenOffset+tokenAtOffset.length);
               if (exact) {
                  matches = tokenMarker.getTokenExactMatchHelp(tokenAtOffset, tokenText);
               }
               else {
                  matches = tokenMarker.getTokenPrefixMatchHelp(lineSegment.toString(), tokenList, tokenAtOffset, tokenText);
               }
            }
         }
         return matches;
      }

       ////////////////////////////////////////////////////////////////////////////////////
       // Compose and display syntax-sensitive help. Typically invoked upon typing a key.
   	 // Results in popup menu.  Is not used for creating tool tips.
       private void applySyntaxSensitiveHelp() {
         if (!mars.Globals.getSettings().getBooleanSetting(mars.Settings.POPUP_INSTRUCTION_GUIDANCE)) {
            return;
         }
         int line = getCaretLine();
         int lineStart = getLineStartOffset(line);
         int offset = Math.max(1,Math.min(getLineLength(line),
            getCaretPosition() - lineStart));
         ArrayList helpItems = getSyntaxSensitiveHelpAtLineOffset(line,offset,false);
         if (helpItems == null && popupMenu != null) {
            popupMenu.setVisible(false);
            popupMenu = null;
         }
         if (helpItems != null) {
            popupMenu = new JPopupMenu();
            int length = PopupHelpItem.maxExampleLength(helpItems) + 2;
            for (int i=0; i<helpItems.size(); i++) {
               PopupHelpItem item = (PopupHelpItem) helpItems.get(i);
               JMenuItem menuItem = new JMenuItem("<tt>"+item.getExamplePaddedToLength(length).replaceAll(" "," ")+"</tt>"+item.getDescription()+"");
               if (item.getExact()) {
                  // The instruction name is completed so the role of the popup changes
               	// to that of floating help to assist in operand specification.
                  menuItem.setSelected(false);
                  menuItem.setEnabled(false);
               }
               else {
                  // Typing of instruction/directive name is still in progress; the action listener
               	// will complete it when its menu item is selected.
                  menuItem.addActionListener(new PopupHelpActionListener(item.getTokenText(), item.getExample()));
               }
               popupMenu.add(menuItem);
            }
            popupMenu.pack();
            int y = lineToY(line);
            int x = offsetToX(line, offset);
            int height = painter.getFontMetrics(painter.getFont()).getHeight();
            int width = painter.getFontMetrics(painter.getFont()).charWidth('w');
            int menuXLoc = x+width+width+width;
            int menuYLoc = y+height+height; // display below;
         	// Modified to always display popup BELOW the current line.
         	// This was done in response to negative student feedback about
         	// the popup blocking information they needed to (e.g. operands from
         	// previous instructions).  Note that if menu is long enough and
         	// current cursor position is low enough, the menu will bottom out at the
         	// bottom of the screen and extend above the current line. DPS 23-Dec-2010
            popupMenu.show(this, menuXLoc, menuYLoc);
            this.requestFocusInWindow(); // get cursor back from the menu
         }
      }

       // Carries out the instruction/directive completion when popup menu
   	 // item is selected.
       private class PopupHelpActionListener implements ActionListener {
         private String tokenText, text;
          public PopupHelpActionListener(String tokenText, String text) {
            this.tokenText = tokenText;
            this.text = text.split(" ")[0];
         }
      	// Completion action will insert either a tab or space character following the
      	// completed instruction mnemonic.  Inserts a tab if tab key was pressed;
      	// space otherwise.  Get this information from the ActionEvent.
          public void actionPerformed(ActionEvent e) {
            String insert = (e.getActionCommand().charAt(0)=='\t') ? "\t" : " ";
            if (this.tokenText.length() >= this.text.length()) {
               overwriteSetSelectedText(insert);
            }
            else {
               overwriteSetSelectedText(this.text.substring(this.tokenText.length())+insert);
            }
         }
      }

       private void checkAutoIndent(KeyEvent evt) {
         if (evt.getKeyCode()==KeyEvent.VK_ENTER) {
            int line = getCaretLine();
            if (line <= 0)
               return;
            int previousLine = line - 1 ;
            int previousLineLength = getLineLength(previousLine);
            if (previousLineLength <= 0)
               return;
            String previous = getText(getLineStartOffset(previousLine), previousLineLength);
            String indent = "";
            for (int position = 0; position < previous.length(); position++) {
               char character = previous.charAt(position);
               if (character == '\t' || character == ' ') {
                  indent += character;
               }
               else {
                  break;
               }
            }
            overwriteSetSelectedText(indent);
         }
      }

       ////////////////////////////////////////////////////////////////////////////////////
       // Called after processing a Key Pressed event. Will make popup menu disappear if
   	 // Enter or Escape keys pressed.  Will update if Backspace or Delete pressed.
   	 // Not really concerned with modifiers here.
       private void checkPopupMenu(KeyEvent evt) {
         if ( evt.getKeyCode()==KeyEvent.VK_BACK_SPACE || evt.getKeyCode()==KeyEvent.VK_DELETE)
            applySyntaxSensitiveHelp();
         if ( (evt.getKeyCode()== KeyEvent.VK_ENTER || evt.getKeyCode() == KeyEvent.VK_ESCAPE)
                   && popupMenu != null && popupMenu.isVisible() )
            popupMenu.setVisible(false);
      }

       ////////////////////////////////////////////////////////////////////////////////////
       // Called before processing Key Pressed event. If popup menu is visible, will process
   	 // tab and enter keys to select from the menu, and arrow keys to traverse the menu.
       private boolean checkPopupCompletion(KeyEvent evt) {
         if ((evt.getKeyCode()==KeyEvent.VK_UP || evt.getKeyCode()==KeyEvent.VK_DOWN)
             && popupMenu != null && popupMenu.isVisible() && popupMenu.getComponentCount() > 0)
         {
            MenuElement[] path = MenuSelectionManager.defaultManager().getSelectedPath();
            if (path.length < 1 || !(path[path.length-1] instanceof AbstractButton))
               return false;
            AbstractButton item = (AbstractButton) path[path.length-1].getComponent();
            if (item.isEnabled()) {
               int index = popupMenu.getComponentIndex(item);
               if (index < 0)
                  return false;
               if (evt.getKeyCode() == KeyEvent.VK_UP) {
                  index = (index==0) ? popupMenu.getComponentCount()-1 : index-1;
               }
               else {
                  index = (index==popupMenu.getComponentCount()-1) ? 0 : index+1;
               }
            	// Neither popupMenu.setSelected() nor popupMenu.getSelectionModel().setSelectedIndex()
            	// have the desired effect (changing the menu item selected).  Found references to
            	// this in a Sun forum.  http://forums.sun.com/thread.jspa?forumID=57&threadID=641745
            	// The solution, as shown here, is to use invokeLater.
               final MenuElement[] newPath = new MenuElement[2];
               newPath[0] = path[0];
               newPath[1] = (MenuElement) popupMenu.getComponentAtIndex(index);
               SwingUtilities.invokeLater(
                      new Runnable() {
                         public void run() {
                           MenuSelectionManager.defaultManager().setSelectedPath(newPath);
                        }
                     });
               return true;
            }
            else {
               return false;
            }
         }
         if ((evt.getKeyCode()==KeyEvent.VK_TAB || evt.getKeyCode()==KeyEvent.VK_ENTER)
             && popupMenu != null && popupMenu.isVisible() && popupMenu.getComponentCount() > 0)
         {
            MenuElement[] path = MenuSelectionManager.defaultManager().getSelectedPath();
            if (path.length < 1 || !(path[path.length-1] instanceof AbstractButton))
               return false;
            AbstractButton item = (AbstractButton) path[path.length-1].getComponent();
            if (item.isEnabled()) {
               ActionListener[] listeners = item.getActionListeners();
               if (listeners.length > 0) {
                  listeners[0].actionPerformed(new ActionEvent(item, ActionEvent.ACTION_FIRST,
                     (evt.getKeyCode()==KeyEvent.VK_TAB) ? "\t" : " "));
                  return true;
               }
            }
         }
         return false;
      }

      static
      {
         caretTimer = new Timer(500,new CaretBlinker());
         caretTimer.setInitialDelay(500);
         caretTimer.start();
      }
   }


text:
package org.apache.beam.sdk.util;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.apache.beam.sdk.transforms.Combine;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests {@link BucketingFunction}. */
@RunWith(JUnit4.class)
public class BucketingFunctionTest {

  private static final int BUCKET_WIDTH = 10;
  private static final int SIGNIFICANT_BUCKETS = 2;
  private static final int SIGNIFICANT_SAMPLES = 10;

  private static final Combine.BinaryCombineLongFn SUM =
      new Combine.BinaryCombineLongFn() {
        @Override
        public long apply(long left, long right) {
          return left + right;
        }

        @Override
        public long identity() {
          return 0;
        }
      };

  private BucketingFunction newFunc() {
    return new BucketingFunction(
        BUCKET_WIDTH, SIGNIFICANT_BUCKETS,
        SIGNIFICANT_SAMPLES, SUM);
  }

  @Test
  public void significantSamples() {
    BucketingFunction f = newFunc();
    assertFalse(f.isSignificant());
    for (int i = 0; i < SIGNIFICANT_SAMPLES - 1; i++) {
      f.add(0, 0);
      assertFalse(f.isSignificant());
    }
    f.add(0, 0);
    assertTrue(f.isSignificant());
  }

  @Test
  public void significantBuckets() {
    BucketingFunction f = newFunc();
    assertFalse(f.isSignificant());
    f.add(0, 0);
    assertFalse(f.isSignificant());
    f.add(BUCKET_WIDTH, 0);
    assertTrue(f.isSignificant());
  }

  @Test
  public void sum() {
    BucketingFunction f = newFunc();
    for (int i = 0; i < 100; i++) {
      f.add(i, i);
      assertEquals(((i + 1) * i) / 2, f.get());
    }
  }

  @Test
  public void movingSum() {
    BucketingFunction f = newFunc();
    int lost = 0;
    for (int i = 0; i < 200; i++) {
      f.add(i, 1);
      if (i >= 100) {
        f.remove(i - 100);
        if (i % BUCKET_WIDTH == BUCKET_WIDTH - 1) {
          lost += BUCKET_WIDTH;
        }
      }
      assertEquals(i + 1 - lost, f.get());
    }
  }
}

redpajama_set_name: RedPajamaGithub


text:
package org.takes.rs.xe;

import java.io.IOException;
import lombok.EqualsAndHashCode;
import org.xembly.Directive;
import org.xembly.Directives;

/**
 * Xembly source to append something to an existing element.
 *
 * <p>The class is immutable and thread-safe.
 *
 * @author Yegor Bugayenko (yegor@teamed.io)
 * @version $Id$
 * @since 0.1
 */
@EqualsAndHashCode(callSuper = true)
public final class XeAppend extends XeWrap {

    /**
     * Ctor.
     * @param target Name of XML element
     * @param value Value to set
     */
    public XeAppend(final String target, final String value) {
        this(target, new XeDirectives(new Directives().set(value)));
    }

    /**
     * Ctor.
     * @param target Name of XML element
     * @param src Source
     */
    public XeAppend(final String target, final XeSource... src) {
        super(
            new XeSource() {
                @Override
                public Iterable<Directive> toXembly() throws IOException {
                    return new Directives().add(target).append(
                        new XeChain(src).toXembly()
                    );
                }
            }
        );
    }

}


text:
import os
import unicodedata
from makeConllFromDBOutput import makeConll

pathToEpic = os.getcwd()
pathToEpic = pathToEpic[0:pathToEpic.rfind("epic")+4]

positiveFile = pathToEpic + "data/epicEvalutationTestSet/positives.txt"
positiveConll = pathToEpic + "data/epicEvalutationTestSet/positives.conll"
negativeFile = pathToEpic + "data/epicEvalutationTestSet/negatives.txt"
negativeConll = pathToEpic + "data/epicEvalutationTestSet/negatives.conll"
positiveFakeFile = pathToEpic + "data/epicEvalutationTestSet/fakePositives.txt"
positiveFakeConll = pathToEpic + "data/epicEvalutationTestSet/fakePositives.conll"

makeConll(positiveFile, positiveConll,0.0)
makeConll(negativeFile, negativeConll,0.0)
makeConll(positiveFakeFile, positiveFakeConll,0.0)

filenames = [positiveConll, positiveFakeConll, negativeConll]
with open(os.path.expanduser(pathToEpic + 'data/epicEvalutationTestSet.conll'), 'w') as outfile:
    for fname in filenames:
        with open(os.path.expanduser(fname)) as infile:
            outfile.write(infile.read())


text:
class Logger;

extern Logger logger;

enum class Level {
    Debug=0,
    Info=1,
    Warn=2,
    Error=3
};

class Logger {
public:
    Logger() = default;
    Logger(Level level);

    void set_level(Level level);

    void operator()(std::string const& message,
                    char const* function,
                    char const* file,
                    int line,
                    Level level);

private:
    Level level;
    std::mutex lock;
};

#define LOG_DEBUG(message) logger(\
                                   static_cast<std::ostringstream&>( \
                                   std::ostringstream().flush() << message \
                                   ).str(),\
                                   __FUNCTION__,\
                                   __FILENAME__,\
                                   __LINE__, \
                                   Level::Debug);
#define LOG_INFO(message) logger(\
                                   static_cast<std::ostringstream&>( \
                                   std::ostringstream().flush() << message \
                                   ).str(),\
                                   __FUNCTION__,\
                                   __FILENAME__,\
                                   __LINE__, \
                                   Level::Info);
#define LOG_WARN(message) logger(\
                                   static_cast<std::ostringstream&>( \
                                   std::ostringstream().flush() << message \
                                   ).str(),\
                                   __FUNCTION__,\
                                   __FILENAME__,\
                                   __LINE__, \
                                   Level::Warn);
#define LOG_ERROR(message) logger(\
                                   static_cast<std::ostringstream&>( \
                                   std::ostringstream().flush() << message \
                                   ).str(),\
                                   __FUNCTION__,\
                                   __FILENAME__,\
                                   __LINE__, \
                                   Level::Error);

#endif //OGP_COMMON_LOG_H


text:
namespace Laughing_HardDrive
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.baseLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.newLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.helpToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
            this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.menuStrip1.SuspendLayout();
            this.SuspendLayout();
            //
            // menuStrip1
            //
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.fileToolStripMenuItem,
            this.viewToolStripMenuItem,
            this.helpToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(505, 24);
            this.menuStrip1.TabIndex = 0;
            this.menuStrip1.Text = "menuStrip1";
            //
            // fileToolStripMenuItem
            //
            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.openToolStripMenuItem,
            this.saveToolStripMenuItem,
            this.saveAsToolStripMenuItem,
            this.exitToolStripMenuItem});
            this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
            this.fileToolStripMenuItem.Text = "File";
            //
            // openToolStripMenuItem
            //
            this.openToolStripMenuItem.Name = "openToolStripMenuItem";
            this.openToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.openToolStripMenuItem.Text = "Open";
            //
            // saveToolStripMenuItem
            //
            this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
            this.saveToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.saveToolStripMenuItem.Text = "Save";
            //
            // saveAsToolStripMenuItem
            //
            this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
            this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.saveAsToolStripMenuItem.Text = "Save As";
            //
            // exitToolStripMenuItem
            //
            this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
            this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.exitToolStripMenuItem.Text = "Exit";
            //
            // viewToolStripMenuItem
            //
            this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.baseLogToolStripMenuItem,
            this.newLogToolStripMenuItem});
            this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
            this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
            this.viewToolStripMenuItem.Text = "View";
            //
            // baseLogToolStripMenuItem
            //
            this.baseLogToolStripMenuItem.Name = "baseLogToolStripMenuItem";
            this.baseLogToolStripMenuItem.Size = new System.Drawing.Size(121, 22);
            this.baseLogToolStripMenuItem.Text = "Base Log";
            //
            // newLogToolStripMenuItem
            //
            this.newLogToolStripMenuItem.Name = "newLogToolStripMenuItem";
            this.newLogToolStripMenuItem.Size = new System.Drawing.Size(121, 22);
            this.newLogToolStripMenuItem.Text = "New Log";
            //
            // helpToolStripMenuItem
            //
            this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.helpToolStripMenuItem1,
            this.aboutToolStripMenuItem});
            this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
            this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
            this.helpToolStripMenuItem.Text = "Help";
            //
            // helpToolStripMenuItem1
            //
            this.helpToolStripMenuItem1.Name = "helpToolStripMenuItem1";
            this.helpToolStripMenuItem1.Size = new System.Drawing.Size(107, 22);
            this.helpToolStripMenuItem1.Text = "Help";
            //
            // aboutToolStripMenuItem
            //
            this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
            this.aboutToolStripMenuItem.Size = new System.Drawing.Size(107, 22);
            this.aboutToolStripMenuItem.Text = "About";
            //
            // groupBox1
            //
            this.groupBox1.Location = new System.Drawing.Point(13, 54);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(200, 245);
            this.groupBox1.TabIndex = 1;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Choose Drive";
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(505, 334);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.menuStrip1);
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "Form1";
            this.Text = "The Laughing Hard Drive";
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.MenuStrip menuStrip1;
        private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem1;
        private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem baseLogToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem newLogToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem;
        private System.Windows.Forms.GroupBox groupBox1;
    }
}


text:
<?php

function __field($options=array()){
	extract($options);

	$heading = $heading?$heading:'h4';
	$type = esc_attr($type);
	$name = esc_attr($name);
	$label = make_label(($label?$label:$name));
	$value = $type=='textarea'?htmlspecialchars($value):esc_attr($value);
	$disabled = $disabled?" disabled='{$disabled}'":'';
	$checked = $checked?" checked='{$checked}'":'';
	$selected = $selected?" selected='{$selected}'":'';
	if(!empty($children)){
		$children_markup = '';
		foreach($children as $child){
			$children_markup .= __field($child);
		}
	}

	switch($type){
	case 'text':
	case 'password':
	case 'hidden':
		$markup = <<<EOT

	<{$heading}>{$label}</{$heading}>
	<input type="{$type}" name="{$name}" value="{$value}"{$disabled}{$checked}{$selected}/>

EOT;
		break;
	case 'checkbox':
		$markup = <<<EOT

	{$label}
		<input type="{$type}" name="{$name}[]" value="{$value}"{$disabled}{$checked}{$selected}/>

EOT;
		break;
	case 'radio':
		$markup = <<<EOT

	{$label}
		<input type="{$type}" name="{$name}" value="{$value}"{$disabled}{$checked}{$selected}/>

EOT;
		break;
	case 'select':
		$markup = <<<EOT

	<{$heading}>{$label}</{$heading}>
	<select name="{$name}">
{$children_markup}
	</select>

EOT;
		break;
	case 'checkboxes':
	case 'radios':
		$markup = <<<EOT

	<{$heading}>{$label}</{$heading}>
{$children_markup}

EOT;
		break;
	}
	return $markup;
}

function _field($options=array()){
	echo __field($options);
}

function __metabox($post,$options=array()){
	$properties = get_properties($post);
	$options['args']['fields']['slide_weight']['children'][$properties['slide_weight']]['checked']='checked';
	$options['args']['fields']['slide_animation']['children'][$properties['slide_animation']]['checked']='checked';
	$options['args']['fields']['slide_title']['children'][$properties['slide_title']]['checked']='checked';
	$options['args']['fields']['slide_content']['children'][$properties['slide_content']]['checked']='checked';
	$options['args']['fields']['slide_author']['children'][$properties['slide_author']]['checked']='checked';
	$options['args']['fields']['slide_date']['children'][$properties['slide_date']]['checked']='checked';
	$options['args']['fields']['slide_category']['children'][$properties['slide_category']]['checked']='checked';
	$options['args']['fields']['slide_tag']['children'][$properties['slide_tag']]['checked']='checked';

	wp_nonce_field($options['id'],$options['id'].'_nonce');
    foreach($options['args']['fields'] as $field){
		_field($field);
	}
}

function _metabox($post=array(),$options=array()){
	echo __metabox($post,$options);
}

function __heading_label($post){
	$default = strtoupper('heading');
	$in_format = strtoupper($default.'_'.$post->format);
	$in_weight = strtoupper($in_format.'_'.$post->slide_weight);

	if(defined($in_weight)){
		$label = $in_weight;
	}else if(defined($in_format)){
		$label = $in_format;
	}else if(defined($default)){
		$label = $default;
	}

	return $label;
}

function _heading_label($post){
	echo __heading_label($post);
}

function __heading($post){
	$heading = isset($post->heading_label)?constant($post->heading_label):constant(__heading_label($post));
	return $heading;
}

function _heading($post){
	echo __heading($post);
}

?>