/*
 * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package javax.swing.text;

import java.io.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.text.*;
import javax.swing.Action;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.UIManager;

/**
 * This is the set of things needed by a text component
 * to be a reasonably functioning editor for some <em>type</em>
 * of text document.  This implementation provides a default
 * implementation which treats text as plain text and
 * provides a minimal set of actions for a simple editor.
 * <p>
 * <dl>
 * <dt><b><font size=+1>Newlines</font></b>
 * <dd>
 * There are two properties which deal with newlines.  The
 * system property, <code>line.separator</code>, is defined to be
 * platform-dependent, either "\n", "\r", or "\r\n".  There is also
 * a property defined in <code>DefaultEditorKit</code>, called
 * <a href=#EndOfLineStringProperty><code>EndOfLineStringProperty</code></a>,
 * which is defined automatically when a document is loaded, to be
 * the first occurrence of any of the newline characters.
 * When a document is loaded, <code>EndOfLineStringProperty</code>
 * is set appropriately, and when the document is written back out, the
 * <code>EndOfLineStringProperty</code> is used.  But while the document
 * is in memory, the "\n" character is used to define a
 * newline, regardless of how the newline is defined when
 * the document is on disk.  Therefore, for searching purposes,
 * "\n" should always be used.  When a new document is created,
 * and the <code>EndOfLineStringProperty</code> has not been defined,
 * it will use the System property when writing out the
 * document.
 * <p>Note that <code>EndOfLineStringProperty</code> is set
 * on the <code>Document</code> using the <code>get/putProperty</code>
 * methods.  Subclasses may override this behavior.
 *
 * </dl>
 *
 * @author  Timothy Prinzing
 */
public class DefaultEditorKit extends EditorKit {

    /**
     * default constructor for DefaultEditorKit
     */
    public DefaultEditorKit() {
    }

    /**
     * Gets the MIME type of the data that this
     * kit represents support for.  The default
     * is <code>text/plain</code>.
     *
     * @return the type
     */
    public String getContentType() {
        return "text/plain";
    }

    /**
     * Fetches a factory that is suitable for producing
     * views of any models that are produced by this
     * kit.  The default is to have the UI produce the
     * factory, so this method has no implementation.
     *
     * @return the view factory
     */
    public ViewFactory getViewFactory() {
        return null;
    }

    /**
     * Fetches the set of commands that can be used
     * on a text component that is using a model and
     * view produced by this kit.
     *
     * @return the command list
     */
    public Action[] getActions() {
        return defaultActions;
    }

    /**
     * Fetches a caret that can navigate through views
     * produced by the associated ViewFactory.
     *
     * @return the caret
     */
    public Caret createCaret() {
        return null;
    }

    /**
     * Creates an uninitialized text storage model (PlainDocument)
     * that is appropriate for this type of editor.
     *
     * @return the model
     */
    public Document createDefaultDocument() {
        return new PlainDocument();
    }

    /**
     * Inserts content from the given stream which is expected
     * to be in a format appropriate for this kind of content
     * handler.
     *
     * @param in  The stream to read from
     * @param doc The destination for the insertion.
     * @param pos The location in the document to place the
     *   content >= 0.
     * @exception IOException on any I/O error
     * @exception BadLocationException if pos represents an invalid
     *   location within the document.
     */
    public void read(InputStream in, Document doc, int pos)
        throws IOException, BadLocationException {

        read(new InputStreamReader(in), doc, pos);
    }

    /**
     * Writes content from a document to the given stream
     * in a format appropriate for this kind of content handler.
     *
     * @param out The stream to write to
     * @param doc The source for the write.
     * @param pos The location in the document to fetch the
     *   content >= 0.
     * @param len The amount to write out >= 0.
     * @exception IOException on any I/O error
     * @exception BadLocationException if pos represents an invalid
     *   location within the document.
     */
    public void write(OutputStream out, Document doc, int pos, int len)
        throws IOException, BadLocationException {
        OutputStreamWriter osw = new OutputStreamWriter(out);

        write(osw, doc, pos, len);
        osw.flush();
    }

    /**
     * Gets the input attributes for the pane. This method exists for
     * the benefit of StyledEditorKit so that the read method will
     * pick up the correct attributes to apply to inserted text.
     * This class's implementation simply returns null.
     *
     * @return null
     */
    MutableAttributeSet getInputAttributes() {
        return null;
    }

    /**
     * Inserts content from the given stream, which will be
     * treated as plain text.
     *
     * @param in  The stream to read from
     * @param doc The destination for the insertion.
     * @param pos The location in the document to place the
     *   content >= 0.
     * @exception IOException on any I/O error
     * @exception BadLocationException if pos represents an invalid
     *   location within the document.
     */
    public void read(Reader in, Document doc, int pos)
        throws IOException, BadLocationException {

        char[] buff = new char[4096];
        int nch;
        boolean lastWasCR = false;
        boolean isCRLF = false;
        boolean isCR = false;
        int last;
        boolean wasEmpty = (doc.getLength() == 0);
        AttributeSet attr = getInputAttributes();

        // Read in a block at a time, mapping \r\n to \n, as well as single
        // \r's to \n's. If a \r\n is encountered, \r\n will be set as the
        // newline string for the document, if \r is encountered it will
        // be set as the newline character, otherwise the newline property
        // for the document will be removed.
        while ((nch = in.read(buff, 0, buff.length)) != -1) {
            last = 0;
            for(int counter = 0; counter < nch; counter++) {
                switch(buff[counter]) {
                case '\r':
                    if (lastWasCR) {
                        isCR = true;
                        if (counter == 0) {
                            doc.insertString(pos, "\n", attr);
                            pos++;
                        }
                        else {
                            buff[counter - 1] = '\n';
                        }
                    }
                    else {
                        lastWasCR = true;
                    }
                    break;
                case '\n':
                    if (lastWasCR) {
                        if (counter > (last + 1)) {
                            doc.insertString(pos, new String(buff, last,
                                            counter - last - 1), attr);
                            pos += (counter - last - 1);
                        }
                        // else nothing to do, can skip \r, next write will
                        // write \n
                        lastWasCR = false;
                        last = counter;
                        isCRLF = true;
                    }
                    break;
                default:
                    if (lastWasCR) {
                        isCR = true;
                        if (counter == 0) {
                            doc.insertString(pos, "\n", attr);
                            pos++;
                        }
                        else {
                            buff[counter - 1] = '\n';
                        }
                        lastWasCR = false;
                    }
                    break;
                }
            }
            if (last < nch) {
                if(lastWasCR) {
                    if (last < (nch - 1)) {
                        doc.insertString(pos, new String(buff, last,
                                         nch - last - 1), attr);
                        pos += (nch - last - 1);
                    }
                }
                else {
                    doc.insertString(pos, new String(buff, last,
                                     nch - last), attr);
                    pos += (nch - last);
                }
            }
        }
        if (lastWasCR) {
            doc.insertString(pos, "\n", attr);
            isCR = true;
        }
        if (wasEmpty) {
            if (isCRLF) {
                doc.putProperty(EndOfLineStringProperty, "\r\n");
            }
            else if (isCR) {
                doc.putProperty(EndOfLineStringProperty, "\r");
            }
            else {
                doc.putProperty(EndOfLineStringProperty, "\n");
            }
        }
    }

