/*
 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package javax.swing.text;

import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import java.beans.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import java.util.EventListener;
import sun.swing.SwingUtilities2;

/**
 * A default implementation of Caret.  The caret is rendered as
 * a vertical line in the color specified by the CaretColor property
 * of the associated JTextComponent.  It can blink at the rate specified
 * by the BlinkRate property.
 * <p>
 * This implementation expects two sources of asynchronous notification.
 * The timer thread fires asynchronously, and causes the caret to simply
 * repaint the most recent bounding box.  The caret also tracks change
 * as the document is modified.  Typically this will happen on the
 * event dispatch thread as a result of some mouse or keyboard event.
 * The caret behavior on both synchronous and asynchronous documents updates
 * is controlled by <code>UpdatePolicy</code> property. The repaint of the
 * new caret location will occur on the event thread in any case, as calls to
 * <code>modelToView</code> are only safe on the event thread.
 * <p>
 * The caret acts as a mouse and focus listener on the text component
 * it has been installed in, and defines the caret semantics based upon
 * those events.  The listener methods can be reimplemented to change the
 * semantics.
 * By default, the first mouse button will be used to set focus and caret
 * position.  Dragging the mouse pointer with the first mouse button will
 * sweep out a selection that is contiguous in the model.  If the associated
 * text component is editable, the caret will become visible when focus
 * is gained, and invisible when focus is lost.
 * <p>
 * The Highlighter bound to the associated text component is used to
 * render the selection by default.
 * Selection appearance can be customized by supplying a
 * painter to use for the highlights.  By default a painter is used that
 * will render a solid color as specified in the associated text component
 * in the <code>SelectionColor</code> property.  This can easily be changed
 * by reimplementing the
 * <a href="#getSelectionHighlighter">getSelectionHighlighter</a>
 * method.
 * <p>
 * A customized caret appearance can be achieved by reimplementing
 * the paint method.  If the paint method is changed, the damage method
 * should also be reimplemented to cause a repaint for the area needed
 * to render the caret.  The caret extends the Rectangle class which
 * is used to hold the bounding box for where the caret was last rendered.
 * This enables the caret to repaint in a thread-safe manner when the
 * caret moves without making a call to modelToView which is unstable
 * between model updates and view repair (i.e. the order of delivery
 * to DocumentListeners is not guaranteed).
 * <p>
 * The magic caret position is set to null when the caret position changes.
 * A timer is used to determine the new location (after the caret change).
 * When the timer fires, if the magic caret position is still null it is
 * reset to the current caret position. Any actions that change
 * the caret position and want the magic caret position to remain the
 * same, must remember the magic caret position, change the cursor, and
 * then set the magic caret position to its original value. This has the
 * benefit that only actions that want the magic caret position to persist
 * (such as open/down) need to know about it.
 * <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}.
 *
 * @author  Timothy Prinzing
 * @see     Caret
 */
public class DefaultCaret extends Rectangle implements Caret, FocusListener, MouseListener, MouseMotionListener {

    /**
     * Indicates that the caret position is to be updated only when
     * document changes are performed on the Event Dispatching Thread.
     * @see #setUpdatePolicy
     * @see #getUpdatePolicy
     * @since 1.5
     */
    public static final int UPDATE_WHEN_ON_EDT = 0;

    /**
     * Indicates that the caret should remain at the same
     * absolute position in the document regardless of any document
     * updates, except when the document length becomes less than
     * the current caret position due to removal. In that case the caret
     * position is adjusted to the end of the document.
     *
     * @see #setUpdatePolicy
     * @see #getUpdatePolicy
     * @since 1.5
     */
    public static final int NEVER_UPDATE = 1;

    /**
     * Indicates that the caret position is to be <b>always</b>
     * updated accordingly to the document changes regardless whether
     * the document updates are performed on the Event Dispatching Thread
     * or not.
     *
     * @see #setUpdatePolicy
     * @see #getUpdatePolicy
     * @since 1.5
     */
    public static final int ALWAYS_UPDATE = 2;

    /**
     * Constructs a default caret.
     */
    public DefaultCaret() {
    }

    /**
     * Sets the caret movement policy on the document updates. Normally
     * the caret updates its absolute position within the document on
     * insertions occurred before or at the caret position and
     * on removals before the caret position. 'Absolute position'
     * means here the position relative to the start of the document.
     * For example if
     * a character is typed within editable text component it is inserted
     * at the caret position and the caret moves to the next absolute
     * position within the document due to insertion and if
     * <code>BACKSPACE</code> is typed then caret decreases its absolute
     * position due to removal of a character before it. Sometimes
     * it may be useful to turn off the caret position updates so that
     * the caret stays at the same absolute position within the
     * document position regardless of any document updates.
     * <p>
     * The following update policies are allowed:
     * <ul>
     *   <li><code>NEVER_UPDATE</code>: the caret stays at the same
     *       absolute position in the document regardless of any document
     *       updates, except when document length becomes less than
     *       the current caret position due to removal. In that case caret
     *       position is adjusted to the end of the document.
     *       The caret doesn't try to keep itself visible by scrolling
     *       the associated view when using this policy. </li>
     *   <li><code>ALWAYS_UPDATE</code>: the caret always tracks document
     *       changes. For regular changes it increases its position
     *       if an insertion occurs before or at its current position,
     *       and decreases position if a removal occurs before
     *       its current position. For undo/redo updates it is always
     *       moved to the position where update occurred. The caret
     *       also tries to keep itself visible by calling
     *       <code>adjustVisibility</code> method.</li>
     *   <li><code>UPDATE_WHEN_ON_EDT</code>: acts like <code>ALWAYS_UPDATE</code>
     *       if the document updates are performed on the Event Dispatching Thread
     *       and like <code>NEVER_UPDATE</code> if updates are performed on
     *       other thread. </li>
     * </ul> <p>
     * The default property value is <code>UPDATE_WHEN_ON_EDT</code>.
     *
     * @param policy one of the following values : <code>UPDATE_WHEN_ON_EDT</code>,
     * <code>NEVER_UPDATE</code>, <code>ALWAYS_UPDATE</code>
     * @throws IllegalArgumentException if invalid value is passed
     *
     * @see #getUpdatePolicy
     * @see #adjustVisibility
     * @see #UPDATE_WHEN_ON_EDT
     * @see #NEVER_UPDATE
     * @see #ALWAYS_UPDATE
     *
     * @since 1.5
     */
    public void setUpdatePolicy(int policy) {
        updatePolicy = policy;
    }

    /**
     * Gets the caret movement policy on document updates.
     *
     * @return one of the following values : <code>UPDATE_WHEN_ON_EDT</code>,
     * <code>NEVER_UPDATE</code>, <code>ALWAYS_UPDATE</code>
     *
     * @see #setUpdatePolicy
     * @see #UPDATE_WHEN_ON_EDT
     * @see #NEVER_UPDATE
     * @see #ALWAYS_UPDATE
     *
     * @since 1.5
     */
    public int getUpdatePolicy() {
        return updatePolicy;
    }

