//----------------------------------------------------------------
// Example 1: Method appears generic from documentation, but it
// is actually highly specialized (also, documentation stale)
//---------------------------------------------------------------- 

/**
 * Tries to wrap cursor at Position p onto previous or next line if
 * "Left" was pressed and cursor crosses left bound, or if "Right"
 * was pressed and cursor crosses right bound.
 * @param p         Position to wrap.
 * @param keyCode   The code of the key that was pressed
 *                  (either left or right).
 * @return          NULL if we can't wrap p at all, or the resulting
 *                  "in-bounds" Position p.
 */
private Position boundedMove(Position p, int indexChange, int lineChange) {
    Position new_p = new Position(p);
    new_p.index += indexChange;
    new_p.line += lineChange;

    // If moving left or right don't remember "ghost" column index.
    if (indexChange != 0)
        savedCursorIndex = new_p.index;

    // If we moved "left" at the beginning of a line, jump to end of
    // previous line.
    if (indexChange < 0 && new_p.index < 0) {
        new_p.line--;
        new_p.index = buffer.getData().getLine(new_p.line).length();
    }

    // If we moved "right" at the end of a line, jump to beginning of
    // next line.
    if (indexChange > 0 && new_p.index == 
            buffer.getData().getLine(new_p.line).length() + 1) {
        new_p.line ++;
        new_p.index = 0;
    }

    // "Remember" index across multiple lines.
    if (lineChange != 0) {
        int max_index = buffer.getData().getLine(new_p.line).length();
        if (savedCursorIndex > new_p.index)
            new_p.index = savedCursorIndex;
        if (max_index < new_p.index)
            new_p.index = max_index;
    }

    if (new_p.line < 0 || new_p.line >= buffer.getData().getNumberOfLines())
        return p;
    return new_p;
}

//----------------------------------------------------------------
// Example 2: Inconsistent argument ordering (and poor name choice)
//----------------------------------------------------------------

public Position(int line, int index) {
    this.line = line;
    this.index = index;
}

public void move(int dx, int dy) {
    index += dx;
    line += dy;
}

//----------------------------------------------------------------
// Example 3: "for" loop suggests that the code is working backwards,
// but the body appears to be in the other order. Also, special
// case for delete (collecting deletedContent even when not deleting?).
//----------------------------------------------------------------

    int curr = 1;
    for (int betweenLine = end.line; betweenLine > start.line; betweenLine--) {
        deletedContent+="\n";
        if (betweenLine != start.line + 1)
            if (!delete) {
                deletedContent += this.fileContents.get(start.line + curr);
                curr++;
            }
            else
                deletedContent += this.fileContents.get(start.line + 1);
        if (delete)
            fileContents.remove(start.line + 1);
    }
    

//----------------------------------------------------------------
// Example 4: classes for GUI.
//----------------------------------------------------------------

public class Editor implements KeyListener, WindowFocusListener,
        WindowListener, EditorPanelChangeListener ...

/***
 * A panel that displays an editable text document, with scroll bars to make 
 * off-screen text visible.
 */
public class EditorPanel extends JPanel implements MouseListener,
        MouseMotionListener, DocumentChangeListener

//----------------------------------------------------------------
// Example 5: classes for GUI.
//----------------------------------------------------------------

/**
 * The main program for the text editor application.
 */
public class TextEditorGUI ...

/**
 * The view that displays the text.
 */
public class TextEditorPanel ...
    ...
    protected final TextEditorController controller;
    ...
    protected TextEditorPanel(TextEditorModel model) {
        ...
        controller = new TextEditorController(this, model);
        ...
        addKeyListener(controller);         // Keyboard listener
        addMouseListener(controller);       // Mouse listener
        addMouseMotionListener(controller); // Mouse motion listener
        ...
    }

/**
 * Module that handles the user input from the keyboard and the mouse and
 * creates the commands to update the text and the display
 */
public class TextEditorController ...
    

//----------------------------------------------------------------
// Example 6: does header documentation need to mention that
// line lengths get updated?
//----------------------------------------------------------------

/**
 * Helper method that Removes the supplied line from the TextBuffer
 *
 * @param lineIndex index of the line to be removed
 */
private void removeLine(int lineIndex) {
    StringBuffer lineBuffer = lines.get(lineIndex);
    int lineLength = lineBuffer.length();
    int count = lineLengthMap.get(lineLength);
    lineLengthMap.put(lineLength, count - 1);
    if (lineLengthMap.get(lineLength) == 0) {
        lineLengthMap.remove(lineLength);
    }
    lines.remove(lineIndex);
}


//----------------------------------------------------------------
// Example 7: what's wrong with this documentation?
//----------------------------------------------------------------

/**
 * Returns the <code>TextRange</code> of the currently selected text, or
 * null if no text is currently selected.
 * <p>
 * Specifically, the selected area starts right before the character
 * specified by the start position of the returned <code>TextRange</code>
 * and ends right before the character specified by the end position of the
 * returned <code>TextRange</code>.
 * 
 * @return the <code>TextRange</code> of the currently selected text, or
 *         null
 */
public TextRange getSelection() {...}