    /**
     * Writes content from a document to the given stream
     * as plain text.
     *
     * @param out  The stream to write to
     * @param doc The source for the write.
     * @param pos The location in the document to fetch the
     *   content from >= 0.
     * @param len The amount to write out >= 0.
     * @exception IOException on any I/O error
     * @exception BadLocationException if pos is not within 0 and
     *   the length of the document.
     */
    public void write(Writer out, Document doc, int pos, int len)
        throws IOException, BadLocationException {

        if ((pos < 0) || ((pos + len) > doc.getLength())) {
            throw new BadLocationException("DefaultEditorKit.write", pos);
        }
        Segment data = new Segment();
        int nleft = len;
        int offs = pos;
        Object endOfLineProperty = doc.getProperty(EndOfLineStringProperty);
        if (endOfLineProperty == null) {
            try {
                endOfLineProperty = System.getProperty("line.separator");
            } catch (SecurityException se) { }
        }
        String endOfLine;
        if (endOfLineProperty instanceof String) {
            endOfLine = (String)endOfLineProperty;
        }
        else {
            endOfLine = null;
        }
        if (endOfLineProperty != null && !endOfLine.equals("\n")) {
            // There is an end of line string that isn't \n, have to iterate
            // through and find all \n's and translate to end of line string.
            while (nleft > 0) {
                int n = Math.min(nleft, 4096);
                doc.getText(offs, n, data);
                int last = data.offset;
                char[] array = data.array;
                int maxCounter = last + data.count;
                for (int counter = last; counter < maxCounter; counter++) {
                    if (array[counter] == '\n') {
                        if (counter > last) {
                            out.write(array, last, counter - last);
                        }
                        out.write(endOfLine);
                        last = counter + 1;
                    }
                }
                if (maxCounter > last) {
                    out.write(array, last, maxCounter - last);
                }
                offs += n;
                nleft -= n;
            }
        }
        else {
            // Just write out text, will already have \n, no mapping to
            // do.
            while (nleft > 0) {
                int n = Math.min(nleft, 4096);
                doc.getText(offs, n, data);
                out.write(data.array, data.offset, data.count);
                offs += n;
                nleft -= n;
            }
        }
        out.flush();
    }


    /**
     * When reading a document if a CRLF is encountered a property
     * with this name is added and the value will be "\r\n".
     */
    public static final String EndOfLineStringProperty = "__EndOfLine__";

    // --- names of well-known actions ---------------------------

    /**
     * Name of the action to place content into the associated
     * document.  If there is a selection, it is removed before
     * the new content is added.
     * @see #getActions
     */
    public static final String insertContentAction = "insert-content";

    /**
     * Name of the action to place a line/paragraph break into
     * the document.  If there is a selection, it is removed before
     * the break is added.
     * @see #getActions
     */
    public static final String insertBreakAction = "insert-break";

    /**
     * Name of the action to place a tab character into
     * the document.  If there is a selection, it is removed before
     * the tab is added.
     * @see #getActions
     */
    public static final String insertTabAction = "insert-tab";

    /**
     * Name of the action to delete the character of content that
     * precedes the current caret position.
     * @see #getActions
     */
    public static final String deletePrevCharAction = "delete-previous";

    /**
     * Name of the action to delete the character of content that
     * follows the current caret position.
     * @see #getActions
     */
    public static final String deleteNextCharAction = "delete-next";

    /**
     * Name of the action to delete the word that
     * follows the beginning of the selection.
     * @see #getActions
     * @see JTextComponent#getSelectionStart
     * @since 1.6
     */
    public static final String deleteNextWordAction = "delete-next-word";

    /**
     * Name of the action to delete the word that
     * precedes the beginning of the selection.
     * @see #getActions
     * @see JTextComponent#getSelectionStart
     * @since 1.6
     */
    public static final String deletePrevWordAction = "delete-previous-word";

    /**
     * Name of the action to set the editor into read-only
     * mode.
     * @see #getActions
     */
    public static final String readOnlyAction = "set-read-only";

    /**
     * Name of the action to set the editor into writeable
     * mode.
     * @see #getActions
     */
    public static final String writableAction = "set-writable";

    /**
     * Name of the action to cut the selected region
     * and place the contents into the system clipboard.
     * @see JTextComponent#cut
     * @see #getActions
     */
    public static final String cutAction = "cut-to-clipboard";

    /**
     * Name of the action to copy the selected region
     * and place the contents into the system clipboard.
     * @see JTextComponent#copy
     * @see #getActions
     */
    public static final String copyAction = "copy-to-clipboard";

    /**
     * Name of the action to paste the contents of the
     * system clipboard into the selected region, or before the
     * caret if nothing is selected.
     * @see JTextComponent#paste
     * @see #getActions
     */
    public static final String pasteAction = "paste-from-clipboard";

    /**
     * Name of the action to create a beep.
     * @see #getActions
     */
    public static final String beepAction = "beep";

    /**
     * Name of the action to page up vertically.
     * @see #getActions
     */
    public static final String pageUpAction = "page-up";

    /**
     * Name of the action to page down vertically.
     * @see #getActions
     */
    public static final String pageDownAction = "page-down";