    /**
     * Gets the text editor component that this caret is
     * is bound to.
     *
     * @return the component
     */
    protected final JTextComponent getComponent() {
        return component;
    }

    /**
     * Cause the caret to be painted.  The repaint
     * area is the bounding box of the caret (i.e.
     * the caret rectangle or <em>this</em>).
     * <p>
     * This method is thread safe, although most Swing methods
     * are not. Please see
     * <A HREF="http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html">How
     * to Use Threads</A> for more information.
     */
    protected final synchronized void repaint() {
        if (component != null) {
            component.repaint(x, y, width, height);
        }
    }

    /**
     * Damages the area surrounding the caret to cause
     * it to be repainted in a new location.  If paint()
     * is reimplemented, this method should also be
     * reimplemented.  This method should update the
     * caret bounds (x, y, width, and height).
     *
     * @param r  the current location of the caret
     * @see #paint
     */
    protected synchronized void damage(Rectangle r) {
        if (r != null) {
            int damageWidth = getCaretWidth(r.height);
            x = r.x - 4 - (damageWidth >> 1);
            y = r.y;
            width = 9 + damageWidth;
            height = r.height;
            repaint();
        }
    }

    /**
     * Scrolls the associated view (if necessary) to make
     * the caret visible.  Since how this should be done
     * is somewhat of a policy, this method can be
     * reimplemented to change the behavior.  By default
     * the scrollRectToVisible method is called on the
     * associated component.
     *
     * @param nloc the new position to scroll to
     */
    protected void adjustVisibility(Rectangle nloc) {
        if(component == null) {
            return;
        }
        if (SwingUtilities.isEventDispatchThread()) {
                component.scrollRectToVisible(nloc);
        } else {
            SwingUtilities.invokeLater(new SafeScroller(nloc));
        }
    }

    /**
     * Gets the painter for the Highlighter.
     *
     * @return the painter
     */
    protected Highlighter.HighlightPainter getSelectionPainter() {
        return DefaultHighlighter.DefaultPainter;
    }

    /**
     * Tries to set the position of the caret from
     * the coordinates of a mouse event, using viewToModel().
     *
     * @param e the mouse event
     */
    protected void positionCaret(MouseEvent e) {
        Point pt = new Point(e.getX(), e.getY());
        Position.Bias[] biasRet = new Position.Bias[1];
        int pos = component.getUI().viewToModel(component, pt, biasRet);
        if(biasRet[0] == null)
            biasRet[0] = Position.Bias.Forward;
        if (pos >= 0) {
            setDot(pos, biasRet[0]);
        }
    }

    /**
     * Tries to move the position of the caret from
     * the coordinates of a mouse event, using viewToModel().
     * This will cause a selection if the dot and mark
     * are different.
     *
     * @param e the mouse event
     */
    protected void moveCaret(MouseEvent e) {
        Point pt = new Point(e.getX(), e.getY());
        Position.Bias[] biasRet = new Position.Bias[1];
        int pos = component.getUI().viewToModel(component, pt, biasRet);
        if(biasRet[0] == null)
            biasRet[0] = Position.Bias.Forward;
        if (pos >= 0) {
            moveDot(pos, biasRet[0]);
        }
    }

    // --- FocusListener methods --------------------------

    /**
     * Called when the component containing the caret gains
     * focus.  This is implemented to set the caret to visible
     * if the component is editable.
     *
     * @param e the focus event
     * @see FocusListener#focusGained
     */
    public void focusGained(FocusEvent e) {
        if (component.isEnabled()) {
            if (component.isEditable()) {
                setVisible(true);
            }
            setSelectionVisible(true);
        }
    }

    /**
     * Called when the component containing the caret loses
     * focus.  This is implemented to set the caret to visibility
     * to false.
     *
     * @param e the focus event
     * @see FocusListener#focusLost
     */
    public void focusLost(FocusEvent e) {
        setVisible(false);
        setSelectionVisible(ownsSelection || e.isTemporary());
    }


    /**
     * Selects word based on the MouseEvent
     */
    private void selectWord(MouseEvent e) {
        if (selectedWordEvent != null
            && selectedWordEvent.getX() == e.getX()
            && selectedWordEvent.getY() == e.getY()) {
            //we already done selection for this
            return;
        }
                    Action a = null;
                    ActionMap map = getComponent().getActionMap();
                    if (map != null) {
                        a = map.get(DefaultEditorKit.selectWordAction);
                    }
                    if (a == null) {
                        if (selectWord == null) {
                            selectWord = new DefaultEditorKit.SelectWordAction();
                        }
                        a = selectWord;
                    }
                    a.actionPerformed(new ActionEvent(getComponent(),
                                                      ActionEvent.ACTION_PERFORMED, null, e.getWhen(), e.getModifiers()));
        selectedWordEvent = e;
    }

    // --- MouseListener methods -----------------------------------

    /**
     * Called when the mouse is clicked.  If the click was generated
     * from button1, a double click selects a word,
     * and a triple click the current line.
     *
     * @param e the mouse event
     * @see MouseListener#mouseClicked
     */
    public void mouseClicked(MouseEvent e) {
        int nclicks = SwingUtilities2.getAdjustedClickCount(getComponent(), e);

        if (! e.isConsumed()) {
            if (SwingUtilities.isLeftMouseButton(e)) {
                // mouse 1 behavior
                if(nclicks == 1) {
                    selectedWordEvent = null;
                } else if(nclicks == 2
                          && SwingUtilities2.canEventAccessSystemClipboard(e)) {
                    selectWord(e);
                    selectedWordEvent = null;
                } else if(nclicks == 3
                          && SwingUtilities2.canEventAccessSystemClipboard(e)) {
                    Action a = null;
                    ActionMap map = getComponent().getActionMap();
                    if (map != null) {
                        a = map.get(DefaultEditorKit.selectLineAction);
                    }
                    if (a == null) {
                        if (selectLine == null) {
                            selectLine = new DefaultEditorKit.SelectLineAction();
                        }
                        a = selectLine;
                    }
                    a.actionPerformed(new ActionEvent(getComponent(),
                                                      ActionEvent.ACTION_PERFORMED, null, e.getWhen(), e.getModifiers()));
                }
            } else if (SwingUtilities.isMiddleMouseButton(e)) {
                // mouse 2 behavior
                if (nclicks == 1 && component.isEditable() && component.isEnabled()
                    && SwingUtilities2.canEventAccessSystemClipboard(e)) {
                    // paste system selection, if it exists
                    JTextComponent c = (JTextComponent) e.getSource();
                    if (c != null) {
                        try {
                            Toolkit tk = c.getToolkit();
                            Clipboard buffer = tk.getSystemSelection();
                            if (buffer != null) {
                                // platform supports system selections, update it.
                                adjustCaret(e);
                                TransferHandler th = c.getTransferHandler();
                                if (th != null) {
                                    Transferable trans = null;

                                    try {
                                        trans = buffer.getContents(null);
                                    } catch (IllegalStateException ise) {
                                        // clipboard was unavailable
                                        UIManager.getLookAndFeel().provideErrorFeedback(c);
                                    }

                                    if (trans != null) {
                                        th.importData(c, trans);
                                    }
                                }
                                adjustFocus(true);
                            }
                        } catch (HeadlessException he) {
                            // do nothing... there is no system clipboard
                        }
                    }
                }
            }
        }
    }

