//# 7 errors, 1,755 messages
//#
/*
    //#TextPaneCanvas.java:1:1: class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2
    //#TextPaneCanvas.java:1:1: method: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2__static_init
    //#TextPaneCanvas.java:1:1: class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1
    //#TextPaneCanvas.java:1:1: method: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1__static_init
    //#TextPaneCanvas.java:1:1: class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.dmdirc.addons.ui_swing.textpane;

import com.dmdirc.addons.ui_swing.UIUtilities;
import com.dmdirc.interfaces.ConfigChangeListener;
import com.dmdirc.ui.messages.IRCTextAttribute;

import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextHitInfo;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.MouseInputListener;

/** Canvas object to draw text. */
class TextPaneCanvas extends JPanel implements MouseInputListener,
    //#TextPaneCanvas.java:53: method: Map com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.access$000(TextPaneCanvas)
    //#input(Map access$000(TextPaneCanvas)): x0
    //#input(Map access$000(TextPaneCanvas)): x0.lineWrap
    //#output(Map access$000(TextPaneCanvas)): return_value
    //#pre[1] (Map access$000(TextPaneCanvas)): x0 != null
    //#post(Map access$000(TextPaneCanvas)): return_value == x0.lineWrap
    //#post(Map access$000(TextPaneCanvas)): init'ed(return_value)
    //#TextPaneCanvas.java:53: end of method: Map com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.access$000(TextPaneCanvas)
        ComponentListener, ConfigChangeListener {

    /**
     * A version number for this class. It should be changed whenever the
     * class structure is changed (or anything else that would prevent
     * serialized objects being unserialized with the new class).
     */
    private static final long serialVersionUID = 8;
    /** Hand cursor. */
    private static final Cursor HAND_CURSOR = new Cursor(Cursor.HAND_CURSOR);
    //#TextPaneCanvas.java:63: method: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): HAND_CURSOR
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.checkForLink()V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.clearSelection()V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.clearWrapCache()V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.componentHidden(Ljava/awt/event/ComponentEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.componentMoved(Ljava/awt/event/ComponentEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.componentResized(Ljava/awt/event/ComponentEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.componentShown(Ljava/awt/event/ComponentEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.configChanged(Ljava/lang/String;Ljava/lang/String;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.doHighlight(IILjava/awt/font/TextLayout;Ljava/awt/Graphics2D;FF)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getAttributeValueAtPoint(Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;)Ljava/lang/Object;
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getClickType(Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;)Lcom/dmdirc/addons/ui_swing/textpane/ClickType;
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getFirstVisibleLine()I
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getHitPosition(IIII)I
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getLastVisibleLine()I
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getNumWrappedLines(Ljava/awt/font/LineBreakMeasurer;IIF)I
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getScrollBarPosition()I
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getSelectedRange()Lcom/dmdirc/addons/ui_swing/textpane/LinePosition;
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getSurroundingWordEnd(Ljava/lang/String;I)I
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getSurroundingWordIndexes(Ljava/lang/String;I)[I
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getSurroundingWordStart(Ljava/lang/String;I)I
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.highlightEvent(Lcom/dmdirc/addons/ui_swing/textpane/MouseEventType;Ljava/awt/event/MouseEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseClicked(Ljava/awt/event/MouseEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseDragged(Ljava/awt/event/MouseEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseEntered(Ljava/awt/event/MouseEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseExited(Ljava/awt/event/MouseEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseMoved(Ljava/awt/event/MouseEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mousePressed(Ljava/awt/event/MouseEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseReleased(Ljava/awt/event/MouseEvent;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.paintComponent(Ljava/awt/Graphics;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.setScrollBarPosition(I)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.setSelectedRange(Lcom/dmdirc/addons/ui_swing/textpane/LinePosition;)V
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): new Cursor(TextPaneCanvas__static_init#1) num objects
    //#new obj(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): new Cursor(TextPaneCanvas__static_init#1)
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): HAND_CURSOR == &new Cursor(TextPaneCanvas__static_init#1)
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas] == &__Dispatch_Table
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.checkForLink()V == &checkForLink
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.clearSelection()V == &clearSelection
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.clearWrapCache()V == &clearWrapCache
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.componentHidden(Ljava/awt/event/ComponentEvent;)V == &componentHidden
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.componentMoved(Ljava/awt/event/ComponentEvent;)V == &componentMoved
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.componentResized(Ljava/awt/event/ComponentEvent;)V == &componentResized
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.componentShown(Ljava/awt/event/ComponentEvent;)V == &componentShown
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.configChanged(Ljava/lang/String;Ljava/lang/String;)V == &configChanged
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.doHighlight(IILjava/awt/font/TextLayout;Ljava/awt/Graphics2D;FF)V == &doHighlight
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getAttributeValueAtPoint(Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;)Ljava/lang/Object; == &getAttributeValueAtPoint
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo; == &getClickPosition
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getClickType(Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;)Lcom/dmdirc/addons/ui_swing/textpane/ClickType; == &getClickType
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getFirstVisibleLine()I == &getFirstVisibleLine
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getHitPosition(IIII)I == &getHitPosition
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getLastVisibleLine()I == &getLastVisibleLine
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getNumWrappedLines(Ljava/awt/font/LineBreakMeasurer;IIF)I == &getNumWrappedLines
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getScrollBarPosition()I == &getScrollBarPosition
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getSelectedRange()Lcom/dmdirc/addons/ui_swing/textpane/LinePosition; == &getSelectedRange
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getSurroundingWordEnd(Ljava/lang/String;I)I == &getSurroundingWordEnd
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getSurroundingWordIndexes(Ljava/lang/String;I)[I == &getSurroundingWordIndexes
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.getSurroundingWordStart(Ljava/lang/String;I)I == &getSurroundingWordStart
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.highlightEvent(Lcom/dmdirc/addons/ui_swing/textpane/MouseEventType;Ljava/awt/event/MouseEvent;)V == &highlightEvent
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseClicked(Ljava/awt/event/MouseEvent;)V == &mouseClicked
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseDragged(Ljava/awt/event/MouseEvent;)V == &mouseDragged
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseEntered(Ljava/awt/event/MouseEvent;)V == &mouseEntered
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseExited(Ljava/awt/event/MouseEvent;)V == &mouseExited
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseMoved(Ljava/awt/event/MouseEvent;)V == &mouseMoved
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mousePressed(Ljava/awt/event/MouseEvent;)V == &mousePressed
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.mouseReleased(Ljava/awt/event/MouseEvent;)V == &mouseReleased
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.paintComponent(Ljava/awt/Graphics;)V == &paintComponent
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.setScrollBarPosition(I)V == &setScrollBarPosition
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): __Dispatch_Table.setSelectedRange(Lcom/dmdirc/addons/ui_swing/textpane/LinePosition;)V == &setSelectedRange
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init): new Cursor(TextPaneCanvas__static_init#1) num objects == 1
    //#TextPaneCanvas.java:63: end of method: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas__static_init
    /** IRCDocument. */
    private final IRCDocument document;
    /** parent textpane. */
    private final TextPane textPane;
    /** Position -> TextLayout. */
    private final Map<Rectangle, TextLayout> positions;
    /** TextLayout -> Line numbers. */
    private final Map<TextLayout, LineInfo> textLayouts;
    /** position of the scrollbar. */
    private int scrollBarPosition;
    /** Selection. */
    private LinePosition selection;
    /** First visible line. */
    private int firstVisibleLine;
    /** Last visible line. */
    private int lastVisibleLine;
    /** Line wrapping cache. */
    private final Map<Integer, Integer> lineWrap;

    /**
     * Creates a new text pane canvas.
     *
     * @param parent parent text pane for the canvas
     * @param document IRCDocument to be displayed
     */
    public TextPaneCanvas(final TextPane parent, final IRCDocument document) {
        super();
    //#TextPaneCanvas.java:90: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)
    //#input(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): document
    //#input(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): parent
    //#input(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#1) num objects
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#2) num objects
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#3) num objects
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new LinePosition(TextPaneCanvas#4) num objects
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.selection.__Tag
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.selection.endLine
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.selection.endPos
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.selection.startLine
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.selection.startPos
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.document
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.lineWrap
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.positions
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.scrollBarPosition
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.selection
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.textLayouts
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.textPane
    //#new obj(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#1)
    //#new obj(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#2)
    //#new obj(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#3)
    //#new obj(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new LinePosition(TextPaneCanvas#4)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.document == document
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): init'ed(this.document)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.lineWrap == &new HashMap(TextPaneCanvas#3)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.positions == &new HashMap(TextPaneCanvas#2)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): init'ed(this.scrollBarPosition)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.selection == &new LinePosition(TextPaneCanvas#4)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.textLayouts == &new HashMap(TextPaneCanvas#1)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.textPane == parent
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): init'ed(this.textPane)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#1) num objects == 1
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#2) num objects == 1
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new HashMap(TextPaneCanvas#3) num objects == 1
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): new LinePosition(TextPaneCanvas#4) num objects == 1
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): init'ed(this.selection.endLine)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): init'ed(this.selection.endPos)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): init'ed(this.selection.startLine)
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)): init'ed(this.selection.startPos)
        this.document = document;
        scrollBarPosition = 0;
        textPane = parent;
        setDoubleBuffered(true);
    //#TextPaneCanvas.java:94: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setDoubleBuffered(bool)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setDoubleBuffered(bool)
        setOpaque(true);
    //#TextPaneCanvas.java:95: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setOpaque(bool)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setOpaque(bool)
        textLayouts = new HashMap<TextLayout, LineInfo>();
        positions = new HashMap<Rectangle, TextLayout>();
        lineWrap = new HashMap<Integer, Integer>();
        selection = new LinePosition(-1, -1, -1, -1);
        addMouseListener(this);
    //#TextPaneCanvas.java:100: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:addMouseListener(MouseListener)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:addMouseListener(MouseListener)
        addMouseMotionListener(this);
    //#TextPaneCanvas.java:101: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:addMouseMotionListener(MouseMotionListener)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:addMouseMotionListener(MouseMotionListener)
        addComponentListener(this);
    //#TextPaneCanvas.java:102: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:addComponentListener(ComponentListener)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:addComponentListener(ComponentListener)
    //TODO issue 2251
    //parent.getFrameContainer().getConfigManager().addChangeListener("ui", "textPaneFontSize", this);
    }
    //#TextPaneCanvas.java:105: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas(TextPane, IRCDocument)

    /**
     * Paints the text onto the canvas.
     *
     * @param graphics graphics object to draw onto
     */
    @Override
    public void paintComponent(final Graphics graphics) {
        final Graphics2D g = (Graphics2D) graphics;
    //#TextPaneCanvas.java:114: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.paintComponent(Graphics)
    //#input(void paintComponent(Graphics)): "."._tainted
    //#input(void paintComponent(Graphics)): "Config option not found: "._tainted
    //#input(void paintComponent(Graphics)): "Unable to insert styled string: "._tainted
    //#input(void paintComponent(Graphics)): "textPaneFontName"._tainted
    //#input(void paintComponent(Graphics)): "ui"._tainted
    //#input(void paintComponent(Graphics)): HAND_CURSOR
    //#input(void paintComponent(Graphics)): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#input(void paintComponent(Graphics)): __Descendant_Table[others]
    //#input(void paintComponent(Graphics)): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#input(void paintComponent(Graphics)): com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(void paintComponent(Graphics)): com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(void paintComponent(Graphics)): com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/Line]
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[others]
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getHeight()I
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getStyled()Ljava/text/AttributedString;
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getText()Ljava/lang/String;
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.logger.ErrorLevel.MEDIUM
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.BACKGROUND
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FAMILY
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FOREGROUND
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE_OBLIQUE
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.SIZE
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE_ON
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT_BOLD
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$CharacterConstants.Underline
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Background
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Foreground
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Bold
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Family
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Italic
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getEndLine()I
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getEndPos()I
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartLine()I
    //#input(void paintComponent(Graphics)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartPos()I
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigManager.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigManager.__Descendant_Table[others]
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigManager.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOptionString(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigManager.stats
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigSource]
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigSource.__Descendant_Table[others]
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigSource.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void paintComponent(Graphics)): com/dmdirc/config/ConfigSource.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void paintComponent(Graphics)): com/dmdirc/config/Identity.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(void paintComponent(Graphics)): com/dmdirc/config/Identity.__Descendant_Table[others]
    //#input(void paintComponent(Graphics)): com/dmdirc/config/Identity.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void paintComponent(Graphics)): com/dmdirc/config/Identity.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void paintComponent(Graphics)): graphics
    //#input(void paintComponent(Graphics)): java.awt.font.TextAttribute.BACKGROUND
    //#input(void paintComponent(Graphics)): java.awt.font.TextAttribute.FOREGROUND
    //#input(void paintComponent(Graphics)): this
    //#input(void paintComponent(Graphics)): this.__Tag
    //#input(void paintComponent(Graphics)): this.document
    //#input(void paintComponent(Graphics)): this.document.cachedLines
    //#input(void paintComponent(Graphics)): this.document.cachedStrings
    //#input(void paintComponent(Graphics)): this.document.lines
    //#input(void paintComponent(Graphics)): this.lineWrap
    //#input(void paintComponent(Graphics)): this.positions
    //#input(void paintComponent(Graphics)): this.scrollBarPosition
    //#input(void paintComponent(Graphics)): this.selection
    //#input(void paintComponent(Graphics)): this.selection.__Tag
    //#input(void paintComponent(Graphics)): this.selection.endLine
    //#input(void paintComponent(Graphics)): this.selection.endPos
    //#input(void paintComponent(Graphics)): this.selection.startLine
    //#input(void paintComponent(Graphics)): this.selection.startPos
    //#input(void paintComponent(Graphics)): this.textLayouts
    //#input(void paintComponent(Graphics)): this.textPane
    //#output(void paintComponent(Graphics)): this.firstVisibleLine
    //#output(void paintComponent(Graphics)): this.lastVisibleLine
    //#pre[1] (void paintComponent(Graphics)): graphics != null
    //#pre[6] (void paintComponent(Graphics)): this.document != null
    //#pre[9] (void paintComponent(Graphics)): this.document.lines != null
    //#pre[11] (void paintComponent(Graphics)): this.positions != null
    //#pre[12] (void paintComponent(Graphics)): init'ed(this.scrollBarPosition)
    //#pre[19] (void paintComponent(Graphics)): this.textLayouts != null
    //#pre[20] (void paintComponent(Graphics)): this.textPane != null
    //#pre[5] (void paintComponent(Graphics)): (soft) this.__Tag == com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas
    //#pre[7] (void paintComponent(Graphics)): (soft) this.document.cachedLines != null
    //#pre[8] (void paintComponent(Graphics)): (soft) this.document.cachedStrings != null
    //#pre[10] (void paintComponent(Graphics)): (soft) this.lineWrap != null
    //#pre[13] (void paintComponent(Graphics)): (soft) this.selection != null
    //#pre[14] (void paintComponent(Graphics)): (soft) this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[15] (void paintComponent(Graphics)): (soft) init'ed(this.selection.endLine)
    //#pre[16] (void paintComponent(Graphics)): (soft) init'ed(this.selection.endPos)
    //#pre[17] (void paintComponent(Graphics)): (soft) init'ed(this.selection.startLine)
    //#pre[18] (void paintComponent(Graphics)): (soft) init'ed(this.selection.startPos)
    //#presumption(void paintComponent(Graphics)): (int) ((float) (com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getWidth(...)@122 - 6)) in {-2_147_483_654..4_294_967_289}
    //#presumption(void paintComponent(Graphics)): (int) ((float) (getLine(...).lineHeight)*21_617_278_211_378_381/18_014_398_509_481_984) in {-2_147_483_648..4_294_967_295}
    //#presumption(void paintComponent(Graphics)): java.awt.Toolkit:getDefaultToolkit(...)@116 != null
    //#presumption(void paintComponent(Graphics)): java.awt.font.LineBreakMeasurer:nextLayout(...)@191 != null
    //#presumption(void paintComponent(Graphics)): java.text.AttributedString:getIterator(...)@253 != null
    //#presumption(void paintComponent(Graphics)): java.util.List:size(...)@78 >= -2_147_483_647
    //#presumption(void paintComponent(Graphics)): java.util.Map:get(...)@174 != null
    //#post(void paintComponent(Graphics)): possibly_updated(this.firstVisibleLine)
    //#post(void paintComponent(Graphics)): possibly_updated(this.lastVisibleLine)
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.LineBreakMeasurer:getPosition
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.LineBreakMeasurer:nextLayout
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.LineBreakMeasurer:setPosition
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Map$Entry:getKey
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Rectangle:contains
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Point:getX
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Point:getY
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:getStyledLine
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.text.AttributedCharacterIterator:setIndex
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.text.AttributedCharacterIterator:getAttributes
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.String:instanceof
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.text.AttributedCharacterIterator:getBeginIndex
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.text.AttributedCharacterIterator:getEndIndex
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getMousePosition
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:getLine
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.ui.messages.Styliser:stipControlCodes
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Rectangle:getX
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getCursor
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Cursor:getDefaultCursor
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:getLineHeight
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.text.AttributedString
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPane:getBackground
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.text.AttributedString:addAttribute
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPane:getForeground
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.text.AttributedString:getIterator
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Graphics2D:getFontRenderContext
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.TextLayout
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.TextLayout:getLogicalHighlightShape
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Shape:getBounds
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Graphics2D:translate
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.font.TextLayout:draw
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.List:get
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.UIManager:getFont
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Font:getSize
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.util.RollingList:contains
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.util.RollingList:getList
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.List:indexOf
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.util.RollingList:get
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.ui.messages.Styliser:getStyledString
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.StyledDocument:getParagraphElement
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.Element:getDocument
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.Document:getLength
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.Document:getText
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.BadLocationException:getMessage
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.logger.Logger:userError
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:hasOption
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Map:containsKey
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.Integer:intValue
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Map:put
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:getOption
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.lang.IllegalArgumentException
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.util.ConfigFile:getKeyDomain
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.util.ConfigFile:isKeyDomain
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Font:getName
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Font
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.awt.Font:getFamily
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.Element:getElementCount
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.Element:getElement
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.Element:getAttributes
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.AttributeSet:getAttributeNames
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Enumeration:hasMoreElements
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.Enumeration:nextElement
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.AttributeSet:getAttribute
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.Element:getStartOffset
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:javax.swing.text.Element:getEndOffset
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:com.dmdirc.util.RollingList:add
    //#unanalyzed(void paintComponent(Graphics)): Effects-of-calling:java.util.List:size
    //#test_vector(void paintComponent(Graphics)): java.awt.Toolkit:getDesktopProperty(...)@116: Addr_Set{null}, Inverse{null}
    //#test_vector(void paintComponent(Graphics)): java.awt.font.TextLayout:isLeftToRight(...)@201: {0}, {1}
    //#test_vector(void paintComponent(Graphics)): java.util.List:size(...)@78: {0}, {-2_147_483_648..-1, 1..4_294_967_295}
    //#test_vector(void paintComponent(Graphics)): java.util.Map:containsKey(...)@172: {0}, {1}

        final Map desktopHints = (Map) Toolkit.getDefaultToolkit().
                getDesktopProperty("awt.font.desktophints");
        if (desktopHints != null) {
            g.addRenderingHints(desktopHints);
        }

        final float formatWidth = getWidth() - 6;
    //#TextPaneCanvas.java:122: Warning: method not available - call not analyzed
    //#    call on int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getWidth()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void paintComponent(Graphics)
    //#    unanalyzed callee: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getWidth()
        final float formatHeight = getHeight();
    //#TextPaneCanvas.java:123: Warning: method not available - call not analyzed
    //#    call on int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getHeight()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void paintComponent(Graphics)
    //#    unanalyzed callee: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getHeight()
        float drawPosY = formatHeight;
        int startLine = scrollBarPosition;

        int paragraphStart;
        int paragraphEnd;
        LineBreakMeasurer lineMeasurer;

        g.setColor(textPane.getBackground());
    //#TextPaneCanvas.java:131: Warning: method not available - call not analyzed
    //#    call on Color com.dmdirc.addons.ui_swing.textpane.TextPane:getBackground()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void paintComponent(Graphics)
    //#    unanalyzed callee: Color com.dmdirc.addons.ui_swing.textpane.TextPane:getBackground()
        g.fill(g.getClipBounds());

        textLayouts.clear();
        positions.clear();

        //check theres something to draw and theres some space to draw in
        if (document.getNumLines() == 0 || formatWidth < 1) {
            setCursor(Cursor.getDefaultCursor());
    //#TextPaneCanvas.java:139: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void paintComponent(Graphics)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
            return;
        }

        // Check the start line is in range
        if (startLine >= document.getNumLines()) {
            startLine = document.getNumLines() - 1;
        }

        if (startLine <= 0) {
            startLine = 0;
        }

        //sets the last visible line
        lastVisibleLine = startLine;
        firstVisibleLine = startLine;

        // Iterate through the lines
        for (int i = startLine; i >= 0; i--) {
            float drawPosX;
            final AttributedCharacterIterator iterator = document.getStyledLine(
                    i);
            int lineHeight = document.getLineHeight(i);
            lineHeight += lineHeight * 0.2;
            paragraphStart = iterator.getBeginIndex();
            paragraphEnd = iterator.getEndIndex();
            lineMeasurer = new LineBreakMeasurer(iterator,
                    g.getFontRenderContext());
            lineMeasurer.setPosition(paragraphStart);

            final int wrappedLine;

            //do we have the line wrapping in the cache?
            if (lineWrap.containsKey(i)) {
                //use it
                wrappedLine = lineWrap.get(i);
            } else {
                //get it and populate the cache
                wrappedLine = getNumWrappedLines(lineMeasurer,
                        paragraphStart, paragraphEnd,
                        formatWidth);
                lineWrap.put(i, wrappedLine);
            }

            if (wrappedLine > 1) {
                drawPosY -= lineHeight * wrappedLine;
            }

            int j = 0;
            int chars = 0;
            // Loop through each wrapped line
            while (lineMeasurer.getPosition() < paragraphEnd) {
                final TextLayout layout = lineMeasurer.nextLayout(formatWidth);

                // Calculate the Y offset
                if (wrappedLine == 1) {
                    drawPosY -= lineHeight;
                } else if (j != 0) {
                    drawPosY += lineHeight;
                }

                // Calculate the initial X position
                if (layout.isLeftToRight()) {
                    drawPosX = 3;
                } else {
                    drawPosX = formatWidth - layout.getAdvance();
                }

                // Check if the target is in range
                if (drawPosY >= 0 || drawPosY <= formatHeight) {

                    g.setColor(textPane.getForeground());
    //#TextPaneCanvas.java:210: Warning: method not available - call not analyzed
    //#    call on Color com.dmdirc.addons.ui_swing.textpane.TextPane:getForeground()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void paintComponent(Graphics)
    //#    unanalyzed callee: Color com.dmdirc.addons.ui_swing.textpane.TextPane:getForeground()

                    layout.draw(g, drawPosX, drawPosY + lineHeight / 2f);
                    doHighlight(i, chars, layout, g, drawPosY, drawPosX);
                    firstVisibleLine = i;
                    textLayouts.put(layout, new LineInfo(i, j));
                    positions.put(new Rectangle(0, (int) drawPosY,
    //#TextPaneCanvas.java:216: ?overflow
    //#    (int) (drawPosY) in {-2_147_483_648..4_294_967_295}
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void paintComponent(Graphics)
    //#    basic block: bb_28
    //#    assertion: (int) (drawPosY) in {-2_147_483_648..4_294_967_295}
    //#    VN: (int) (drawPosY)
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {-Inf..-2_147_483_649, 4_294_967_296..+Inf}
    //#    Attribs:  Int  Bad < Exp  Bad > Exp
                            (int) formatWidth + 6,
                            lineHeight), layout);
                }

                j++;
    //#TextPaneCanvas.java:221: ?overflow
    //#    j in {-2_147_483_649..4_294_967_294}
    //#    severity: LOW
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void paintComponent(Graphics)
    //#    basic block: bb_29
    //#    assertion: j in {-2_147_483_649..4_294_967_294}
    //#    VN: j + 1
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {4_294_967_296}
    //#    Attribs:  Int  Bad singleton  Bad > Exp
                chars += layout.getCharacterCount();
    //#TextPaneCanvas.java:222: ?overflow
    //#    chars + java/awt/font/TextLayout:getCharacterCount(...) in {-2_147_483_648..4_294_967_295}
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void paintComponent(Graphics)
    //#    basic block: bb_29
    //#    assertion: chars + java/awt/font/TextLayout:getCharacterCount(...) in {-2_147_483_648..4_294_967_295}
    //#    VN: java.awt.font.TextLayout:getCharacterCount(...)@222 + chars
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {-4_294_967_296..-2_147_483_649, 4_294_967_296..8_589_934_590}
    //#    Attribs:  Int  Bad < Exp  Bad > Exp
            }
            if (j > 1) {
                drawPosY -= lineHeight * (wrappedLine - 1);
            }
            if (drawPosY <= 0) {
                break;
            }
        }
        checkForLink();
    }
    //#TextPaneCanvas.java:232: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.paintComponent(Graphics)

    /**
     * Returns the number of timesa line will wrap.
     *
     * @param lineMeasurer LineBreakMeasurer to work out wrapping for
     * @param paragraphStart Start index of the paragraph
     * @param paragraphEnd End index of the paragraph
     * @param formatWidth Width to wrap at
     *
     * @return Number of times the line wraps
     */
    private int getNumWrappedLines(final LineBreakMeasurer lineMeasurer,
            final int paragraphStart,
            final int paragraphEnd,
            final float formatWidth) {
        int wrappedLine = 0;
    //#TextPaneCanvas.java:248: method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getNumWrappedLines(LineBreakMeasurer, int, int, float)
    //#input(int getNumWrappedLines(LineBreakMeasurer, int, int, float)): formatWidth
    //#input(int getNumWrappedLines(LineBreakMeasurer, int, int, float)): lineMeasurer
    //#input(int getNumWrappedLines(LineBreakMeasurer, int, int, float)): paragraphEnd
    //#input(int getNumWrappedLines(LineBreakMeasurer, int, int, float)): paragraphStart
    //#output(int getNumWrappedLines(LineBreakMeasurer, int, int, float)): return_value
    //#pre[2] (int getNumWrappedLines(LineBreakMeasurer, int, int, float)): lineMeasurer != null
    //#post(int getNumWrappedLines(LineBreakMeasurer, int, int, float)): return_value >= 0

        while (lineMeasurer.getPosition() < paragraphEnd) {
            lineMeasurer.nextLayout(formatWidth);

            wrappedLine++;
    //#TextPaneCanvas.java:253: ?overflow
    //#    wrappedLine in {-2_147_483_649..4_294_967_294}
    //#    severity: LOW
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: int getNumWrappedLines(LineBreakMeasurer, int, int, float)
    //#    basic block: bb_3
    //#    assertion: wrappedLine in {-2_147_483_649..4_294_967_294}
    //#    VN: wrappedLine + 1
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {4_294_967_296}
    //#    Attribs:  Int  Bad singleton  Bad > Exp
        }

        lineMeasurer.setPosition(paragraphStart);

        return wrappedLine;
    //#TextPaneCanvas.java:258: end of method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getNumWrappedLines(LineBreakMeasurer, int, int, float)
    }

    /**
     * Redraws the text that has been highlighted.
     *
     * @param line Line number
     * @param chars Number of characters so far in the line
     * @param layout Current line textlayout
     * @param g Graphics surface to draw highlight on
     * @param drawPosY current y location of the line
     * @param drawPosX current x location of the line
     */
    private void doHighlight(final int line, final int chars,
            final TextLayout layout, final Graphics2D g,
            final float drawPosY, final float drawPosX) {
        int startLine;
        int startChar;
        int endLine;
        int endChar;

        if (selection.getStartLine() > selection.getEndLine()) {
    //#TextPaneCanvas.java:279: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.doHighlight(int, int, TextLayout, Graphics2D, float, float)
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): "."._tainted
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): "Config option not found: "._tainted
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): "Unable to insert styled string: "._tainted
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): "textPaneFontName"._tainted
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): "ui"._tainted
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): chars
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/Line]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[others]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getHeight()I
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getStyled()Ljava/text/AttributedString;
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getText()Ljava/lang/String;
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.logger.ErrorLevel.MEDIUM
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.BACKGROUND
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FAMILY
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FOREGROUND
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE_OBLIQUE
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.SIZE
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE_ON
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT_BOLD
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$CharacterConstants.Underline
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Background
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Foreground
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Bold
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Family
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Italic
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getEndLine()I
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getEndPos()I
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartLine()I
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartPos()I
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigManager.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigManager.__Descendant_Table[others]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigManager.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOptionString(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigManager.stats
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigSource]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigSource.__Descendant_Table[others]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigSource.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/ConfigSource.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/Identity.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/Identity.__Descendant_Table[others]
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/Identity.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com/dmdirc/config/Identity.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): drawPosX
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): drawPosY
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): g
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): java.awt.font.TextAttribute.BACKGROUND
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): java.awt.font.TextAttribute.FOREGROUND
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): layout
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): line
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.document
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.document.cachedLines
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.document.cachedStrings
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.document.lines
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection.__Tag
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection.endLine
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection.endPos
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection.startLine
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection.startPos
    //#input(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.textPane
    //#pre[15] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection != null
    //#pre[16] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[17] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): init'ed(this.selection.endLine)
    //#pre[21] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): init'ed(this.selection.endPos)
    //#pre[23] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): init'ed(this.selection.startLine)
    //#pre[24] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): init'ed(this.selection.startPos)
    //#pre[7] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (soft) g != null
    //#pre[8] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (soft) layout != null
    //#pre[11] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (soft) this.document != null
    //#pre[12] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (soft) this.document.cachedLines != null
    //#pre[13] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (soft) this.document.cachedStrings != null
    //#pre[14] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (soft) this.document.lines != null
    //#pre[25] (void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (soft) this.textPane != null
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (int) ((float) (getLine(...).lineHeight)*21_617_278_211_378_381/18_014_398_509_481_984) in {-2_147_483_648..4_294_967_295}
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (int) ((float) (getLineHeight(...)@333)*21_617_278_211_378_381/18_014_398_509_481_984) in range
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (int) (drawPosY + (float) ((int) ((float) (getLine(...).lineHeight)*21_617_278_211_378_381/18_014_398_509_481_984))/2) in {-2_147_483_648..4_294_967_295}
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): (int) (drawPosY + (float) ((int) ((float) (getLineHeight(...)@333)*21_617_278_211_378_381/18_014_398_509_481_984))/2) in range
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): chars + java.awt.font.TextLayout:getCharacterCount(...)@314 in {-2_147_483_648..4_294_967_295}
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): com.dmdirc.ui.messages.Styliser:stipControlCodes(...)@107 != null
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): getLine(...).lineParts != null
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): getLine(...).lineParts.length <= 4_294_967_295
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): java.awt.Shape:getBounds(...)@352 != null
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): java.awt.Shape:getBounds(...)@358 != null
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): init'ed(java.awt.font.TextAttribute.BACKGROUND)
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): init'ed(java.awt.font.TextAttribute.FOREGROUND)
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): java.awt.font.TextLayout:getLogicalHighlightShape(...)@346 != null
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): java.util.List:get(...)@89 != null
    //#presumption(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): java.util.List:get(...)@89.__Tag == com/dmdirc/addons/ui_swing/textpane/Line
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.ui.messages.Styliser:stipControlCodes
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.List:get
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:getStyledLine
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.UIManager:getFont
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.awt.Font:getSize
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.util.RollingList:contains
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.util.RollingList:getList
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.List:indexOf
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.util.RollingList:get
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.ui.messages.Styliser:getStyledString
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.StyledDocument:getParagraphElement
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.Element:getDocument
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.Document:getLength
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.Document:getText
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.text.AttributedString
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.BadLocationException:getMessage
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.logger.Logger:userError
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:hasOption
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.Map:containsKey
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.lang.Integer:intValue
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.Map:put
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:getOption
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.lang.IllegalArgumentException
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.util.ConfigFile:getKeyDomain
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.util.ConfigFile:isKeyDomain
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.awt.Font:getName
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.text.AttributedString:getIterator
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.text.AttributedCharacterIterator:getEndIndex
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.awt.Font
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.text.AttributedString:addAttribute
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.awt.Font:getFamily
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.Element:getElementCount
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.Element:getElement
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.Element:getAttributes
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.AttributeSet:getAttributeNames
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.Enumeration:hasMoreElements
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:java.util.Enumeration:nextElement
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.AttributeSet:getAttribute
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.Element:getStartOffset
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:javax.swing.text.Element:getEndOffset
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:com.dmdirc.util.RollingList:add
    //#unanalyzed(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): Effects-of-calling:getLineHeight
    //#test_vector(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection.endLine - this.selection.startLine: {1..6_442_450_943}, {-6_442_450_943..-1}, {0}
    //#test_vector(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): this.selection.endPos - this.selection.startPos: {0..6_442_450_943}, {-6_442_450_943..-1}
    //#test_vector(void doHighlight(int, int, TextLayout, Graphics2D, float, float)): java.lang.String:isEmpty(...)@327: {0}, {1}
            // Swap both
            startLine = selection.getEndLine();
            startChar = selection.getEndPos();
            endLine = selection.getStartLine();
            endChar = selection.getStartPos();
        } else if (selection.getStartLine() == selection.getEndLine() &&
                selection.getStartPos() > selection.getEndPos()) {
            // Just swap the chars
            startLine = selection.getStartLine();
            startChar = selection.getEndPos();
            endLine = selection.getEndLine();
            endChar = selection.getStartPos();
        } else {
            // Swap nothing
            startLine = selection.getStartLine();
            startChar = selection.getStartPos();
            endLine = selection.getEndLine();
            endChar = selection.getEndPos();
        }

        //Does this line need highlighting?
        if (startLine <= line && endLine >= line) {
            int firstChar;
            int lastChar;

            // Determine the first char we care about
            if (startLine < line || startChar < chars) {
                firstChar = chars;
            } else {
                firstChar = startChar;
            }

            // ... And the last
            if (endLine > line || endChar > chars + layout.getCharacterCount()) {
                lastChar = chars + layout.getCharacterCount();
            } else {
                lastChar = endChar;
            }

            // If the selection includes the chars we're showing
            if (lastChar > chars && firstChar < chars +
                    layout.getCharacterCount()) {
                String text = document.getLine(line).getText();
                if (firstChar >= 0 && text.length() > lastChar) {
                    text = text.substring(firstChar, lastChar);
                }

                if (text.isEmpty()) {
                    return;
                }

                final AttributedCharacterIterator iterator = document.
                        getStyledLine(line);
                int lineHeight = document.getLineHeight(line);
                lineHeight += lineHeight * 0.2;
                final AttributedString as = new AttributedString(iterator,
                        firstChar,
                        lastChar);
                final int trans = (int) (lineHeight / 2f + drawPosY);

                as.addAttribute(TextAttribute.FOREGROUND,
    //#TextPaneCanvas.java:340: Warning: method not available - call not analyzed
    //#    call on Color com.dmdirc.addons.ui_swing.textpane.TextPane:getBackground()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void doHighlight(int, int, TextLayout, Graphics2D, float, float)
    //#    unanalyzed callee: Color com.dmdirc.addons.ui_swing.textpane.TextPane:getBackground()
                        textPane.getBackground());
                as.addAttribute(TextAttribute.BACKGROUND,
    //#TextPaneCanvas.java:342: Warning: method not available - call not analyzed
    //#    call on Color com.dmdirc.addons.ui_swing.textpane.TextPane:getForeground()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void doHighlight(int, int, TextLayout, Graphics2D, float, float)
    //#    unanalyzed callee: Color com.dmdirc.addons.ui_swing.textpane.TextPane:getForeground()
                        textPane.getForeground());
                final TextLayout newLayout = new TextLayout(as.getIterator(),
                        g.getFontRenderContext());
                final Shape shape = layout.getLogicalHighlightShape(firstChar -
    //#TextPaneCanvas.java:346: ?overflow
    //#    lastChar - chars in {-2_147_483_648..4_294_967_295}
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void doHighlight(int, int, TextLayout, Graphics2D, float, float)
    //#    basic block: bb_24
    //#    assertion: lastChar - chars in {-2_147_483_648..4_294_967_295}
    //#    VN: lastChar - chars
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {4_294_967_296..6_442_450_943}
    //#    Attribs:  Int  Bad > Exp
                        chars,
                        lastChar -
                        chars);

                if (firstChar != 0) {
                    g.translate(shape.getBounds().getX(), 0);
                }

                newLayout.draw(g, drawPosX, trans);

                if (firstChar != 0) {
                    g.translate(-1 * shape.getBounds().getX(), 0);
                }
            }
        }
    }
    //#TextPaneCanvas.java:362: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.doHighlight(int, int, TextLayout, Graphics2D, float, float)

    /**
     * sets the position of the scroll bar, and repaints if required.
     * @param position scroll bar position
     */
    protected void setScrollBarPosition(final int position) {
        if (scrollBarPosition != position) {
    //#TextPaneCanvas.java:369: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.setScrollBarPosition(int)
    //#input(void setScrollBarPosition(int)): position
    //#input(void setScrollBarPosition(int)): this
    //#input(void setScrollBarPosition(int)): this.scrollBarPosition
    //#input(void setScrollBarPosition(int)): this.textPane
    //#output(void setScrollBarPosition(int)): this.scrollBarPosition
    //#pre[1] (void setScrollBarPosition(int)): init'ed(this.scrollBarPosition)
    //#pre[5] (void setScrollBarPosition(int)): (soft) this.textPane != null
    //#post(void setScrollBarPosition(int)): this.scrollBarPosition == One-of{old this.scrollBarPosition, position}
    //#post(void setScrollBarPosition(int)): init'ed(this.scrollBarPosition)
    //#test_vector(void setScrollBarPosition(int)): this.scrollBarPosition - position: {0}, {-6_442_450_943..-1, 1..6_442_450_943}
    //#test_vector(void setScrollBarPosition(int)): com.dmdirc.addons.ui_swing.textpane.TextPane:isVisible(...)@371: {0}, {1}
            scrollBarPosition = position;
            if (textPane.isVisible()) {
    //#TextPaneCanvas.java:371: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.addons.ui_swing.textpane.TextPane:isVisible()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void setScrollBarPosition(int)
    //#    unanalyzed callee: bool com.dmdirc.addons.ui_swing.textpane.TextPane:isVisible()
                repaint();
    //#TextPaneCanvas.java:372: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void setScrollBarPosition(int)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
            }
        }
    }
    //#TextPaneCanvas.java:375: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.setScrollBarPosition(int)

    /**
     * Returns the current scroll bar position.
     * 
     * @return Scroll bar position
     */
    protected int getScrollBarPosition() {
        return scrollBarPosition;
    //#TextPaneCanvas.java:383: method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getScrollBarPosition()
    //#input(int getScrollBarPosition()): this
    //#input(int getScrollBarPosition()): this.scrollBarPosition
    //#output(int getScrollBarPosition()): return_value
    //#pre[2] (int getScrollBarPosition()): init'ed(this.scrollBarPosition)
    //#post(int getScrollBarPosition()): return_value == this.scrollBarPosition
    //#post(int getScrollBarPosition()): init'ed(return_value)
    //#TextPaneCanvas.java:383: end of method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getScrollBarPosition()
    }

    /** 
     * {@inheritDoc}
     * 
     * @param e Mouse event
     */
    @Override
    public void mouseClicked(final MouseEvent e) {
        String clickedText = "";
    //#TextPaneCanvas.java:393: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseClicked(MouseEvent)
    //#TextPaneCanvas.java:393: Warning: unused assignment
    //#    Unused assignment into clickedText
    //#    severity: LOW
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void mouseClicked(MouseEvent)
    //#input(void mouseClicked(MouseEvent)): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#input(void mouseClicked(MouseEvent)): __Descendant_Table[others]
    //#input(void mouseClicked(MouseEvent)): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#input(void mouseClicked(MouseEvent)): __Dispatch_Table.getSurroundingWordIndexes(Ljava/lang/String;I)[I
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/Line]
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[others]
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getText()Ljava/lang/String;
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndLine(I)V
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndPos(I)V
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartLine(I)V
    //#input(void mouseClicked(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartPos(I)V
    //#input(void mouseClicked(MouseEvent)): e
    //#input(void mouseClicked(MouseEvent)): this
    //#input(void mouseClicked(MouseEvent)): this.__Tag
    //#input(void mouseClicked(MouseEvent)): this.document
    //#input(void mouseClicked(MouseEvent)): this.document.lines
    //#input(void mouseClicked(MouseEvent)): this.positions
    //#input(void mouseClicked(MouseEvent)): this.selection
    //#input(void mouseClicked(MouseEvent)): this.selection.__Tag
    //#input(void mouseClicked(MouseEvent)): this.textLayouts
    //#input(void mouseClicked(MouseEvent)): this.textPane
    //#output(void mouseClicked(MouseEvent)): this.selection.endLine
    //#output(void mouseClicked(MouseEvent)): this.selection.endPos
    //#output(void mouseClicked(MouseEvent)): this.selection.startLine
    //#output(void mouseClicked(MouseEvent)): this.selection.startPos
    //#pre[1] (void mouseClicked(MouseEvent)): e != null
    //#pre[7] (void mouseClicked(MouseEvent)): this.__Tag == com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas
    //#pre[14] (void mouseClicked(MouseEvent)): this.textPane != null
    //#pre[8] (void mouseClicked(MouseEvent)): (soft) this.document != null
    //#pre[9] (void mouseClicked(MouseEvent)): (soft) this.document.lines != null
    //#pre[10] (void mouseClicked(MouseEvent)): (soft) this.positions != null
    //#pre[11] (void mouseClicked(MouseEvent)): (soft) this.selection != null
    //#pre[12] (void mouseClicked(MouseEvent)): (soft) this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[13] (void mouseClicked(MouseEvent)): (soft) this.textLayouts != null
    //#presumption(void mouseClicked(MouseEvent)): com.dmdirc.ui.messages.Styliser:stipControlCodes(...)@107 != null
    //#presumption(void mouseClicked(MouseEvent)): extent.length@406 >= 2
    //#presumption(void mouseClicked(MouseEvent)): getLine(...).lineParts != null
    //#presumption(void mouseClicked(MouseEvent)): getLine(...).lineParts.length <= 4_294_967_295
    //#presumption(void mouseClicked(MouseEvent)): getLine(...)@400 init'ed
    //#presumption(void mouseClicked(MouseEvent)): java.util.List:get(...)@89 != null
    //#presumption(void mouseClicked(MouseEvent)): java.util.List:get(...)@89.__Tag == com/dmdirc/addons/ui_swing/textpane/Line
    //#post(void mouseClicked(MouseEvent)): possibly_updated(this.selection.endLine)
    //#post(void mouseClicked(MouseEvent)): possibly_updated(this.selection.endPos)
    //#post(void mouseClicked(MouseEvent)): possibly_updated(this.selection.startLine)
    //#post(void mouseClicked(MouseEvent)): possibly_updated(this.selection.startPos)
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getKey
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.awt.Rectangle:contains
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.awt.Point:getX
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.awt.Point:getY
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:com.dmdirc.ui.messages.Styliser:stipControlCodes
    //#unanalyzed(void mouseClicked(MouseEvent)): Effects-of-calling:java.util.List:get
    //#test_vector(void mouseClicked(MouseEvent)): java.awt.event.MouseEvent:getClickCount(...)@413: {-2_147_483_648..1, 3..4_294_967_295}, {2}
    //#test_vector(void mouseClicked(MouseEvent)): java.awt.event.MouseEvent:getClickCount(...)@418: {-2_147_483_648..2, 4..4_294_967_295}, {3}
        final int start;
        final int end;

        final LineInfo lineInfo = getClickPosition(getMousePosition());
    //#TextPaneCanvas.java:397: Warning: method not available - call not analyzed
    //#    call on Point com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getMousePosition()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void mouseClicked(MouseEvent)
    //#    unanalyzed callee: Point com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getMousePosition()

        if (lineInfo.getLine() != -1) {
            clickedText = document.getLine(lineInfo.getLine()).getText();

            if (lineInfo.getIndex() == -1) {
                start = -1;
                end = -1;
            } else {
                final int[] extent =
                        getSurroundingWordIndexes(clickedText,
                        lineInfo.getIndex());
                start = extent[0];
                end = extent[1];
            }

            if (e.getClickCount() == 2) {
                selection.setStartLine(lineInfo.getLine());
                selection.setEndLine(lineInfo.getLine());
                selection.setStartPos(start);
                selection.setEndPos(end);
            } else if (e.getClickCount() == 3) {
                selection.setStartLine(lineInfo.getLine());
                selection.setEndLine(lineInfo.getLine());
                selection.setStartPos(0);
                selection.setEndPos(clickedText.length());
            }
        }

        e.setSource(textPane);
        textPane.dispatchEvent(e);
    //#TextPaneCanvas.java:427: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPane:dispatchEvent(AWTEvent)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void mouseClicked(MouseEvent)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPane:dispatchEvent(AWTEvent)
    }
    //#TextPaneCanvas.java:428: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseClicked(MouseEvent)

    /**
     * Returns the type of text this click represents.
     * 
     * @param lineInfo Line info of click.
     * 
     * @return Click type for specified position
     */
    public ClickType getClickType(final LineInfo lineInfo) {
        if (lineInfo.getLine() != -1) {
    //#TextPaneCanvas.java:438: method: ClickType com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getClickType(LineInfo)
    //#input(ClickType getClickType(LineInfo)): "."._tainted
    //#input(ClickType getClickType(LineInfo)): "Config option not found: "._tainted
    //#input(ClickType getClickType(LineInfo)): "Unable to insert styled string: "._tainted
    //#input(ClickType getClickType(LineInfo)): "textPaneFontName"._tainted
    //#input(ClickType getClickType(LineInfo)): "ui"._tainted
    //#input(ClickType getClickType(LineInfo)): com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(ClickType getClickType(LineInfo)): com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(ClickType getClickType(LineInfo)): com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/ClickType.CHANNEL
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/ClickType.HYPERLINK
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/ClickType.NICKNAME
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/ClickType.NORMAL
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/Line]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[others]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getStyled()Ljava/text/AttributedString;
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.logger.ErrorLevel.MEDIUM
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.BACKGROUND
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FAMILY
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FOREGROUND
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE_OBLIQUE
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.SIZE
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE_ON
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT_BOLD
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$CharacterConstants.Underline
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Background
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Foreground
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Bold
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Family
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Italic
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigManager.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigManager.__Descendant_Table[others]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigManager.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOptionString(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigManager.stats
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigSource]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigSource.__Descendant_Table[others]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigSource.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/ConfigSource.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/Identity.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/Identity.__Descendant_Table[others]
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/Identity.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(ClickType getClickType(LineInfo)): com/dmdirc/config/Identity.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(ClickType getClickType(LineInfo)): lineInfo
    //#input(ClickType getClickType(LineInfo)): lineInfo.index
    //#input(ClickType getClickType(LineInfo)): lineInfo.line
    //#input(ClickType getClickType(LineInfo)): this
    //#input(ClickType getClickType(LineInfo)): this.document
    //#input(ClickType getClickType(LineInfo)): this.document.cachedLines
    //#input(ClickType getClickType(LineInfo)): this.document.cachedStrings
    //#input(ClickType getClickType(LineInfo)): this.document.lines
    //#output(ClickType getClickType(LineInfo)): return_value
    //#pre[1] (ClickType getClickType(LineInfo)): lineInfo != null
    //#pre[3] (ClickType getClickType(LineInfo)): init'ed(lineInfo.line)
    //#pre[2] (ClickType getClickType(LineInfo)): (soft) init'ed(lineInfo.index)
    //#pre[5] (ClickType getClickType(LineInfo)): (soft) this.document != null
    //#pre[6] (ClickType getClickType(LineInfo)): (soft) this.document.cachedLines != null
    //#pre[7] (ClickType getClickType(LineInfo)): (soft) this.document.cachedStrings != null
    //#pre[8] (ClickType getClickType(LineInfo)): (soft) this.document.lines != null
    //#presumption(ClickType getClickType(LineInfo)): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL)
    //#presumption(ClickType getClickType(LineInfo)): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK)
    //#presumption(ClickType getClickType(LineInfo)): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME)
    //#presumption(ClickType getClickType(LineInfo)): getStyledLine(...)@439 init'ed
    //#presumption(ClickType getClickType(LineInfo)): java.text.AttributedCharacterIterator:getAttributes(...)@444 != null
    //#presumption(ClickType getClickType(LineInfo)): java.text.AttributedCharacterIterator:getAttributes(...)@449 != null
    //#presumption(ClickType getClickType(LineInfo)): java.text.AttributedCharacterIterator:getAttributes(...)@454 != null
    //#presumption(ClickType getClickType(LineInfo)): java.text.AttributedString:getIterator(...)@253 != null
    //#post(ClickType getClickType(LineInfo)): return_value in Addr_Set{&com.dmdirc.addons.ui_swing.textpane.ClickType__static_init.new ClickType(ClickType__static_init#3),&com.dmdirc.addons.ui_swing.textpane.ClickType__static_init.new ClickType(ClickType__static_init#2),&com.dmdirc.addons.ui_swing.textpane.ClickType__static_init.new ClickType(ClickType__static_init#1),&com.dmdirc.addons.ui_swing.textpane.ClickType__static_init.new ClickType(ClickType__static_init#4)}
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.List:get
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:getStyledLine
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.UIManager:getFont
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.awt.Font:getSize
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:com.dmdirc.util.RollingList:contains
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:com.dmdirc.util.RollingList:getList
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.List:indexOf
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:com.dmdirc.util.RollingList:get
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:com.dmdirc.ui.messages.Styliser:getStyledString
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.StyledDocument:getParagraphElement
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.Element:getDocument
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.Document:getLength
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.Document:getText
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.text.AttributedString
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.BadLocationException:getMessage
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:com.dmdirc.logger.Logger:userError
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:hasOption
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.Map:containsKey
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.lang.Integer:intValue
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.Map:put
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:getOption
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.lang.IllegalArgumentException
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:com.dmdirc.util.ConfigFile:getKeyDomain
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:com.dmdirc.util.ConfigFile:isKeyDomain
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.awt.Font:getName
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.text.AttributedString:getIterator
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.text.AttributedCharacterIterator:getEndIndex
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.awt.Font
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.text.AttributedString:addAttribute
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.awt.Font:getFamily
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.Element:getElementCount
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.Element:getElement
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.Element:getAttributes
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.AttributeSet:getAttributeNames
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.Enumeration:hasMoreElements
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:java.util.Enumeration:nextElement
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.AttributeSet:getAttribute
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.Element:getStartOffset
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:javax.swing.text.Element:getEndOffset
    //#unanalyzed(ClickType getClickType(LineInfo)): Effects-of-calling:com.dmdirc.util.RollingList:add
    //#test_vector(ClickType getClickType(LineInfo)): lineInfo.line: {-1}, {-2_147_483_648..-2, 0..4_294_967_295}
            final AttributedCharacterIterator iterator = document.getStyledLine(
                    lineInfo.getLine());
            final int index = lineInfo.getIndex();
            if (index >= iterator.getBeginIndex() && index <= iterator.getEndIndex()) {
                iterator.setIndex(lineInfo.getIndex());
                Object linkattr =
                        iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
                if (linkattr instanceof String) {
                    return ClickType.HYPERLINK;
                }
                linkattr =
                        iterator.getAttributes().get(IRCTextAttribute.CHANNEL);
                if (linkattr instanceof String) {
                    return ClickType.CHANNEL;
                }
                linkattr = iterator.getAttributes().get(
                        IRCTextAttribute.NICKNAME);
                if (linkattr instanceof String) {
                    return ClickType.NICKNAME;
                }
            } else {
                return ClickType.NORMAL;
            }
        }
        return ClickType.NORMAL;
    //#TextPaneCanvas.java:463: end of method: ClickType com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getClickType(LineInfo)
    }

    /**
     * Returns the atrriute value for the specified location.
     * 
     * @param lineInfo Specified location
     * 
     * @return Specified value
     */
    public Object getAttributeValueAtPoint(LineInfo lineInfo) {
        if (lineInfo.getLine() != -1) {
    //#TextPaneCanvas.java:474: method: Object com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getAttributeValueAtPoint(LineInfo)
    //#input(Object getAttributeValueAtPoint(LineInfo)): "."._tainted
    //#input(Object getAttributeValueAtPoint(LineInfo)): "Config option not found: "._tainted
    //#input(Object getAttributeValueAtPoint(LineInfo)): "Unable to insert styled string: "._tainted
    //#input(Object getAttributeValueAtPoint(LineInfo)): "textPaneFontName"._tainted
    //#input(Object getAttributeValueAtPoint(LineInfo)): "ui"._tainted
    //#input(Object getAttributeValueAtPoint(LineInfo)): com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(Object getAttributeValueAtPoint(LineInfo)): com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(Object getAttributeValueAtPoint(LineInfo)): com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/Line]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[others]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getStyled()Ljava/text/AttributedString;
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.logger.ErrorLevel.MEDIUM
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.BACKGROUND
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FAMILY
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FOREGROUND
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE_OBLIQUE
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.SIZE
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE_ON
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT_BOLD
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$CharacterConstants.Underline
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Background
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Foreground
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Bold
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Family
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Italic
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigManager.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigManager.__Descendant_Table[others]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigManager.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOptionString(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigManager.stats
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigSource]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigSource.__Descendant_Table[others]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigSource.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/ConfigSource.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/Identity.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/Identity.__Descendant_Table[others]
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/Identity.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(Object getAttributeValueAtPoint(LineInfo)): com/dmdirc/config/Identity.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(Object getAttributeValueAtPoint(LineInfo)): lineInfo
    //#input(Object getAttributeValueAtPoint(LineInfo)): lineInfo.index
    //#input(Object getAttributeValueAtPoint(LineInfo)): lineInfo.line
    //#input(Object getAttributeValueAtPoint(LineInfo)): this
    //#input(Object getAttributeValueAtPoint(LineInfo)): this.document
    //#input(Object getAttributeValueAtPoint(LineInfo)): this.document.cachedLines
    //#input(Object getAttributeValueAtPoint(LineInfo)): this.document.cachedStrings
    //#input(Object getAttributeValueAtPoint(LineInfo)): this.document.lines
    //#output(Object getAttributeValueAtPoint(LineInfo)): return_value
    //#pre[1] (Object getAttributeValueAtPoint(LineInfo)): lineInfo != null
    //#pre[3] (Object getAttributeValueAtPoint(LineInfo)): init'ed(lineInfo.line)
    //#pre[2] (Object getAttributeValueAtPoint(LineInfo)): (soft) init'ed(lineInfo.index)
    //#pre[5] (Object getAttributeValueAtPoint(LineInfo)): (soft) this.document != null
    //#pre[6] (Object getAttributeValueAtPoint(LineInfo)): (soft) this.document.cachedLines != null
    //#pre[7] (Object getAttributeValueAtPoint(LineInfo)): (soft) this.document.cachedStrings != null
    //#pre[8] (Object getAttributeValueAtPoint(LineInfo)): (soft) this.document.lines != null
    //#presumption(Object getAttributeValueAtPoint(LineInfo)): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL)
    //#presumption(Object getAttributeValueAtPoint(LineInfo)): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK)
    //#presumption(Object getAttributeValueAtPoint(LineInfo)): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME)
    //#presumption(Object getAttributeValueAtPoint(LineInfo)): getStyledLine(...)@475 init'ed
    //#presumption(Object getAttributeValueAtPoint(LineInfo)): java.text.AttributedCharacterIterator:getAttributes(...)@478 != null
    //#presumption(Object getAttributeValueAtPoint(LineInfo)): java.text.AttributedCharacterIterator:getAttributes(...)@483 != null
    //#presumption(Object getAttributeValueAtPoint(LineInfo)): java.text.AttributedCharacterIterator:getAttributes(...)@487 != null
    //#presumption(Object getAttributeValueAtPoint(LineInfo)): java.text.AttributedString:getIterator(...)@253 != null
    //#post(Object getAttributeValueAtPoint(LineInfo)): init'ed(return_value)
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.List:get
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:getStyledLine
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.UIManager:getFont
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.awt.Font:getSize
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:com.dmdirc.util.RollingList:contains
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:com.dmdirc.util.RollingList:getList
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.List:indexOf
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:com.dmdirc.util.RollingList:get
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:com.dmdirc.ui.messages.Styliser:getStyledString
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.StyledDocument:getParagraphElement
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.Element:getDocument
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.Document:getLength
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.Document:getText
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.text.AttributedString
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.BadLocationException:getMessage
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:com.dmdirc.logger.Logger:userError
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:hasOption
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.Map:containsKey
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.lang.Integer:intValue
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.Map:put
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:getOption
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.lang.IllegalArgumentException
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:com.dmdirc.util.ConfigFile:getKeyDomain
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:com.dmdirc.util.ConfigFile:isKeyDomain
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.awt.Font:getName
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.text.AttributedString:getIterator
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.text.AttributedCharacterIterator:getEndIndex
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.awt.Font
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.text.AttributedString:addAttribute
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.awt.Font:getFamily
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.Element:getElementCount
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.Element:getElement
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.Element:getAttributes
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.AttributeSet:getAttributeNames
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.Enumeration:hasMoreElements
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:java.util.Enumeration:nextElement
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.AttributeSet:getAttribute
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.Element:getStartOffset
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:javax.swing.text.Element:getEndOffset
    //#unanalyzed(Object getAttributeValueAtPoint(LineInfo)): Effects-of-calling:com.dmdirc.util.RollingList:add
    //#test_vector(Object getAttributeValueAtPoint(LineInfo)): lineInfo.line: {-1}, {-2_147_483_648..-2, 0..4_294_967_295}
            final AttributedCharacterIterator iterator = document.getStyledLine(
                    lineInfo.getLine());
            iterator.setIndex(lineInfo.getIndex());
            Object linkattr =
                    iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
            if (linkattr instanceof String) {
                return linkattr;
            }
            linkattr = iterator.getAttributes().get(IRCTextAttribute.CHANNEL);
            if (linkattr instanceof String) {
                return linkattr;
            }
            linkattr = iterator.getAttributes().get(IRCTextAttribute.NICKNAME);
            if (linkattr instanceof String) {
                return linkattr;
            }
        }
        return null;
    //#TextPaneCanvas.java:492: end of method: Object com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getAttributeValueAtPoint(LineInfo)
    }

    /**
     * Returns the indexes for the word surrounding the index in the specified
     * string.
     *
     * @param text Text to get word from
     * @param index Index to get surrounding word
     *
     * @return Indexes of the word surrounding the index (start, end)
     */
    protected int[] getSurroundingWordIndexes(final String text,
            final int index) {
        final int start = getSurroundingWordStart(text, index);
    //#TextPaneCanvas.java:506: method: int[] com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getSurroundingWordIndexes(String, int)
    //#input(int[] getSurroundingWordIndexes(String, int)): index
    //#input(int[] getSurroundingWordIndexes(String, int)): text
    //#input(int[] getSurroundingWordIndexes(String, int)): this
    //#output(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1) num objects
    //#output(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1).length
    //#output(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1)[0]
    //#output(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1)[1]
    //#output(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2) num objects
    //#output(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2).length
    //#output(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2)[0]
    //#output(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2)[1]
    //#output(int[] getSurroundingWordIndexes(String, int)): return_value
    //#new obj(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1)
    //#new obj(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2)
    //#pre[2] (int[] getSurroundingWordIndexes(String, int)): text != null
    //#post(int[] getSurroundingWordIndexes(String, int)): return_value in Addr_Set{&new int[](getSurroundingWordIndexes#2),&new int[](getSurroundingWordIndexes#1)}
    //#post(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1) num objects <= 1
    //#post(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1).length == 2
    //#post(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1)[0] == 0
    //#post(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#1)[1] == 0
    //#post(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2) num objects <= 1
    //#post(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2).length == 2
    //#post(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2)[0] >= 0
    //#post(int[] getSurroundingWordIndexes(String, int)): new int[](getSurroundingWordIndexes#2)[1] >= 0
    //#unanalyzed(int[] getSurroundingWordIndexes(String, int)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(int[] getSurroundingWordIndexes(String, int)): Effects-of-calling:java.lang.String:charAt
        final int end = getSurroundingWordEnd(text, index);

        if (start < 0 || end > text.length() || start > end) {
            return new int[]{0, 0};
        }

        return new int[]{start, end};
    //#TextPaneCanvas.java:513: end of method: int[] com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getSurroundingWordIndexes(String, int)

    }

    /**
     * Returns the start index for the word surrounding the index in the
     * specified string.
     *
     * @param text Text to get word from
     * @param index Index to get surrounding word
     *
     * @return Start index of the word surrounding the index
     */
    private int getSurroundingWordStart(final String text, final int index) {
        int start = index;
    //#TextPaneCanvas.java:527: method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getSurroundingWordStart(String, int)
    //#input(int getSurroundingWordStart(String, int)): index
    //#input(int getSurroundingWordStart(String, int)): text
    //#output(int getSurroundingWordStart(String, int)): return_value
    //#pre[2] (int getSurroundingWordStart(String, int)): text != null
    //#post(int getSurroundingWordStart(String, int)): init'ed(return_value)
    //#test_vector(int getSurroundingWordStart(String, int)): java.lang.String:charAt(...)@530: {32}, {0..31, 33..65_535}
    //#test_vector(int getSurroundingWordStart(String, int)): java.lang.String:charAt(...)@533: {0..31, 33..65_535}, {32}

        // Traverse backwards
        while (start > 0 && start < text.length() && text.charAt(start) != ' ') {
            start--;
        }
        if (start + 1 < text.length() && text.charAt(start) == ' ') {
            start++;
        }

        return start;
    //#TextPaneCanvas.java:537: end of method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getSurroundingWordStart(String, int)
    }

    /**
     * Returns the end index for the word surrounding the index in the
     * specified string.
     *
     * @param text Text to get word from
     * @param index Index to get surrounding word
     *
     * @return End index of the word surrounding the index
     */
    private int getSurroundingWordEnd(final String text, final int index) {
        int end = index;
    //#TextPaneCanvas.java:550: method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getSurroundingWordEnd(String, int)
    //#input(int getSurroundingWordEnd(String, int)): index
    //#input(int getSurroundingWordEnd(String, int)): text
    //#output(int getSurroundingWordEnd(String, int)): return_value
    //#pre[2] (int getSurroundingWordEnd(String, int)): text != null
    //#post(int getSurroundingWordEnd(String, int)): init'ed(return_value)
    //#post(int getSurroundingWordEnd(String, int)): return_value - index in {0..6_442_450_943}
    //#test_vector(int getSurroundingWordEnd(String, int)): java.lang.String:charAt(...)@553: {32}, {0..31, 33..65_535}

        // And forwards
        while (end < text.length() && end > 0 && text.charAt(end) != ' ') {
            end++;
        }

        return end;
    //#TextPaneCanvas.java:557: end of method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getSurroundingWordEnd(String, int)
    }

    /** 
     * {@inheritDoc}
     * 
     * @param e Mouse event
     */
    @Override
    public void mousePressed(final MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON1) {
    //#TextPaneCanvas.java:567: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mousePressed(MouseEvent)
    //#input(void mousePressed(MouseEvent)): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#input(void mousePressed(MouseEvent)): __Descendant_Table[others]
    //#input(void mousePressed(MouseEvent)): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#input(void mousePressed(MouseEvent)): __Dispatch_Table.highlightEvent(Lcom/dmdirc/addons/ui_swing/textpane/MouseEventType;Ljava/awt/event/MouseEvent;)V
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndLine(I)V
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndPos(I)V
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartLine(I)V
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartPos(I)V
    //#input(void mousePressed(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/MouseEventType.CLICK
    //#input(void mousePressed(MouseEvent)): e
    //#input(void mousePressed(MouseEvent)): this
    //#input(void mousePressed(MouseEvent)): this.__Tag
    //#input(void mousePressed(MouseEvent)): this.positions
    //#input(void mousePressed(MouseEvent)): this.selection
    //#input(void mousePressed(MouseEvent)): this.selection.__Tag
    //#input(void mousePressed(MouseEvent)): this.textLayouts
    //#input(void mousePressed(MouseEvent)): this.textPane
    //#output(void mousePressed(MouseEvent)): this.selection.endLine
    //#output(void mousePressed(MouseEvent)): this.selection.endPos
    //#output(void mousePressed(MouseEvent)): this.selection.startLine
    //#output(void mousePressed(MouseEvent)): this.selection.startPos
    //#pre[1] (void mousePressed(MouseEvent)): e != null
    //#pre[12] (void mousePressed(MouseEvent)): this.textPane != null
    //#pre[7] (void mousePressed(MouseEvent)): (soft) this.__Tag == com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas
    //#pre[8] (void mousePressed(MouseEvent)): (soft) this.positions != null
    //#pre[9] (void mousePressed(MouseEvent)): (soft) this.selection != null
    //#pre[10] (void mousePressed(MouseEvent)): (soft) this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[11] (void mousePressed(MouseEvent)): (soft) this.textLayouts != null
    //#post(void mousePressed(MouseEvent)): possibly_updated(this.selection.endLine)
    //#post(void mousePressed(MouseEvent)): possibly_updated(this.selection.endPos)
    //#post(void mousePressed(MouseEvent)): possibly_updated(this.selection.startLine)
    //#post(void mousePressed(MouseEvent)): possibly_updated(this.selection.startPos)
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getKey
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.Rectangle:contains
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.Point:getX
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.Point:getY
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.event.MouseEvent:getLocationOnScreen
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:javax.swing.SwingUtilities:convertPointFromScreen
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getBounds
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.event.MouseEvent:getPoint
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getX
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.Point:setLocation
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getWidth
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getY
    //#unanalyzed(void mousePressed(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getHeight
    //#test_vector(void mousePressed(MouseEvent)): java.awt.event.MouseEvent:getButton(...)@567: {-2_147_483_648..0, 2..4_294_967_295}, {1}
            highlightEvent(MouseEventType.CLICK, e);
        }
        e.setSource(textPane);
        textPane.dispatchEvent(e);
    //#TextPaneCanvas.java:571: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPane:dispatchEvent(AWTEvent)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void mousePressed(MouseEvent)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPane:dispatchEvent(AWTEvent)
    }
    //#TextPaneCanvas.java:572: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mousePressed(MouseEvent)

    /** 
     * {@inheritDoc}
     * 
     * @param e Mouse event
     */
    @Override
    public void mouseReleased(final MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON1) {
    //#TextPaneCanvas.java:581: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseReleased(MouseEvent)
    //#input(void mouseReleased(MouseEvent)): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#input(void mouseReleased(MouseEvent)): __Descendant_Table[others]
    //#input(void mouseReleased(MouseEvent)): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#input(void mouseReleased(MouseEvent)): __Dispatch_Table.highlightEvent(Lcom/dmdirc/addons/ui_swing/textpane/MouseEventType;Ljava/awt/event/MouseEvent;)V
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndLine(I)V
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndPos(I)V
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartLine(I)V
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartPos(I)V
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/MouseEventType.CLICK
    //#input(void mouseReleased(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/MouseEventType.RELEASE
    //#input(void mouseReleased(MouseEvent)): e
    //#input(void mouseReleased(MouseEvent)): this
    //#input(void mouseReleased(MouseEvent)): this.__Tag
    //#input(void mouseReleased(MouseEvent)): this.positions
    //#input(void mouseReleased(MouseEvent)): this.selection
    //#input(void mouseReleased(MouseEvent)): this.selection.__Tag
    //#input(void mouseReleased(MouseEvent)): this.textLayouts
    //#input(void mouseReleased(MouseEvent)): this.textPane
    //#output(void mouseReleased(MouseEvent)): this.selection.endLine
    //#output(void mouseReleased(MouseEvent)): this.selection.endPos
    //#output(void mouseReleased(MouseEvent)): this.selection.startLine
    //#output(void mouseReleased(MouseEvent)): this.selection.startPos
    //#pre[1] (void mouseReleased(MouseEvent)): e != null
    //#pre[12] (void mouseReleased(MouseEvent)): this.textPane != null
    //#pre[7] (void mouseReleased(MouseEvent)): (soft) this.__Tag == com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas
    //#pre[8] (void mouseReleased(MouseEvent)): (soft) this.positions != null
    //#pre[9] (void mouseReleased(MouseEvent)): (soft) this.selection != null
    //#pre[10] (void mouseReleased(MouseEvent)): (soft) this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[11] (void mouseReleased(MouseEvent)): (soft) this.textLayouts != null
    //#post(void mouseReleased(MouseEvent)): possibly_updated(this.selection.endLine)
    //#post(void mouseReleased(MouseEvent)): possibly_updated(this.selection.endPos)
    //#post(void mouseReleased(MouseEvent)): possibly_updated(this.selection.startLine)
    //#post(void mouseReleased(MouseEvent)): possibly_updated(this.selection.startPos)
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getKey
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.Rectangle:contains
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.Point:getX
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.Point:getY
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.event.MouseEvent:getLocationOnScreen
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:javax.swing.SwingUtilities:convertPointFromScreen
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getBounds
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.event.MouseEvent:getPoint
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getX
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.Point:setLocation
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getWidth
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getY
    //#unanalyzed(void mouseReleased(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getHeight
    //#test_vector(void mouseReleased(MouseEvent)): java.awt.event.MouseEvent:getButton(...)@581: {-2_147_483_648..0, 2..4_294_967_295}, {1}
            highlightEvent(MouseEventType.RELEASE, e);
        }
        e.setSource(textPane);
        textPane.dispatchEvent(e);
    //#TextPaneCanvas.java:585: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPane:dispatchEvent(AWTEvent)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void mouseReleased(MouseEvent)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPane:dispatchEvent(AWTEvent)
    }
    //#TextPaneCanvas.java:586: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseReleased(MouseEvent)

    /** 
     * {@inheritDoc}
     * 
     * @param e Mouse event
     */
    @Override
    public void mouseDragged(final MouseEvent e) {
        if (e.getModifiersEx() == MouseEvent.BUTTON1_DOWN_MASK) {
    //#TextPaneCanvas.java:595: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseDragged(MouseEvent)
    //#input(void mouseDragged(MouseEvent)): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#input(void mouseDragged(MouseEvent)): __Descendant_Table[others]
    //#input(void mouseDragged(MouseEvent)): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#input(void mouseDragged(MouseEvent)): __Dispatch_Table.highlightEvent(Lcom/dmdirc/addons/ui_swing/textpane/MouseEventType;Ljava/awt/event/MouseEvent;)V
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndLine(I)V
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndPos(I)V
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartLine(I)V
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartPos(I)V
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/MouseEventType.CLICK
    //#input(void mouseDragged(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/MouseEventType.DRAG
    //#input(void mouseDragged(MouseEvent)): e
    //#input(void mouseDragged(MouseEvent)): this
    //#input(void mouseDragged(MouseEvent)): this.__Tag
    //#input(void mouseDragged(MouseEvent)): this.positions
    //#input(void mouseDragged(MouseEvent)): this.selection
    //#input(void mouseDragged(MouseEvent)): this.selection.__Tag
    //#input(void mouseDragged(MouseEvent)): this.textLayouts
    //#input(void mouseDragged(MouseEvent)): this.textPane
    //#output(void mouseDragged(MouseEvent)): this.selection.endLine
    //#output(void mouseDragged(MouseEvent)): this.selection.endPos
    //#output(void mouseDragged(MouseEvent)): this.selection.startLine
    //#output(void mouseDragged(MouseEvent)): this.selection.startPos
    //#pre[1] (void mouseDragged(MouseEvent)): e != null
    //#pre[12] (void mouseDragged(MouseEvent)): this.textPane != null
    //#pre[7] (void mouseDragged(MouseEvent)): (soft) this.__Tag == com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas
    //#pre[8] (void mouseDragged(MouseEvent)): (soft) this.positions != null
    //#pre[9] (void mouseDragged(MouseEvent)): (soft) this.selection != null
    //#pre[10] (void mouseDragged(MouseEvent)): (soft) this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[11] (void mouseDragged(MouseEvent)): (soft) this.textLayouts != null
    //#post(void mouseDragged(MouseEvent)): possibly_updated(this.selection.endLine)
    //#post(void mouseDragged(MouseEvent)): possibly_updated(this.selection.endPos)
    //#post(void mouseDragged(MouseEvent)): possibly_updated(this.selection.startLine)
    //#post(void mouseDragged(MouseEvent)): possibly_updated(this.selection.startPos)
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getKey
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.Rectangle:contains
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.Point:getX
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.Point:getY
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.event.MouseEvent:getLocationOnScreen
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:javax.swing.SwingUtilities:convertPointFromScreen
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getBounds
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.event.MouseEvent:getPoint
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getX
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.Point:setLocation
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getWidth
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getY
    //#unanalyzed(void mouseDragged(MouseEvent)): Effects-of-calling:java.awt.Rectangle:getHeight
    //#test_vector(void mouseDragged(MouseEvent)): java.awt.event.MouseEvent:getModifiersEx(...)@595: {-2_147_483_648..1_023, 1_025..4_294_967_295}, {1_024}
            highlightEvent(MouseEventType.DRAG, e);
        }

        e.setSource(textPane);
        textPane.dispatchEvent(e);
    //#TextPaneCanvas.java:600: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPane:dispatchEvent(AWTEvent)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void mouseDragged(MouseEvent)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPane:dispatchEvent(AWTEvent)
    }
    //#TextPaneCanvas.java:601: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseDragged(MouseEvent)

    /** 
     * {@inheritDoc}
     * 
     * @param e Mouse event
     */
    @Override
    public void mouseEntered(final MouseEvent e) {
        //Ignore
    }
    //#TextPaneCanvas.java:611: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseEntered(MouseEvent)
    //#TextPaneCanvas.java:611: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseEntered(MouseEvent)

    /** 
     * {@inheritDoc}
     * 
     * @param e Mouse event
     */
    @Override
    public void mouseExited(final MouseEvent e) {
        //Ignore
    }
    //#TextPaneCanvas.java:621: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseExited(MouseEvent)
    //#TextPaneCanvas.java:621: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseExited(MouseEvent)

    /** 
     * {@inheritDoc}
     * 
     * @param e Mouse event
     */
    @Override
    public void mouseMoved(final MouseEvent e) {
        checkForLink();
    //#TextPaneCanvas.java:630: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseMoved(MouseEvent)
    //#input(void mouseMoved(MouseEvent)): "."._tainted
    //#input(void mouseMoved(MouseEvent)): "Config option not found: "._tainted
    //#input(void mouseMoved(MouseEvent)): "Unable to insert styled string: "._tainted
    //#input(void mouseMoved(MouseEvent)): "textPaneFontName"._tainted
    //#input(void mouseMoved(MouseEvent)): "ui"._tainted
    //#input(void mouseMoved(MouseEvent)): HAND_CURSOR
    //#input(void mouseMoved(MouseEvent)): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#input(void mouseMoved(MouseEvent)): __Descendant_Table[others]
    //#input(void mouseMoved(MouseEvent)): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#input(void mouseMoved(MouseEvent)): com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(void mouseMoved(MouseEvent)): com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(void mouseMoved(MouseEvent)): com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/Line]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[others]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getStyled()Ljava/text/AttributedString;
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.logger.ErrorLevel.MEDIUM
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.BACKGROUND
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FAMILY
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FOREGROUND
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE_OBLIQUE
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.SIZE
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE_ON
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT_BOLD
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$CharacterConstants.Underline
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Background
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Foreground
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Bold
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Family
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Italic
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigManager.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigManager.__Descendant_Table[others]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigManager.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOptionString(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigManager.stats
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigSource]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigSource.__Descendant_Table[others]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigSource.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/ConfigSource.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/Identity.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/Identity.__Descendant_Table[others]
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/Identity.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void mouseMoved(MouseEvent)): com/dmdirc/config/Identity.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void mouseMoved(MouseEvent)): this
    //#input(void mouseMoved(MouseEvent)): this.__Tag
    //#input(void mouseMoved(MouseEvent)): this.document
    //#input(void mouseMoved(MouseEvent)): this.document.cachedLines
    //#input(void mouseMoved(MouseEvent)): this.document.cachedStrings
    //#input(void mouseMoved(MouseEvent)): this.document.lines
    //#input(void mouseMoved(MouseEvent)): this.positions
    //#input(void mouseMoved(MouseEvent)): this.textLayouts
    //#pre[2] (void mouseMoved(MouseEvent)): this.__Tag == com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas
    //#pre[3] (void mouseMoved(MouseEvent)): (soft) this.document != null
    //#pre[4] (void mouseMoved(MouseEvent)): (soft) this.document.cachedLines != null
    //#pre[5] (void mouseMoved(MouseEvent)): (soft) this.document.cachedStrings != null
    //#pre[6] (void mouseMoved(MouseEvent)): (soft) this.document.lines != null
    //#pre[7] (void mouseMoved(MouseEvent)): (soft) this.positions != null
    //#pre[8] (void mouseMoved(MouseEvent)): (soft) this.textLayouts != null
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Map$Entry:getKey
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.Rectangle:contains
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.Point:getX
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.Point:getY
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:getStyledLine
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.text.AttributedCharacterIterator:setIndex
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.text.AttributedCharacterIterator:getAttributes
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.String:instanceof
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.text.AttributedCharacterIterator:getBeginIndex
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.text.AttributedCharacterIterator:getEndIndex
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getMousePosition
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:getLine
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getCursor
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.Cursor:getDefaultCursor
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.List:get
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.UIManager:getFont
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.Font:getSize
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.util.RollingList:contains
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.util.RollingList:getList
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.List:indexOf
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.util.RollingList:get
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.ui.messages.Styliser:getStyledString
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.StyledDocument:getParagraphElement
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.Element:getDocument
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.Document:getLength
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.Document:getText
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.text.AttributedString
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.BadLocationException:getMessage
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.logger.Logger:userError
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:hasOption
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Map:containsKey
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.Integer:intValue
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Map:put
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:getOption
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.IllegalArgumentException
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.util.ConfigFile:getKeyDomain
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.util.ConfigFile:isKeyDomain
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.Font:getName
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.text.AttributedString:getIterator
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.Font
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.text.AttributedString:addAttribute
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.awt.Font:getFamily
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.Element:getElementCount
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.Element:getElement
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.Element:getAttributes
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.AttributeSet:getAttributeNames
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Enumeration:hasMoreElements
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:java.util.Enumeration:nextElement
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.AttributeSet:getAttribute
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.Element:getStartOffset
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:javax.swing.text.Element:getEndOffset
    //#unanalyzed(void mouseMoved(MouseEvent)): Effects-of-calling:com.dmdirc.util.RollingList:add
    }
    //#TextPaneCanvas.java:631: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.mouseMoved(MouseEvent)

    /** Checks for a link under the cursor and sets appropriately. */
    private void checkForLink() {
        final LineInfo lineInfo = getClickPosition(getMousePosition());
    //#TextPaneCanvas.java:635: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.checkForLink()
    //#TextPaneCanvas.java:635: Warning: method not available - call not analyzed
    //#    call on Point com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getMousePosition()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void checkForLink()
    //#    unanalyzed callee: Point com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getMousePosition()
    //#input(void checkForLink()): "."._tainted
    //#input(void checkForLink()): "Config option not found: "._tainted
    //#input(void checkForLink()): "Unable to insert styled string: "._tainted
    //#input(void checkForLink()): "textPaneFontName"._tainted
    //#input(void checkForLink()): "ui"._tainted
    //#input(void checkForLink()): HAND_CURSOR
    //#input(void checkForLink()): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#input(void checkForLink()): __Descendant_Table[others]
    //#input(void checkForLink()): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#input(void checkForLink()): com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(void checkForLink()): com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(void checkForLink()): com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/Line]
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.__Descendant_Table[others]
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.__Dispatch_Table.getStyled()Ljava/text/AttributedString;
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.logger.ErrorLevel.MEDIUM
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.BACKGROUND
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FAMILY
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.FOREGROUND
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.POSTURE_OBLIQUE
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.SIZE
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.UNDERLINE_ON
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.java.awt.font.TextAttribute.WEIGHT_BOLD
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$CharacterConstants.Underline
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Background
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$ColorConstants.Foreground
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Bold
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Family
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/Line.javax.swing.text.StyleConstants$FontConstants.Italic
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(void checkForLink()): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(void checkForLink()): com/dmdirc/config/ConfigManager.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(void checkForLink()): com/dmdirc/config/ConfigManager.__Descendant_Table[others]
    //#input(void checkForLink()): com/dmdirc/config/ConfigManager.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void checkForLink()): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void checkForLink()): com/dmdirc/config/ConfigManager.__Dispatch_Table.hasOptionString(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void checkForLink()): com/dmdirc/config/ConfigManager.stats
    //#input(void checkForLink()): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigManager]
    //#input(void checkForLink()): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/ConfigSource]
    //#input(void checkForLink()): com/dmdirc/config/ConfigSource.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(void checkForLink()): com/dmdirc/config/ConfigSource.__Descendant_Table[others]
    //#input(void checkForLink()): com/dmdirc/config/ConfigSource.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void checkForLink()): com/dmdirc/config/ConfigSource.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void checkForLink()): com/dmdirc/config/Identity.__Descendant_Table[com/dmdirc/config/Identity]
    //#input(void checkForLink()): com/dmdirc/config/Identity.__Descendant_Table[others]
    //#input(void checkForLink()): com/dmdirc/config/Identity.__Dispatch_Table.getOption(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    //#input(void checkForLink()): com/dmdirc/config/Identity.__Dispatch_Table.hasOption(Ljava/lang/String;Ljava/lang/String;)Z
    //#input(void checkForLink()): this
    //#input(void checkForLink()): this.__Tag
    //#input(void checkForLink()): this.document
    //#input(void checkForLink()): this.document.cachedLines
    //#input(void checkForLink()): this.document.cachedStrings
    //#input(void checkForLink()): this.document.lines
    //#input(void checkForLink()): this.positions
    //#input(void checkForLink()): this.textLayouts
    //#pre[2] (void checkForLink()): this.__Tag == com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas
    //#pre[3] (void checkForLink()): (soft) this.document != null
    //#pre[4] (void checkForLink()): (soft) this.document.cachedLines != null
    //#pre[5] (void checkForLink()): (soft) this.document.cachedStrings != null
    //#pre[6] (void checkForLink()): (soft) this.document.lines != null
    //#pre[7] (void checkForLink()): (soft) this.positions != null
    //#pre[8] (void checkForLink()): (soft) this.textLayouts != null
    //#presumption(void checkForLink()): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.CHANNEL)
    //#presumption(void checkForLink()): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.HYPERLINK)
    //#presumption(void checkForLink()): init'ed(com.dmdirc.ui.messages.IRCTextAttribute.NICKNAME)
    //#presumption(void checkForLink()): java.text.AttributedCharacterIterator:getAttributes(...)@646 != null
    //#presumption(void checkForLink()): java.text.AttributedCharacterIterator:getAttributes(...)@652 != null
    //#presumption(void checkForLink()): java.text.AttributedCharacterIterator:getAttributes(...)@657 != null
    //#presumption(void checkForLink()): java.text.AttributedString:getIterator(...)@253 != null
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Map$Entry:getKey
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.Rectangle:contains
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.Point:getX
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.Point:getY
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.List:get
    //#unanalyzed(void checkForLink()): Effects-of-calling:getStyledLine
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.UIManager:getFont
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.Font:getSize
    //#unanalyzed(void checkForLink()): Effects-of-calling:com.dmdirc.util.RollingList:contains
    //#unanalyzed(void checkForLink()): Effects-of-calling:com.dmdirc.util.RollingList:getList
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.List:indexOf
    //#unanalyzed(void checkForLink()): Effects-of-calling:com.dmdirc.util.RollingList:get
    //#unanalyzed(void checkForLink()): Effects-of-calling:com.dmdirc.ui.messages.Styliser:getStyledString
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.StyledDocument:getParagraphElement
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.Element:getDocument
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.Document:getLength
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.Document:getText
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.text.AttributedString
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.BadLocationException:getMessage
    //#unanalyzed(void checkForLink()): Effects-of-calling:com.dmdirc.logger.Logger:userError
    //#unanalyzed(void checkForLink()): Effects-of-calling:hasOption
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Map:containsKey
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.lang.Integer:intValue
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.lang.Integer:valueOf
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Map:put
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void checkForLink()): Effects-of-calling:getOption
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.lang.IllegalArgumentException
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.lang.String:isEmpty
    //#unanalyzed(void checkForLink()): Effects-of-calling:com.dmdirc.util.ConfigFile:getKeyDomain
    //#unanalyzed(void checkForLink()): Effects-of-calling:com.dmdirc.util.ConfigFile:isKeyDomain
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.Font:getName
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.text.AttributedString:getIterator
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.text.AttributedCharacterIterator:getEndIndex
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.Font
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.text.AttributedString:addAttribute
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.awt.Font:getFamily
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.Element:getElementCount
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.Element:getElement
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.Element:getAttributes
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.AttributeSet:getAttributeNames
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Enumeration:hasMoreElements
    //#unanalyzed(void checkForLink()): Effects-of-calling:java.util.Enumeration:nextElement
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.AttributeSet:getAttribute
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.Element:getStartOffset
    //#unanalyzed(void checkForLink()): Effects-of-calling:javax.swing.text.Element:getEndOffset
    //#unanalyzed(void checkForLink()): Effects-of-calling:com.dmdirc.util.RollingList:add
    //#test_vector(void checkForLink()): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getCursor(...)@663: Inverse{&new Cursor(TextPaneCanvas__static_init#1)}, Addr_Set{&new Cursor(TextPaneCanvas__static_init#1)}
    //#test_vector(void checkForLink()): java.util.List:get(...)@89: Addr_Set{null}, Inverse{null}

        if (lineInfo.getLine() != -1 && document.getLine(lineInfo.getLine()) !=
                null) {
            final AttributedCharacterIterator iterator = document.getStyledLine(
                    lineInfo.getLine());
            if (lineInfo.getIndex() < iterator.getBeginIndex() ||
                    lineInfo.getIndex() > iterator.getEndIndex()) {
                return;
            }
            iterator.setIndex(lineInfo.getIndex());
            Object linkattr =
                    iterator.getAttributes().get(IRCTextAttribute.HYPERLINK);
            if (linkattr instanceof String) {
                setCursor(HAND_CURSOR);
    //#TextPaneCanvas.java:649: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void checkForLink()
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
                return;
            }
            linkattr = iterator.getAttributes().get(IRCTextAttribute.CHANNEL);
            if (linkattr instanceof String) {
                setCursor(HAND_CURSOR);
    //#TextPaneCanvas.java:654: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void checkForLink()
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
                return;
            }
            linkattr = iterator.getAttributes().get(IRCTextAttribute.NICKNAME);
            if (linkattr instanceof String) {
                setCursor(HAND_CURSOR);
    //#TextPaneCanvas.java:659: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void checkForLink()
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
                return;
            }
        }
        if (getCursor() == HAND_CURSOR) {
    //#TextPaneCanvas.java:663: Warning: method not available - call not analyzed
    //#    call on Cursor com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getCursor()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void checkForLink()
    //#    unanalyzed callee: Cursor com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getCursor()
            setCursor(Cursor.getDefaultCursor());
    //#TextPaneCanvas.java:664: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void checkForLink()
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:setCursor(Cursor)
        }
    }
    //#TextPaneCanvas.java:666: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.checkForLink()

    /**
     * Sets the selection for the given event.
     *
     * @param type mouse event type
     * @param e responsible mouse event
     */
    protected void highlightEvent(final MouseEventType type,
            final MouseEvent e) {
        if (isVisible()) {
    //#TextPaneCanvas.java:676: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.highlightEvent(MouseEventType, MouseEvent)
    //#TextPaneCanvas.java:676: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void highlightEvent(MouseEventType, MouseEvent)
    //#    unanalyzed callee: bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
    //#input(void highlightEvent(MouseEventType, MouseEvent)): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas]
    //#input(void highlightEvent(MouseEventType, MouseEvent)): __Descendant_Table[others]
    //#input(void highlightEvent(MouseEventType, MouseEvent)): __Dispatch_Table.getClickPosition(Ljava/awt/Point;)Lcom/dmdirc/addons/ui_swing/textpane/LineInfo;
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndLine(I)V
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndPos(I)V
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartLine(I)V
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setStartPos(I)V
    //#input(void highlightEvent(MouseEventType, MouseEvent)): com/dmdirc/addons/ui_swing/textpane/MouseEventType.CLICK
    //#input(void highlightEvent(MouseEventType, MouseEvent)): e
    //#input(void highlightEvent(MouseEventType, MouseEvent)): this
    //#input(void highlightEvent(MouseEventType, MouseEvent)): this.__Tag
    //#input(void highlightEvent(MouseEventType, MouseEvent)): this.positions
    //#input(void highlightEvent(MouseEventType, MouseEvent)): this.selection
    //#input(void highlightEvent(MouseEventType, MouseEvent)): this.selection.__Tag
    //#input(void highlightEvent(MouseEventType, MouseEvent)): this.textLayouts
    //#input(void highlightEvent(MouseEventType, MouseEvent)): type
    //#output(void highlightEvent(MouseEventType, MouseEvent)): this.selection.endLine
    //#output(void highlightEvent(MouseEventType, MouseEvent)): this.selection.endPos
    //#output(void highlightEvent(MouseEventType, MouseEvent)): this.selection.startLine
    //#output(void highlightEvent(MouseEventType, MouseEvent)): this.selection.startPos
    //#pre[1] (void highlightEvent(MouseEventType, MouseEvent)): (soft) e != null
    //#pre[7] (void highlightEvent(MouseEventType, MouseEvent)): (soft) this.__Tag == com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas
    //#pre[8] (void highlightEvent(MouseEventType, MouseEvent)): (soft) this.positions != null
    //#pre[9] (void highlightEvent(MouseEventType, MouseEvent)): (soft) this.selection != null
    //#pre[10] (void highlightEvent(MouseEventType, MouseEvent)): (soft) this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[11] (void highlightEvent(MouseEventType, MouseEvent)): (soft) this.textLayouts != null
    //#presumption(void highlightEvent(MouseEventType, MouseEvent)): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getBounds(...)@680 != null
    //#presumption(void highlightEvent(MouseEventType, MouseEvent)): java.awt.event.MouseEvent:getLocationOnScreen(...)@677 != null
    //#presumption(void highlightEvent(MouseEventType, MouseEvent)): java.awt.event.MouseEvent:getPoint(...)@681 != null
    //#post(void highlightEvent(MouseEventType, MouseEvent)): possibly_updated(this.selection.endLine)
    //#post(void highlightEvent(MouseEventType, MouseEvent)): possibly_updated(this.selection.endPos)
    //#post(void highlightEvent(MouseEventType, MouseEvent)): possibly_updated(this.selection.startLine)
    //#post(void highlightEvent(MouseEventType, MouseEvent)): possibly_updated(this.selection.startPos)
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.util.Map$Entry:getKey
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.awt.Rectangle:contains
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.awt.Point:getX
    //#unanalyzed(void highlightEvent(MouseEventType, MouseEvent)): Effects-of-calling:java.awt.Point:getY
    //#test_vector(void highlightEvent(MouseEventType, MouseEvent)): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains(...)@679: {1}, {0}
    //#test_vector(void highlightEvent(MouseEventType, MouseEvent)): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains(...)@701: {0}, {1}
    //#test_vector(void highlightEvent(MouseEventType, MouseEvent)): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible(...)@676: {0}, {1}
            Point point = e.getLocationOnScreen();
            SwingUtilities.convertPointFromScreen(point, this);
            if (!contains(point)) {
    //#TextPaneCanvas.java:679: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains(Point)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void highlightEvent(MouseEventType, MouseEvent)
    //#    unanalyzed callee: bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains(Point)
                final Rectangle bounds = getBounds();
    //#TextPaneCanvas.java:680: Warning: method not available - call not analyzed
    //#    call on Rectangle com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getBounds()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void highlightEvent(MouseEventType, MouseEvent)
    //#    unanalyzed callee: Rectangle com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:getBounds()
                final Point mousePos = e.getPoint();
                if (mousePos.getX() < bounds.getX()) {
                    point.setLocation(bounds.getX() + 3, point.getY());
                } else if (mousePos.getX() > (bounds.getX() + bounds.getWidth())) {
                    point.setLocation(bounds.getX() + bounds.getWidth() - 3,
                            point.getY());
                }
                if (mousePos.getY() < bounds.getY()) {
                    point.setLocation(point.getX(), bounds.getY() + 6);
                } else if (mousePos.getY() >
                        (bounds.getY() + bounds.getHeight())) {
                    //Nice text selection behaviour
                    //point.setLocation(point.getX(), bounds.getY() +
                    //        bounds.getHeight() - 6);
                    point.setLocation(bounds.getX() + bounds.getWidth() - 3,
                            bounds.getY() +
                            bounds.getHeight() - 6);
                }
            }
            final LineInfo info = getClickPosition(point);
            if (info.getLine() == -1 && info.getPart() == -1 && contains(point)) {
    //#TextPaneCanvas.java:701: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains(Point)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void highlightEvent(MouseEventType, MouseEvent)
    //#    unanalyzed callee: bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:contains(Point)
                info.setLine(0);
                info.setPart(0);
                //Nice text selection behaviour
                //info.setIndex(getHitPosition(info.getLine(), info.getPart(),
                //        point.x, 0));
                info.setIndex(0);
            }
            if (info.getLine() != -1 && info.getPart() != -1) {
                if (type == MouseEventType.CLICK) {
                    selection.setStartLine(info.getLine());
                    selection.setStartPos(info.getIndex());
                }
                selection.setEndLine(info.getLine());
                selection.setEndPos(info.getIndex());

                repaint();
    //#TextPaneCanvas.java:717: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void highlightEvent(MouseEventType, MouseEvent)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
            }
        }
    }
    //#TextPaneCanvas.java:720: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.highlightEvent(MouseEventType, MouseEvent)

    /**
     *
     * Returns the line information from a mouse click inside the textpane.
     *
     * @param point mouse position
     *
     * @return line number, line part, position in whole line
     */
    public LineInfo getClickPosition(final Point point) {
        int lineNumber = -1;
    //#TextPaneCanvas.java:731: method: LineInfo com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getClickPosition(Point)
    //#input(LineInfo getClickPosition(Point)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(LineInfo getClickPosition(Point)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(LineInfo getClickPosition(Point)): point
    //#input(LineInfo getClickPosition(Point)): this
    //#input(LineInfo getClickPosition(Point)): this.positions
    //#input(LineInfo getClickPosition(Point)): this.textLayouts
    //#output(LineInfo getClickPosition(Point)): new LineInfo(getClickPosition#1) num objects
    //#output(LineInfo getClickPosition(Point)): return_value.__Tag
    //#output(LineInfo getClickPosition(Point)): return_value.index
    //#output(LineInfo getClickPosition(Point)): return_value.line
    //#output(LineInfo getClickPosition(Point)): return_value.part
    //#output(LineInfo getClickPosition(Point)): return_value
    //#new obj(LineInfo getClickPosition(Point)): new LineInfo(getClickPosition#1)
    //#pre[3] (LineInfo getClickPosition(Point)): (soft) this.positions != null
    //#pre[4] (LineInfo getClickPosition(Point)): (soft) this.textLayouts != null
    //#presumption(LineInfo getClickPosition(Point)): (int) (java.awt.Point:getX(...)@743) in {-2_147_483_648..4_294_967_295}
    //#presumption(LineInfo getClickPosition(Point)): (int) (java.awt.Point:getY(...)@743) in {-2_147_483_648..4_294_967_295}
    //#presumption(LineInfo getClickPosition(Point)): java.util.Iterator:next(...)@736 != null
    //#presumption(LineInfo getClickPosition(Point)): java.util.Map:entrySet(...)@736 != null
    //#presumption(LineInfo getClickPosition(Point)): java.util.Map:get(...).__Tag@738 == com/dmdirc/addons/ui_swing/textpane/LineInfo
    //#presumption(LineInfo getClickPosition(Point)): java.util.Map:get(...).__Tag@739 == com/dmdirc/addons/ui_swing/textpane/LineInfo
    //#presumption(LineInfo getClickPosition(Point)): java.util.Map:get(...)@738 != null
    //#presumption(LineInfo getClickPosition(Point)): java.util.Map:get(...)@739 != null
    //#presumption(LineInfo getClickPosition(Point)): java.util.Map_Entry:getKey(...)@737 != null
    //#post(LineInfo getClickPosition(Point)): return_value == &new LineInfo(getClickPosition#1)
    //#post(LineInfo getClickPosition(Point)): new LineInfo(getClickPosition#1) num objects == 1
    //#post(LineInfo getClickPosition(Point)): return_value.__Tag == com/dmdirc/addons/ui_swing/textpane/LineInfo
    //#post(LineInfo getClickPosition(Point)): init'ed(return_value.index)
    //#post(LineInfo getClickPosition(Point)): init'ed(return_value.line)
    //#post(LineInfo getClickPosition(Point)): init'ed(return_value.part)
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.util.Map:entrySet
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.util.Map$Entry:getValue
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.util.Map:get
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.awt.font.TextLayout:getCharacterCount
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.awt.font.TextLayout:hitTestChar
    //#unanalyzed(LineInfo getClickPosition(Point)): Effects-of-calling:java.awt.font.TextHitInfo:getInsertionIndex
    //#test_vector(LineInfo getClickPosition(Point)): point: Addr_Set{null}, Inverse{null}
    //#test_vector(LineInfo getClickPosition(Point)): java.awt.Rectangle:contains(...)@737: {0}, {1}
    //#test_vector(LineInfo getClickPosition(Point)): java.util.Iterator:hasNext(...)@736: {0}, {1}
        int linePart = -1;
        int pos = 0;

        if (point != null) {
            for (Map.Entry<Rectangle, TextLayout> entry : positions.entrySet()) {
                if (entry.getKey().contains(point)) {
                    lineNumber = textLayouts.get(entry.getValue()).getLine();
                    linePart = textLayouts.get(entry.getValue()).getPart();
                }
            }

            pos = getHitPosition(lineNumber, linePart, (int) point.getX(),
                    (int) point.getY());
        }

        return new LineInfo(lineNumber, linePart, pos);
    //#TextPaneCanvas.java:747: end of method: LineInfo com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getClickPosition(Point)
    }

    /**
     * Returns the character index for a specified line and part for a specific hit position.
     * 
     * @param lineNumber Line number
     * @param linePart Line part
     * @param x X position
     * @param y Y position
     * 
     * @return Hit position
     */
    private int getHitPosition(final int lineNumber, final int linePart,
            final int x, final int y) {
        int pos = 0;
    //#TextPaneCanvas.java:762: method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getHitPosition(int, int, int, int)
    //#input(int getHitPosition(int, int, int, int)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LineInfo]
    //#input(int getHitPosition(int, int, int, int)): com/dmdirc/addons/ui_swing/textpane/LineInfo.__Descendant_Table[others]
    //#input(int getHitPosition(int, int, int, int)): lineNumber
    //#input(int getHitPosition(int, int, int, int)): linePart
    //#input(int getHitPosition(int, int, int, int)): this
    //#input(int getHitPosition(int, int, int, int)): this.positions
    //#input(int getHitPosition(int, int, int, int)): this.textLayouts
    //#input(int getHitPosition(int, int, int, int)): x
    //#input(int getHitPosition(int, int, int, int)): y
    //#output(int getHitPosition(int, int, int, int)): return_value
    //#pre[6] (int getHitPosition(int, int, int, int)): this.positions != null
    //#pre[7] (int getHitPosition(int, int, int, int)): (soft) this.textLayouts != null
    //#presumption(int getHitPosition(int, int, int, int)): java.awt.font.TextLayout:hitTestChar(...)@770 != null
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Iterator:next(...)@764 != null
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map:entrySet(...)@764 != null
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map:get(...).__Tag@765 == com/dmdirc/addons/ui_swing/textpane/LineInfo
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map:get(...).__Tag@766 == com/dmdirc/addons/ui_swing/textpane/LineInfo
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map:get(...).__Tag@768 == com/dmdirc/addons/ui_swing/textpane/LineInfo
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map:get(...)@765 != null
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map:get(...)@766 != null
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map:get(...)@768 != null
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map_Entry:getValue(...)@767 != null
    //#presumption(int getHitPosition(int, int, int, int)): java.util.Map_Entry:getValue(...)@770 != null
    //#post(int getHitPosition(int, int, int, int)): init'ed(return_value)
    //#test_vector(int getHitPosition(int, int, int, int)): java.util.Iterator:hasNext(...)@764: {0}, {1}

        for (Map.Entry<Rectangle, TextLayout> entry : positions.entrySet()) {
            if (textLayouts.get(entry.getValue()).getLine() == lineNumber) {
                if (textLayouts.get(entry.getValue()).getPart() < linePart) {
                    pos += entry.getValue().getCharacterCount();
    //#TextPaneCanvas.java:767: ?overflow
    //#    pos + java/awt/font/TextLayout:getCharacterCount(...) in {-2_147_483_648..4_294_967_295}
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: int getHitPosition(int, int, int, int)
    //#    basic block: bb_5
    //#    assertion: pos + java/awt/font/TextLayout:getCharacterCount(...) in {-2_147_483_648..4_294_967_295}
    //#    VN: java.awt.font.TextLayout:getCharacterCount(...)@767 + pos
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {-4_294_967_296..-2_147_483_649, 4_294_967_296..8_589_934_590}
    //#    Attribs:  Int  Bad < Exp  Bad > Exp
                } else if (textLayouts.get(entry.getValue()).getPart() ==
                        linePart) {
                    final TextHitInfo hit = entry.getValue().hitTestChar(x - 6,
                            y);
                    pos += hit.getInsertionIndex();
    //#TextPaneCanvas.java:772: ?overflow
    //#    pos + java/awt/font/TextHitInfo:getInsertionIndex(...) in {-2_147_483_648..4_294_967_295}
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: int getHitPosition(int, int, int, int)
    //#    basic block: bb_7
    //#    assertion: pos + java/awt/font/TextHitInfo:getInsertionIndex(...) in {-2_147_483_648..4_294_967_295}
    //#    VN: java.awt.font.TextHitInfo:getInsertionIndex(...)@772 + pos
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {-4_294_967_296..-2_147_483_649, 4_294_967_296..8_589_934_590}
    //#    Attribs:  Int  Bad < Exp  Bad > Exp
                }
            }
        }

        return pos;
    //#TextPaneCanvas.java:777: end of method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getHitPosition(int, int, int, int)
    }

    /**
     * Returns the selected range info.
     *
     * @return Selected range info
     */
    protected LinePosition getSelectedRange() {
        if (selection.getStartLine() > selection.getEndLine()) {
    //#TextPaneCanvas.java:786: method: LinePosition com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getSelectedRange()
    //#input(LinePosition getSelectedRange()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(LinePosition getSelectedRange()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(LinePosition getSelectedRange()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getEndLine()I
    //#input(LinePosition getSelectedRange()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getEndPos()I
    //#input(LinePosition getSelectedRange()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartLine()I
    //#input(LinePosition getSelectedRange()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartPos()I
    //#input(LinePosition getSelectedRange()): this
    //#input(LinePosition getSelectedRange()): this.selection
    //#input(LinePosition getSelectedRange()): this.selection.__Tag
    //#input(LinePosition getSelectedRange()): this.selection.endLine
    //#input(LinePosition getSelectedRange()): this.selection.endPos
    //#input(LinePosition getSelectedRange()): this.selection.startLine
    //#input(LinePosition getSelectedRange()): this.selection.startPos
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1) num objects
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).__Tag
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).endLine
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).endPos
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).startLine
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).startPos
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2) num objects
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).__Tag
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).endLine
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).endPos
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).startLine
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).startPos
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3) num objects
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).__Tag
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).endLine
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).endPos
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).startLine
    //#output(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).startPos
    //#output(LinePosition getSelectedRange()): return_value
    //#new obj(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1)
    //#new obj(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2)
    //#new obj(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3)
    //#pre[5] (LinePosition getSelectedRange()): this.selection != null
    //#pre[6] (LinePosition getSelectedRange()): this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[7] (LinePosition getSelectedRange()): init'ed(this.selection.endLine)
    //#pre[11] (LinePosition getSelectedRange()): init'ed(this.selection.endPos)
    //#pre[13] (LinePosition getSelectedRange()): init'ed(this.selection.startLine)
    //#pre[14] (LinePosition getSelectedRange()): init'ed(this.selection.startPos)
    //#post(LinePosition getSelectedRange()): return_value in Addr_Set{&new LinePosition(getSelectedRange#2),&new LinePosition(getSelectedRange#3),&new LinePosition(getSelectedRange#1)}
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1) num objects <= 1
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).endLine == this.selection.startLine
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).endLine >= -2_147_483_647
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).endPos == this.selection.startPos
    //#post(LinePosition getSelectedRange()): init'ed(new LinePosition(getSelectedRange#1).endPos)
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).startLine == this.selection.endLine
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).startLine <= 4_294_967_294
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#1).startPos == this.selection.endPos
    //#post(LinePosition getSelectedRange()): init'ed(new LinePosition(getSelectedRange#1).startPos)
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2) num objects <= 1
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).endLine == this.selection.endLine
    //#post(LinePosition getSelectedRange()): init'ed(new LinePosition(getSelectedRange#2).endLine)
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).endPos == this.selection.startPos
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).endPos >= -2_147_483_647
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).startLine == this.selection.startLine
    //#post(LinePosition getSelectedRange()): init'ed(new LinePosition(getSelectedRange#2).startLine)
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).startPos == this.selection.endPos
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#2).startPos <= 4_294_967_294
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3) num objects <= 1
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).endLine == this.selection.endLine
    //#post(LinePosition getSelectedRange()): init'ed(new LinePosition(getSelectedRange#3).endLine)
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).endPos == this.selection.endPos
    //#post(LinePosition getSelectedRange()): init'ed(new LinePosition(getSelectedRange#3).endPos)
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).startLine == this.selection.startLine
    //#post(LinePosition getSelectedRange()): init'ed(new LinePosition(getSelectedRange#3).startLine)
    //#post(LinePosition getSelectedRange()): new LinePosition(getSelectedRange#3).startPos == this.selection.startPos
    //#post(LinePosition getSelectedRange()): init'ed(new LinePosition(getSelectedRange#3).startPos)
    //#test_vector(LinePosition getSelectedRange()): this.selection.endLine - this.selection.startLine: {1..6_442_450_943}, {-6_442_450_943..-1}, {0}
    //#test_vector(LinePosition getSelectedRange()): this.selection.endPos - this.selection.startPos: {0..6_442_450_943}, {-6_442_450_943..-1}
            // Swap both
            return new LinePosition(selection.getEndLine(),
                    selection.getEndPos(), selection.getStartLine(),
                    selection.getStartPos());
        } else if (selection.getStartLine() == selection.getEndLine() &&
                selection.getStartPos() > selection.getEndPos()) {
            // Just swap the chars
            return new LinePosition(selection.getStartLine(), selection.
                    getEndPos(), selection.getEndLine(),
                    selection.getStartPos());
        } else {
            // Swap nothing
            return new LinePosition(selection.getStartLine(), selection.
    //#TextPaneCanvas.java:799: end of method: LinePosition com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getSelectedRange()
                    getStartPos(), selection.getEndLine(),
                    selection.getEndPos());
        }
    }

    /** Clears the selection. */
    protected void clearSelection() {
        selection.setEndLine(selection.getStartLine());
    //#TextPaneCanvas.java:807: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.clearSelection()
    //#input(void clearSelection()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void clearSelection()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void clearSelection()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartLine()I
    //#input(void clearSelection()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartPos()I
    //#input(void clearSelection()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndLine(I)V
    //#input(void clearSelection()): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.setEndPos(I)V
    //#input(void clearSelection()): this
    //#input(void clearSelection()): this.selection
    //#input(void clearSelection()): this.selection.__Tag
    //#input(void clearSelection()): this.selection.startLine
    //#input(void clearSelection()): this.selection.startPos
    //#output(void clearSelection()): this.selection.endLine
    //#output(void clearSelection()): this.selection.endPos
    //#pre[2] (void clearSelection()): this.selection != null
    //#pre[3] (void clearSelection()): this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[4] (void clearSelection()): init'ed(this.selection.startLine)
    //#pre[5] (void clearSelection()): init'ed(this.selection.startPos)
    //#post(void clearSelection()): this.selection.endLine == this.selection.startLine
    //#post(void clearSelection()): init'ed(this.selection.endLine)
    //#post(void clearSelection()): this.selection.endPos == this.selection.startPos
    //#post(void clearSelection()): init'ed(this.selection.endPos)
    //#test_vector(void clearSelection()): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible(...)@809: {0}, {1}
        selection.setEndPos(selection.getStartPos());
        if (isVisible()) {
    //#TextPaneCanvas.java:809: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void clearSelection()
    //#    unanalyzed callee: bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
            repaint();
    //#TextPaneCanvas.java:810: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void clearSelection()
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
        }
    }
    //#TextPaneCanvas.java:812: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.clearSelection()

    /**
     * Selects the specified region of text.
     *
     * @param position Line position
     */
    public void setSelectedRange(final LinePosition position) {
        selection = new LinePosition(position);
    //#TextPaneCanvas.java:820: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.setSelectedRange(LinePosition)
    //#input(void setSelectedRange(LinePosition)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[com/dmdirc/addons/ui_swing/textpane/LinePosition]
    //#input(void setSelectedRange(LinePosition)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Descendant_Table[others]
    //#input(void setSelectedRange(LinePosition)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getEndLine()I
    //#input(void setSelectedRange(LinePosition)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getEndPos()I
    //#input(void setSelectedRange(LinePosition)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartLine()I
    //#input(void setSelectedRange(LinePosition)): com/dmdirc/addons/ui_swing/textpane/LinePosition.__Dispatch_Table.getStartPos()I
    //#input(void setSelectedRange(LinePosition)): position
    //#input(void setSelectedRange(LinePosition)): position.__Tag
    //#input(void setSelectedRange(LinePosition)): position.endLine
    //#input(void setSelectedRange(LinePosition)): position.endPos
    //#input(void setSelectedRange(LinePosition)): position.startLine
    //#input(void setSelectedRange(LinePosition)): position.startPos
    //#input(void setSelectedRange(LinePosition)): this
    //#output(void setSelectedRange(LinePosition)): new LinePosition(setSelectedRange#1) num objects
    //#output(void setSelectedRange(LinePosition)): this.selection.__Tag
    //#output(void setSelectedRange(LinePosition)): this.selection.endLine
    //#output(void setSelectedRange(LinePosition)): this.selection.endPos
    //#output(void setSelectedRange(LinePosition)): this.selection.startLine
    //#output(void setSelectedRange(LinePosition)): this.selection.startPos
    //#output(void setSelectedRange(LinePosition)): this.selection
    //#new obj(void setSelectedRange(LinePosition)): new LinePosition(setSelectedRange#1)
    //#pre[1] (void setSelectedRange(LinePosition)): position != null
    //#pre[2] (void setSelectedRange(LinePosition)): position.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#pre[3] (void setSelectedRange(LinePosition)): init'ed(position.endLine)
    //#pre[4] (void setSelectedRange(LinePosition)): init'ed(position.endPos)
    //#pre[5] (void setSelectedRange(LinePosition)): init'ed(position.startLine)
    //#pre[6] (void setSelectedRange(LinePosition)): init'ed(position.startPos)
    //#post(void setSelectedRange(LinePosition)): this.selection == &new LinePosition(setSelectedRange#1)
    //#post(void setSelectedRange(LinePosition)): new LinePosition(setSelectedRange#1) num objects == 1
    //#post(void setSelectedRange(LinePosition)): this.selection.__Tag == com/dmdirc/addons/ui_swing/textpane/LinePosition
    //#post(void setSelectedRange(LinePosition)): this.selection.endLine == position.endLine
    //#post(void setSelectedRange(LinePosition)): init'ed(this.selection.endLine)
    //#post(void setSelectedRange(LinePosition)): this.selection.endPos == position.endPos
    //#post(void setSelectedRange(LinePosition)): init'ed(this.selection.endPos)
    //#post(void setSelectedRange(LinePosition)): this.selection.startLine == position.startLine
    //#post(void setSelectedRange(LinePosition)): init'ed(this.selection.startLine)
    //#post(void setSelectedRange(LinePosition)): this.selection.startPos == position.startPos
    //#post(void setSelectedRange(LinePosition)): init'ed(this.selection.startPos)
    //#test_vector(void setSelectedRange(LinePosition)): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible(...)@821: {0}, {1}
        if (isVisible()) {
    //#TextPaneCanvas.java:821: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void setSelectedRange(LinePosition)
    //#    unanalyzed callee: bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
            repaint();
    //#TextPaneCanvas.java:822: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void setSelectedRange(LinePosition)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
        }
    }
    //#TextPaneCanvas.java:824: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.setSelectedRange(LinePosition)

    /**nee
     * Returns the first visible line.
     *
     * @return the line number of the first visible line
     */
    public int getFirstVisibleLine() {
        return firstVisibleLine;
    //#TextPaneCanvas.java:832: method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getFirstVisibleLine()
    //#input(int getFirstVisibleLine()): this
    //#input(int getFirstVisibleLine()): this.firstVisibleLine
    //#output(int getFirstVisibleLine()): return_value
    //#pre[2] (int getFirstVisibleLine()): init'ed(this.firstVisibleLine)
    //#post(int getFirstVisibleLine()): return_value == this.firstVisibleLine
    //#post(int getFirstVisibleLine()): init'ed(return_value)
    //#TextPaneCanvas.java:832: end of method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getFirstVisibleLine()
    }

    /**
     * Returns the last visible line.
     *
     * @return the line number of the last visible line
     */
    public int getLastVisibleLine() {
        return lastVisibleLine;
    //#TextPaneCanvas.java:841: method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getLastVisibleLine()
    //#input(int getLastVisibleLine()): this
    //#input(int getLastVisibleLine()): this.lastVisibleLine
    //#output(int getLastVisibleLine()): return_value
    //#pre[2] (int getLastVisibleLine()): init'ed(this.lastVisibleLine)
    //#post(int getLastVisibleLine()): return_value == this.lastVisibleLine
    //#post(int getLastVisibleLine()): init'ed(return_value)
    //#TextPaneCanvas.java:841: end of method: int com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.getLastVisibleLine()
    }

    /** 
     * {@inheritDoc}
     * 
     * @param e Component event
     */
    @Override
    public void componentResized(final ComponentEvent e) {
        //line wrap cache now invalid, clear and repaint
        lineWrap.clear();
    //#TextPaneCanvas.java:852: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.componentResized(ComponentEvent)
    //#input(void componentResized(ComponentEvent)): this
    //#input(void componentResized(ComponentEvent)): this.lineWrap
    //#pre[2] (void componentResized(ComponentEvent)): this.lineWrap != null
    //#test_vector(void componentResized(ComponentEvent)): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible(...)@853: {0}, {1}
        if (isVisible()) {
    //#TextPaneCanvas.java:853: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void componentResized(ComponentEvent)
    //#    unanalyzed callee: bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
            repaint();
    //#TextPaneCanvas.java:854: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void componentResized(ComponentEvent)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
        }
    }
    //#TextPaneCanvas.java:856: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.componentResized(ComponentEvent)

    /** 
     * {@inheritDoc}
     * 
     * @param e Component event
     */
    @Override
    public void componentMoved(final ComponentEvent e) {
        //Ignore
    }
    //#TextPaneCanvas.java:866: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.componentMoved(ComponentEvent)
    //#TextPaneCanvas.java:866: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.componentMoved(ComponentEvent)

    /** 
     * {@inheritDoc}
     * 
     * @param e Component event
     */
    @Override
    public void componentShown(final ComponentEvent e) {
        //Ignore
    }
    //#TextPaneCanvas.java:876: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.componentShown(ComponentEvent)
    //#TextPaneCanvas.java:876: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.componentShown(ComponentEvent)

    /** 
     * {@inheritDoc}
     * 
     * @param e Component event
     */
    @Override
    public void componentHidden(final ComponentEvent e) {
        //Ignore
    }
    //#TextPaneCanvas.java:886: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.componentHidden(ComponentEvent)
    //#TextPaneCanvas.java:886: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.componentHidden(ComponentEvent)

    /** Clears the line wrapping cache. */
    protected void clearWrapCache() {
        UIUtilities.invokeLater(new Runnable() {
    //#TextPaneCanvas.java:890: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1(TextPaneCanvas)
    //#input(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1(TextPaneCanvas)): Param_1
    //#input(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1(TextPaneCanvas)): this
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1(TextPaneCanvas)): this.this$0
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1(TextPaneCanvas)): this.this$0 == Param_1
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1(TextPaneCanvas)): init'ed(this.this$0)
    //#TextPaneCanvas.java:890: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1(TextPaneCanvas)
    //#TextPaneCanvas.java:890: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.clearWrapCache()
    //#TextPaneCanvas.java:890: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.UIUtilities:invokeLater(Runnable)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void clearWrapCache()
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.UIUtilities:invokeLater(Runnable)
    //#input(void clearWrapCache()): this

            /** {@inheritDoc} */
            @Override
            public void run() {
                lineWrap.clear();
    //#TextPaneCanvas.java:895: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1.run()
    //#input(void run()): this
    //#input(void run()): this.this$0
    //#input(void run()): this.this$0.lineWrap
    //#pre[2] (void run()): this.this$0 != null
    //#pre[3] (void run()): this.lineWrap != null
            }
    //#TextPaneCanvas.java:896: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1.run()
        });
    }
    //#TextPaneCanvas.java:898: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.clearWrapCache()

    /** {@inheritDoc} */
    @Override
    public void configChanged(final String domain, final String key) {
        UIUtilities.invokeLater(new Runnable() {
    //#TextPaneCanvas.java:903: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2(TextPaneCanvas)
    //#input(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2(TextPaneCanvas)): Param_1
    //#input(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2(TextPaneCanvas)): this
    //#output(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2(TextPaneCanvas)): this.this$0
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2(TextPaneCanvas)): this.this$0 == Param_1
    //#post(void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2(TextPaneCanvas)): init'ed(this.this$0)
    //#TextPaneCanvas.java:903: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2(TextPaneCanvas)
    //#TextPaneCanvas.java:903: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.configChanged(String, String)
    //#TextPaneCanvas.java:903: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.UIUtilities:invokeLater(Runnable)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
    //#    method: void configChanged(String, String)
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.UIUtilities:invokeLater(Runnable)
    //#input(void configChanged(String, String)): this

            /** {@inheritDoc} */
            @Override
            public void run() {
                if (isVisible()) {
    //#TextPaneCanvas.java:908: method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2.run()
    //#TextPaneCanvas.java:908: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2
    //#    method: void run()
    //#    unanalyzed callee: bool com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible()
    //#input(void run()): this
    //#input(void run()): this.this$0
    //#pre[2] (void run()): this.this$0 != null
    //#test_vector(void run()): com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:isVisible(...)@908: {0}, {1}
                    repaint();
    //#TextPaneCanvas.java:909: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2
    //#    method: void run()
    //#    unanalyzed callee: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas:repaint()
                }
            }
    //#TextPaneCanvas.java:911: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2.run()
        });
    }
    //#TextPaneCanvas.java:913: end of method: void com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas.configChanged(String, String)
}
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2__static_init): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas$2]
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2__static_init): __Dispatch_Table.run()V
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2__static_init): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas$2] == &__Dispatch_Table
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2__static_init): __Dispatch_Table.run()V == &run
    //#TextPaneCanvas.java:: end of method: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2__static_init
    //#TextPaneCanvas.java:: end of class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$2
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1__static_init): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas$1]
    //#output(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1__static_init): __Dispatch_Table.run()V
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1__static_init): __Descendant_Table[com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas$1] == &__Dispatch_Table
    //#post(com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1__static_init): __Dispatch_Table.run()V == &run
    //#TextPaneCanvas.java:: end of method: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1.com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1__static_init
    //#TextPaneCanvas.java:: end of class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas$1
    //#TextPaneCanvas.java:: end of class: com.dmdirc.addons.ui_swing.textpane.TextPaneCanvas