    /**
     * Name of the action to page up vertically, and move the
     * selection.
     * @see #getActions
     */
    /*public*/ static final String selectionPageUpAction = "selection-page-up";

    /**
     * Name of the action to page down vertically, and move the
     * selection.
     * @see #getActions
     */
    /*public*/ static final String selectionPageDownAction = "selection-page-down";

    /**
     * Name of the action to page left horizontally, and move the
     * selection.
     * @see #getActions
     */
    /*public*/ static final String selectionPageLeftAction = "selection-page-left";

    /**
     * Name of the action to page right horizontally, and move the
     * selection.
     * @see #getActions
     */
    /*public*/ static final String selectionPageRightAction = "selection-page-right";

    /**
     * Name of the Action for moving the caret
     * logically forward one position.
     * @see #getActions
     */
    public static final String forwardAction = "caret-forward";

    /**
     * Name of the Action for moving the caret
     * logically backward one position.
     * @see #getActions
     */
    public static final String backwardAction = "caret-backward";

    /**
     * Name of the Action for extending the selection
     * by moving the caret logically forward one position.
     * @see #getActions
     */
    public static final String selectionForwardAction = "selection-forward";

    /**
     * Name of the Action for extending the selection
     * by moving the caret logically backward one position.
     * @see #getActions
     */
    public static final String selectionBackwardAction = "selection-backward";

    /**
     * Name of the Action for moving the caret
     * logically upward one position.
     * @see #getActions
     */
    public static final String upAction = "caret-up";

    /**
     * Name of the Action for moving the caret
     * logically downward one position.
     * @see #getActions
     */
    public static final String downAction = "caret-down";

    /**
     * Name of the Action for moving the caret
     * logically upward one position, extending the selection.
     * @see #getActions
     */
    public static final String selectionUpAction = "selection-up";

    /**
     * Name of the Action for moving the caret
     * logically downward one position, extending the selection.
     * @see #getActions
     */
    public static final String selectionDownAction = "selection-down";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the beginning of a word.
     * @see #getActions
     */
    public static final String beginWordAction = "caret-begin-word";

    /**
     * Name of the Action for moving the caret
     * to the end of a word.
     * @see #getActions
     */
    public static final String endWordAction = "caret-end-word";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the beginning of a word, extending the selection.
     * @see #getActions
     */
    public static final String selectionBeginWordAction = "selection-begin-word";

    /**
     * Name of the Action for moving the caret
     * to the end of a word, extending the selection.
     * @see #getActions
     */
    public static final String selectionEndWordAction = "selection-end-word";

    /**
     * Name of the <code>Action</code> for moving the caret to the
     * beginning of the previous word.
     * @see #getActions
     */
    public static final String previousWordAction = "caret-previous-word";

    /**
     * Name of the <code>Action</code> for moving the caret to the
     * beginning of the next word.
     * @see #getActions
     */
    public static final String nextWordAction = "caret-next-word";

    /**
     * Name of the <code>Action</code> for moving the selection to the
     * beginning of the previous word, extending the selection.
     * @see #getActions
     */
    public static final String selectionPreviousWordAction = "selection-previous-word";

    /**
     * Name of the <code>Action</code> for moving the selection to the
     * beginning of the next word, extending the selection.
     * @see #getActions
     */
    public static final String selectionNextWordAction = "selection-next-word";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the beginning of a line.
     * @see #getActions
     */
    public static final String beginLineAction = "caret-begin-line";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the end of a line.
     * @see #getActions
     */
    public static final String endLineAction = "caret-end-line";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the beginning of a line, extending the selection.
     * @see #getActions
     */
    public static final String selectionBeginLineAction = "selection-begin-line";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the end of a line, extending the selection.
     * @see #getActions
     */
    public static final String selectionEndLineAction = "selection-end-line";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the beginning of a paragraph.
     * @see #getActions
     */
    public static final String beginParagraphAction = "caret-begin-paragraph";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the end of a paragraph.
     * @see #getActions
     */
    public static final String endParagraphAction = "caret-end-paragraph";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the beginning of a paragraph, extending the selection.
     * @see #getActions
     */
    public static final String selectionBeginParagraphAction = "selection-begin-paragraph";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the end of a paragraph, extending the selection.
     * @see #getActions
     */
    public static final String selectionEndParagraphAction = "selection-end-paragraph";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the beginning of the document.
     * @see #getActions
     */
    public static final String beginAction = "caret-begin";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the end of the document.
     * @see #getActions
     */
    public static final String endAction = "caret-end";

    /**
     * Name of the <code>Action</code> for moving the caret
     * to the beginning of the document.
     * @see #getActions
     */
    public static final String selectionBeginAction = "selection-begin";

    /**
     * Name of the Action for moving the caret
     * to the end of the document.
     * @see #getActions
     */
    public static final String selectionEndAction = "selection-end";

    /**
     * Name of the Action for selecting a word around the caret.
     * @see #getActions
     */
    public static final String selectWordAction = "select-word";

    /**
     * Name of the Action for selecting a line around the caret.
     * @see #getActions
     */
    public static final String selectLineAction = "select-line";

    /**
     * Name of the Action for selecting a paragraph around the caret.
     * @see #getActions
     */
    public static final String selectParagraphAction = "select-paragraph";

    /**
     * Name of the Action for selecting the entire document
     * @see #getActions
     */
    public static final String selectAllAction = "select-all";

    /**
     * Name of the Action for removing selection
     * @see #getActions
     */
    /*public*/ static final String unselectAction = "unselect";

    /**
     * Name of the Action for toggling the component's orientation.
     * @see #getActions
     */
    /*public*/ static final String toggleComponentOrientationAction
        = "toggle-componentOrientation";

    /**
     * Name of the action that is executed by default if
     * a <em>key typed event</em> is received and there
     * is no keymap entry.
     * @see #getActions
     */
    public static final String defaultKeyTypedAction = "default-typed";

    // --- Action implementations ---------------------------------