    /**
     * If button 1 is pressed, this is implemented to
     * request focus on the associated text component,
     * and to set the caret position. If the shift key is held down,
     * the caret will be moved, potentially resulting in a selection,
     * otherwise the
     * caret position will be set to the new location.  If the component
     * is not enabled, there will be no request for focus.
     *
     * @param e the mouse event
     * @see MouseListener#mousePressed
     */
    public void mousePressed(MouseEvent e) {
        int nclicks = SwingUtilities2.getAdjustedClickCount(getComponent(), e);

        if (SwingUtilities.isLeftMouseButton(e)) {
            if (e.isConsumed()) {
                shouldHandleRelease = true;
            } else {
                shouldHandleRelease = false;
                adjustCaretAndFocus(e);
                if (nclicks == 2
                    && SwingUtilities2.canEventAccessSystemClipboard(e)) {
                    selectWord(e);
                }
            }
        }
    }

    void adjustCaretAndFocus(MouseEvent e) {
        adjustCaret(e);
        adjustFocus(false);
    }

    /**
     * Adjusts the caret location based on the MouseEvent.
     */
    private void adjustCaret(MouseEvent e) {
        if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0 &&
            getDot() != -1) {
            moveCaret(e);
        } else if (!e.isPopupTrigger()) {
            positionCaret(e);
        }
    }

    /**
     * Adjusts the focus, if necessary.
     *
     * @param inWindow if true indicates requestFocusInWindow should be used
     */
    private void adjustFocus(boolean inWindow) {
        if ((component != null) && component.isEnabled() &&
                                   component.isRequestFocusEnabled()) {
            if (inWindow) {
                component.requestFocusInWindow();
            }
            else {
                component.requestFocus();
            }
        }
    }

    /**
     * Called when the mouse is released.
     *
     * @param e the mouse event
     * @see MouseListener#mouseReleased
     */
    public void mouseReleased(MouseEvent e) {
        if (!e.isConsumed()
                && shouldHandleRelease
                && SwingUtilities.isLeftMouseButton(e)) {

            adjustCaretAndFocus(e);
        }
    }

    /**
     * Called when the mouse enters a region.
     *
     * @param e the mouse event
     * @see MouseListener#mouseEntered
     */
    public void mouseEntered(MouseEvent e) {
    }

    /**
     * Called when the mouse exits a region.
     *
     * @param e the mouse event
     * @see MouseListener#mouseExited
     */
    public void mouseExited(MouseEvent e) {
    }

    // --- MouseMotionListener methods -------------------------

    /**
     * Moves the caret position
     * according to the mouse pointer's current
     * location.  This effectively extends the
     * selection.  By default, this is only done
     * for mouse button 1.
     *
     * @param e the mouse event
     * @see MouseMotionListener#mouseDragged
     */
    public void mouseDragged(MouseEvent e) {
        if ((! e.isConsumed()) && SwingUtilities.isLeftMouseButton(e)) {
            moveCaret(e);
        }
    }

    /**
     * Called when the mouse is moved.
     *
     * @param e the mouse event
     * @see MouseMotionListener#mouseMoved
     */
    public void mouseMoved(MouseEvent e) {
    }

    // ---- Caret methods ---------------------------------

    /**
     * Renders the caret as a vertical line.  If this is reimplemented
     * the damage method should also be reimplemented as it assumes the
     * shape of the caret is a vertical line.  Sets the caret color to
     * the value returned by getCaretColor().
     * <p>
     * If there are multiple text directions present in the associated
     * document, a flag indicating the caret bias will be rendered.
     * This will occur only if the associated document is a subclass
     * of AbstractDocument and there are multiple bidi levels present
     * in the bidi element structure (i.e. the text has multiple
     * directions associated with it).
     *
     * @param g the graphics context
     * @see #damage
     */
    public void paint(Graphics g) {
        if(isVisible()) {
            try {
                TextUI mapper = component.getUI();
                Rectangle r = mapper.modelToView(component, dot, dotBias);

                if ((r == null) || ((r.width == 0) && (r.height == 0))) {
                    return;
                }
                if (width > 0 && height > 0 &&
                                !this._contains(r.x, r.y, r.width, r.height)) {
                    // We seem to have gotten out of sync and no longer
                    // contain the right location, adjust accordingly.
                    Rectangle clip = g.getClipBounds();

                    if (clip != null && !clip.contains(this)) {
                        // Clip doesn't contain the old location, force it
                        // to be repainted lest we leave a caret around.
                        repaint();
                    }
                    // This will potentially cause a repaint of something
                    // we're already repainting, but without changing the
                    // semantics of damage we can't really get around this.
                    damage(r);
                }
                g.setColor(component.getCaretColor());
                int paintWidth = getCaretWidth(r.height);
                r.x -= paintWidth  >> 1;
                g.fillRect(r.x, r.y, paintWidth, r.height);

                // see if we should paint a flag to indicate the bias
                // of the caret.
                // PENDING(prinz) this should be done through
                // protected methods so that alternative LAF
                // will show bidi information.
                Document doc = component.getDocument();
                if (doc instanceof AbstractDocument) {
                    Element bidi = ((AbstractDocument)doc).getBidiRootElement();
                    if ((bidi != null) && (bidi.getElementCount() > 1)) {
                        // there are multiple directions present.
                        flagXPoints[0] = r.x + ((dotLTR) ? paintWidth : 0);
                        flagYPoints[0] = r.y;
                        flagXPoints[1] = flagXPoints[0];
                        flagYPoints[1] = flagYPoints[0] + 4;
                        flagXPoints[2] = flagXPoints[0] + ((dotLTR) ? 4 : -4);
                        flagYPoints[2] = flagYPoints[0];
                        g.fillPolygon(flagXPoints, flagYPoints, 3);
                    }
                }
            } catch (BadLocationException e) {
                // can't render I guess
                //System.err.println("Can't render cursor");
            }
        }
    }

    /**
     * Called when the UI is being installed into the
     * interface of a JTextComponent.  This can be used
     * to gain access to the model that is being navigated
     * by the implementation of this interface.  Sets the dot
     * and mark to 0, and establishes document, property change,
     * focus, mouse, and mouse motion listeners.
     *
     * @param c the component
     * @see Caret#install
     */
    public void install(JTextComponent c) {
        component = c;
        Document doc = c.getDocument();
        dot = mark = 0;
        dotLTR = markLTR = true;
        dotBias = markBias = Position.Bias.Forward;
        if (doc != null) {
            doc.addDocumentListener(handler);
        }
        c.addPropertyChangeListener(handler);
        c.addFocusListener(this);
        c.addMouseListener(this);
        c.addMouseMotionListener(this);

        // if the component already has focus, it won't
        // be notified.
        if (component.hasFocus()) {
            focusGained(null);
        }

        Number ratio = (Number) c.getClientProperty("caretAspectRatio");
        if (ratio != null) {
            aspectRatio = ratio.floatValue();
        } else {
            aspectRatio = -1;
        }

        Integer width = (Integer) c.getClientProperty("caretWidth");
        if (width != null) {
            caretWidth = width.intValue();
        } else {
            caretWidth = -1;
        }
    }

    /**
     * Called when the UI is being removed from the
     * interface of a JTextComponent.  This is used to
     * unregister any listeners that were attached.
     *
     * @param c the component
     * @see Caret#deinstall
     */
    public void deinstall(JTextComponent c) {
        c.removeMouseListener(this);
        c.removeMouseMotionListener(this);
        c.removeFocusListener(this);
        c.removePropertyChangeListener(handler);
        Document doc = c.getDocument();
        if (doc != null) {
            doc.removeDocumentListener(handler);
        }
        synchronized(this) {
            component = null;
        }
        if (flasher != null) {
            flasher.stop();
        }


    }

    /**
     * Adds a listener to track whenever the caret position has
     * been changed.
     *
     * @param l the listener
     * @see Caret#addChangeListener
     */
    public void addChangeListener(ChangeListener l) {
        listenerList.add(ChangeListener.class, l);
    }

    /**
     * Removes a listener that was tracking caret position changes.
     *
     * @param l the listener
     * @see Caret#removeChangeListener
     */
    public void removeChangeListener(ChangeListener l) {
        listenerList.remove(ChangeListener.class, l);
    }

    /**
     * Returns an array of all the change listeners
     * registered on this caret.
     *
     * @return all of this caret's <code>ChangeListener</code>s
     *         or an empty
     *         array if no change listeners are currently registered
     *
     * @see #addChangeListener
     * @see #removeChangeListener
     *
     * @since 1.4
     */
    public ChangeListener[] getChangeListeners() {
        return listenerList.getListeners(ChangeListener.class);
    }

    /**
     * Notifies all listeners that have registered interest for
     * notification on this event type.  The event instance
     * is lazily created using the parameters passed into
     * the fire method.  The listener list is processed last to first.
     *
     * @see EventListenerList
     */
    protected void fireStateChanged() {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();
        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==ChangeListener.class) {
                // Lazily create the event:
                if (changeEvent == null)
                    changeEvent = new ChangeEvent(this);
                ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
            }
        }
    }

    /**
     * Returns an array of all the objects currently registered
     * as <code><em>Foo</em>Listener</code>s
     * upon this caret.
     * <code><em>Foo</em>Listener</code>s are registered using the
     * <code>add<em>Foo</em>Listener</code> method.
     *
     * <p>
     *
     * You can specify the <code>listenerType</code> argument
     * with a class literal,
     * such as
     * <code><em>Foo</em>Listener.class</code>.
     * For example, you can query a
     * <code>DefaultCaret</code> <code>c</code>
     * for its change listeners with the following code:
     *
     * <pre>ChangeListener[] cls = (ChangeListener[])(c.getListeners(ChangeListener.class));</pre>
     *
     * If no such listeners exist, this method returns an empty array.
     *
     * @param listenerType the type of listeners requested; this parameter
     *          should specify an interface that descends from
     *          <code>java.util.EventListener</code>
     * @return an array of all objects registered as
     *          <code><em>Foo</em>Listener</code>s on this component,
     *          or an empty array if no such
     *          listeners have been added
     * @exception ClassCastException if <code>listenerType</code>
     *          doesn't specify a class or interface that implements
     *          <code>java.util.EventListener</code>
     *
     * @see #getChangeListeners
     *
     * @since 1.3
     */
    public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
        return listenerList.getListeners(listenerType);
    }

    /**
     * Changes the selection visibility.
     *
     * @param vis the new visibility
     */
    public void setSelectionVisible(boolean vis) {
        if (vis != selectionVisible) {
            selectionVisible = vis;
            if (selectionVisible) {
                // show
                Highlighter h = component.getHighlighter();
                if ((dot != mark) && (h != null) && (selectionTag == null)) {
                    int p0 = Math.min(dot, mark);
                    int p1 = Math.max(dot, mark);
                    Highlighter.HighlightPainter p = getSelectionPainter();
                    try {
                        selectionTag = h.addHighlight(p0, p1, p);
                    } catch (BadLocationException bl) {
                        selectionTag = null;
                    }
                }
            } else {
                // hide
                if (selectionTag != null) {
                    Highlighter h = component.getHighlighter();
                    h.removeHighlight(selectionTag);
                    selectionTag = null;
                }
            }
        }
    }

    /**
     * Checks whether the current selection is visible.
     *
     * @return true if the selection is visible
     */
    public boolean isSelectionVisible() {
        return selectionVisible;
    }

    /**
     * Determines if the caret is currently active.
     * <p>
     * This method returns whether or not the <code>Caret</code>
     * is currently in a blinking state. It does not provide
     * information as to whether it is currently blinked on or off.
     * To determine if the caret is currently painted use the
     * <code>isVisible</code> method.
     *
     * @return <code>true</code> if active else <code>false</code>
     * @see #isVisible
     *
     * @since 1.5
     */
    public boolean isActive() {
        return active;
    }

    /**
     * Indicates whether or not the caret is currently visible. As the
     * caret flashes on and off the return value of this will change
     * between true, when the caret is painted, and false, when the
     * caret is not painted. <code>isActive</code> indicates whether
     * or not the caret is in a blinking state, such that it <b>can</b>
     * be visible, and <code>isVisible</code> indicates whether or not
     * the caret <b>is</b> actually visible.
     * <p>
     * Subclasses that wish to render a different flashing caret
     * should override paint and only paint the caret if this method
     * returns true.
     *
     * @return true if visible else false
     * @see Caret#isVisible
     * @see #isActive
     */
    public boolean isVisible() {
        return visible;
    }

    /**
     * Sets the caret visibility, and repaints the caret.
     * It is important to understand the relationship between this method,
     * <code>isVisible</code> and <code>isActive</code>.
     * Calling this method with a value of <code>true</code> activates the
     * caret blinking. Setting it to <code>false</code> turns it completely off.
     * To determine whether the blinking is active, you should call
     * <code>isActive</code>. In effect, <code>isActive</code> is an
     * appropriate corresponding "getter" method for this one.
     * <code>isVisible</code> can be used to fetch the current
     * visibility status of the caret, meaning whether or not it is currently
     * painted. This status will change as the caret blinks on and off.
     * <p>
     * Here's a list showing the potential return values of both
     * <code>isActive</code> and <code>isVisible</code>
     * after calling this method:
     * <p>
     * <b><code>setVisible(true)</code></b>:
     * <ul>
     *     <li>isActive(): true</li>
     *     <li>isVisible(): true or false depending on whether
     *         or not the caret is blinked on or off</li>
     * </ul>
     * <p>
     * <b><code>setVisible(false)</code></b>:
     * <ul>
     *     <li>isActive(): false</li>
     *     <li>isVisible(): false</li>
     * </ul>
     *
     * @param e the visibility specifier
     * @see #isActive
     * @see Caret#setVisible
     */
    public void setVisible(boolean e) {
        // focus lost notification can come in later after the
        // caret has been deinstalled, in which case the component
        // will be null.
        if (component != null) {
            active = e;
            TextUI mapper = component.getUI();
            if (visible != e) {
                visible = e;
                // repaint the caret
                try {
                    Rectangle loc = mapper.modelToView(component, dot,dotBias);
                    damage(loc);
                } catch (BadLocationException badloc) {
                    // hmm... not legally positioned
                }
            }
        }
        if (flasher != null) {
            if (visible) {
                flasher.start();
            } else {
                flasher.stop();
            }
        }
    }

    /**
     * Sets the caret blink rate.
     *
     * @param rate the rate in milliseconds, 0 to stop blinking
     * @see Caret#setBlinkRate
     */
    public void setBlinkRate(int rate) {
        if (rate != 0) {
            if (flasher == null) {
                flasher = new Timer(rate, handler);
            }
            flasher.setDelay(rate);
        } else {
            if (flasher != null) {
                flasher.stop();
                flasher.removeActionListener(handler);
                flasher = null;
            }
        }
    }

    /**
     * Gets the caret blink rate.
     *
     * @return the delay in milliseconds.  If this is
     *  zero the caret will not blink.
     * @see Caret#getBlinkRate
     */
    public int getBlinkRate() {
        return (flasher == null) ? 0 : flasher.getDelay();
    }

    /**
     * Fetches the current position of the caret.
     *
     * @return the position &gt;= 0
     * @see Caret#getDot
     */
    public int getDot() {
        return dot;
    }

    /**
     * Fetches the current position of the mark.  If there is a selection,
     * the dot and mark will not be the same.
     *
     * @return the position &gt;= 0
     * @see Caret#getMark
     */
    public int getMark() {
        return mark;
    }

    /**
     * Sets the caret position and mark to the specified position,
     * with a forward bias. This implicitly sets the
     * selection range to zero.
     *
     * @param dot the position &gt;= 0
     * @see #setDot(int, Position.Bias)
     * @see Caret#setDot
     */
    public void setDot(int dot) {
        setDot(dot, Position.Bias.Forward);
    }

    /**
     * Moves the caret position to the specified position,
     * with a forward bias.
     *
     * @param dot the position &gt;= 0
     * @see #moveDot(int, javax.swing.text.Position.Bias)
     * @see Caret#moveDot
     */
    public void moveDot(int dot) {
        moveDot(dot, Position.Bias.Forward);
    }

    // ---- Bidi methods (we could put these in a subclass)

    /**
     * Moves the caret position to the specified position, with the
     * specified bias.
     *
     * @param dot the position &gt;= 0
     * @param dotBias the bias for this position, not <code>null</code>
     * @throws IllegalArgumentException if the bias is <code>null</code>
     * @see Caret#moveDot
     * @since 1.6
     */
    public void moveDot(int dot, Position.Bias dotBias) {
        if (dotBias == null) {
            throw new IllegalArgumentException("null bias");
        }

        if (! component.isEnabled()) {
            // don't allow selection on disabled components.
            setDot(dot, dotBias);
            return;
        }
        if (dot != this.dot) {
            NavigationFilter filter = component.getNavigationFilter();

            if (filter != null) {
                filter.moveDot(getFilterBypass(), dot, dotBias);
            }
            else {
                handleMoveDot(dot, dotBias);
            }
        }
    }

    void handleMoveDot(int dot, Position.Bias dotBias) {
        changeCaretPosition(dot, dotBias);

        if (selectionVisible) {
            Highlighter h = component.getHighlighter();
            if (h != null) {
                int p0 = Math.min(dot, mark);
                int p1 = Math.max(dot, mark);

                // if p0 == p1 then there should be no highlight, remove it if necessary
                if (p0 == p1) {
                    if (selectionTag != null) {
                        h.removeHighlight(selectionTag);
                        selectionTag = null;
                    }
                // otherwise, change or add the highlight
                } else {
                    try {
                        if (selectionTag != null) {
                            h.changeHighlight(selectionTag, p0, p1);
                        } else {
                            Highlighter.HighlightPainter p = getSelectionPainter();
                            selectionTag = h.addHighlight(p0, p1, p);
                        }
                    } catch (BadLocationException e) {
                        throw new StateInvariantError("Bad caret position");
                    }
                }
            }
        }
    }

    /**
     * Sets the caret position and mark to the specified position, with the
     * specified bias. This implicitly sets the selection range
     * to zero.
     *
     * @param dot the position &gt;= 0
     * @param dotBias the bias for this position, not <code>null</code>
     * @throws IllegalArgumentException if the bias is <code>null</code>
     * @see Caret#setDot
     * @since 1.6
     */
    public void setDot(int dot, Position.Bias dotBias) {
        if (dotBias == null) {
            throw new IllegalArgumentException("null bias");
        }

        NavigationFilter filter = component.getNavigationFilter();

        if (filter != null) {
            filter.setDot(getFilterBypass(), dot, dotBias);
        }
        else {
            handleSetDot(dot, dotBias);
        }
    }

    void handleSetDot(int dot, Position.Bias dotBias) {
        // move dot, if it changed
        Document doc = component.getDocument();
        if (doc != null) {
            dot = Math.min(dot, doc.getLength());
        }
        dot = Math.max(dot, 0);

        // The position (0,Backward) is out of range so disallow it.
        if( dot == 0 )
            dotBias = Position.Bias.Forward;

        mark = dot;
        if (this.dot != dot || this.dotBias != dotBias ||
            selectionTag != null || forceCaretPositionChange) {
            changeCaretPosition(dot, dotBias);
        }
        this.markBias = this.dotBias;
        this.markLTR = dotLTR;
        Highlighter h = component.getHighlighter();
        if ((h != null) && (selectionTag != null)) {
            h.removeHighlight(selectionTag);
            selectionTag = null;
        }
    }

    /**
     * Returns the bias of the caret position.
     *
     * @return the bias of the caret position
     * @since 1.6
     */
    public Position.Bias getDotBias() {
        return dotBias;
    }

    /**
     * Returns the bias of the mark.
     *
     * @return the bias of the mark
     * @since 1.6
     */
    public Position.Bias getMarkBias() {
        return markBias;
    }

    boolean isDotLeftToRight() {
        return dotLTR;
    }

    boolean isMarkLeftToRight() {
        return markLTR;
    }

    boolean isPositionLTR(int position, Position.Bias bias) {
        Document doc = component.getDocument();
        if(doc instanceof AbstractDocument ) {
            if(bias == Position.Bias.Backward && --position < 0)
                position = 0;
            return ((AbstractDocument)doc).isLeftToRight(position, position);
        }
        return true;
    }

    Position.Bias guessBiasForOffset(int offset, Position.Bias lastBias,
                                     boolean lastLTR) {
        // There is an abiguous case here. That if your model looks like:
        // abAB with the cursor at abB]A (visual representation of
        // 3 forward) deleting could either become abB] or
        // ab[B. I'ld actually prefer abB]. But, if I implement that
        // a delete at abBA] would result in aBA] vs a[BA which I
        // think is totally wrong. To get this right we need to know what
        // was deleted. And we could get this from the bidi structure
        // in the change event. So:
        // PENDING: base this off what was deleted.
        if(lastLTR != isPositionLTR(offset, lastBias)) {
            lastBias = Position.Bias.Backward;
        }
        else if(lastBias != Position.Bias.Backward &&
                lastLTR != isPositionLTR(offset, Position.Bias.Backward)) {
            lastBias = Position.Bias.Backward;
        }
        if (lastBias == Position.Bias.Backward && offset > 0) {
            try {
                Segment s = new Segment();
                component.getDocument().getText(offset - 1, 1, s);
                if (s.count > 0 && s.array[s.offset] == '\n') {
                    lastBias = Position.Bias.Forward;
                }
            }
            catch (BadLocationException ble) {}
        }
        return lastBias;
    }

    // ---- local methods --------------------------------------------

    /**
     * Sets the caret position (dot) to a new location.  This
     * causes the old and new location to be repainted.  It
     * also makes sure that the caret is within the visible
     * region of the view, if the view is scrollable.
     */
    void changeCaretPosition(int dot, Position.Bias dotBias) {
        // repaint the old position and set the new value of
        // the dot.
        repaint();


        // Make sure the caret is visible if this window has the focus.
        if (flasher != null && flasher.isRunning()) {
            visible = true;
            flasher.restart();
        }

        // notify listeners at the caret moved
        this.dot = dot;
        this.dotBias = dotBias;
        dotLTR = isPositionLTR(dot, dotBias);
        fireStateChanged();

        updateSystemSelection();

        setMagicCaretPosition(null);

        // We try to repaint the caret later, since things
        // may be unstable at the time this is called
        // (i.e. we don't want to depend upon notification
        // order or the fact that this might happen on
        // an unsafe thread).
        Runnable callRepaintNewCaret = new Runnable() {
            public void run() {
                repaintNewCaret();
            }
        };
        SwingUtilities.invokeLater(callRepaintNewCaret);
    }

    /**
     * Repaints the new caret position, with the
     * assumption that this is happening on the
     * event thread so that calling <code>modelToView</code>
     * is safe.
     */
    void repaintNewCaret() {
        if (component != null) {
            TextUI mapper = component.getUI();
            Document doc = component.getDocument();
            if ((mapper != null) && (doc != null)) {
                // determine the new location and scroll if
                // not visible.
                Rectangle newLoc;
                try {
                    newLoc = mapper.modelToView(component, this.dot, this.dotBias);
                } catch (BadLocationException e) {
                    newLoc = null;
                }
                if (newLoc != null) {
                    adjustVisibility(newLoc);
                    // If there is no magic caret position, make one
                    if (getMagicCaretPosition() == null) {
                        setMagicCaretPosition(new Point(newLoc.x, newLoc.y));
                    }
                }

                // repaint the new position
                damage(newLoc);
            }
        }
    }

    private void updateSystemSelection() {
        if ( ! SwingUtilities2.canCurrentEventAccessSystemClipboard() ) {
            return;
        }
        if (this.dot != this.mark && component != null) {
            Clipboard clip = getSystemSelection();
            if (clip != null) {
                String selectedText;
                if (component instanceof JPasswordField
                    && component.getClientProperty("JPasswordField.cutCopyAllowed") !=
                    Boolean.TRUE) {
                    //fix for 4793761
                    StringBuffer txt = null;
                    char echoChar = ((JPasswordField)component).getEchoChar();
                    int p0 = Math.min(getDot(), getMark());
                    int p1 = Math.max(getDot(), getMark());
                    for (int i = p0; i < p1; i++) {
                        if (txt == null) {
                            txt = new StringBuffer();
                        }
                        txt.append(echoChar);
                    }
                    selectedText = (txt != null) ? txt.toString() : null;
                } else {
                    selectedText = component.getSelectedText();
                }
                try {
                    clip.setContents(
                        new StringSelection(selectedText), getClipboardOwner());

                    ownsSelection = true;
                } catch (IllegalStateException ise) {
                    // clipboard was unavailable
                    // no need to provide error feedback to user since updating
                    // the system selection is not a user invoked action
                }
            }
        }
    }

    private Clipboard getSystemSelection() {
        try {
            return component.getToolkit().getSystemSelection();
        } catch (HeadlessException he) {
            // do nothing... there is no system clipboard
        } catch (SecurityException se) {
            // do nothing... there is no allowed system clipboard
        }
        return null;
    }

    private ClipboardOwner getClipboardOwner() {
        return handler;
    }

    /**
     * This is invoked after the document changes to verify the current
     * dot/mark is valid. We do this in case the <code>NavigationFilter</code>
     * changed where to position the dot, that resulted in the current location
     * being bogus.
     */
    private void ensureValidPosition() {
        int length = component.getDocument().getLength();
        if (dot > length || mark > length) {
            // Current location is bogus and filter likely vetoed the
            // change, force the reset without giving the filter a
            // chance at changing it.
            handleSetDot(length, Position.Bias.Forward);
        }
    }


    /**
     * Saves the current caret position.  This is used when
     * caret up/down actions occur, moving between lines
     * that have uneven end positions.
     *
     * @param p the position
     * @see #getMagicCaretPosition
     */
    public void setMagicCaretPosition(Point p) {
        magicCaretPosition = p;
    }

    /**
     * Gets the saved caret position.
     *
     * @return the position
     * see #setMagicCaretPosition
     */
    public Point getMagicCaretPosition() {
        return magicCaretPosition;
    }

    /**
     * Compares this object to the specified object.
     * The superclass behavior of comparing rectangles
     * is not desired, so this is changed to the Object
     * behavior.
     *
     * @param     obj   the object to compare this font with
     * @return    <code>true</code> if the objects are equal;
     *            <code>false</code> otherwise
     */
    public boolean equals(Object obj) {
        return (this == obj);
    }

    public String toString() {
        String s = "Dot=(" + dot + ", " + dotBias + ")";
        s += " Mark=(" + mark + ", " + markBias + ")";
        return s;
    }

    private NavigationFilter.FilterBypass getFilterBypass() {
        if (filterBypass == null) {
            filterBypass = new DefaultFilterBypass();
        }
        return filterBypass;
    }

    // Rectangle.contains returns false if passed a rect with a w or h == 0,
    // this won't (assuming X,Y are contained with this rectangle).
    private boolean _contains(int X, int Y, int W, int H) {
        int w = this.width;
        int h = this.height;
        if ((w | h | W | H) < 0) {
            // At least one of the dimensions is negative...
            return false;
        }
        // Note: if any dimension is zero, tests below must return false...
        int x = this.x;
        int y = this.y;
        if (X < x || Y < y) {
            return false;
        }
        if (W > 0) {
            w += x;
            W += X;
            if (W <= X) {
                // X+W overflowed or W was zero, return false if...
                // either original w or W was zero or
                // x+w did not overflow or
                // the overflowed x+w is smaller than the overflowed X+W
                if (w >= x || W > w) return false;
            } else {
                // X+W did not overflow and W was not zero, return false if...
                // original w was zero or
                // x+w did not overflow and x+w is smaller than X+W
                if (w >= x && W > w) return false;
            }
        }
        else if ((x + w) < X) {
            return false;
        }
        if (H > 0) {
            h += y;
            H += Y;
            if (H <= Y) {
                if (h >= y || H > h) return false;
            } else {
                if (h >= y && H > h) return false;
            }
        }
        else if ((y + h) < Y) {
            return false;
        }
        return true;
    }

    int getCaretWidth(int height) {
        if (aspectRatio > -1) {
            return (int) (aspectRatio * height) + 1;
        }

        if (caretWidth > -1) {
            return caretWidth;
        }

        return 1;
    }

    // --- serialization ---------------------------------------------

    private void readObject(ObjectInputStream s)
      throws ClassNotFoundException, IOException
    {
        s.defaultReadObject();
        handler = new Handler();
        if (!s.readBoolean()) {
            dotBias = Position.Bias.Forward;
        }
        else {
            dotBias = Position.Bias.Backward;
        }
        if (!s.readBoolean()) {
            markBias = Position.Bias.Forward;
        }
        else {
            markBias = Position.Bias.Backward;
        }
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        s.writeBoolean((dotBias == Position.Bias.Backward));
        s.writeBoolean((markBias == Position.Bias.Backward));
    }

    // ---- member variables ------------------------------------------

    /**
     * The event listener list.
     */
    protected EventListenerList listenerList = new EventListenerList();

    /**
     * The change event for the model.
     * Only one ChangeEvent is needed per model instance since the
     * event's only (read-only) state is the source property.  The source
     * of events generated here is always "this".
     */
    protected transient ChangeEvent changeEvent = null;

    // package-private to avoid inner classes private member
    // access bug
    JTextComponent component;

    int updatePolicy = UPDATE_WHEN_ON_EDT;
    boolean visible;
    boolean active;
    int dot;
    int mark;
    Object selectionTag;
    boolean selectionVisible;
    Timer flasher;
    Point magicCaretPosition;
    transient Position.Bias dotBias;
    transient Position.Bias markBias;
    boolean dotLTR;
    boolean markLTR;
    transient Handler handler = new Handler();
    transient private int[] flagXPoints = new int[3];
    transient private int[] flagYPoints = new int[3];
    private transient NavigationFilter.FilterBypass filterBypass;
    static private transient Action selectWord = null;
    static private transient Action selectLine = null;
    /**
     * This is used to indicate if the caret currently owns the selection.
     * This is always false if the system does not support the system
     * clipboard.
     */
    private boolean ownsSelection;

    /**
     * If this is true, the location of the dot is updated regardless of
     * the current location. This is set in the DocumentListener
     * such that even if the model location of dot hasn't changed (perhaps do
     * to a forward delete) the visual location is updated.
     */
    private boolean forceCaretPositionChange;

    /**
     * Whether or not mouseReleased should adjust the caret and focus.
     * This flag is set by mousePressed if it wanted to adjust the caret
     * and focus but couldn't because of a possible DnD operation.
     */
    private transient boolean shouldHandleRelease;


    /**
     * holds last MouseEvent which caused the word selection
     */
    private transient MouseEvent selectedWordEvent = null;

    /**
     * The width of the caret in pixels.
     */
    private int caretWidth = -1;
    private float aspectRatio = -1;

    class SafeScroller implements Runnable {

        SafeScroller(Rectangle r) {
            this.r = r;
        }

        public void run() {
            if (component != null) {
                component.scrollRectToVisible(r);
            }
        }

        Rectangle r;
    }


    class Handler implements PropertyChangeListener, DocumentListener, ActionListener, ClipboardOwner {

        // --- ActionListener methods ----------------------------------

        /**
         * Invoked when the blink timer fires.  This is called
         * asynchronously.  The simply changes the visibility
         * and repaints the rectangle that last bounded the caret.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            if (width == 0 || height == 0) {
                // setVisible(true) will cause a scroll, only do this if the
                // new location is really valid.
                if (component != null) {
                    TextUI mapper = component.getUI();
                    try {
                        Rectangle r = mapper.modelToView(component, dot,
                                                         dotBias);
                        if (r != null && r.width != 0 && r.height != 0) {
                            damage(r);
                        }
                    } catch (BadLocationException ble) {
                    }
                }
            }
            visible = !visible;
            repaint();
        }

        // --- DocumentListener methods --------------------------------

        /**
         * Updates the dot and mark if they were changed by
         * the insertion.
         *
         * @param e the document event
         * @see DocumentListener#insertUpdate
         */
        public void insertUpdate(DocumentEvent e) {
            if (getUpdatePolicy() == NEVER_UPDATE ||
                    (getUpdatePolicy() == UPDATE_WHEN_ON_EDT &&
                    !SwingUtilities.isEventDispatchThread())) {

                if ((e.getOffset() <= dot || e.getOffset() <= mark)
                        && selectionTag != null) {
                    try {
                        component.getHighlighter().changeHighlight(selectionTag,
                                Math.min(dot, mark), Math.max(dot, mark));
                    } catch (BadLocationException e1) {
                        e1.printStackTrace();
                    }
                }
                return;
            }
            int adjust = 0;
            int offset = e.getOffset();
            int length = e.getLength();
            int newDot = dot;
            short changed = 0;

            if (e instanceof AbstractDocument.UndoRedoDocumentEvent) {
                setDot(offset + length);
                return;
            }
            if (newDot >= offset) {
                newDot += length;
                changed |= 1;
            }
            int newMark = mark;
            if (newMark >= offset) {
                newMark += length;
                changed |= 2;
            }

            if (changed != 0) {
                Position.Bias dotBias = DefaultCaret.this.dotBias;
                if (dot == offset) {
                    Document doc = component.getDocument();
                    boolean isNewline;
                    try {
                        Segment s = new Segment();
                        doc.getText(newDot - 1, 1, s);
                        isNewline = (s.count > 0 &&
                                s.array[s.offset] == '\n');
                    } catch (BadLocationException ble) {
                        isNewline = false;
                    }
                    if (isNewline) {
                        dotBias = Position.Bias.Forward;
                    } else {
                        dotBias = Position.Bias.Backward;
                    }
                }
                if (newMark == newDot) {
                    setDot(newDot, dotBias);
                    ensureValidPosition();
                }
                else {
                    setDot(newMark, markBias);
                    if (getDot() == newMark) {
                        // Due this test in case the filter vetoed the
                        // change in which case this probably won't be
                        // valid either.
                        moveDot(newDot, dotBias);
                    }
                    ensureValidPosition();
                }
            }
        }

        /**
         * Updates the dot and mark if they were changed
         * by the removal.
         *
         * @param e the document event
         * @see DocumentListener#removeUpdate
         */
        public void removeUpdate(DocumentEvent e) {
            if (getUpdatePolicy() == NEVER_UPDATE ||
                    (getUpdatePolicy() == UPDATE_WHEN_ON_EDT &&
                    !SwingUtilities.isEventDispatchThread())) {

                int length = component.getDocument().getLength();
                dot = Math.min(dot, length);
                mark = Math.min(mark, length);
                if ((e.getOffset() < dot || e.getOffset() < mark)
                        && selectionTag != null) {
                    try {
                        component.getHighlighter().changeHighlight(selectionTag,
                                Math.min(dot, mark), Math.max(dot, mark));
                    } catch (BadLocationException e1) {
                        e1.printStackTrace();
                    }
                }
                return;
            }
            int offs0 = e.getOffset();
            int offs1 = offs0 + e.getLength();
            int adjust = 0;
            int newDot = dot;
            boolean adjustDotBias = false;
            int newMark = mark;
            boolean adjustMarkBias = false;

            if(e instanceof AbstractDocument.UndoRedoDocumentEvent) {
                setDot(offs0);
                return;
            }
            if (newDot >= offs1) {
                newDot -= (offs1 - offs0);
                if(newDot == offs1) {
                    adjustDotBias = true;
                }
            } else if (newDot >= offs0) {
                newDot = offs0;
                adjustDotBias = true;
            }
            if (newMark >= offs1) {
                newMark -= (offs1 - offs0);
                if(newMark == offs1) {
                    adjustMarkBias = true;
                }
            } else if (newMark >= offs0) {
                newMark = offs0;
                adjustMarkBias = true;
            }
            if (newMark == newDot) {
                forceCaretPositionChange = true;
                try {
                    setDot(newDot, guessBiasForOffset(newDot, dotBias,
                            dotLTR));
                } finally {
                    forceCaretPositionChange = false;
                }
                ensureValidPosition();
            } else {
                Position.Bias dotBias = DefaultCaret.this.dotBias;
                Position.Bias markBias = DefaultCaret.this.markBias;
                if(adjustDotBias) {
                    dotBias = guessBiasForOffset(newDot, dotBias, dotLTR);
                }
                if(adjustMarkBias) {
                    markBias = guessBiasForOffset(mark, markBias, markLTR);
                }
                setDot(newMark, markBias);
                if (getDot() == newMark) {
                    // Due this test in case the filter vetoed the change
                    // in which case this probably won't be valid either.
                    moveDot(newDot, dotBias);
                }
                ensureValidPosition();
            }
        }

        /**
         * Gives notification that an attribute or set of attributes changed.
         *
         * @param e the document event
         * @see DocumentListener#changedUpdate
         */
        public void changedUpdate(DocumentEvent e) {
            if (getUpdatePolicy() == NEVER_UPDATE ||
                    (getUpdatePolicy() == UPDATE_WHEN_ON_EDT &&
                    !SwingUtilities.isEventDispatchThread())) {
                return;
            }
            if(e instanceof AbstractDocument.UndoRedoDocumentEvent) {
                setDot(e.getOffset() + e.getLength());
            }
        }

        // --- PropertyChangeListener methods -----------------------

        /**
         * This method gets called when a bound property is changed.
         * We are looking for document changes on the editor.
         */
        public void propertyChange(PropertyChangeEvent evt) {
            Object oldValue = evt.getOldValue();
            Object newValue = evt.getNewValue();
            if ((oldValue instanceof Document) || (newValue instanceof Document)) {
                setDot(0);
                if (oldValue != null) {
                    ((Document)oldValue).removeDocumentListener(this);
                }
                if (newValue != null) {
                    ((Document)newValue).addDocumentListener(this);
                }
            } else if("enabled".equals(evt.getPropertyName())) {
                Boolean enabled = (Boolean) evt.getNewValue();
                if(component.isFocusOwner()) {
                    if(enabled == Boolean.TRUE) {
                        if(component.isEditable()) {
                            setVisible(true);
                        }
                        setSelectionVisible(true);
                    } else {
                        setVisible(false);
                        setSelectionVisible(false);
                    }
                }
            } else if("caretWidth".equals(evt.getPropertyName())) {
                Integer newWidth = (Integer) evt.getNewValue();
                if (newWidth != null) {
                    caretWidth = newWidth.intValue();
                } else {
                    caretWidth = -1;
                }
                repaint();
            } else if("caretAspectRatio".equals(evt.getPropertyName())) {
                Number newRatio = (Number) evt.getNewValue();
                if (newRatio != null) {
                    aspectRatio = newRatio.floatValue();
                } else {
                    aspectRatio = -1;
                }
                repaint();
            }
        }


        //
        // ClipboardOwner
        //
        /**
         * Toggles the visibility of the selection when ownership is lost.
         */
        public void lostOwnership(Clipboard clipboard,
                                      Transferable contents) {
            if (ownsSelection) {
                ownsSelection = false;
                if (component != null && !component.hasFocus()) {
                    setSelectionVisible(false);
                }
            }
        }
    }


    private class DefaultFilterBypass extends NavigationFilter.FilterBypass {
        public Caret getCaret() {
            return DefaultCaret.this;
        }

        public void setDot(int dot, Position.Bias bias) {
            handleSetDot(dot, bias);
        }

        public void moveDot(int dot, Position.Bias bias) {
            handleMoveDot(dot, bias);
        }
    }
}