    private static final Action[] defaultActions = {
        new InsertContentAction(), new DeletePrevCharAction(),
        new DeleteNextCharAction(), new ReadOnlyAction(),
        new DeleteWordAction(deletePrevWordAction),
        new DeleteWordAction(deleteNextWordAction),
        new WritableAction(), new CutAction(),
        new CopyAction(), new PasteAction(),
        new VerticalPageAction(pageUpAction, -1, false),
        new VerticalPageAction(pageDownAction, 1, false),
        new VerticalPageAction(selectionPageUpAction, -1, true),
        new VerticalPageAction(selectionPageDownAction, 1, true),
        new PageAction(selectionPageLeftAction, true, true),
        new PageAction(selectionPageRightAction, false, true),
        new InsertBreakAction(), new BeepAction(),
        new NextVisualPositionAction(forwardAction, false,
                                     SwingConstants.EAST),
        new NextVisualPositionAction(backwardAction, false,
                                     SwingConstants.WEST),
        new NextVisualPositionAction(selectionForwardAction, true,
                                     SwingConstants.EAST),
        new NextVisualPositionAction(selectionBackwardAction, true,
                                     SwingConstants.WEST),
        new NextVisualPositionAction(upAction, false,
                                     SwingConstants.NORTH),
        new NextVisualPositionAction(downAction, false,
                                     SwingConstants.SOUTH),
        new NextVisualPositionAction(selectionUpAction, true,
                                     SwingConstants.NORTH),
        new NextVisualPositionAction(selectionDownAction, true,
                                     SwingConstants.SOUTH),
        new BeginWordAction(beginWordAction, false),
        new EndWordAction(endWordAction, false),
        new BeginWordAction(selectionBeginWordAction, true),
        new EndWordAction(selectionEndWordAction, true),
        new PreviousWordAction(previousWordAction, false),
        new NextWordAction(nextWordAction, false),
        new PreviousWordAction(selectionPreviousWordAction, true),
        new NextWordAction(selectionNextWordAction, true),
        new BeginLineAction(beginLineAction, false),
        new EndLineAction(endLineAction, false),
        new BeginLineAction(selectionBeginLineAction, true),
        new EndLineAction(selectionEndLineAction, true),
        new BeginParagraphAction(beginParagraphAction, false),
        new EndParagraphAction(endParagraphAction, false),
        new BeginParagraphAction(selectionBeginParagraphAction, true),
        new EndParagraphAction(selectionEndParagraphAction, true),
        new BeginAction(beginAction, false),
        new EndAction(endAction, false),
        new BeginAction(selectionBeginAction, true),
        new EndAction(selectionEndAction, true),
        new DefaultKeyTypedAction(), new InsertTabAction(),
        new SelectWordAction(), new SelectLineAction(),
        new SelectParagraphAction(), new SelectAllAction(),
        new UnselectAction(), new ToggleComponentOrientationAction(),
        new DumpModelAction()
    };

    /**
     * The action that is executed by default if
     * a <em>key typed event</em> is received and there
     * is no keymap entry.  There is a variation across
     * different VM's in what gets sent as a <em>key typed</em>
     * event, and this action tries to filter out the undesired
     * events.  This filters the control characters and those
     * with the ALT modifier.  It allows Control-Alt sequences
     * through as these form legitimate unicode characters on
     * some PC keyboards.
     * <p>
     * If the event doesn't get filtered, it will try to insert
     * content into the text editor.  The content is fetched
     * from the command string of the ActionEvent.  The text
     * entry is done through the <code>replaceSelection</code>
     * method on the target text component.  This is the
     * action that will be fired for most text entry tasks.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see DefaultEditorKit#defaultKeyTypedAction
     * @see DefaultEditorKit#getActions
     * @see Keymap#setDefaultAction
     * @see Keymap#getDefaultAction
     */
    public static class DefaultKeyTypedAction extends TextAction {

        /**
         * Creates this object with the appropriate identifier.
         */
        public DefaultKeyTypedAction() {
            super(defaultKeyTypedAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if ((target != null) && (e != null)) {
                if ((! target.isEditable()) || (! target.isEnabled())) {
                    return;
                }
                String content = e.getActionCommand();
                int mod = e.getModifiers();
                if ((content != null) && (content.length() > 0) &&
                    ((mod & ActionEvent.ALT_MASK) == (mod & ActionEvent.CTRL_MASK))) {
                    char c = content.charAt(0);
                    if ((c >= 0x20) && (c != 0x7F)) {
                        target.replaceSelection(content);
                    }
                }
            }
        }
    }

    /**
     * Places content into the associated document.
     * If there is a selection, it is removed before
     * the new content is added.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see DefaultEditorKit#insertContentAction
     * @see DefaultEditorKit#getActions
     */
    public static class InsertContentAction extends TextAction {

        /**
         * Creates this object with the appropriate identifier.
         */
        public InsertContentAction() {
            super(insertContentAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if ((target != null) && (e != null)) {
                if ((! target.isEditable()) || (! target.isEnabled())) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                    return;
                }
                String content = e.getActionCommand();
                if (content != null) {
                    target.replaceSelection(content);
                } else {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                }
            }
        }
    }

    /**
     * Places a line/paragraph break into the document.
     * If there is a selection, it is removed before
     * the break is added.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see DefaultEditorKit#insertBreakAction
     * @see DefaultEditorKit#getActions
     */
    public static class InsertBreakAction extends TextAction {

        /**
         * Creates this object with the appropriate identifier.
         */
        public InsertBreakAction() {
            super(insertBreakAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                if ((! target.isEditable()) || (! target.isEnabled())) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                    return;
                }
                target.replaceSelection("\n");
            }
        }
    }

    /**
     * Places a tab character into the document. If there
     * is a selection, it is removed before the tab is added.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see DefaultEditorKit#insertTabAction
     * @see DefaultEditorKit#getActions
     */
    public static class InsertTabAction extends TextAction {

        /**
         * Creates this object with the appropriate identifier.
         */
        public InsertTabAction() {
            super(insertTabAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                if ((! target.isEditable()) || (! target.isEnabled())) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                    return;
                }
                target.replaceSelection("\t");
            }
        }
    }

    /*
     * Deletes the character of content that precedes the
     * current caret position.
     * @see DefaultEditorKit#deletePrevCharAction
     * @see DefaultEditorKit#getActions
     */
    static class DeletePrevCharAction extends TextAction {

        /**
         * Creates this object with the appropriate identifier.
         */
        DeletePrevCharAction() {
            super(deletePrevCharAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            boolean beep = true;
            if ((target != null) && (target.isEditable())) {
                try {
                    Document doc = target.getDocument();
                    Caret caret = target.getCaret();
                    int dot = caret.getDot();
                    int mark = caret.getMark();
                    if (dot != mark) {
                        doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
                        beep = false;
                    } else if (dot > 0) {
                        int delChars = 1;

                        if (dot > 1) {
                            String dotChars = doc.getText(dot - 2, 2);
                            char c0 = dotChars.charAt(0);
                            char c1 = dotChars.charAt(1);

                            if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
                                c1 >= '\uDC00' && c1 <= '\uDFFF') {
                                delChars = 2;
                            }
                        }

                        doc.remove(dot - delChars, delChars);
                        beep = false;
                    }
                } catch (BadLocationException bl) {
                }
            }
            if (beep) {
                UIManager.getLookAndFeel().provideErrorFeedback(target);
            }
        }
    }

    /*
     * Deletes the character of content that follows the
     * current caret position.
     * @see DefaultEditorKit#deleteNextCharAction
     * @see DefaultEditorKit#getActions
     */
    static class DeleteNextCharAction extends TextAction {

        /* Create this object with the appropriate identifier. */
        DeleteNextCharAction() {
            super(deleteNextCharAction);
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            boolean beep = true;
            if ((target != null) && (target.isEditable())) {
                try {
                    Document doc = target.getDocument();
                    Caret caret = target.getCaret();
                    int dot = caret.getDot();
                    int mark = caret.getMark();
                    if (dot != mark) {
                        doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
                        beep = false;
                    } else if (dot < doc.getLength()) {
                        int delChars = 1;

                        if (dot < doc.getLength() - 1) {
                            String dotChars = doc.getText(dot, 2);
                            char c0 = dotChars.charAt(0);
                            char c1 = dotChars.charAt(1);

                            if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
                                c1 >= '\uDC00' && c1 <= '\uDFFF') {
                                delChars = 2;
                            }
                        }

                        doc.remove(dot, delChars);
                        beep = false;
                    }
                } catch (BadLocationException bl) {
                }
            }
            if (beep) {
                UIManager.getLookAndFeel().provideErrorFeedback(target);
            }
        }
    }


    /*
     * Deletes the word that precedes/follows the beginning of the selection.
     * @see DefaultEditorKit#getActions
     */
    static class DeleteWordAction extends TextAction {
        DeleteWordAction(String name) {
            super(name);
            assert (name == deletePrevWordAction)
                || (name == deleteNextWordAction);
        }
        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            final JTextComponent target = getTextComponent(e);
            if ((target != null) && (e != null)) {
                if ((! target.isEditable()) || (! target.isEnabled())) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                    return;
                }
                boolean beep = true;
                try {
                    final int start = target.getSelectionStart();
                    final Element line =
                        Utilities.getParagraphElement(target, start);
                    int end;
                    if (deleteNextWordAction == getValue(Action.NAME)) {
                        end = Utilities.
                            getNextWordInParagraph(target, line, start, false);
                        if (end == java.text.BreakIterator.DONE) {
                            //last word in the paragraph
                            final int endOfLine = line.getEndOffset();
                            if (start == endOfLine - 1) {
                                //for last position remove last \n
                                end = endOfLine;
                            } else {
                                //remove to the end of the paragraph
                                end = endOfLine - 1;
                            }
                        }
                    } else {
                        end = Utilities.
                            getPrevWordInParagraph(target, line, start);
                        if (end == java.text.BreakIterator.DONE) {
                            //there is no previous word in the paragraph
                            final int startOfLine = line.getStartOffset();
                            if (start == startOfLine) {
                                //for first position remove previous \n
                                end = startOfLine - 1;
                            } else {
                                //remove to the start of the paragraph
                                end = startOfLine;
                            }
                        }
                    }
                    int offs = Math.min(start, end);
                    int len = Math.abs(end - start);
                    if (offs >= 0) {
                        target.getDocument().remove(offs, len);
                        beep = false;
                    }
                } catch (BadLocationException ignore) {
                }
                if (beep) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                }
            }
        }
    }


    /*
     * Sets the editor into read-only mode.
     * @see DefaultEditorKit#readOnlyAction
     * @see DefaultEditorKit#getActions
     */
    static class ReadOnlyAction extends TextAction {

        /* Create this object with the appropriate identifier. */
        ReadOnlyAction() {
            super(readOnlyAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                target.setEditable(false);
            }
        }
    }

    /*
     * Sets the editor into writeable mode.
     * @see DefaultEditorKit#writableAction
     * @see DefaultEditorKit#getActions
     */
    static class WritableAction extends TextAction {

        /* Create this object with the appropriate identifier. */
        WritableAction() {
            super(writableAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                target.setEditable(true);
            }
        }
    }

    /**
     * Cuts the selected region and place its contents
     * into the system clipboard.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see DefaultEditorKit#cutAction
     * @see DefaultEditorKit#getActions
     */
    public static class CutAction extends TextAction {

        /** Create this object with the appropriate identifier. */
        public CutAction() {
            super(cutAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                target.cut();
            }
        }
    }

    /**
     * Copies the selected region and place its contents
     * into the system clipboard.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see DefaultEditorKit#copyAction
     * @see DefaultEditorKit#getActions
     */
    public static class CopyAction extends TextAction {

        /** Create this object with the appropriate identifier. */
        public CopyAction() {
            super(copyAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                target.copy();
            }
        }
    }

    /**
     * Pastes the contents of the system clipboard into the
     * selected region, or before the caret if nothing is
     * selected.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see DefaultEditorKit#pasteAction
     * @see DefaultEditorKit#getActions
     */
    public static class PasteAction extends TextAction {

        /** Create this object with the appropriate identifier. */
        public PasteAction() {
            super(pasteAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                target.paste();
            }
        }
    }

    /**
     * Creates a beep.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     *
     * @see DefaultEditorKit#beepAction
     * @see DefaultEditorKit#getActions
     */
    public static class BeepAction extends TextAction {

        /** Create this object with the appropriate identifier. */
        public BeepAction() {
            super(beepAction);
        }

        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            UIManager.getLookAndFeel().provideErrorFeedback(target);
        }
    }

    /**
     * Scrolls up/down vertically.  The select version of this action extends
     * the selection, instead of simply moving the caret.
     *
     * @see DefaultEditorKit#pageUpAction
     * @see DefaultEditorKit#pageDownAction
     * @see DefaultEditorKit#getActions
     */
    static class VerticalPageAction extends TextAction {

        /** Create this object with the appropriate identifier. */
        public VerticalPageAction(String nm, int direction, boolean select) {
            super(nm);
            this.select = select;
            this.direction = direction;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                Rectangle visible = target.getVisibleRect();
                Rectangle newVis = new Rectangle(visible);
                int selectedIndex = target.getCaretPosition();
                int scrollAmount = direction *
                        target.getScrollableBlockIncrement(
                                  visible, SwingConstants.VERTICAL, direction);
                int initialY = visible.y;
                Caret caret = target.getCaret();
                Point magicPosition = caret.getMagicCaretPosition();

                if (selectedIndex != -1) {
                    try {
                        Rectangle dotBounds = target.modelToView(
                                                     selectedIndex);
                        int x = (magicPosition != null) ? magicPosition.x :
                                                          dotBounds.x;
                        int h = dotBounds.height;
                        if (h > 0) {
                            // We want to scroll by a multiple of caret height,
                            // rounding towards lower integer
                            scrollAmount = scrollAmount / h * h;
                        }
                        newVis.y = constrainY(target,
                                initialY + scrollAmount, visible.height);

                        int newIndex;

                        if (visible.contains(dotBounds.x, dotBounds.y)) {
                            // Dot is currently visible, base the new
                            // location off the old, or
                            newIndex = target.viewToModel(
                                new Point(x, constrainY(target,
                                          dotBounds.y + scrollAmount, 0)));
                        }
                        else {
                            // Dot isn't visible, choose the top or the bottom
                            // for the new location.
                            if (direction == -1) {
                                newIndex = target.viewToModel(new Point(
                                    x, newVis.y));
                            }
                            else {
                                newIndex = target.viewToModel(new Point(
                                    x, newVis.y + visible.height));
                            }
                        }
                        newIndex = constrainOffset(target, newIndex);
                        if (newIndex != selectedIndex) {
                            // Make sure the new visible location contains
                            // the location of dot, otherwise Caret will
                            // cause an additional scroll.
                            adjustScrollIfNecessary(target, newVis, initialY,
                                                    newIndex);
                            if (select) {
                                target.moveCaretPosition(newIndex);
                            }
                            else {
                                target.setCaretPosition(newIndex);
                            }
                        }
                    } catch (BadLocationException ble) { }
                } else {
                    newVis.y = constrainY(target,
                            initialY + scrollAmount, visible.height);
                }
                if (magicPosition != null) {
                    caret.setMagicCaretPosition(magicPosition);
                }
                target.scrollRectToVisible(newVis);
            }
        }

        /**
         * Makes sure <code>y</code> is a valid location in
         * <code>target</code>.
         */
        private int constrainY(JTextComponent target, int y, int vis) {
            if (y < 0) {
                y = 0;
            }
            else if (y + vis > target.getHeight()) {
                y = Math.max(0, target.getHeight() - vis);
            }
            return y;
        }

        /**
         * Ensures that <code>offset</code> is a valid offset into the
         * model for <code>text</code>.
         */
        private int constrainOffset(JTextComponent text, int offset) {
            Document doc = text.getDocument();

            if ((offset != 0) && (offset > doc.getLength())) {
                offset = doc.getLength();
            }
            if (offset  < 0) {
                offset = 0;
            }
            return offset;
        }

        /**
         * Adjusts the rectangle that indicates the location to scroll to
         * after selecting <code>index</code>.
         */
        private void adjustScrollIfNecessary(JTextComponent text,
                                             Rectangle visible, int initialY,
                                             int index) {
            try {
                Rectangle dotBounds = text.modelToView(index);

                if (dotBounds.y < visible.y ||
                       (dotBounds.y > (visible.y + visible.height)) ||
                       (dotBounds.y + dotBounds.height) >
                       (visible.y + visible.height)) {
                    int y;

                    if (dotBounds.y < visible.y) {
                        y = dotBounds.y;
                    }
                    else {
                        y = dotBounds.y + dotBounds.height - visible.height;
                    }
                    if ((direction == -1 && y < initialY) ||
                                        (direction == 1 && y > initialY)) {
                        // Only adjust if won't cause scrolling upward.
                        visible.y = y;
                    }
                }
            } catch (BadLocationException ble) {}
        }

        /**
         * Adjusts the Rectangle to contain the bounds of the character at
         * <code>index</code> in response to a page up.
         */
        private boolean select;

        /**
         * Direction to scroll, 1 is down, -1 is up.
         */
        private int direction;
    }


    /**
     * Pages one view to the left or right.
     */
    static class PageAction extends TextAction {

        /** Create this object with the appropriate identifier. */
        public PageAction(String nm, boolean left, boolean select) {
            super(nm);
            this.select = select;
            this.left = left;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                int selectedIndex;
                Rectangle visible = new Rectangle();
                target.computeVisibleRect(visible);
                if (left) {
                    visible.x = Math.max(0, visible.x - visible.width);
                }
                else {
                    visible.x += visible.width;
                }

                selectedIndex = target.getCaretPosition();
                if(selectedIndex != -1) {
                    if (left) {
                        selectedIndex = target.viewToModel
                            (new Point(visible.x, visible.y));
                    }
                    else {
                        selectedIndex = target.viewToModel
                            (new Point(visible.x + visible.width - 1,
                                       visible.y + visible.height - 1));
                    }
                    Document doc = target.getDocument();
                    if ((selectedIndex != 0) &&
                        (selectedIndex  > (doc.getLength()-1))) {
                        selectedIndex = doc.getLength()-1;
                    }
                    else if(selectedIndex  < 0) {
                        selectedIndex = 0;
                    }
                    if (select)
                        target.moveCaretPosition(selectedIndex);
                    else
                        target.setCaretPosition(selectedIndex);
                }
            }
        }

        private boolean select;
        private boolean left;
    }

    static class DumpModelAction extends TextAction {

        DumpModelAction() {
            super("dump-model");
        }

        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                Document d = target.getDocument();
                if (d instanceof AbstractDocument) {
                    ((AbstractDocument) d).dump(System.err);
                }
            }
        }
    }

    /*
     * Action to move the selection by way of the
     * getNextVisualPositionFrom method. Constructor indicates direction
     * to use.
     */
    static class NextVisualPositionAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        NextVisualPositionAction(String nm, boolean select, int direction) {
            super(nm);
            this.select = select;
            this.direction = direction;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                Caret caret = target.getCaret();
                DefaultCaret bidiCaret = (caret instanceof DefaultCaret) ?
                                              (DefaultCaret)caret : null;
                int dot = caret.getDot();
                Position.Bias[] bias = new Position.Bias[1];
                Point magicPosition = caret.getMagicCaretPosition();

                try {
                    if(magicPosition == null &&
                       (direction == SwingConstants.NORTH ||
                        direction == SwingConstants.SOUTH)) {
                        Rectangle r = (bidiCaret != null) ?
                                target.getUI().modelToView(target, dot,
                                                      bidiCaret.getDotBias()) :
                                target.modelToView(dot);
                        magicPosition = new Point(r.x, r.y);
                    }

                    NavigationFilter filter = target.getNavigationFilter();

                    if (filter != null) {
                        dot = filter.getNextVisualPositionFrom
                                     (target, dot, (bidiCaret != null) ?
                                      bidiCaret.getDotBias() :
                                      Position.Bias.Forward, direction, bias);
                    }
                    else {
                        dot = target.getUI().getNextVisualPositionFrom
                                     (target, dot, (bidiCaret != null) ?
                                      bidiCaret.getDotBias() :
                                      Position.Bias.Forward, direction, bias);
                    }
                    if(bias[0] == null) {
                        bias[0] = Position.Bias.Forward;
                    }
                    if(bidiCaret != null) {
                        if (select) {
                            bidiCaret.moveDot(dot, bias[0]);
                        } else {
                            bidiCaret.setDot(dot, bias[0]);
                        }
                    }
                    else {
                        if (select) {
                            caret.moveDot(dot);
                        } else {
                            caret.setDot(dot);
                        }
                    }
                    if(magicPosition != null &&
                       (direction == SwingConstants.NORTH ||
                        direction == SwingConstants.SOUTH)) {
                        target.getCaret().setMagicCaretPosition(magicPosition);
                    }
                } catch (BadLocationException ex) {
                }
            }
        }

        private boolean select;
        private int direction;
    }

    /*
     * Position the caret to the beginning of the word.
     * @see DefaultEditorKit#beginWordAction
     * @see DefaultEditorKit#selectBeginWordAction
     * @see DefaultEditorKit#getActions
     */
    static class BeginWordAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        BeginWordAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                try {
                    int offs = target.getCaretPosition();
                    int begOffs = Utilities.getWordStart(target, offs);
                    if (select) {
                        target.moveCaretPosition(begOffs);
                    } else {
                        target.setCaretPosition(begOffs);
                    }
                } catch (BadLocationException bl) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                }
            }
        }

        private boolean select;
    }

    /*
     * Position the caret to the end of the word.
     * @see DefaultEditorKit#endWordAction
     * @see DefaultEditorKit#selectEndWordAction
     * @see DefaultEditorKit#getActions
     */
    static class EndWordAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        EndWordAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                try {
                    int offs = target.getCaretPosition();
                    int endOffs = Utilities.getWordEnd(target, offs);
                    if (select) {
                        target.moveCaretPosition(endOffs);
                    } else {
                        target.setCaretPosition(endOffs);
                    }
                } catch (BadLocationException bl) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                }
            }
        }

        private boolean select;
    }

    /*
     * Position the caret to the beginning of the previous word.
     * @see DefaultEditorKit#previousWordAction
     * @see DefaultEditorKit#selectPreviousWordAction
     * @see DefaultEditorKit#getActions
     */
    static class PreviousWordAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        PreviousWordAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                int offs = target.getCaretPosition();
                boolean failed = false;
                try {
                    Element curPara =
                            Utilities.getParagraphElement(target, offs);
                    offs = Utilities.getPreviousWord(target, offs);
                    if(offs < curPara.getStartOffset()) {
                        // we should first move to the end of the
                        // previous paragraph (bug #4278839)
                        offs = Utilities.getParagraphElement(target, offs).
                                getEndOffset() - 1;
                    }
                } catch (BadLocationException bl) {
                    if (offs != 0) {
                        offs = 0;
                    }
                    else {
                        failed = true;
                    }
                }
                if (!failed) {
                    if (select) {
                        target.moveCaretPosition(offs);
                    } else {
                        target.setCaretPosition(offs);
                    }
                }
                else {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                }
            }
        }

        private boolean select;
    }

    /*
     * Position the caret to the next of the word.
     * @see DefaultEditorKit#nextWordAction
     * @see DefaultEditorKit#selectNextWordAction
     * @see DefaultEditorKit#getActions
     */
    static class NextWordAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        NextWordAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                int offs = target.getCaretPosition();
                boolean failed = false;
                int oldOffs = offs;
                Element curPara =
                        Utilities.getParagraphElement(target, offs);
                try {
                    offs = Utilities.getNextWord(target, offs);
                    if(offs >= curPara.getEndOffset() &&
                            oldOffs != curPara.getEndOffset() - 1) {
                        // we should first move to the end of current
                        // paragraph (bug #4278839)
                        offs = curPara.getEndOffset() - 1;
                    }
                } catch (BadLocationException bl) {
                    int end = target.getDocument().getLength();
                    if (offs != end) {
                        if(oldOffs != curPara.getEndOffset() - 1) {
                            offs = curPara.getEndOffset() - 1;
                        } else {
                        offs = end;
                    }
                    }
                    else {
                        failed = true;
                    }
                }
                if (!failed) {
                    if (select) {
                        target.moveCaretPosition(offs);
                    } else {
                        target.setCaretPosition(offs);
                    }
                }
                else {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                }
            }
        }

        private boolean select;
    }

    /*
     * Position the caret to the beginning of the line.
     * @see DefaultEditorKit#beginLineAction
     * @see DefaultEditorKit#selectBeginLineAction
     * @see DefaultEditorKit#getActions
     */
    static class BeginLineAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        BeginLineAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                try {
                    int offs = target.getCaretPosition();
                    int begOffs = Utilities.getRowStart(target, offs);
                    if (select) {
                        target.moveCaretPosition(begOffs);
                    } else {
                        target.setCaretPosition(begOffs);
                    }
                } catch (BadLocationException bl) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                }
            }
        }

        private boolean select;
    }

    /*
     * Position the caret to the end of the line.
     * @see DefaultEditorKit#endLineAction
     * @see DefaultEditorKit#selectEndLineAction
     * @see DefaultEditorKit#getActions
     */
    static class EndLineAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        EndLineAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                try {
                    int offs = target.getCaretPosition();
                    int endOffs = Utilities.getRowEnd(target, offs);
                    if (select) {
                        target.moveCaretPosition(endOffs);
                    } else {
                        target.setCaretPosition(endOffs);
                    }
                } catch (BadLocationException bl) {
                    UIManager.getLookAndFeel().provideErrorFeedback(target);
                }
            }
        }

        private boolean select;
    }

    /*
     * Position the caret to the beginning of the paragraph.
     * @see DefaultEditorKit#beginParagraphAction
     * @see DefaultEditorKit#selectBeginParagraphAction
     * @see DefaultEditorKit#getActions
     */
    static class BeginParagraphAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        BeginParagraphAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                int offs = target.getCaretPosition();
                Element elem = Utilities.getParagraphElement(target, offs);
                offs = elem.getStartOffset();
                if (select) {
                    target.moveCaretPosition(offs);
                } else {
                    target.setCaretPosition(offs);
                }
            }
        }

        private boolean select;
    }

    /*
     * Position the caret to the end of the paragraph.
     * @see DefaultEditorKit#endParagraphAction
     * @see DefaultEditorKit#selectEndParagraphAction
     * @see DefaultEditorKit#getActions
     */
    static class EndParagraphAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        EndParagraphAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                int offs = target.getCaretPosition();
                Element elem = Utilities.getParagraphElement(target, offs);
                offs = Math.min(target.getDocument().getLength(),
                                elem.getEndOffset());
                if (select) {
                    target.moveCaretPosition(offs);
                } else {
                    target.setCaretPosition(offs);
                }
            }
        }

        private boolean select;
    }

    /*
     * Move the caret to the beginning of the document.
     * @see DefaultEditorKit#beginAction
     * @see DefaultEditorKit#getActions
     */
    static class BeginAction extends TextAction {

        /* Create this object with the appropriate identifier. */
        BeginAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                if (select) {
                    target.moveCaretPosition(0);
                } else {
                    target.setCaretPosition(0);
                }
            }
        }

        private boolean select;
    }

    /*
     * Move the caret to the end of the document.
     * @see DefaultEditorKit#endAction
     * @see DefaultEditorKit#getActions
     */
    static class EndAction extends TextAction {

        /* Create this object with the appropriate identifier. */
        EndAction(String nm, boolean select) {
            super(nm);
            this.select = select;
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                Document doc = target.getDocument();
                int dot = doc.getLength();
                if (select) {
                    target.moveCaretPosition(dot);
                } else {
                    target.setCaretPosition(dot);
                }
            }
        }

        private boolean select;
    }

    /*
     * Select the word around the caret
     * @see DefaultEditorKit#endAction
     * @see DefaultEditorKit#getActions
     */
    static class SelectWordAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        SelectWordAction() {
            super(selectWordAction);
            start = new BeginWordAction("pigdog", false);
            end = new EndWordAction("pigdog", true);
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            start.actionPerformed(e);
            end.actionPerformed(e);
        }

        private Action start;
        private Action end;
    }

    /*
     * Select the line around the caret
     * @see DefaultEditorKit#endAction
     * @see DefaultEditorKit#getActions
     */
    static class SelectLineAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        SelectLineAction() {
            super(selectLineAction);
            start = new BeginLineAction("pigdog", false);
            end = new EndLineAction("pigdog", true);
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            start.actionPerformed(e);
            end.actionPerformed(e);
        }

        private Action start;
        private Action end;
    }

    /*
     * Select the paragraph around the caret
     * @see DefaultEditorKit#endAction
     * @see DefaultEditorKit#getActions
     */
    static class SelectParagraphAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        SelectParagraphAction() {
            super(selectParagraphAction);
            start = new BeginParagraphAction("pigdog", false);
            end = new EndParagraphAction("pigdog", true);
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            start.actionPerformed(e);
            end.actionPerformed(e);
        }

        private Action start;
        private Action end;
    }

    /*
     * Select the entire document
     * @see DefaultEditorKit#endAction
     * @see DefaultEditorKit#getActions
     */
    static class SelectAllAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         * @param nm  the name of the action, Action.NAME.
         * @param select whether to extend the selection when
         *  changing the caret position.
         */
        SelectAllAction() {
            super(selectAllAction);
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                Document doc = target.getDocument();
                target.setCaretPosition(0);
                target.moveCaretPosition(doc.getLength());
            }
        }

    }

    /*
     * Remove the selection, if any.
     * @see DefaultEditorKit#unselectAction
     * @see DefaultEditorKit#getActions
     */
    static class UnselectAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         */
        UnselectAction() {
            super(unselectAction);
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                target.setCaretPosition(target.getCaretPosition());
            }
        }

    }

    /*
     * Toggles the ComponentOrientation of the text component.
     * @see DefaultEditorKit#toggleComponentOrientationAction
     * @see DefaultEditorKit#getActions
     */
    static class ToggleComponentOrientationAction extends TextAction {

        /**
         * Create this action with the appropriate identifier.
         */
        ToggleComponentOrientationAction() {
            super(toggleComponentOrientationAction);
        }

        /** The operation to perform when this action is triggered. */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            if (target != null) {
                ComponentOrientation last = target.getComponentOrientation();
                ComponentOrientation next;
                if( last == ComponentOrientation.RIGHT_TO_LEFT )
                    next = ComponentOrientation.LEFT_TO_RIGHT;
                else
                    next = ComponentOrientation.RIGHT_TO_LEFT;
                target.setComponentOrientation(next);
                target.repaint();
            }
        }
    }

}
