Index: unk/src/org/expeditee/AbsoluteLayout.java
===================================================================
--- /trunk/src/org/expeditee/AbsoluteLayout.java	(revision 1098)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/**
- *    AbsoluteLayout.java
- *    Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
- *
- *    This program is free software: you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation, either version 3 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.expeditee;
-
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.LayoutManager;
-
-public class AbsoluteLayout implements LayoutManager {
-
-	public void addLayoutComponent(String name, Component comp) {}
-	public void removeLayoutComponent(Component comp) {}
-	
-	
-	
-	public Dimension minimumLayoutSize(Container parent) {
-		return parent.getMinimumSize();
-	}
-
-	public Dimension preferredLayoutSize(Container parent) {
-		return parent.getPreferredSize();
-	}
-
-	public void layoutContainer(Container parent) {}
-
-}
Index: unk/src/org/expeditee/gui/DisplayIO.java
===================================================================
--- /trunk/src/org/expeditee/gui/DisplayIO.java	(revision 1098)
+++ 	(revision )
@@ -1,1038 +1,0 @@
-/**
- *    DisplayIO.java
- *    Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
- *
- *    This program is free software: you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation, either version 3 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.expeditee.gui;
-
-import java.awt.AWTException;
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Robot;
-import java.awt.Toolkit;
-import java.awt.event.KeyEvent;
-import java.awt.geom.Point2D;
-import java.awt.image.MemoryImageSource;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Stack;
-
-import javax.swing.JOptionPane;
-
-import org.expeditee.items.Item;
-import org.expeditee.items.ItemParentStateChangedEvent;
-import org.expeditee.items.ItemUtils;
-import org.expeditee.items.Picture;
-import org.expeditee.items.Text;
-import org.expeditee.items.MagneticConstraint.MagneticConstraints;
-import org.expeditee.settings.UserSettings;
-import org.expeditee.stats.SessionStats;
-import org.expeditee.taskmanagement.EntitySaveManager;
-
-/**
- * This Interface is used by the Frame to control all display input and output.
- * 
- * @author jdm18
- * 
- */
-public class DisplayIO {
-
-	private static final int SMALL_CURSOR_SIZE = 16;
-
-	private static final int MEDIUM_CURSOR_SIZE = 32;
-
-	private static final int LARGE_CURSOR_SIZE = 64;
-
-	/**
-	 * The color to be used to highlight the linked parent item, when the user
-	 * navigates backwards.
-	 */
-	public static final Color BACK_HIGHLIGHT_COLOR = Color.MAGENTA;
-
-	private static Browser _Browser;
-
-	// The current Frame being displayed on the screen.
-	private static Frame _CurrentFrames[] = new Frame[2];
-
-	// Maintains the list of frames visited thus-far for back-tracking
-	@SuppressWarnings("unchecked")
-	private static Stack<String>[] _VisitedFrames = new Stack[2];
-
-	@SuppressWarnings("unchecked")
-	private static Stack<String>[] _BackedUpFrames = new Stack[2];
-
-	// used to change the mouse cursor position on the screen
-	private static Robot _Robot;
-
-	private static boolean _TwinFrames = false;
-
-	/** Notified whenever the frame changes */
-	private static HashSet<DisplayIOObserver> _displayIOObservers = new HashSet<DisplayIOObserver>();
-
-	private static GraphicsDevice screen = null;
-    
-	/**
-	 * The title to display in the Title bar.
-	 */
-	public static String TITLE = "Expedite";
-
-	private DisplayIO() {
-	}
-
-	public static void Init(Browser browser) {
-		_Browser = browser;
-		try {
-			_Robot = new Robot();
-		} catch (AWTException e) {
-			e.printStackTrace();
-		}
-
-		Point mouse = _Browser.getMousePosition();
-		if (mouse != null) {
-			FrameMouseActions.MouseX = mouse.x;
-			FrameMouseActions.MouseY = mouse.y;
-		}
-
-		_VisitedFrames[0] = new Stack<String>();
-		_VisitedFrames[1] = new Stack<String>();
-		_BackedUpFrames[0] = new Stack<String>();
-		_BackedUpFrames[1] = new Stack<String>();
-
-		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
-		screen = ge.getDefaultScreenDevice();
-		if (!screen.isFullScreenSupported()) {
-			// Can this be printed to the MessageBuffer
-			MessageBay.errorMessage("Full-screen mode not supported");
-			screen =null;
-		}
-	}
-
-	public static boolean fullScreenTransitionPending = false;
-	public static int beforeFullScreenWidth  = 0;
-	public static int beforeFullScreenHeight = 0;
-	public static boolean fullScreenCapable()
-	{
-		return (screen!=null);
-	}
-	
-	public static void enterFullScreenMode()
-	{
-		if (screen!=null) {
-			// Move all these routines to Browser?
-			beforeFullScreenWidth  = _Browser.getWidth();
-			beforeFullScreenHeight = _Browser.getHeight();
-			
-			fullScreenTransitionPending=true;
-			_Browser.dispose();
-			_Browser.setUndecorated(true);
-			_Browser.pack();
-			_Browser.setVisible(true);
-		        
-			screen.setFullScreenWindow(_Browser);
-		
-		}
-		else {
-			System.err.println("Warning: DisplayIO::enterFullScreenMode() called when not available -- ignoring");
-		}
-	}
-	
-	public static void leaveFullScreenMode()
-	{
-		fullScreenTransitionPending=true;
-		_Browser.dispose();
-		_Browser.setUndecorated(false);
-		_Browser.setSizes(new Dimension(beforeFullScreenWidth, beforeFullScreenHeight));
-		
-		screen.setFullScreenWindow(null);
-		_Browser.pack();
-		_Browser.setVisible(true);
-	}
-	
-	
-	/**
-	 * Notifies observers that the frame has changed.
-	 */
-	private static void fireFrameChanged() {
-		for (DisplayIOObserver observer : _displayIOObservers) {
-			observer.frameChanged();
-		}
-	}
-
-	/**
-	 * Adds a DisplayIOObserver to the DisplayIO. DisplayIOObserver's are
-	 * notified when frame changes.
-	 * 
-	 * @see #removeDisplayIOObserver(DisplayIOObserver)
-	 * 
-	 * @param observer
-	 *            The observer to add
-	 * 
-	 * @throws NullPointerException
-	 *             If observer is null.
-	 */
-	public static void addDisplayIOObserver(DisplayIOObserver observer) {
-		if (observer == null)
-			throw new NullPointerException("observer");
-		_displayIOObservers.add(observer);
-	}
-
-	/**
-	 * Removes a DisplayIOObserver from the DisplayIO.
-	 * 
-	 * @see #addDisplayIOObserver(DisplayIOObserver)
-	 * 
-	 * @param observer
-	 *            The observer to add
-	 * 
-	 * @throws NullPointerException
-	 *             If observer is null.
-	 */
-	public static void removeDisplayIOObserver(DisplayIOObserver observer) {
-		if (observer == null)
-			throw new NullPointerException("observer");
-		_displayIOObservers.remove(observer);
-	}
-
-	public static void setTextCursor(Text text, int cursorMovement) {
-		setTextCursor(text, cursorMovement, false, false, false, false);
-	}
-
-	public static void setTextCursor(Text text, int cursorMovement,
-			boolean newSize, boolean isShiftDown, boolean isCtrlDown,
-			boolean allowClearSelection) {
-
-		int size = Math.round(text.getSize());
-		if (allowClearSelection && !isShiftDown && text.hasSelection())
-			text.clearSelection();
-
-		Point2D.Float newMouse = text.moveCursor(cursorMovement, DisplayIO
-				.getFloatMouseX(), FrameMouseActions.MouseY, isShiftDown,
-				isCtrlDown);
-						
-		if(isCtrlDown 
-				|| (DisplayIO.getFloatMouseX() + 1 >= newMouse.x && DisplayIO.getFloatMouseX() <= newMouse.x)
-				|| (DisplayIO.getFloatMouseX() > newMouse.x && cursorMovement == Text.RIGHT)) {
-			if(cursorMovement == Text.RIGHT && !MagneticConstraints.getInstance().rightBorderHit(text)) {
-				MagneticConstraints.getInstance().endOfLineHit(text);
-			} else {
-				if(cursorMovement == Text.LEFT && !MagneticConstraints.getInstance().leftBorderHit(text)) {
-					MagneticConstraints.getInstance().startOfLineHit(text);
-				}
-			}
-			newMouse.x = DisplayIO.getFloatMouseX();
-			newMouse.y = DisplayIO.getFloatMouseY();
-		} else if(cursorMovement == Text.UP && MagneticConstraints.getInstance().topBorderHit(text)) {
-			newMouse.x = DisplayIO.getFloatMouseX();
-			newMouse.y = DisplayIO.getFloatMouseY();
-		} else if(cursorMovement == Text.DOWN && MagneticConstraints.getInstance().bottomBorderHit(text)) {
-			newMouse.x = DisplayIO.getFloatMouseX();
-			newMouse.y = DisplayIO.getFloatMouseY();
-		}
-
-		if (!newSize && cursorType == Item.TEXT_CURSOR) {
-			if (cursorMovement != 0)
-				DisplayIO.setCursorPosition(newMouse, false);
-			return;
-		}
-
-		cursorType = Item.TEXT_CURSOR;
-
-		// Do some stuff to adjust the cursor size based on the font size
-		final int MEDIUM_CURSOR_CUTOFF = 31;
-		final int LARGE_CURSOR_CUTOFF = 62;
-
-		int cursorSize = LARGE_CURSOR_SIZE;
-		int hotspotPos = 0;
-		int start = 0;
-
-		Toolkit toolkit = Toolkit.getDefaultToolkit();
-		Dimension best_cursor_dim = toolkit.getBestCursorSize(cursorSize,cursorSize);
-		int best_cursor_height = best_cursor_dim.height;
-		
-		if (best_cursor_height < cursorSize) {
-			// not able to provide the size of cursor Expeditee wants to
-			// => lock on to 'best_cursor_height' and use this to generate dependent values
-			cursorSize = best_cursor_height; // OS + Java version dependent: most likely MEDIUM_CURSOR_SIZE
-			if (size < best_cursor_height) {
-				start = cursorSize - size - 1;
-				hotspotPos = cursorSize - (size + 1) / 4;
-			}
-			else {
-				start = size - best_cursor_height;
-				hotspotPos = cursorSize -1;
-			}
-			
-		}
-		else if (size < MEDIUM_CURSOR_CUTOFF) {
-			cursorSize = MEDIUM_CURSOR_SIZE;
-			start = cursorSize - size - 1;
-			hotspotPos = cursorSize - (size + 1) / 4;
-		} else if (size < LARGE_CURSOR_CUTOFF) {
-			hotspotPos = cursorSize - (size - 5) / 4;
-			start = cursorSize - size - 2;
-		} else {
-			int FIXED_CURSOR_MIN = 77;
-			if (size >= FIXED_CURSOR_MIN) {
-				hotspotPos = cursorSize - 2;
-			} else {
-				hotspotPos = size - (FIXED_CURSOR_MIN - cursorSize);
-			}
-		}
-		
-		int[] pixels = new int[cursorSize * cursorSize];
-
-		for (int i = start; i < cursorSize; i++) {
-			pixels[i * cursorSize] = pixels[i * cursorSize + 1] = 0xFF000000;
-		}
-
-		MemoryImageSource memory_image = new MemoryImageSource(cursorSize, cursorSize, pixels, 0, cursorSize);
-		Image image = toolkit.createImage(memory_image);
-		
-		Cursor textCursor = toolkit.createCustomCursor(image, new Point(0, hotspotPos), "textcursor");
-		_Browser.setCursor(textCursor);
-		
-		if (cursorMovement != Text.NONE) {
-			DisplayIO.setCursorPosition(newMouse, false);
-		}
-	}
-
-	/**
-	 * Sets the type of cursor the display should be using
-	 * 
-	 * @param type
-	 *            The type of cursor to display, using constants defined in the
-	 *            Cursor class.
-	 */
-	public static void setCursor(int type) {
-		// avoid flicker when not changing
-		if (type == cursorType || type == Item.UNCHANGED_CURSOR)
-			return;
-
-		cursorType = type;
-		
-		if(_Browser != null){
-			refreshCursor();
-		}
-	}
-	
-	public static void refreshCursor() {
-		if (cursorType == Item.HIDDEN_CURSOR
-				|| (FreeItems.hasCursor() && cursorType == Item.DEFAULT_CURSOR)) {
-			int[] pixels = new int[SMALL_CURSOR_SIZE * SMALL_CURSOR_SIZE];
-			Image image = Toolkit.getDefaultToolkit().createImage(
-					new MemoryImageSource(SMALL_CURSOR_SIZE, SMALL_CURSOR_SIZE,
-							pixels, 0, SMALL_CURSOR_SIZE));
-			Cursor transparentCursor = Toolkit.getDefaultToolkit()
-					.createCustomCursor(image, new Point(0, 0),
-							"invisiblecursor");
-				_Browser.setCursor(transparentCursor);
-		} else 
-			_Browser.setCursor(new Cursor(cursorType));
-	}
-
-	private static int cursorType = Item.DEFAULT_CURSOR;
-
-	public static int getCursor() {
-		return cursorType;
-	}
-
-	/**
-	 * Moves the mouse cursor to the given x,y coordinates on the screen
-	 * 
-	 * @param x
-	 *            The x coordinate
-	 * @param y
-	 *            The y coordinate
-	 */
-	public static void setCursorPosition(float x, float y) {
-		setCursorPosition(x, y, true);
-	}
-
-	public static void setCursorPosition(float x, float y, boolean forceArrow) {
-		// Adjust the position to move the mouse to to account for being in
-		// TwinFramesMode
-		if (_TwinFrames) {
-			if (getCurrentSide() == 1) {
-				int middle = getMiddle();
-				x += middle;
-			}
-		}
-
-		float deltax = x - FrameMouseActions.MouseX;
-		float deltay = y - FrameMouseActions.MouseY;
-
-		// When the Robot moves the cursor... a short time later a mouseMoved
-		// event is generated...
-		// We want to ignore this event by remembering the location the robot
-		// was shifted to.
-		FrameMouseActions.setLastRobotMove(x, y);
-
-		if (FreeItems.itemsAttachedToCursor()) {
-			List<Item> toMove = FreeItems.getInstance();
-			for (Item move : toMove) {
-				move.setPosition(move.getX() + deltax, move.getY() + deltay);
-			}
-		}
-
-		// cheat
-		FrameMouseActions.setForceArrow(forceArrow);
-		int mouseX = (int) _Browser.getContentPane().getLocationOnScreen()
-				.getX()
-				+ Math.round(x);
-		int mouseY = (int) _Browser.getContentPane().getLocationOnScreen()
-				.getY()
-				+ Math.round(y);
-		_Robot.mouseMove(mouseX, mouseY);
-		// System.out.println("MouseMoved: " + x + "," + y);
-	}
-
-	public static void resetCursorOffset() {
-		FrameMouseActions.resetOffset();
-	}
-
-	/**
-	 * Sets the current cursor position in the current frame
-	 * 
-	 * @param pos
-	 */
-	public static void setCursorPosition(Point2D.Float pos) {
-		setCursorPosition(pos.x, pos.y);
-	}
-
-	public static void setCursorPosition(Point pos) {
-		setCursorPosition(pos.x, pos.y);
-	}
-
-	public static void setCursorPosition(Point pos, boolean forceArrow) {
-		setCursorPosition(pos.x, pos.y, forceArrow);
-	}
-
-	public static void setCursorPosition(Point2D.Float pos, boolean forceArrow) {
-		setCursorPosition(pos.x, pos.y, forceArrow);
-	}
-
-	/**
-	 * Returns the top item (last added) of the Back-Stack (which is popped off)
-	 * 
-	 * @return The name of the last Frame added to the back-stack
-	 */
-	public static String getLastFrame() {
-		int side = getCurrentSide();
-
-		if (_VisitedFrames[side].size() > 0)
-			return _VisitedFrames[side].pop();
-		else
-			return null;
-	}
-
-	/**
-	 * Adds the given Frame to the back-stack
-	 * 
-	 * @param frame
-	 *            The Frame to add
-	 */
-	public static void addToBack(Frame toAdd) {
-		int side = getCurrentSide();
-
-		// // do not allow duplicate frames
-		// if (_VisitedFrames[side].size() > 0)
-		// if (_VisitedFrames[side].peek().equals(toAdd.getName())) {
-		// return;
-		// }
-
-		Item ip = FrameUtils.getCurrentItem();
-		if (ip == null)
-			_VisitedFrames[side].push(toAdd.getName());
-		else
-			_VisitedFrames[side].push(toAdd.getName());
-		// System.out.println("Added: " + _VisitedFrames[side].size());
-	}
-
-	public static String removeFromBack() {
-		int side = getCurrentSide();
-
-		// there must be a frame to go back to
-		if (_VisitedFrames[side].size() > 0) {
-			return _VisitedFrames[side].pop();
-		}
-		return null;
-	}
-
-	/**
-	 * Returns a 'peek' at the end element on the back-stack of the current
-	 * side. If the back-stack is empty, null is returned.
-	 * 
-	 * @return The name of the most recent Frame added to the back-stack, or
-	 *         null if the back-stack is empty.
-	 */
-	public static String peekFromBackUpStack() {
-		int side = getCurrentSide();
-
-		// check that the stack is not empty
-		if (_VisitedFrames[side].size() > 0)
-			return _VisitedFrames[side].peek();
-
-		// if the stack is empty, return null
-		return null;
-	}
-
-	public static void setCurrentFrame(Frame frame, boolean incrementStats) {
-		if (frame == null)
-			return;
-
-		if (_TwinFrames) {
-			if (_CurrentFrames[0] == null) {
-				_CurrentFrames[0] = frame;
-				fireFrameChanged();
-				return;
-			}
-			if (_CurrentFrames[1] == null) {
-				_CurrentFrames[1] = frame;
-				fireFrameChanged();
-				return;
-			}
-		}
-
-		// if this is already the current frame
-		if (frame == getCurrentFrame()) {
-			FrameGraphics.Repaint();
-			MessageBay.displayMessage(frame.getName()
-					+ " is already the current frame.");
-			return;
-		} else if (incrementStats) {
-			SessionStats.AccessedFrame();
-		}
-
-		// Invalidate free items
-		if (!FreeItems.getInstance().isEmpty() && getCurrentFrame() != null) {
-
-			// Empty free items temporarily so that the old frames buffer is
-			// repainted
-			// without the free items.
-			ArrayList<? extends Item> tmp = (ArrayList<? extends Item>) FreeItems
-					.getInstance().clone();
-			FreeItems.getInstance().clear(); // NOTE: This will invalidate
-			// all the cleared free items
-			FrameGraphics.refresh(true);
-			FreeItems.getInstance().addAll(tmp);
-
-		}
-
-		// Changing frames is a Save point for saveable entities:
-		EntitySaveManager.getInstance().saveAll();
-
-		if (_TwinFrames) {
-			// if the same frame is being shown in both sides, load a fresh
-			// copy from disk
-			if (_CurrentFrames[getOppositeSide()] == frame
-					|| _CurrentFrames[getOppositeSide()].hasOverlay(frame)) {
-				FrameIO.SuspendCache();
-				frame = FrameIO.LoadFrame(frame.getName());
-				FrameIO.ResumeCache();
-			}
-
-			// If the frames are the same then the items for the
-			// frame that is just about to hide will still be in view
-			// so only notify items that they are hidden if the
-			// frames differ.
-			if (_CurrentFrames[getCurrentSide()] != null
-					&& _CurrentFrames[0] != _CurrentFrames[1]) {
-				for (Item i : _CurrentFrames[getCurrentSide()].getItems()) {
-					i.onParentStateChanged(new ItemParentStateChangedEvent(
-							_CurrentFrames[getCurrentSide()],
-							ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN));
-				}
-			}
-			_CurrentFrames[getCurrentSide()] = frame;
-
-			// BROOK : TODO... overlays and loadable widgets
-			for (Item i : _CurrentFrames[getCurrentSide()].getItems()) {
-				i.onParentStateChanged(new ItemParentStateChangedEvent(
-						_CurrentFrames[getCurrentSide()],
-						ItemParentStateChangedEvent.EVENT_TYPE_SHOWN));
-			}
-		} else {
-
-			// Notifying items on the frame being hidden that they
-			// are about to be hidden.
-			// ie. Widgets use this method to remove themselves from the JPanel
-			List<Frame> currentOnlyOverlays = new LinkedList<Frame>();
-			List<Frame> nextOnlyOverlays = new LinkedList<Frame>();
-			List<Frame> sharedOverlays = new LinkedList<Frame>();
-
-			// Get all overlayed frames seen by the next frame
-			for (Overlay o : frame.getOverlays()) {
-				if (!nextOnlyOverlays.contains(o))
-					nextOnlyOverlays.add(o.Frame);
-			}
-
-			// Get all overlayed frames seen by the current frame
-			if (_CurrentFrames[getCurrentSide()] != null) {
-				for (Overlay o : _CurrentFrames[getCurrentSide()].getOverlays()) {
-					if (!currentOnlyOverlays.contains(o))
-						currentOnlyOverlays.add(o.Frame);
-				}
-			}
-
-			// Extract shared overlays between the current and next frame
-			for (Frame of : currentOnlyOverlays) {
-				if (nextOnlyOverlays.contains(of)) {
-					sharedOverlays.add(of);
-				}
-			}
-
-			// The first set, currentOnlyOverlays, must be notified that they
-			// are hidden
-			Collection<Item> items = new LinkedList<Item>();
-
-			// Notify items that will not be in view any more
-			if (_CurrentFrames[getCurrentSide()] != null) {
-				List<Frame> seen = new LinkedList<Frame>();
-				seen.addAll(sharedOverlays); // Signify that seen all shared
-				// overlays
-				seen.remove(_CurrentFrames[getCurrentSide()]); // must ensure
-				// excluded
-
-				// Get all items seen from the current frame - including all
-				// possible non-shared overlays
-				items = _CurrentFrames[getCurrentSide()].getAllItems();
-				for (Frame f : seen)
-					items.removeAll(f.getAllItems());
-
-				// Notify items that they are hidden
-				for (Item i : items) {
-					i.onParentStateChanged(new ItemParentStateChangedEvent(
-							_CurrentFrames[getCurrentSide()],
-							ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN));
-				}
-			}
-
-			// Set the new frame
-			_CurrentFrames[getCurrentSide()] = frame;
-			frame.refreshSize();
-			// Notify items on the frame being displayed that they are in view
-			// ie. widgets use this method to add themselves to the content pane
-			items.clear();
-
-			// Notify overlay items that they are shown
-			for (Item i : frame.getOverlayItems()) {
-				Overlay owner = frame.getOverlayOwner(i);
-				// if (owner == null) i.onParentFameShown(false, 0);
-				// else ...
-				assert (owner != null);
-				i
-						.onParentStateChanged(new ItemParentStateChangedEvent(
-								frame,
-								ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY,
-								owner.permission));
-			}
-
-			for (Item i : frame.getItems()) {
-				i.onParentStateChanged(new ItemParentStateChangedEvent(frame,
-						ItemParentStateChangedEvent.EVENT_TYPE_SHOWN));
-			}
-		}
-		
-		frame.reset();
-		
-		// fix text items
-		ItemUtils.Justify(frame);
-		
-		FrameMouseActions.getInstance().refreshHighlights();
-		FrameGraphics.refresh(false);
-		fireFrameChanged();
-	}
-
-	public static void UpdateTitle() {
-		StringBuffer title = new StringBuffer(TITLE);
-
-		if (FrameGraphics.isAudienceMode())
-			title.append(" - Audience Mode");
-		else if (FrameGraphics.isXRayMode())
-			title.append(" - X-Ray Mode");
-		else
-			title.append(" [").append(SessionStats.getShortStats()).append(']');
-
-		if(DisplayIO.title != "") 
-			_Browser.setTitle(DisplayIO.title + " ~~~ " + title.toString());
-		else _Browser.setTitle(title.toString());
-	}
-	
-	private static String title = "";
-	public static void setTitle(String str) {
-	    title = str;
-	}
-
-	public static int getCurrentSide() {
-		if (_Browser == null)
-			return 0;
-
-		if (_TwinFrames
-				&& FrameMouseActions.MouseX >= (_Browser.getWidth() / 2F)
-				&& _CurrentFrames[1] != null)
-			return 1;
-
-		if (_CurrentFrames[0] == null && _CurrentFrames[1] != null)
-			return 1;
-
-		return 0;
-	}
-
-	private static int getOppositeSide() {
-		if (getCurrentSide() == 0)
-			return 1;
-
-		return 0;
-	}
-
-	public static int FrameOnSide(Frame toFind) {
-		if (_CurrentFrames[0] == toFind)
-			return 0;
-
-		if (_CurrentFrames[1] == toFind)
-			return 1;
-
-		return -1;
-	}
-
-	/**
-	 * Returns the Frame currently being displayed on the screen.
-	 * 
-	 * @return The Frame currently displayed.
-	 */
-	public static Frame getCurrentFrame() {
-		return _CurrentFrames[getCurrentSide()];
-	}
-
-	public static Frame getOppositeFrame() {
-		return _CurrentFrames[getOppositeSide()];
-	}
-
-	public static Frame[] getFrames() {
-		return _CurrentFrames;
-	}
-
-	public static int getMiddle() {
-		return _Browser.getWidth() / 2;
-	}
-
-	public static int getHeight() {
-		return _Browser.getHeight();
-	}
-
-	/**
-	 * Returns the current mouse X coordinate. This coordinate is relative to
-	 * the left edge of the frame the mouse is in. It takes into account the
-	 * user being in twin frames mode.
-	 * 
-	 * @return The X coordinate of the mouse.
-	 */
-	public static float getFloatMouseX() {
-		if (_TwinFrames
-				&& FrameMouseActions.MouseY < FrameGraphics.getMaxSize().height)
-			return FrameMouseActions.MouseX % (_Browser.getWidth() / 2);
-
-		return FrameMouseActions.MouseX;
-	}
-
-
-	/**
-	 * Returns the current mouse X coordinate. This coordinate is relative to
-	 * the left edge of the frame the mouse is in. It takes into account the
-	 * user being in twin frames mode.
-	 * 
-	 * @return The X coordinate of the mouse.
-	 */
-	public static int getMouseX() {
-		return Math.round(getFloatMouseX());
-	}
-	
-	
-	/**
-	 * Returns the current mouse Y coordinate. This coordinate is relative to
-	 * the top edge of the frame the mouse is in. 
-	 * 
-	 * @return The Y coordinate of the mouse.
-	 */
-	public static float getFloatMouseY() {
-	
-		return FrameMouseActions.MouseY;
-	}
-	
-	/**
-	 * Returns the current mouse Y coordinate. This coordinate is relative to
-	 * the top edge of the frame the mouse is in. 
-	 * 
-	 * @return The Y coordinate of the mouse.
-	 */
-	public static int getMouseY() {
-		return Math.round(getFloatMouseY());
-	}
-	
-	public static boolean Back() {
-		int side = getCurrentSide();
-
-		// there must be a frame to go back to
-		if (_VisitedFrames[side].size() < 1) {
-			MessageBay.displayMessageOnce("You are already on the home frame");
-			return false;
-		}
-
-		if (!FrameUtils.LeavingFrame(getCurrentFrame())) {
-			MessageBay.displayMessage("Error navigating back");
-			return false;
-		}
-
-		String oldFrame = getCurrentFrame().getName().toLowerCase();
-
-		// do not get a cached version (in case it is in the other window)
-		if (isTwinFramesOn())
-			FrameIO.SuspendCache();
-		Frame frame = FrameIO.LoadFrame(removeFromBack());
-		// If the top frame on the backup stack is the current frame go back
-		// again... or if it has been deleted
-		// Recursively backup the stack
-		if (frame == null || frame.equals(getCurrentFrame())) {
-			Back();
-			return false;
-		}
-
-		if (isTwinFramesOn()) {
-			FrameIO.ResumeCache();
-		}
-		_BackedUpFrames[side].push(oldFrame);
-		FrameUtils.DisplayFrame(frame, false, true);
-		FrameMouseActions.setHighlightHold(true);
-
-		for (Item i : frame.getItems()) {
-			if (i.getLink() != null
-					&& i.getAbsoluteLink().toLowerCase().equals(oldFrame)) {
-				if (i.getHighlightMode() != Item.HighlightMode.Normal) {
-					i.setHighlightMode(Item.HighlightMode.Normal,
-							BACK_HIGHLIGHT_COLOR);
-				}
-				// check if its an @f item and if so update the buffer
-				if (i instanceof Picture) {
-					Picture p = (Picture) i;
-					p.refresh();
-				}
-			}
-		}
-		FrameGraphics.requestRefresh(true);
-		return true;
-	}
-
-	public static boolean Forward() {
-		int side = getCurrentSide();
-
-		// there must be a frame to go back to
-		if (_BackedUpFrames[side].size() == 0) {
-			return false;
-		}
-
-		if (!FrameUtils.LeavingFrame(getCurrentFrame())) {
-			MessageBay.displayMessage("Error navigating forward");
-			return false;
-		}
-
-		String oldFrame = getCurrentFrame().getName().toLowerCase();
-
-		// do not get a cached version (in case it is in the other window)
-		if (isTwinFramesOn())
-			FrameIO.SuspendCache();
-		Frame frame = FrameIO.LoadFrame(_BackedUpFrames[side].pop());
-		// If the top frame on the backup stack is the current frame go back
-		// again... or if it has been deleted
-		// Recursively backup the stack
-		if (frame == null || frame.equals(getCurrentFrame())) {
-			Forward();
-			return false;
-		}
-
-		if (isTwinFramesOn()) {
-			FrameIO.ResumeCache();
-		}
-		_VisitedFrames[side].push(oldFrame);
-		FrameUtils.DisplayFrame(frame, false, true);
-		FrameGraphics.requestRefresh(true);
-		return true;
-	}
-
-	/**
-	 * Toggles the display of frames between TwinFrames mode and Single frame
-	 * mode.
-	 */
-	public static void ToggleTwinFrames() {
-		// determine which side is the active side
-		int opposite = getOppositeSide();
-		int current = getCurrentSide();
-		_TwinFrames = !_TwinFrames;
-
-		// if TwinFrames is being turned on
-		if (_TwinFrames) {
-			// if this is the first time TwinFrames has been toggled on,
-			// load the user's first frame
-			if (_VisitedFrames[opposite].size() == 0) {
-				FrameIO.SuspendCache();
-				setCurrentFrame(FrameIO.LoadFrame(UserSettings.HomeFrame.get()), true);
-				FrameIO.ResumeCache();
-			} else {
-				// otherwise, restore the frame from the side's back-stack
-				setCurrentFrame(FrameIO.LoadFrame(_VisitedFrames[opposite]
-						.pop()), true);
-			}
-
-			// else, TwinFrames is being turned off
-		} else {
-			// add the frame to the back-stack
-			Frame hiding = _CurrentFrames[opposite];
-			FrameUtils.LeavingFrame(hiding);
-			_VisitedFrames[opposite].add(hiding.getName());
-			_CurrentFrames[opposite] = null;
-			_CurrentFrames[current].refreshSize();
-		}
-		if (_CurrentFrames[current] != null)
-			_CurrentFrames[current].refreshSize();
-		if (_CurrentFrames[opposite] != null)
-			_CurrentFrames[opposite].refreshSize();
-
-		FrameGraphics.Clear();
-		FrameGraphics.requestRefresh(false);
-		FrameGraphics.Repaint();
-	}
-
-	public static boolean isTwinFramesOn() {
-		return _TwinFrames;
-	}
-
-	public static void Reload(int side) {
-		if (side < 0)
-			return;
-
-		FrameIO.SuspendCache();
-		_CurrentFrames[side] = FrameIO
-				.LoadFrame(_CurrentFrames[side].getName());
-		FrameIO.ResumeCache();
-	}
-
-	public static boolean DisplayConfirmDialog(String message, String title,
-			int type, int options, int res) {
-		return JOptionPane.showConfirmDialog(_Browser, message, title, options,
-				type) == res;
-	}
-
-	public static final int RESULT_OK = JOptionPane.OK_OPTION;
-
-	public static final int OPTIONS_OK_CANCEL = JOptionPane.OK_CANCEL_OPTION;
-
-	public static final int TYPE_WARNING = JOptionPane.WARNING_MESSAGE;
-
-	public static void pressMouse(int buttons) {
-		_Robot.mousePress(buttons);
-	}
-
-	public static void releaseMouse(int buttons) {
-		_Robot.mouseRelease(buttons);
-	}
-
-	public static void clickMouse(int buttons) throws InterruptedException {
-		_Robot.mousePress(buttons);
-		Thread.sleep(100);
-		_Robot.mouseRelease(buttons);
-	}
-
-	public static void typeKey(int key) throws InterruptedException {
-		_Robot.keyPress(key);
-		// _Robot.waitForIdle();
-		_Robot.keyRelease(key);
-		// _Robot.waitForIdle();
-		Thread.sleep(200);
-	}
-
-	public static void typeText(String s) throws InterruptedException {
-		for (int i = 0; i < s.length(); i++) {
-			char c = s.charAt(i);
-			if (Character.isUpperCase(c))
-				_Robot.keyPress(KeyEvent.VK_SHIFT);
-			typeKey(getKeyCode(c));
-			if (Character.isUpperCase(c))
-				_Robot.keyRelease(KeyEvent.VK_SHIFT);
-		}
-	}
-
-	protected static int getKeyCode(char c) {
-		switch (c) {
-		case '\n':
-			return KeyEvent.VK_ENTER;
-		case ' ':
-			return KeyEvent.VK_SPACE;
-		}
-
-		if (Character.isSpaceChar(c))
-			return KeyEvent.VK_SPACE;
-		else if (Character.isDigit(c)) {
-			return (int) (KeyEvent.VK_0 + c - '0');
-		} else if (Character.isUpperCase(c)) {
-			return c;
-		}
-
-		return (int) (KeyEvent.VK_A + c - 'a');
-	}
-
-	/**
-	 * Moves the cursor the end of this item.
-	 * 
-	 * @param i
-	 */
-	public static void MoveCursorToEndOfItem(Item i) {
-		setTextCursor((Text) i, Text.END, true, false, false, false);
-	}
-
-	public static void translateCursor(int deltaX, int deltaY) {
-		setCursorPosition(FrameMouseActions.MouseX + deltaX,
-				FrameMouseActions.MouseY + deltaY, false);
-	}
-
-	public static void clearBackedUpFrames() {
-		_BackedUpFrames[getCurrentSide()].clear();
-	}
-
-	/**
-	 * @param secondsDelay
-	 * @param s
-	 * @throws InterruptedException
-	 */
-	public static void typeStringDirect(double secondsDelay, String s)
-			throws InterruptedException {
-		for (int i = 0; i < s.length(); i++) {
-			FrameKeyboardActions.processChar(s.charAt(i), false);
-			Thread.sleep((int) (secondsDelay * 1000));
-		}
-	}
-
-	public static List<String> getUnmodifiableVisitedList() {
-		return Collections.unmodifiableList(_VisitedFrames[getCurrentSide()]);
-	}
-}
Index: unk/src/org/expeditee/gui/DisplayIOObserver.java
===================================================================
--- /trunk/src/org/expeditee/gui/DisplayIOObserver.java	(revision 1098)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/**
- *    DisplayIOObserver.java
- *    Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
- *
- *    This program is free software: you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation, either version 3 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.expeditee.gui;
-
-/**
- * An {@link DisplayIOObserver} can observe the {@link DisplayIO} for detecting when
- * frame changes occur.
- * 
- * @author Brook Novak
- *
- */
-public interface DisplayIOObserver {
-	
-	/**
-	 * Raised whenever a frame change occurs.
-	 */
-	public void frameChanged();
-}
Index: unk/src/org/expeditee/gui/ExpediteeRepaintManager.java
===================================================================
--- /trunk/src/org/expeditee/gui/ExpediteeRepaintManager.java	(revision 1098)
+++ 	(revision )
@@ -1,111 +1,0 @@
-/**
- *    ExpediteeRepaintManager.java
- *    Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
- *
- *    This program is free software: you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation, either version 3 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.expeditee.gui;
-
-import java.awt.Component;
-import java.awt.Point;
-import java.awt.Rectangle;
-
-import javax.swing.JComponent;
-import javax.swing.RepaintManager;
-
-public class ExpediteeRepaintManager extends RepaintManager {
-	
-	private static ExpediteeRepaintManager _instance = null;
-	private ExpediteeRepaintManager() {
-		super();
-		setDoubleBufferingEnabled(false); // use as less resources as possible
-	}
-	
-	public static ExpediteeRepaintManager getInstance() {
-		if (_instance == null) {
-			_instance = new ExpediteeRepaintManager();
-		}
-		return _instance;
-	}
-	
-	
-    public synchronized void addDirtyRegion(JComponent c, int x, int y, int w, int h) {
- 
-    	if (c != null) {
-    		
-    		if (Browser._theBrowser == null || c == Browser._theBrowser.getContentPane()) return;
-
-    		Rectangle dirty = new Rectangle();
-    		convertRectangleOrigin(c, new Rectangle(x, y, w, h), dirty);
-			FrameGraphics.invalidateArea(dirty);
-			FrameGraphics.requestRefresh(true); // ALWAYS REQUEST: Avoids AWT locks
-    		
-    	/*	if (convertRectangleOrigin(c, new Rectangle(x, y, w, h), dirty)) {
-        		FrameGraphics.invalidateArea(dirty);
-        		FrameGraphics.refresh(true);
-    		} else {
-    			FrameGraphics.invalidateArea(dirty);
-    			FrameGraphics.requestRefresh(true);
-    		}*/
-
-    		// DEBUGGING
-    		//Browser._theBrowser.g.setColor(Color.ORANGE);
-    		//Browser._theBrowser.g.fillRect(dirty.x, dirty.y, dirty.width, dirty.height);
-    		
-    	}
-    }
-    
-	/*@Override
-	public void addDirtyRegion(Applet applet, int x, int y, int w, int h) {
-		// Ignore
-	}
-
-	@Override
-	public void addDirtyRegion(Window window, int x, int y, int w, int h) {
-		// Ignore
-	}*/
-    
-    /**
-     * Converts a rectangle from swing/awt space to expeditee space
-     * @param c
-     * @param dirty
-     * @return
-     */
-    private boolean convertRectangleOrigin(JComponent c, Rectangle dirty, Rectangle dest) {
-    	Point p = new Point(0,0);
-    	boolean isInContentPane = getPointInContentPane(c, p);
-    	dest.setBounds(dirty);
-    	dest.translate(p.x, p.y);
-    	return isInContentPane;
-    }
-    
-    private boolean getPointInContentPane(Component c, Point p) {
-    	
-    	if (c == Browser._theBrowser.getContentPane()) 
-    		return true;
-    	else if (c == null || 
-    			c == Browser._theBrowser.getLayeredPane()) {
-    		return false;
-    	}
-
-    	p.translate(c.getX(), c.getY());
-    	
-    	return getPointInContentPane(c.getParent(), p);
-    }
-    
-
-
-
-}
Index: unk/src/org/expeditee/gui/FrameTransitions.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameTransitions.java	(revision 1098)
+++ 	(revision )
@@ -1,338 +1,0 @@
-package org.expeditee.gui;
-
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.GradientPaint;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.RenderingHints;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-
-import org.expeditee.items.Item;
-
-//Manages slide animations between frames
-//Reflection is used to call these methods, therefore any additions should only need to be added in this class.
-//No further changes to other code should be required.
-public class FrameTransitions {	
-	
-	//Stores the frame before the new frame being transitioned to
-	private static Image _slideModeBaseImage = null;
-	private static Image _slideModeScratchImage = null;
-	
-	//Tells graphics which method of transition is going to be used
-	private static String _slideModeMethod;
-	
-	//Used for power point slide effects
-	private static boolean slide = false;
-		
-	public static Boolean getSlide(){
-		
-		return slide;
-	}
-	public static void setSlideFalse(){
-		
-		slide = false;
-	}
-	public static void setSlideTrue(){
-		
-		slide = true;
-	}
-	public static void setSlideModeBaseImage(Image i){
-		
-		_slideModeBaseImage = i;
-		_slideModeScratchImage = new BufferedImage(i.getWidth(null), i.getHeight(null), BufferedImage.TYPE_INT_ARGB);
-	}
-	public static Image getSlideModeBaseImage(){
-		
-		return _slideModeBaseImage;		
-	}
-	public static void setSlideModeMethod(String s){
-		
-		_slideModeMethod = s;
-	}
-	public static String getslideModeMethod(){
-		
-		return _slideModeMethod;
-	}
-	
-	//Slides new frame over current from from Right to Left
-	public static void CoverFromRight(Graphics g, Image i, Dimension d){
-
-		Image image = i;
-
-		int frameX = d.width;
-
-		while(frameX >= 0){
-
-			g.drawImage(image, frameX, 0, Item.DEFAULT_BACKGROUND, null);
-
-			frameX -= 2;								
-		}	
-	}
-
-
-	public static void CoverFromLeft(Graphics g, Image i, Dimension d){
-
-		Image image = i;
-
-		int frameX = 0;
-
-		while(frameX <= d.width){
-
-			g.drawImage(image, frameX, 0, Item.DEFAULT_BACKGROUND, null);
-
-			frameX += 2;								
-		}	
-	}
-
-	//Slides new frame over current from from Right to Left
-	public static void Swipe(Graphics g, Image i, Dimension d){
-		CoverFromRight(g,i,d);
-	}
-		
-	
-
-	public static void WipeFromLeft(Graphics g, Image i, Dimension d)
-	{
-		Image image = i;
-		int image_y_dim = image.getHeight(null);
-		
-
-		int frameX = 0;
-
-		while(frameX <= d.width){
-			
-			g.drawImage(image, 0,0, frameX,image_y_dim, 0,0, frameX,image_y_dim, null);
-
-			frameX += 2;								
-		}	
-	}
-	
-	public static void WipeFromRight(Graphics g, Image i, Dimension d)
-	{
-		Image image = i;
-		int image_x_dim = image.getWidth(null);
-		int image_y_dim = image.getHeight(null);
-		
-
-		int frameX = d.width;
-
-		while (frameX >= 0) {
-			
-			g.drawImage(image, frameX,0, image_x_dim,image_y_dim, frameX,0, image_x_dim,image_y_dim, null);
-
-			frameX -= 2;								
-		}	
-	}
-	
-	//Drops new frame from top of display
-	//Draws rectangle with gradient effect to create illusion of drop shadow	
-	public static void FallDown(Graphics g, Image i, Dimension d){
-		
-		Graphics2D g2 = (Graphics2D) g;
-	    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-	    RenderingHints.VALUE_ANTIALIAS_ON);
-
-	    Image image = i;		
-		int frameY = 0 - d.height;
-		int vertCount = 0;
-		
-		while (frameY <= 0){
-			
-			GradientPaint shadow = new GradientPaint(0, vertCount + 10, Color.WHITE, 0, vertCount, Color.gray);
-		    g2.setPaint(shadow);
-			g.drawImage(image,  0,  frameY,  Item.DEFAULT_BACKGROUND,  null);	
-			g2.fillRect(0, vertCount, d.width, 10);		
-			
-			frameY+=8;
-			vertCount+=8;
-			try {
-				Thread.sleep(4);
-			} catch (InterruptedException e) {
-			
-				e.printStackTrace();
-			}			
-		}        
-	}		
-
-	//Use synchronized to ensure no issues with concurrent update issues	
-	//Fades out current frame to black, fades new slide in from black
-	public static void FadeInBlack(Graphics g, Image i, Dimension d){		
-	
-		String fadeType = "black";
-		float alpha = 1.0f;		
-		Graphics2D g2d = (Graphics2D) g;		
-		
-		while(alpha >= 0.3f){
-			
-			g.drawImage(FrameTransitions.getSlideModeBaseImage(),  0,  0,  Item.DEFAULT_BACKGROUND,  null);			
-			g2d.setComposite(alphaCalcUp(alpha, fadeType));				
-			g2d.fillRect(0, 0, d.width, d.height);
-			alpha = alphaCalcUp(alpha, fadeType).getAlpha();
-			
-			try {
-				Thread.sleep(30);
-			} catch (InterruptedException e) {
-			
-				e.printStackTrace();
-			}			
-		}		
-		while(alpha <= 0.8f){			
-		
-			g.drawImage(i,  0,  0,  Item.DEFAULT_BACKGROUND,  null);
-			g2d.setComposite(alphaCalcDown(alpha, fadeType));			
-			g2d.fillRect(0, 0, d.width, d.height);
-			alpha = alphaCalcDown(alpha, fadeType).getAlpha();
-			
-			try {
-				Thread.sleep(30);
-			} catch (InterruptedException e) {
-
-				e.printStackTrace();
-			}	
-		}       
-	}
-	//Fades current frame out, and new frame in
-	//Calls AlphaCalcUp and AlphaCalcDown to calculate Alpha values of these transitions
-	//AlphaComposite is passed in as a parameter, and it holds the alpha value
-	public static void FadeInWhite(Graphics g, Image i, Dimension d){
-		
-		String fadeType = "white";
-		float alpha = 1.0f;
-		
-		Graphics2D g2d = (Graphics2D) g;		
-		
-		Graphics2D scratch_g2d = (Graphics2D)_slideModeScratchImage.getGraphics();
-		
-		while(alpha >= 0.1f){			
-			
-			
-			scratch_g2d.drawImage(getSlideModeBaseImage(),  0,  0,  Item.DEFAULT_BACKGROUND,  null);			
-			scratch_g2d.setComposite(alphaCalcUp(alpha, fadeType));				
-			scratch_g2d.setColor(Color.WHITE);
-			scratch_g2d.fillRect(0, 0, d.width, d.height);
-			
-			g2d.drawImage(_slideModeScratchImage, 0, 0, null);
-			
-			alpha = alphaCalcUp(alpha, fadeType).getAlpha();
-			
-			try {
-				Thread.sleep(25);
-			} catch (InterruptedException e) {
-			
-				e.printStackTrace();
-			}			
-			
-			System.out.println(alpha);
-		}		
-		while(alpha <= 0.75f){			
-		
-			scratch_g2d.drawImage(i,  0,  0,  Item.DEFAULT_BACKGROUND,  null);
-			scratch_g2d.setComposite(alphaCalcDown(alpha, fadeType));
-			scratch_g2d.setColor(Color.WHITE);
-			scratch_g2d.fillRect(0, 0, d.width, d.height);
-		
-			g2d.drawImage(_slideModeScratchImage, 0, 0, null);
-			
-			alpha = alphaCalcDown(alpha, fadeType).getAlpha();
-			
-			try {
-				Thread.sleep(100);
-			} catch (InterruptedException e) {
-
-				e.printStackTrace();
-			}	
-			
-			System.out.println(alpha);
-		} 
-	}
-
-	//Calculates alpha values for transitions from transparent to opaque
-	//AlphaComposite is returned
-	private static AlphaComposite alphaCalcUp(float i, String fadeType){
-		
-		float alpha = i;
-		float increment = -0.05f;
-		alpha += increment;		
-
-		if(fadeType == "black"){
-		
-			AlphaComposite alcom = AlphaComposite.getInstance(AlphaComposite.DST_IN, alpha);
-			return alcom;		
-		}
-		else{
-			//fadeType White
-			AlphaComposite alcom = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha);
-			return alcom;
-		}
-	}
-	//Calculates alpha values for transitions from opaque to transparent	
-	//AlphaComposite is returned
-	private static AlphaComposite alphaCalcDown(float i, String fadeType){
-
-		float alpha = i;
-		float increment = -0.05f;
-		alpha -= increment;		
-
-		if(fadeType == "black"){
-		
-			AlphaComposite alcom = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
-			return alcom;		
-		}
-		else{
-			//fadeType White
-			//AlphaComposite alcom = AlphaComposite.SrcOver.derive(alpha);
-			AlphaComposite alcom = AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha);
-			return alcom;
-		}
-	}
-	
-	public static void CrossFade(Graphics g, Image i, Dimension d)
-	{ 
-		// Based on: http://stackoverflow.com/questions/20346661/java-fade-in-and-out-of-images
-		// TODO: make use of timer, as this example does, rather than fixed delay
-		
-		Image inImage = i;
-		Image outImage = _slideModeBaseImage;
-		int scratch_x_dim = _slideModeScratchImage.getWidth(null);
-		int scratch_y_dim = _slideModeScratchImage.getHeight(null);
-
-		int anim_timestep_msec = 10;
-		float alpha = 0.0f;
-		float alpha_inc = 0.04f;
-		
-		Graphics2D g2d = (Graphics2D) g;		
-
-		Graphics scratch_g = _slideModeScratchImage.getGraphics();
-
-		while(alpha <= 1.0f){			
-
-			//scratch_g.clearRect(0, 0, scratch_x_dim, scratch_y_dim);
-			scratch_g.setColor(Color.WHITE);
-			scratch_g.fillRect(0, 0, scratch_x_dim, scratch_y_dim);
-			
-			Graphics2D scratch_g2d = (Graphics2D) scratch_g.create();
-			scratch_g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
-			scratch_g2d.drawImage(inImage, 0, 0, null);
-
-			scratch_g2d.setComposite(AlphaComposite.SrcOver.derive(1f - alpha));
-			scratch_g2d.drawImage(outImage, 0, 0, null);
-			scratch_g2d.dispose();
-
-			g2d.drawImage(_slideModeScratchImage, 0, 0, null);
-
-			try {
-				Thread.sleep(anim_timestep_msec);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}			
-
-			alpha += alpha_inc;	
-		}		
-	}	
-
-	
-}
Index: unk/src/org/expeditee/gui/MouseEventRouter.java
===================================================================
--- /trunk/src/org/expeditee/gui/MouseEventRouter.java	(revision 1098)
+++ 	(revision )
@@ -1,404 +1,0 @@
-/**
- *    MouseEventRouter.java
- *    Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
- *
- *    This program is free software: you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation, either version 3 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.expeditee.gui;
-
-import java.awt.AWTEvent;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
-import java.awt.event.AWTEventListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.swing.JComponent;
-import javax.swing.JMenuBar;
-import javax.swing.JPopupMenu;
-import javax.swing.SwingUtilities;
-
-import org.expeditee.io.ExpClipReader;
-import org.expeditee.io.ItemSelection;
-import org.expeditee.io.ItemSelection.ExpDataHandler;
-import org.expeditee.items.Item;
-import org.expeditee.items.ItemUtils;
-
-/**
- * The gateway for mouse input; conditionally forwards mouse messages to swing
- * components / expeditee frames for the Browser.
- * 
- * Various mouse listeners can attatch themselves here to listen to mouse events
- * forwared to expeditee .. this excludes widget-exclusive mouse messages.
- * 
- * @author Brook Novak
- * 
- */
-public class MouseEventRouter extends JComponent {
-
-	private static final long serialVersionUID = 1L;
-
-	private JMenuBar _menuBar;
-
-	private Container _contentPane;
-
-	private List<MouseListener> _mouseListeners = new LinkedList<MouseListener>();
-
-	private List<MouseMotionListener> _mouseMotionListeners = new LinkedList<MouseMotionListener>();
-
-	private List<MouseWheelListener> _mouseWheelListeners = new LinkedList<MouseWheelListener>();
-
-	private static MouseEvent _currentMouseEvent = null;
-
-	/**
-	 * Routes events on given frame layers... the menu bar and content pane
-	 * 
-	 * @param menuBar
-	 *            Must not be null.
-	 * 
-	 * @param contentPane
-	 *            Must not be null.
-	 */
-	public MouseEventRouter(JMenuBar menuBar, Container contentPane) {
-
-		if (contentPane == null)
-			throw new NullPointerException("contentPane");
-
-		// Listen for all AWT events (ensures popups are included)
-		Toolkit.getDefaultToolkit().addAWTEventListener(
-				new EventCatcher(),
-				AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK
-						| AWTEvent.MOUSE_WHEEL_EVENT_MASK);
-
-		this._menuBar = menuBar;
-		this._contentPane = contentPane;
-	}
-
-	/**
-	 * Listens only to events to frames... i.e. to exeditee, not to widgets.
-	 * 
-	 * @param listener
-	 *            The listener to add.
-	 */
-	public void addExpediteeMouseListener(MouseListener listener) {
-		if (listener == null)
-			throw new NullPointerException("listener");
-		_mouseListeners.add(listener);
-	}
-
-	public void removeExpediteeMouseListener(MouseListener listener) {
-		if (listener == null)
-			throw new NullPointerException("listener");
-		_mouseListeners.remove(listener);
-	}
-
-	public void addExpediteeMouseMotionListener(MouseMotionListener listener) {
-		if (listener == null)
-			throw new NullPointerException("listener");
-		_mouseMotionListeners.add(listener);
-	}
-
-	public void removeExpediteeMouseMotionListener(MouseMotionListener listener) {
-		if (listener == null)
-			throw new NullPointerException("listener");
-		_mouseMotionListeners.remove(listener);
-	}
-
-	public void addExpediteeMouseWheelListener(MouseWheelListener listener) {
-		if (listener == null)
-			throw new NullPointerException("listener");
-		_mouseWheelListeners.add(listener);
-	}
-
-	public void removeExpediteeMouseWheelListener(MouseWheelListener listener) {
-		if (listener == null)
-			throw new NullPointerException("listener");
-		_mouseWheelListeners.remove(listener);
-	}
-
-	/**
-	 * Conceal event catching from outside
-	 * 
-	 * @author Brook Novak
-	 */
-	private class EventCatcher implements AWTEventListener {
-
-		/**
-		 * All events for every component in frame are fired to here
-		 */
-		public void eventDispatched(AWTEvent event) {
-			if (event instanceof MouseEvent) {
-				routeMouseEvent((MouseEvent) event);
-			}
-		}
-
-	}
-
-	/**
-	 * Forwards the mouse event to its appropriate destination. For events that
-	 * belong to Expiditee space the events are consumed and manually routed to
-	 * the mouse actions handler.
-	 * 
-	 * @param e
-	 *            The mouse event for any component in the browser frame
-	 */
-	private void routeMouseEvent(MouseEvent e) {
-		_currentMouseEvent = e;
-
-		// First convert the point to expeditee space
-		Point containerPoint = SwingUtilities.convertPoint(e.getComponent(), e
-				.getPoint(), _contentPane);
-		
-		// TODO: Find a reliable way of detecting when the mouse moved onto a window that isn't a child of ours
-		if(e.getID() == MouseEvent.MOUSE_EXITED) {
-			// System.out.println(e.getComponent());
-			if(containerPoint.x <= 0 || containerPoint.x >= _contentPane.getWidth() ||
-					containerPoint.y <= 0 || containerPoint.y >= _contentPane.getHeight()) {
-				FrameMouseActions.mouseExitedWindow(e);
-			}
-		}
-
-		if (containerPoint.y < 0) { // not in the content pane
-
-			if (_menuBar != null
-					&& containerPoint.y + _menuBar.getHeight() >= 0) {
-				// The mouse event is over the menu bar.
-				// Could handle specially.
-			} else {
-				// The mouse event is over non-system window
-				// decorations, such as the ones provided by
-				// the Java look and feel.
-				// Could handle specially.
-			}
-
-		} else {
-
-			// Check to see if the mouse is over an expeditee item or
-			// whether an expeditee item is currently picked up
-			boolean forwardToExpiditee = false;
-			boolean isOverPopup = PopupManager.getInstance().isPointOverPopup(
-					containerPoint);
-			if (isOverPopup) {
-				// Popups have highest preference
-				// forwardToExpiditee = false...
-
-				// If there ate items in free space - keep them moving with the
-				// cursor over the
-				// popups.
-				if (!FreeItems.getInstance().isEmpty()) {
-					FrameMouseActions.move(FreeItems.getInstance());
-				}
-
-				// Note: all frame.content pane events belong to expeditee
-			} else if (e.getSource() == _contentPane
-					|| e.getSource() == Browser._theBrowser
-					|| !FreeItems.getInstance().isEmpty()) {
-				forwardToExpiditee = true;
-			} else if (DisplayIO.getCurrentFrame() != null) {
-				/* is mouse over a specific expeditee item? */
-				// NOTE: Do not use FrameUtils.getCurrentItem() - thats relevent
-				// for old mouse position only
-				/*
-				 * for (Item i : DisplayIO.getCurrentFrame().getItems()) { if
-				 * (i.getPolygon().contains(containerPoint)) {
-				 * forwardToExpiditee = true; break; } }
-				 */// ABOVE: Does not consider overlays
-				// NOTE: Below is an expensive operation and could be re-used
-				// when passing mouse events!!!
-				forwardToExpiditee = (FrameUtils.onItem(DisplayIO
-						.getCurrentFrame(), containerPoint.x, containerPoint.y,
-						true) != null);
-			}
-
-			// Create artificial mouse event and forward it to expeditee
-			MouseEvent expediteeEvent = SwingUtilities.convertMouseEvent(e
-					.getComponent(), e, _contentPane);
-
-			// NOTE: Convert util masks-out the needed extensions
-			MouseEvent withExtensions = null;
-
-			if (forwardToExpiditee) {
-
-				// Ensure that underlying widgets don't get the event
-				e.consume();
-
-				switch (e.getID()) {
-				case MouseEvent.MOUSE_MOVED:
-
-					for (MouseMotionListener listener : _mouseMotionListeners) {
-						listener.mouseMoved(expediteeEvent);
-					}
-
-					// Ensure that expiditee has focus only if no popups exist
-					if (Browser._theBrowser != null
-							&& Browser._theBrowser.getContentPane() != null) {
-						if (!Browser._theBrowser.getContentPane()
-								.isFocusOwner()
-								&& !isPopupVisible()) {
-							Browser._theBrowser.getContentPane().requestFocus();
-						}
-					}
-
-					break;
-
-				case MouseEvent.MOUSE_CLICKED:
-
-					withExtensions = duplicateMouseEvent(expediteeEvent, e
-							.getModifiers()
-							| e.getModifiersEx());
-
-					for (MouseListener listener : _mouseListeners) {
-						listener.mouseClicked(withExtensions);
-					}
-
-					break;
-
-				case MouseEvent.MOUSE_PRESSED:
-
-					withExtensions = duplicateMouseEvent(expediteeEvent, e
-							.getModifiers()
-							| e.getModifiersEx());
-
-					for (MouseListener listener : _mouseListeners) {
-						listener.mousePressed(withExtensions);
-					}
-
-					break;
-
-				case MouseEvent.MOUSE_RELEASED:
-					withExtensions = duplicateMouseEvent(expediteeEvent, e
-							.getModifiers()
-							| e.getModifiersEx());
-
-					for (MouseListener listener : _mouseListeners) {
-						listener.mouseReleased(withExtensions);
-					}
-
-					break;
-				case MouseEvent.MOUSE_WHEEL:
-					MouseWheelEvent mwe = (MouseWheelEvent) expediteeEvent;
-					for (MouseWheelListener listener : _mouseWheelListeners) {
-						listener.mouseWheelMoved(mwe);
-					}
-					break;
-				case MouseEvent.MOUSE_ENTERED:
-					withExtensions = duplicateMouseEvent(expediteeEvent, e
-							.getModifiers()
-							| e.getModifiersEx());
-					for (MouseListener listener : _mouseListeners) {
-						listener.mouseEntered(withExtensions);
-					}
-					break;
-				case MouseEvent.MOUSE_EXITED:
-					for (MouseListener listener : _mouseListeners) {
-						listener.mouseExited(withExtensions);
-					}
-					break;
-				case MouseEvent.MOUSE_DRAGGED:
-					for (MouseMotionListener listener : _mouseMotionListeners) {
-						listener.mouseDragged(expediteeEvent);
-					}
-					break;
-				}
-
-			} else {
-
-				// Keep expeditees mouse X/Y updated
-				FrameMouseActions.MouseX = expediteeEvent.getX();
-				FrameMouseActions.MouseY = expediteeEvent.getY();
-
-				// If forwarding to swing ensure that widgets are not
-				// highlighted
-				// to give visual feedback yo users such that swing has focus.
-				Item i = FrameMouseActions.getlastHighlightedItem();
-				if (i != null
-						&& i.getHighlightMode() != Item.HighlightMode.None) {
-					FrameGraphics.changeHighlightMode(i,
-							Item.HighlightMode.None);
-				}
-
-				// Also bring expideditee behaviour to swing: Auto-focus on
-				// component
-				// whenever the mouse moves over it.
-				if (e.getID() == MouseEvent.MOUSE_MOVED) {
-					if (e.getSource() instanceof Component) {
-						Component target = (Component) e.getSource();
-						if (!target.isFocusOwner()) {
-							target.requestFocus();
-						}
-					}
-					// Auto-hide popups when user click on something other other
-					// than
-					// a popup - and is not a on a popup invoker
-				} else if (!isOverPopup
-						&& e.getID() == MouseEvent.MOUSE_PRESSED
-						&& !PopupManager.getInstance().isInvoker(
-								e.getComponent())) {
-					PopupManager.getInstance().hideAutohidePopups();
-				}
-			}
-		}
-		
-		Help.updateStatus();
-	}
-
-	public static boolean isPopupVisible() {
-		return isPopupVisible(Browser._theBrowser.getLayeredPane());
-	}
-
-	private static boolean isPopupVisible(Container parent) {
-
-		for (Component c : parent.getComponents()) {
-
-			if (c instanceof JPopupMenu && ((JPopupMenu) c).isVisible()) {
-				return true;
-
-			} else if (c instanceof Container
-					&& c != Browser._theBrowser.getContentPane()) {
-				if (isPopupVisible((Container) c))
-					return true;
-			}
-		}
-
-		return false;
-	}
-
-	private MouseEvent duplicateMouseEvent(MouseEvent e, int modifiers) {
-		return new MouseEvent(e.getComponent(), e.getID(), e.getWhen(),
-				modifiers, e.getX(), e.getY(),
-				/** The below methods are not compatible with Java 1.5 */
-				/*
-				 * e.getXOnScreen(), e.getYOnScreen(),
-				 */
-				e.getClickCount(), e.isPopupTrigger(), e.getButton());
-	}
-
-	public static MouseEvent getCurrentMouseEvent() {
-
-		return _currentMouseEvent;
-
-	}
-}
Index: unk/src/org/expeditee/items/widgets/InteractiveWidget.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/InteractiveWidget.java	(revision 1098)
+++ 	(revision )
@@ -1,2172 +1,0 @@
-/**
- *    InteractiveWidget.java
- *    Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
- *
- *    This program is free software: you can redistribute it and/or modify
- *    it under the terms of the GNU General Public License as published by
- *    the Free Software Foundation, either version 3 of the License, or
- *    (at your option) any later version.
- *
- *    This program is distributed in the hope that it will be useful,
- *    but WITHOUT ANY WARRANTY; without even the implied warranty of
- *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *    GNU General Public License for more details.
- *
- *    You should have received a copy of the GNU General Public License
- *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.expeditee.items.widgets;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.event.ContainerEvent;
-import java.awt.event.ContainerListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.awt.event.MouseEvent;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import javax.swing.JComponent;
-import javax.swing.SwingUtilities;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionBuilder;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.expeditee.actions.Actions;
-import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameKeyboardActions;
-import org.expeditee.gui.FreeItems;
-import org.expeditee.gui.MouseEventRouter;
-import org.expeditee.items.Item;
-import org.expeditee.items.ItemParentStateChangedEvent;
-import org.expeditee.items.ItemUtils;
-import org.expeditee.items.Text;
-import org.expeditee.items.UserAppliedPermission;
-
-/**
- * The bridge between swing space and Expeditee space
- * 
- * @author Brook
- * 
- */
-public abstract class InteractiveWidget implements ContainerListener, KeyListener {
-
-	protected JComponent _swingComponent;
-
-	/** A widget is comprised of dots and lines that basically form a rectangle */
-	private WidgetCorner _d1, _d2, _d3, _d4;
-
-	private WidgetEdge _l1, _l2, _l3, _l4;
-
-	/*
-	 * GUIDE: l1 d1-------d2 | | l4 | X | 12 | | d4-------d3 13
-	 */
-	private List<Item> _expediteeItems; // used for quickly returning item list
-
-	// Widget size restrictions
-	private int _minWidth = 50;
-
-	private int _minHeight = 50;
-
-	private int _maxWidth = 300;
-
-	private int _maxHeight = 300;
-
-	// The Expeditee item that is used for saving widget state in expeditee
-	// world
-	protected Text _textRepresentation;
-
-	protected Float _anchorLeft;
-	protected Float _anchorRight;
-	protected Float _anchorTop;
-	protected Float _anchorBottom;
-	
-	protected final static Color FREESPACE_BACKCOLOR = new Color(100, 100, 100);
-
-	// A flag for signifying whether the swing components are ready to paint.
-	// If the swing components has not been layed out, if they are painted they
-	// will not draw in the correct positions.
-	// Also for setting AWT and Swing -Related drawing options after
-	// construction
-	private boolean _isReadyToPaint = false;
-
-	/** For ensuring only one event is listened to - instead of four. */
-	private MouseEvent _lastParentStateChangedMouseEvent = null;
-
-	/** For ensuring only one event is listened to - instead of four. */
-	private ItemParentStateChangedEvent _lastParentStateChangedEvent = null;
-
-	/** The minum border thickness for widgets. */
-	public final static float DEFAULT_MINIMUM_BORDER_THICKNESS = 1.0f;
-
-	/**
-	 * Creates a InteractiveWidget from a text item.
-	 * 
-	 * @param source
-	 *            Must not be null, first line of text used - which the format
-	 *            must be as follows: "@iw: <<widget_class_name>> [<<width>>] [<<height>>] [: [<<arg1>>] [<<arg2>>]
-	 *            [...]]".
-	 * 
-	 * e.g: "@iw: org.expeditee.items.SampleWidget1 100 20 : 2" creates a
-	 * SampleWidget1 with width = 100 and height = 20 with 1 argument = "2"
-	 * 
-	 * @return An InteractiveWidget instance. Never null.
-	 * 
-	 * @throws NullPointerException
-	 *             if source is null
-	 * 
-	 * @throws IllegalArgumentException
-	 *             if source's text is in the incorrect format or if source's
-	 *             parent is null
-	 * 
-	 * @throws InteractiveWidgetNotAvailableException
-	 *             If the given widget class name in the source text doesn't
-	 *             exist or not an InteractiveWidget or the widget does not
-	 *             supply a valid constructor for creation.
-	 * 
-	 * @throws InteractiveWidgetInitialisationFailedException
-	 *             The sub-constructor failed - depends on the type of widget
-	 *             being instantainiated.
-	 * 
-	 * class names beginning with $, the $ will be replaced with
-	 * "org.expeditee.items."
-	 */
-	public static InteractiveWidget createWidget(Text source)
-			throws InteractiveWidgetNotAvailableException,
-			InteractiveWidgetInitialisationFailedException {
-
-		if (source == null)
-			throw new NullPointerException("source");
-		if (source.getParent() == null)
-			throw new IllegalArgumentException(
-					"source's parent is null, InteractiveWidget's must be created from Text items with non-null parents");
-
-		String TAG = ItemUtils.GetTag(ItemUtils.TAG_IWIDGET);
-
-		String text = source.getText();
-		if (text == null) {
-			throw new IllegalArgumentException("source does not have any text");
-		}
-
-		text = text.trim();
-
-		// Check starts with the widget tag and separator
-		if (!text.startsWith(TAG + ":"))
-			throw new IllegalArgumentException("Source text must begin with \"" + TAG + ":\"");
-
-		// skip over the '@iw:' preamble
-		text = text.substring(TAG.length() + 1).trim();
-
-		int index = 0;
-		if (text.length() > 0) {
-		    // Having removed @iw:, then next ':' is used for signifying start of arguments
-		    index = text.indexOf(':'); 
-		}
-
-		if (index == 0) {
-		    throw new IllegalArgumentException("Source text must begin with \"" + TAG + "\"");
-		}
-
-		//
-		// Step 1: 
-		//   For an X-rayable text item in the form:
-		//     @iw: <class name> [options] width height : <rest...>
-		//
-		//    the 'core' part of the X-rayable text item
-		//   i.e, the text between the first ':' and the second ':'
-		//  
-		//
-		
-		String tokens_str = (index == -1) ? text : text.substring(0, index);
-
-		String[] tokens = Text.parseArgsApache(tokens_str);
-
-		// make anything starting with a '-' lowercase
-		for (int i=0; i<tokens.length; i++) {
-			if (tokens[i].startsWith("-")) {
-				tokens[i] = tokens[i].toLowerCase();
-			}
-		}
-		
-		// create the command line parser
-		CommandLineParser parser = new GnuParser();
-
-		// create the Options
-		Options options = new Options();
-		options.addOption( "al", "anchorleft",   true, "Anchor the vertical left-hand edge of the interactive widget to the value provided " );
-		options.addOption( "ar", "anchorright",  true, "Anchor the vertical right-hand edge of the interactive widget to the value provided " );
-		options.addOption( "at", "anchortop",    true, "Anchor the vertical top edge of the interactive widget to the value provided " );
-		options.addOption( "ab", "anchorbottom", true, "Anchor the vertical bottom edge of the interactive widget to the value provided " );
-		
-		/*
-		 * Alternative way to do the above, but with more control over how the values are set up and can be used
-		 * 
-		@SuppressWarnings("static-access")
-		Option anchor_left_opt = OptionBuilder.withLongOpt( "anchorleft" )
-				.withDescription( "use <x-pos> as left anchor for the vertical lefthand edge of the interactive widget" )
-				.hasArg()
-				.withArgName("<x-pos>")
-				.create("al");
-         
-		@SuppressWarnings("static-access")
-		Option anchor_right_opt = OptionBuilder.withLongOpt( "anchorright" )
-				.withDescription( "use <x-pos> as right anchor for the vertical righthand edge of the interactive widget" )
-				.hasArg()
-				.withArgName("<x-pos>")
-				.create("ar");
-		
-		
-		@SuppressWarnings("static-access")
-		Option anchor_top_opt = OptionBuilder.withLongOpt( "anchortop" )
-				.withDescription( "use <y-pos> as top anchor for the horizontal top end of the interactive widget" )
-				.hasArg()
-				.withArgName("<x-pos>")
-				.create("at");
-         
-		@SuppressWarnings("static-access")
-		Option anchor_bottom_opt = OptionBuilder.withLongOpt( "anchorbottom" )
-				.withDescription( "use <y-pos> as bottom anchor for the horizontal bottom edge of the interactive widget" )
-				.hasArg()
-				.withArgName("<x-pos>")
-				.create("ab");
-		
-		options.addOption(anchor_left_opt);
-		options.addOption(anchor_right_opt);
-		options.addOption(anchor_top_opt);
-		options.addOption(anchor_bottom_opt);
-		*/
-
-		CommandLine core_line;
-		try {
-		    // parse the command line arguments
-		    core_line = parser.parse( options, tokens );
-		    
-		    // Update tokens to be version with the options removed
-		    tokens = core_line.getArgs();
-		    
-		}
-		catch( ParseException exp ) {
-		    System.err.println( "Unexpected exception:" + exp.getMessage() );
-		    core_line = null;
-		    
-		}
-		
-		HelpFormatter formatter = new HelpFormatter();
-		StringWriter usage_str_writer = new StringWriter();
-	    PrintWriter printWriter = new PrintWriter(usage_str_writer);
-	    
-	    String widget_name = tokens[0];
-	    final String widget_prefix = "org.expeditee.items.widgets";
-	    if (widget_name.startsWith(widget_prefix)) {
-	    	widget_name = widget_name.substring(widget_prefix.length());
-	    }
-	    
-		formatter.printHelp(printWriter, 80, TAG + ":" + widget_name + " [options] width height", null, options, 4, 0, null);
-		//System.out.println(usage_str_writer.toString());
-		
-		float width = -1, height = -1;
-
-		if (tokens.length < 1) {
-			throw new IllegalArgumentException("Missing widget class name in source text");
-		}
-
-		try {
-
-			if (tokens.length >= 2) { // parse optional width
-				width = Integer.parseInt(tokens[1]);
-				width = (width <= 0) ? width = -1 : width;
-			}
-
-			if (tokens.length >= 3) { // parse optional height
-				height = Integer.parseInt(tokens[2]);
-				height = (height <= 0) ? height = -1 : height;
-			}
-
-		} catch (NumberFormatException nfe) {
-			throw new IllegalArgumentException(
-					"Bad width or height given in source text", nfe);
-		}
-
-		if (tokens.length > 3)
-			throw new IllegalArgumentException(
-					"to many arguments given before \":\" in source text");
-
-		String classname = tokens[0];
-		if (classname.charAt(0) == '$'){
-			classname = classname.substring(1);
-		}
-		
-		// Attempt to locate the class using reflection
-		Class<?> iwclass = findIWidgetClass(classname);
-
-		if (iwclass == null) // ensure it exists
-			throw new InteractiveWidgetNotAvailableException(classname
-					+ " does not exist or is not an InteractiveWidget");
-
-		
-		//
-		// Step 2: 
-		//   For an X-rayable text item in the form:
-		//     @iw: <class name> [options] width height : <rest...>
-		//
-		//   Parse the <rest ...> part
-		
-		// Extract out the parameters - if any
-		String[] args = null;
-		if (index > 0) { // index of the first ":"
-			if (text.length()>(index+1)) {
-				String args_str = text.substring(index + 1);
-				
-				 args = Text.parseArgsApache(args_str);
-		
-			}	
-		}
-
-		InteractiveWidget inst = null;
-		try {
-			// Instantiate the widget - passing the params
-			Class parameterTypes[] = new Class[] { Text.class, String[].class };
-			Constructor ct = iwclass.getConstructor(parameterTypes);
-
-			Object arglist[] = new Object[] { source, args };
-
-			inst = (InteractiveWidget) ct.newInstance(arglist);
-		} catch (Exception e) {
-			throw new InteractiveWidgetNotAvailableException(
-					"Failed to create instance via reflection: " + e.toString(),
-					e);
-		}
-
-		// Step 3: 
-		//    Set up the size and position of the widget
-
-		// Use default dimensions if not provided (or provided as negative
-		// values)
-		if (width <= 0) {
-			width = inst.getWidth();
-		}
-		if (height <= 0) {
-			height = inst.getHeight();
-		}
-
-		inst.setSize(width, height);
-		
-		// Apply any anchor values supplied in the core part of the @iw item
-		Float anchor_left   = null;
-		Float anchor_right  = null;
-		Float anchor_top    = null;
-		Float anchor_bottom = null;
-		
-	    if(core_line.hasOption( "anchorleft" ) ) {
-	    	String al_str = core_line.getOptionValue( "anchorleft" );
-	    	
-	    	anchor_left = Float.parseFloat(al_str);
-	    }
-	    
-	    if(core_line.hasOption( "anchorright" ) ) {
-	    	String ar_str = core_line.getOptionValue( "anchorright" );
-	    	
-	    	anchor_right = Float.parseFloat(ar_str);
-	    }
-	    
-	    if(core_line.hasOption( "anchortop" ) ) {
-	    	String at_str = core_line.getOptionValue( "anchortop" );
-	    	
-	    	anchor_top = Float.parseFloat(at_str);
-	    }
-	    
-	    if(core_line.hasOption( "anchorbottom" ) ) {
-	    	String ab_str = core_line.getOptionValue( "anchorbottom" );
-	    	
-	    	anchor_bottom = Float.parseFloat(ab_str);
-	    }
-	    
-	    inst.setAnchorCorners(anchor_left,anchor_right,anchor_top,anchor_bottom);
-	    
-	
-		
-		return inst;
-	}
-
-	/**
-	 * Locates the class from the classname of an InteractiveWidget class
-	 * 
-	 * @param classname
-	 *            The name of the class to search
-	 * @return Null if doesn't exist or not an InteractiveWidget
-	 */
-	private static Class findIWidgetClass(String classname) {
-		if(classname == null)
-			return null;
-		// try just the classname
-		try {
-			Class c = Class.forName(classname); // attempt to find the class
-
-			// If one is found, ensure that it is a descendant of an
-			// InteractiveWidget
-			for (Class superclass = c.getSuperclass(); superclass != null
-					&& superclass != Item.class; superclass = superclass
-					.getSuperclass()) {
-				if (superclass == InteractiveWidget.class)
-					return c;
-			}
-
-		} catch (ClassNotFoundException e) {
-		}
-		// see if the class is a widget with invalid capitalisation, or missing the widget package prefix
-		if(classname.startsWith(Actions.WIDGET_PACKAGE)) {
-			classname = classname.substring(Actions.WIDGET_PACKAGE.length());
-		}
-		try {
-			Class c = Class.forName(Actions.getClassName(classname)); // attempt to find the class
-
-			// If one is found, ensure that it is a descendant of an
-			// InteractiveWidget
-			for (Class superclass = c.getSuperclass(); superclass != null
-					&& superclass != Item.class; superclass = superclass
-					.getSuperclass()) {
-				if (superclass == InteractiveWidget.class)
-					return c;
-			}
-
-		} catch (ClassNotFoundException e) {
-		}
-
-		// Doesn't exist or not an InteractiveWidget
-		return null;
-	}
-
-	/**
-	 * Using Microsofts commandline convention: Args seperated with white
-	 * spaces. Options with white spaces enclosed with quotes. Args with quotes
-	 * must be double quoted args1 args2=sfasas args3="option with spaces"
-	 * arg""4""
-	 * 
-	 * @param args
-	 *            Null and empty excepted
-	 * @return An array of args. null if none provided
-	 */
-	public static String[] parseArgs(String args) {
-
-		if (args == null)
-			return null;
-
-		args = args.trim();
-		if (args.length() == 0)
-			return null;
-
-		List<String> vargs = new LinkedList<String>();
-		StringBuilder sb = new StringBuilder();
-		boolean quoteOn = false;
-		for (int i = 0; i < args.length(); i++) {
-
-			char c = args.charAt(i);
-			if (c == ' ' && !quoteOn) {
-
-				// Extract arg
-				vargs.add(sb.toString());
-				sb = new StringBuilder();
-
-				// Consume white spaces
-				while (args.charAt(++i) == ' ' && i < args.length()) {
-				}
-				i--;
-
-			} else if (c == '\"') {
-				// If double quoted
-				if (args.length() >= (i + 2) && args.charAt(i + 1) == '\"') {
-
-					sb.append(c); // add escaped
-					i++;
-
-				} else {
-					quoteOn = !quoteOn;
-				}
-
-			} else {
-				sb.append(c);
-			}
-		}
-
-		if (sb.length() > 0)
-			vargs.add(sb.toString());
-
-		if (vargs.size() == 0)
-			return null;
-		else
-			return vargs.toArray(new String[vargs.size()]);
-	}
-
-	/**
-	 * Reverse of parseArgs
-	 * 
-	 * @return Null if args is null or empty / all whitespace
-	 */
-	public static String formatArgs(String[] args) {
-		if (args == null)
-			return null;
-
-		StringBuilder sb = new StringBuilder();
-
-		for (String s : args) {
-			if (s == null)
-				continue;
-
-			// Escape quotes
-			StringBuilder formatted = new StringBuilder(s.replaceAll("\"",
-					"\"\""));
-
-			// Encapsulate spaces
-			int index = formatted.indexOf(" ");
-			if (index >= 0) {
-				formatted.insert(index, "\"");
-				formatted.append('\"');
-			}
-
-			if (sb.length() > 0)
-				sb.append(' ');
-			sb.append(formatted);
-		}
-
-		return sb.length() > 0 ? sb.toString() : null;
-	}
-
-
-
-
-    
-
-
-
-	/**
-	 * Arguments represent the widgets <i>current state</i> state. They are
-	 * used for saving, loading, creating and cloning Special formatting is done
-	 * for you.
-	 * 
-	 * @see #getData()
-	 * 
-	 * @return Can be null for no params.
-	 */
-	protected abstract String[] getArgs();
-
-	/**
-	 * Data represents the widgets <i>current state</i> state. For any state
-	 * information you do not wish to be defined as arguments (e.g. metadata),
-	 * you can set as the widgets source items data.
-	 * 
-	 * The default implementation returns null. Override to make use of.
-	 * 
-	 * @see #getArgs()
-	 * 
-	 * @return Null for for data. Otherwise the data that represent this widgets
-	 *         <i>current state</i>
-	 */
-	protected List<String> getData() {
-		return null;
-	}
-
-	/**
-	 * Constructor
-	 * 
-	 * @param source
-	 *            Must not be null. Neither must it's parent
-	 * 
-	 * @param component
-	 *            Must not be null.
-	 * 
-	 * @param minWidth
-	 *            The min width restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param maxWidth
-	 *            The max width restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param minHeight
-	 *            The min height restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param maxHeight
-	 *            The max height restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @throws NullPointerException
-	 *             If source, component if null.
-	 * 
-	 * @throws IllegalArgumentException
-	 *             If source's parent is null. If maxWidth smaller than minWidth
-	 *             and maxWidth larger or equal to zero or if maxHeight smaller
-	 *             than minHeight && maxHeight is larger or equal to zero
-	 * 
-	 */
-	protected InteractiveWidget(Text source, JComponent component,
-			int minWidth, int maxWidth, int minHeight, int maxHeight) {
-
-
-		if (component == null)
-			throw new NullPointerException("component");
-		if (source == null)
-			throw new NullPointerException("source");
-		if (source.getParent() == null)
-			throw new IllegalArgumentException(
-					"source's parent is null, InteractiveWidget's must be created from Text items with non-null parents");
-
-		_swingComponent = component;
-		_swingComponent.addContainerListener(this);
-		keyListenerToChildren(_swingComponent, true);
-		
-		_textRepresentation = source;
-
-		setSizeRestrictions(minWidth, maxWidth, minHeight, maxHeight); // throws IllegalArgumentException's
-
-		int x = source.getX();
-		int y = source.getY();
-		int width = (int) ((_minWidth < 0) ? 10 : _minWidth);
-		int height = (int) ((_minHeight < 0) ? 10 : _minHeight);
-
-		Frame idAllocator = _textRepresentation.getParent();
-
-		// create WidgetCorners
-		_d1 = new WidgetCorner(x, y, idAllocator.getNextItemID(), this);
-		_d2 = new WidgetCorner(x + width, y, idAllocator.getNextItemID(), this);
-		_d3 = new WidgetCorner(x + width, y + height, idAllocator.getNextItemID(), this);
-		_d4 = new WidgetCorner(x, y + height, idAllocator.getNextItemID(), this);
-
-		// create WidgetEdges
-		_l1 = new WidgetEdge(_d1, _d2, idAllocator.getNextItemID(), this);
-		_l2 = new WidgetEdge(_d2, _d3, idAllocator.getNextItemID(), this);
-		_l3 = new WidgetEdge(_d3, _d4, idAllocator.getNextItemID(), this);
-		_l4 = new WidgetEdge(_d4, _d1, idAllocator.getNextItemID(), this);
-
-		Collection<Item> enclist = new ArrayList<Item>(4);
-		enclist.add(_d1);
-		enclist.add(_d2);
-		enclist.add(_d3);
-		enclist.add(_d4);
-		_d1.setEnclosedList(enclist);
-		_d2.setEnclosedList(enclist);
-		_d3.setEnclosedList(enclist);
-		_d4.setEnclosedList(enclist);
-
-		_expediteeItems = new ArrayList<Item>(8); // Note: order important
-		_expediteeItems.add(_d1);
-		_expediteeItems.add(_d2);
-		_expediteeItems.add(_d3);
-		_expediteeItems.add(_d4);
-		_expediteeItems.add(_l1);
-		_expediteeItems.add(_l2);
-		_expediteeItems.add(_l3);
-		_expediteeItems.add(_l4);
-
-		setWidgetEdgeColor(source.getBorderColor());
-		setWidgetEdgeThickness(source.getThickness());
-	}
-
-	/**
-	 * Sets the restrictions - checks values.
-	 * 
-	 * @param minWidth
-	 *            The min width restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param maxWidth
-	 *            The max width restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param minHeight
-	 *            The min height restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param maxHeight
-	 *            The max height restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @throws IllegalArgumentException
-	 *             If maxWidth smaller than minWidth and maxWidth larger or
-	 *             equal to zero or if maxHeight smaller than minHeight &&
-	 *             maxHeight is larger or equal to zero
-	 * 
-	 */
-	private void setSizeRestrictions(int minWidth, int maxWidth, int minHeight,
-			int maxHeight) {
-
-		_minWidth = minWidth;
-
-		if (maxWidth < _minWidth && maxWidth >= 0)
-			throw new IllegalArgumentException(
-					"maxWidth smaller than the min Width");
-		_maxWidth = maxWidth;
-
-		_minHeight = minHeight;
-		if (maxHeight < _minHeight && maxHeight >= 0)
-			throw new IllegalArgumentException(
-					"maxHeight smaller than the min Height");
-		_maxHeight = maxHeight;
-	}
-
-	/**
-	 * This can be overrided for creating custom copies. The default
-	 * implementation creates a new widget based on the current state of the
-	 * widget (via getArgs).
-	 * 
-	 * @see InteractiveWidget#getArgs().
-	 * 
-	 * @return A copy of this widget.
-	 * 
-	 */
-	public InteractiveWidget copy()
-			throws InteractiveWidgetNotAvailableException,
-			InteractiveWidgetInitialisationFailedException {
-
-		Text t = _textRepresentation.copy();
-		String clonedAnnotation = getAnnotationString();
-		t.setText(clonedAnnotation);
-		t.setData(getData());
-		return InteractiveWidget.createWidget(t);
-
-	}
-
-	/**
-	 * Notifies widget of delete
-	 */
-	public void onDelete() {
-
-		// Allocate new ID's
-		Frame parent = getParentFrame();
-		if (parent == null)
-			parent = DisplayIO.getCurrentFrame();
-
-		if (parent != null) {
-			for (Item i : _expediteeItems) {
-				i.setID(parent.getNextItemID());
-			}
-		}
-
-		invalidateLink();
-
-	}
-
-	/**
-	 * Note updates the source text with current state info
-	 * 
-	 * @return The Text item that this widget was created from.
-	 */
-	public Item getSource() {
-
-		// Build the annotation string such that it represents this widgets
-		// current state
-		String newAnnotation = getAnnotationString();
-
-		// Set the new text
-		_textRepresentation.setText(newAnnotation);
-
-		// Set the data
-		_textRepresentation.setData(getData());
-
-		return _textRepresentation;
-	}
-
-	/**
-	 * @return The current representation for this widget. The representation
-	 *         stores link information, data etc... It is used for saving and
-	 *         loading of the widget. Never null.
-	 * 
-	 */
-	protected Item getCurrentRepresentation() {
-		return _textRepresentation;
-	}
-
-	/**
-	 * @return The Expeditee annotation string.
-	 */
-	protected String getAnnotationString() {
-
-		// Create tag and append classname
-		StringBuilder sb = new StringBuilder(ItemUtils
-				.GetTag(ItemUtils.TAG_IWIDGET));
-		sb.append(':');
-		sb.append(' ');
-		sb.append(getClass().getName());
-
-		if (_anchorLeft != null) {
-		    sb.append(" --anchorLeft " + Math.round(_anchorLeft));
-		}
-		if (_anchorRight != null) {
-		    sb.append(" --anchorRight " + Math.round(_anchorRight));
-		}
-
-		if (_anchorTop != null) {
-		    sb.append(" --anchorTop " + Math.round(_anchorTop));
-		}
-
-		if (_anchorBottom != null) {
-		    sb.append(" --anchorBottom " + Math.round(_anchorBottom));
-		}
-
-		// Append size information if needed (not an attribute of text items)
-		if (!isFixedSize()) {
-			sb.append(' ');
-			sb.append(getWidth());
-			sb.append(' ');
-			sb.append(getHeight());
-		}
-
-		// Append arguments if any
-		String stateArgs = InteractiveWidget.formatArgs(getArgs());
-		if (stateArgs != null) {
-			sb.append(':');
-			sb.append(stateArgs);
-		}
-
-		return sb.toString();
-	}
-
-	/**
-	 * Sets both the new size as well as the new min/max widget/height
-	 * restrictions.
-	 * 
-	 * @param minWidth
-	 *            The min width restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param maxWidth
-	 *            The max width restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param minHeight
-	 *            The min height restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param maxHeight
-	 *            The max height restriction for the widget. If negative, then
-	 *            there is no restriction.
-	 * 
-	 * @param newWidth
-	 *            Clamped to new restrictions.
-	 * 
-	 * @param newHeight
-	 *            Clamped to new restrictions.
-	 * 
-	 * @throws IllegalArgumentException
-	 *             If maxWidth smaller than minWidth and maxWidth larger or
-	 *             equal to zero or if maxHeight smaller than minHeight &&
-	 *             maxHeight is larger or equal to zero
-	 * 
-	 * @see #setSize(float, float)
-	 * 
-	 */
-	public void setSize(int minWidth, int maxWidth, int minHeight,
-			int maxHeight, float newWidth, float newHeight) {
-
-		setSizeRestrictions(minWidth, maxWidth, minHeight, maxHeight); // throws
-		// IllegalArgumentException's
-		setSize(newWidth, newHeight);
-	}
-
-	/**
-	 * Clamped to current min/max width/height.
-	 * 
-	 * @param width
-	 *            Clamped to current restrictions.
-	 * @param height
-	 *            Clamped to current restrictions.
-	 * 
-	 * @see #setSize(int, int, int, int, float, float)
-	 */
-	public void setSize(float width, float height) {
-
-		// If 'width' and 'height' exceed the min/max values for width/height
-		// => clamp to the relevant min/max value 
-		if (width < _minWidth && _minWidth >= 0) {
-			width = _minWidth;
-		}
-		else if (width > _maxWidth && _maxWidth >= 0) {
-			width = _maxWidth;
-		}
-		
-		if (height < _minHeight && _minHeight >= 0) {
-			height = _minHeight;
-		}
-		else if (height > _maxHeight && _maxHeight >= 0) {
-			height = _maxHeight;
-		}
-		
-		// Remember current isFloating() values
-		boolean vfloating[] = new boolean[] { _d1.isFloating(),
-				_d2.isFloating(), _d3.isFloating(), _d4.isFloating() };
-
-		_d1.setFloating(true);
-		_d2.setFloating(true);
-		_d3.setFloating(true);
-		_d4.setFloating(true);
-
-		float xr = _d1.getX() + width;
-		float yb = _d1.getY() + height;
-
-		_d2.setX(xr);
-		_d3.setX(xr);
-		_d3.setY(yb);
-		_d4.setY(yb);
-
-		// Restore isFloating() values
-		_d1.setFloating(vfloating[0]);
-		_d2.setFloating(vfloating[1]);
-		_d3.setFloating(vfloating[2]);
-		_d4.setFloating(vfloating[3]);
-
-		onSizeChanged();
-	}
-
-    public void setAnchorCorners(Float left, Float right, Float top, Float bottom)
-    {
-    	setAnchorLeft(left);
-    	setAnchorRight(right);
-    	setAnchorTop(top);
-    	setAnchorBottom(bottom);
-    }
-    
-
-	public void setPosition(int x, int y) {
-		if (x == getX() && y == getY())
-			return;
-
-		// Remember current isFloating() values
-		boolean vfloating[] = new boolean[] { _d1.isFloating(),
-				_d2.isFloating(), _d3.isFloating(), _d4.isFloating() };
-
-		int width = getWidth();
-		int height = getHeight();
-
-		invalidateLink();
-
-		_d1.setFloating(true);
-		_d2.setFloating(true);
-		_d3.setFloating(true);
-		_d4.setFloating(true);
-
-		_d1.setPosition(x, y);
-		_d2.setPosition(x + width, y);
-		_d3.setPosition(x + width, y + height);
-		_d4.setPosition(x, y + height);
-
-		// Restore isFloating() values
-		_d1.setFloating(vfloating[0]);
-		_d2.setFloating(vfloating[1]);
-		_d3.setFloating(vfloating[2]);
-		_d4.setFloating(vfloating[3]);
-
-		invalidateLink();
-
-		onMoved();
-
-	}
-
-	private boolean _settingPositionFlag = false; // used for recursion
-
-	/**
-	 * Updates position of given WidgetCorner to the given (x,y), 
-	 *   and updates related values (connected corners, width and height)
-	 * 
-	 * @param src
-	 * @param x
-	 * @param y
-	 * @return False if need to call super.setPosition
-	 */
-	boolean setPositions(WidgetCorner src, float x, float y) {
-
-		if (_settingPositionFlag)
-			return false;
-		_settingPositionFlag = true;
-
-		invalidateLink();
-
-		// Check to see if the widget is fully being picked up
-		boolean isAllPickedUp = (_d1.isFloating() && _d2.isFloating()
-				&& _d3.isFloating() && _d4.isFloating());
-
-		// If so, then this will be called one by one ..
-		if (isAllPickedUp) {
-			src.setPosition(x, y);
-		} else {
-
-			float newX = x;
-
-			// Reference:
-			// D1 D2
-			// D3 D4
-
-			//
-			// GUIDE:
-			// l1
-			// d1-------d2
-			// | |
-			// l4 | X | 12
-			// | |
-			// d4-------d3
-			// 13
-			//
-
-			// X Positions
-			if (src == _d1 || src == _d4) {
-
-				// Check min X constraint
-				if (_minWidth >= 0) {
-					if ((_d2.getX() - x) < _minWidth) {
-						newX = _d2.getX() - _minWidth;
-					}
-				}
-				// Check max X constraint
-				if (_maxWidth >= 0) {
-					if ((_d2.getX() - x) > _maxWidth) {
-						newX = _d2.getX() - _maxWidth;
-					}
-				}
-
-				if (!(src == _d4 && _d1.isFloating() && _d4.isFloating()))
-					_d1.setX(newX);
-				if (!(src == _d1 && _d4.isFloating() && _d1.isFloating()))
-					_d4.setX(newX);
-
-			} else if (src == _d2 || src == _d3) {
-
-				// Check min X constraint
-				if (_minWidth >= 0) {
-					if ((x - _d1.getX()) < _minWidth) {
-						newX = _d1.getX() + _minWidth;
-					}
-				}
-				// Check max X constraint
-				if (_maxWidth >= 0) {
-					if ((x - _d1.getX()) > _maxWidth) {
-						newX = _d1.getX() + _maxWidth;
-					}
-				}
-
-				if (!(src == _d3 && _d2.isFloating() && _d3.isFloating()))
-					_d2.setX(newX);
-				if (!(src == _d2 && _d3.isFloating() && _d2.isFloating()))
-					_d3.setX(newX);
-			}
-
-			float newY = y;
-
-			// Y Positions
-			if (src == _d1 || src == _d2) {
-
-				// Check min Y constraint
-				if (_minHeight >= 0) {
-					if ((_d4.getY() - y) < _minHeight) {
-						newY = _d4.getY() - _minHeight;
-					}
-				}
-				// Check max Y constraint
-				if (_maxHeight >= 0) {
-					if ((_d4.getY() - y) > _maxHeight) {
-						newY = _d4.getY() - _maxHeight;
-					}
-				}
-
-				if (!(src == _d2 && _d1.isFloating() && _d2.isFloating()))
-					_d1.setY(newY);
-				if (!(src == _d1 && _d2.isFloating() && _d1.isFloating()))
-					_d2.setY(newY);
-
-			} else if (src == _d3 || src == _d4) {
-
-				// Check min Y constraint
-				if (_minHeight >= 0) {
-					if ((y - _d1.getY()) < _minHeight) {
-						newY = _d1.getY() + _minHeight;
-					}
-				}
-				// Check max Y constraint
-				if (_maxHeight >= 0) {
-					if ((y - _d1.getY()) > _maxHeight) {
-						newY = _d1.getY() + _maxHeight;
-					}
-				}
-
-				if (!(src == _d4 && _d3.isFloating() && _d4.isFloating()))
-					_d3.setY(newY);
-				if (!(src == _d3 && _d4.isFloating() && _d3.isFloating()))
-					_d4.setY(newY);
-			}
-		}
-
-		// Update source text position so position is remembered from loading
-		float newTextX = getX();
-		float newTextY = getY();
-		if (_textRepresentation.getX() != newTextX
-				|| _textRepresentation.getY() != newTextY)
-			_textRepresentation.setPosition(newTextX, newTextY);
-
-		_settingPositionFlag = false;
-
-		invalidateLink();
-
-		onMoved();
-
-		return true;
-	}
-
-	public int getX() {
-		return Math.min(_d1.getX(), _d2.getX());
-	}
-
-	public int getY() {
-		return Math.min(_d1.getY(), _d4.getY());
-	}
-
-	public int getWidth() {
-
-		return Math.abs(_d2.getX() - _d1.getX());
-	}
-
-	public int getHeight() {
-		return Math.abs(_d4.getY() - _d1.getY());
-	}
-	
-	public Point getPosition() {
-		return new Point(getX(), getY());
-	}
-
-	/**
-	 * The order of the items in the list is as specified: _d1 _d2 _d3 _d4 _l1
-	 * _l2 _l3 _l4
-	 * 
-	 * @return All of the Expeditee items that form the bounderies of this
-	 *         widget in an unmodifiable list
-	 */
-	public List<Item> getItems() {
-		return Collections.unmodifiableList(_expediteeItems);
-	}
-
-	public JComponent getComponant() {
-		return _swingComponent;
-	}
-
-	public final void onParentStateChanged(ItemParentStateChangedEvent e) {
-
-		// Because widgets are comprised of four corners - they all report this
-		// event one after the
-		// other. So must filter out redundant notifications like so:
-		if (_lastParentStateChangedEvent != null
-				&& _lastParentStateChangedEvent.getEventType() == e
-						.getEventType()
-				&& _lastParentStateChangedMouseEvent == MouseEventRouter
-						.getCurrentMouseEvent())
-			return; // already dealt with this event
-
-		_lastParentStateChangedEvent = e;
-		_lastParentStateChangedMouseEvent = MouseEventRouter
-				.getCurrentMouseEvent();
-		
-		switch (e.getEventType()) {
-
-		case ItemParentStateChangedEvent.EVENT_TYPE_REMOVED:
-		case ItemParentStateChangedEvent.EVENT_TYPE_REMOVED_VIA_OVERLAY:
-		case ItemParentStateChangedEvent.EVENT_TYPE_HIDDEN:
-			if (_swingComponent.getParent() != null) {
-				_swingComponent.getParent().remove(_swingComponent);
-			}
-			break;
-
-		case ItemParentStateChangedEvent.EVENT_TYPE_ADDED:
-		case ItemParentStateChangedEvent.EVENT_TYPE_ADDED_VIA_OVERLAY:
-		case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN:
-		case ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY:
-			if (_swingComponent.getParent() == null) {
-				addJComponantToFrame(e);
-			}
-			break;
-
-		}
-
-		FrameGraphics.invalidateItem(_d1, _swingComponent.getBounds());
-
-		// Forward filtered event to upper classeses...
-		onParentStateChanged(e.getEventType());
-	}
-
-	/**
-	 * Override to make use of. Internally this is reported once by all corners,
-	 * but is filterted out so that this method is invoked once per event.
-	 * 
-	 * @param eventType
-	 *            The {@link ItemParentStateChangedEvent#getEventType()} that
-	 *            occured.
-	 * 
-	 */
-	protected void onParentStateChanged(int eventType) {
-	}
-
-	protected void addJComponantToFrame(ItemParentStateChangedEvent e) {
-
-		if ((e.getEventType() == ItemParentStateChangedEvent.EVENT_TYPE_ADDED_VIA_OVERLAY || e
-				.getEventType() == ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY)
-				&& e.getOverlayLevel().equals(UserAppliedPermission.none)) {
-			return; // item belongs to a non-active overlay
-		}
-
-		if (_swingComponent.getParent() == null) {
-
-			if (Browser._theBrowser != null) {
-				// Due to precaching - before adding physical swing
-				// componant must check to see that this widget belongs to a
-				// frame that is
-				// considered current. If the widget is shown however this does
-				// not apply -
-				// since it has been explicitly made clear the the widget is
-				// shown.
-				if (e.getEventType() == ItemParentStateChangedEvent.EVENT_TYPE_SHOWN
-						|| e.getEventType() == ItemParentStateChangedEvent.EVENT_TYPE_SHOWN_VIA_OVERLAY
-						|| e.getSource() == DisplayIO.getCurrentFrame()) {
-	
-					onBoundsChanged();
-					Browser._theBrowser.getContentPane().add(_swingComponent);
-					layout(_swingComponent);
-				}
-
-			} else { // if widgets exist on startup frame this will occur
-
-				synchronized (_widgetsToAddLater) {
-					_widgetsToAddLater.add(new DelayedWidgetEvent(this, e));
-				}
-				SwingUtilities.invokeLater(new AddToFrameLater());
-			}
-
-		}
-
-	}
-
-	/**
-	 * @return True if at least one corner is floating
-	 */
-	public boolean isFloating() {
-		return _d1.isFloating() || _d2.isFloating() || _d3.isFloating()
-				|| _d4.isFloating();
-	}
-
-	public boolean areCornersFullyAnchored() {
-		return _d1.getParent() != null && _d2.getParent() != null
-				&& _d3.getParent() != null && _d4.getParent() != null;
-	}
-
-	/**
-	 * Used for passing info to the swing thread
-	 * 
-	 * @author Brook Novak
-	 */
-	private class DelayedWidgetEvent {
-
-		DelayedWidgetEvent(InteractiveWidget widget,
-				ItemParentStateChangedEvent e) {
-			_widget = widget;
-			_e = e;
-		}
-
-		InteractiveWidget _widget;
-
-		ItemParentStateChangedEvent _e;
-	}
-
-	/**
-	 * Must be able to add widgets on first loaded frame: these are loaded
-	 * before the browser singleton is made available.
-	 */
-	private static List<DelayedWidgetEvent> _widgetsToAddLater = new LinkedList<DelayedWidgetEvent>();
-
-	/**
-	 * Ensures widgets are added correctly to first loaded frame
-	 */
-	class AddToFrameLater implements Runnable {
-		public void run() {
-			if (!_widgetsToAddLater.isEmpty()) {
-				List<DelayedWidgetEvent> tmp = null;
-				synchronized (_widgetsToAddLater) {
-					tmp = new LinkedList<DelayedWidgetEvent>(_widgetsToAddLater);
-				}
-				_widgetsToAddLater.clear();
-				for (DelayedWidgetEvent iwi : tmp) {
-					iwi._widget.addJComponantToFrame(iwi._e);
-					iwi._widget.invalidateSelf();
-				}
-			}
-		}
-	}
-
-	final void onBoundsChanged() {
-		if (isFixedSize())
-			_swingComponent.setBounds(getX(), getY(), _maxWidth, _maxHeight);
-		else
-			_swingComponent.setBounds(getX(), getY(), getWidth(), getHeight());
-	}
-
-	/**
-	 * 
-	 * @return The current bounds for this widget. Never null.
-	 */
-	public Rectangle getBounds() {
-		return new Rectangle(getX(), getY(), getWidth(), getHeight());
-	}
-
-	/**
-	 * Due to absolute positioning...
-	 * 
-	 * @param parent
-	 */
-	protected void layout(Component parent) {
-
-		parent.validate();
-
-		if (parent instanceof Container) {
-			for (Component c : ((Container) parent).getComponents()) {
-
-				if (c instanceof Container)
-					layout(c);
-				else
-					c.validate();
-			}
-		}
-
-	}
-
-	private void ignoreAWTPainting(Component c) {
-
-		if (c instanceof JComponent) {
-			((JComponent) c).setDoubleBuffered(false);
-		}
-
-		c.setIgnoreRepaint(true);
-
-		if (c instanceof Container) {
-			for (Component child : ((Container) c).getComponents()) {
-
-				if (child instanceof Container) {
-					ignoreAWTPainting(child);
-				} else {
-					if (child instanceof JComponent) {
-						((JComponent) child).setDoubleBuffered(false);
-					}
-
-					child.setIgnoreRepaint(true);
-				}
-			}
-		}
-	}
-
-	private void prepareToPaint() {
-		_isReadyToPaint = true;
-		layout(_swingComponent);
-		ignoreAWTPainting(_swingComponent);
-	}
-
-	/**
-	 * Paints the widget excluding the boundries. That is, the Swing graphics
-	 * 
-	 * @param g
-	 */
-	public void paint(Graphics g) {
-
-		if (!_isReadyToPaint) {
-			prepareToPaint();
-		}
-
-		Point loc = _swingComponent.getLocation();
-
-		g.translate(loc.x, loc.y);
-		_swingComponent.paint(g);
-		g.translate(-loc.x, -loc.y);
-
-		paintLink((Graphics2D) g);
-
-	}
-
-	protected void paintLink(Graphics2D g) {
-		// If this widget is linked .. then draw the link icon
-		if (_textRepresentation.getLink() != null
-				|| _textRepresentation.hasAction()) {
-			// System.out.println("Painted link");
-			_textRepresentation.paintLinkGraphic(g, getLinkX(), getLinkY());
-
-		}
-
-	}
-
-	private int getLinkX() {
-		return getX() - Item.LEFT_MARGIN;
-	}
-
-	private int getLinkY() {
-		return getY() + (getHeight() / 2);
-	}
-
-	/**
-	 * Invoked whenever the widget is to be repainted in free space.
-	 * 
-	 * @param g
-	 */
-	protected void paintInFreeSpace(Graphics g) {
-		g.setColor(FREESPACE_BACKCOLOR);
-		g.fillRect(getX(), getY(), getWidth(), getHeight());
-	}
-
-	/**
-	 * Called from the widgets corners: Whenever one of the corners are invoked
-	 * for a refill of the enclosed area.
-	 * 
-	 * If the widget is floating (e.g. currently picked up / rubberbanding) then
-	 * a shaded area is drawn instead of the actual widget so the manipulation
-	 * of the widget is as smooth as possible.
-	 * 
-	 * @param g
-	 * @param notifier
-	 */
-	void paintFill(Graphics g) {
-		if (_swingComponent.getParent() == null) {
-			// Note that frames with @f may want to paint the widgets so do not
-			// paint over the widget interface in these cases: must only
-			// paint if an object is floating
-			if (isFloating()) {
-				paintInFreeSpace(g);
-				paintLink((Graphics2D) g);
-			}
-		}
-	}
-
-	/**
-	 * @return True if this widget cannot be resized in either directions
-	 */
-	public boolean isFixedSize() {
-		return this._minHeight == this._maxHeight
-				&& this._minWidth == this._maxWidth && this._minHeight >= 0
-				&& this._minWidth >= 0;
-	}
-
-	/**
-	 * Removes this widget from the parent frame or free space.
-	 * 
-	 * @return True if removed from a parent frame. Thus a parent changed event
-	 *         will be invoked.
-	 * 
-	 * False if removed purely from free space.
-	 */
-	protected boolean removeSelf() {
-
-		Frame parent = getParentFrame();
-
-		if (parent != null) {
-			parent.removeAllItems(_expediteeItems);
-		}
-
-		FreeItems.getInstance().removeAll(_expediteeItems);
-
-		return (parent != null);
-
-	}
-
-	/**
-	 * @return The parent frame. Null if has none. Note: Based on corners
-	 *         parents.
-	 */
-	public Frame getParentFrame() {
-
-		Frame parent = null;
-		if (_d1.getParent() != null)
-			parent = _d1.getParent();
-		else if (_d2.getParent() != null)
-			parent = _d2.getParent();
-		else if (_d3.getParent() != null)
-			parent = _d3.getParent();
-		else if (_d4.getParent() != null)
-			parent = _d4.getParent();
-
-		return parent;
-	}
-
-	protected void invalidateSelf() {
-		Rectangle dirty = new Rectangle((int) getX(), (int) getY(),
-				(int) getWidth(), (int) getHeight());
-		FrameGraphics.invalidateArea(dirty);
-		invalidateLink();
-		//FrameGraphics.refresh(true);
-	}
-
-	/**
-	 * Invalidates the link for this widget - if it has one.
-	 */
-	protected void invalidateLink() {
-		if (_textRepresentation.getLink() != null
-				|| _textRepresentation.hasAction()) {
-			Rectangle linkArea = _textRepresentation.getLinkDrawArea(
-					getLinkX(), getLinkY());
-			FrameGraphics.invalidateArea(linkArea);
-		}
-
-	}
-
-	/**
-	 * @see ItemUtils#isVisible(Item)
-	 * 
-	 * @return True if this widget is visible from the current frame. Considers
-	 *         overlays and vectors.
-	 * 
-	 */
-	public boolean isVisible() {
-		return ItemUtils.isVisible(_d1);
-	}
-
-	/**
-	 * Invoked whenever the widget have moved. Can override.
-	 * 
-	 */
-	protected void onMoved() {
-	}
-
-	/**
-	 * Invoked whenever the widget have moved. Can override.
-	 * 
-	 */
-	protected void onSizeChanged() {
-	}
-
-	/**
-	 * Override to have a custom min border thickness for your widget.
-	 * 
-	 * @see #DEFAULT_MINIMUM_BORDER_THICKNESS
-	 * 
-	 * @return The minimum border thickness. Should be larger or equal to zero.
-	 * 
-	 */
-	public float getMinimumBorderThickness() {
-		return DEFAULT_MINIMUM_BORDER_THICKNESS;
-	}
-
-	/**
-	 * Looks fors a dataline in the current representation of the widget.
-	 * 
-	 * @see #getCurrentRepresentation
-	 * @see #getStrippedDataInt(String, int)
-	 * @see #getStrippedDataLong(String, long)
-	 * 
-	 * @param tag
-	 *            The prefix of a dataline that will be matched. Must be larger
-	 *            the zero and not null.
-	 * 
-	 * @return The <i>first</i> dataline that matched the prefix - without the
-	 *         prefix. Null if their was no data that matched the given prefix.
-	 * 
-	 * @throws IllegalArgumentException
-	 *             If tag is null.
-	 * 
-	 * @throws NullPointerException
-	 *             If tag is empty.
-	 */
-	protected String getStrippedDataString(String tag) {
-		if (tag == null)
-			throw new NullPointerException("tag");
-		else if (tag.length() == 0)
-			throw new IllegalArgumentException("tag is empty");
-
-		if (getCurrentRepresentation().getData() != null) {
-			for (String str : getCurrentRepresentation().getData()) {
-				if (str != null && str.startsWith(tag)
-						&& str.length() > tag.length()) {
-					return str.substring(tag.length());
-				}
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Looks fors a dataline in the current representation of the widget.
-	 * 
-	 * @see #getCurrentRepresentation
-	 * @see #getStrippedDataString(String)
-	 * @see #getStrippedDataLong(String, long)
-	 * 
-	 * @param tag
-	 *            The prefix of a dataline that will be matched. Must be larger
-	 *            the zero and not null.
-	 * 
-	 * @param defaultValue
-	 *            The default value if the tag does not exist or contains
-	 *            invalid data.
-	 * 
-	 * @return The <i>first</i> dataline that matched the prefix - parsed as an
-	 *         int (after the prefix). defaultValue if their was no data that
-	 *         matched the given prefix or the data was invalid.
-	 * 
-	 * @throws IllegalArgumentException
-	 *             If tag is null.
-	 * 
-	 * @throws NullPointerException
-	 *             If tag is empty.
-	 * 
-	 */
-	protected Integer getStrippedDataInt(String tag, Integer defaultValue) {
-
-		String strippedStr = getStrippedDataString(tag);
-
-		if (strippedStr != null) {
-			strippedStr = strippedStr.trim();
-			if (strippedStr.length() > 0) {
-				try {
-					return Integer.parseInt(strippedStr);
-				} catch (NumberFormatException e) { /* Consume */
-				}
-			}
-		}
-
-		return defaultValue;
-	}
-	
-	
-
-	/**
-	 * Looks for a dataline in the current representation of the widget.
-	 * 
-	 * @see #getCurrentRepresentation
-	 * @see #getStrippedDataString(String)
-	 * @see #getStrippedDataInt(String, int)
-	 * 
-	 * @param tag
-	 *            The prefix of a dataline that will be matched. Must be larger
-	 *            the zero and not null.
-	 * 
-	 * @param defaultValue
-	 *            The default value if the tag does not exist or contains
-	 *            invalid data.
-	 * 
-	 * @return The <i>first</i> dataline that matched the prefix - parsed as a
-	 *         long (after the prefix). defaultValue if their was no data that
-	 *         matched the given prefix or the data was invalid.
-	 * 
-	 * @throws IllegalArgumentException
-	 *             If tag is null.
-	 * 
-	 * @throws NullPointerException
-	 *             If tag is empty.
-	 * 
-	 */
-	protected Long getStrippedDataLong(String tag, Long defaultValue) {
-		String strippedStr = getStrippedDataString(tag);
-
-		if (strippedStr != null) {
-			strippedStr = strippedStr.trim();
-			if (strippedStr.length() > 0) {
-				try {
-					return Long.parseLong(strippedStr);
-				} catch (NumberFormatException e) { /* Consume */
-				}
-			}
-		}
-
-		return defaultValue;
-	}
-
-	/**
-	 * Looks for a data-line in the current representation of the widget.
-	 * 
-	 * @see #getCurrentRepresentation
-	 * @see #getStrippedDataString(String)
-	 * @see #getStrippedDataLong(String, long)
-	 * 
-	 * @param tag
-	 *            The prefix of a data-line that will be matched. Must be larger
-	 *            the zero and not null.
-	 * 
-	 * @param defaultValue
-	 *            The default value if the tag does not exist or contains
-	 *            invalid data.
-	 * 
-	 * @return The <i>first</i> data-line that matched the prefix - if
-	 *         case insensitive match is 'true' then return true, otherwise
-	 *         false. defaultValue if their was no data that
-	 *         matched the given prefix or the data was invalid.
-	 *         
-	 * @throws IllegalArgumentException
-	 *             If tag is null.
-	 * 
-	 * @throws NullPointerException
-	 *             If tag is empty.
-	 * 
-	 */
-	protected Boolean getStrippedDataBool(String tag, Boolean defaultValue) {
-
-		String strippedStr = getStrippedDataString(tag);
-
-		if (strippedStr != null) {
-			strippedStr = strippedStr.trim();
-			if (strippedStr.length() > 0) {
-				return strippedStr.equalsIgnoreCase("true") ? true : false;
-			}
-		}
-
-		return defaultValue;
-	}
-	
-	
-	/**
-	 * All data is removed that is prefixed with the given tag.
-	 * 
-	 * @param tag
-	 *            The prefix of the data lines to remove. Must be larger the
-	 *            zero and not null.
-	 * 
-	 * @throws IllegalArgumentException
-	 *             If tag is null.
-	 * 
-	 * @throws NullPointerException
-	 *             If tag is empty.
-	 * 
-	 */
-	protected void removeData(String tag) {
-		updateData(tag, null);
-	}
-
-	protected void addDataIfCaseInsensitiveNotExists(String tag) {
-		if (tag == null) throw new NullPointerException("tag");
-		
-		List<String> data = getCurrentRepresentation().getData();
-		
-		if (data == null) {
-			data = new LinkedList<String>();
-		}
-		
-		for (String s : data) {
-			if (s != null && s.equalsIgnoreCase(tag)) {
-				return;
-			}
-		}
-		
-		data.add(tag);
-		getCurrentRepresentation().setData(data);
-	}
-
-	
-	/**
-	 * Updates the data with a given tag. All data is removed that is prefixed
-	 * with the given tag. Then a new line is added (if not null).
-	 * 
-	 * Note that passing newData with null is the equivelant of removing tag
-	 * lines.
-	 * 
-	 * @param tag
-	 *            The prefix of the data lines to remove. Must be larger the
-	 *            zero and not null.
-	 * 
-	 * @param newData
-	 *            The new line to add. Can be null - for not adding anything.
-	 * 
-	 * @throws IllegalArgumentException
-	 *             If tag is null.
-	 * 
-	 * @throws NullPointerException
-	 *             If tag is empty.
-	 * 
-	 * @see #removeData(String)
-	 * 
-	 */
-	protected void updateData(String tag, String newData) {
-		if (tag == null)
-			throw new NullPointerException("tag");
-		else if (tag.length() == 0)
-			throw new IllegalArgumentException("tag is empty");
-
-		// Get current data
-		List<String> data = getCurrentRepresentation().getData();
-
-		if (data != null) {
-			for (int i = 0; i < data.size(); i++) {
-				String str = data.get(i);
-				if (str != null && str.startsWith(tag)) {
-					data.remove(i);
-				}
-			}
-		}
-
-		if (newData != null) {
-			if (data != null)
-				data.add(newData);
-			else {
-				data = new LinkedList<String>();
-				data.add(newData);
-				getCurrentRepresentation().setData(data);
-
-			}
-		}
-	}
-	
-	public boolean containsData(String str) {
-		assert(str != null);
-		if (getCurrentRepresentation().getData() != null) 
-			return getCurrentRepresentation().getData().contains(str);
-		return false;
-	}
-	
-	public boolean containsDataTrimmedIgnoreCase(String str) {
-		assert(str != null);
-		if (getCurrentRepresentation().getData() != null) {
-			for (String data : getCurrentRepresentation().getData()) {
-				if (data != null && data.trim().equalsIgnoreCase(str)) {
-					return true;
-				}
-			}
-		}
-			
-		return false;
-	}
-
-	/**
-	 * Sets the link for this widget.
-	 * 
-	 * @param link
-	 *          The new frame link. Can be null (for no link)
-	 * 
-	 * @param linker
-	 * 			The text item creating the link. Null if not created from
-	 * 			a text item.
-	 */
-	public void setLink(String link, Text linker) {
-		// Make sure the link is redrawn when a link is added
-		if (link == null)
-			invalidateLink();
-		getSource().setLink(link);
-		if (link != null)
-			invalidateLink();
-	}
-
-	public void setBackgroundColor(Color c) {
-		getSource().setBackgroundColor(c);
-	}
-
-	/**
-	 * @return The link for this widget. Null if none.
-	 */
-	public String getLink() {
-		return _textRepresentation.getLink();
-	}
-
-	/**
-	 * <b>Note:</b> That if the widget has no parent (e.g. the widget is a
-	 * free-item) then the absolute link returned will be for the frameset of
-	 * the current frame.
-	 * 
-	 * @return The absolute link for this item. Null if there is no link, or if
-	 *         there is no parent for this widget and the current frame is
-	 *         unavailable.
-	 * 
-	 */
-	public String getAbsoluteLink() {
-
-		// Note: cannot return the source absolute link since it does not have
-		// a parent ... thus must manually format link
-
-		String link = getLink();
-
-		if (link == null || link.length() == 0)
-			return null;
-
-		if (FrameIO.isPositiveInteger(link)) { // relative - convert to
-												// absolute
-
-			// Get the frameset of this item
-			Frame parent = getParentFrame();
-			if (parent == null)
-				parent = DisplayIO.getCurrentFrame();
-			if (parent == null)
-				return null;
-
-			String framesetName = parent.getFramesetName();
-
-			if (framesetName == null)
-				return null;
-
-			return framesetName + link;
-
-		} else if (FrameIO.isValidFrameName(link)) { // already absolute
-			return link;
-		}
-
-		return null;
-	}
-	
-	/**
-	 * Sets the border color for the widget.
-	 * That is, for the source (so it is remembered) and also for all the
-	 * corners/edges.
-	 * 
-	 * @param c
-	 * 		The color to set.
-	 */
-	public void setWidgetEdgeColor(Color c) {
-		for (Item i : _expediteeItems) i.setColor(c);
-		// Above indirectly invokes setSourceBorderColor accordingly
-	}
-	
-	/**
-	 * Sets the thickness of the widget edge.
-	 * 
-	 * @see Item#setThickness(float)
-	 * 
-	 * @param thickness
-	 * 		The new thickness to set.
-	 */
-	public void setWidgetEdgeThickness(float thickness) {
-		_l1.setThickness(thickness, true);
-		//for (Item i : _expediteeItems) i.setThickness(thickness);
-//		 Above indirectly invokes setSourceThickness accordingly
-	}
-	
-	/**
-	 * Override to dis-allow widget thickness manipulation from the user.
-	 * @return
-	 */
-	public boolean isWidgetEdgeThicknessAdjustable() {
-		return true;
-	}
-
-	// TODO: Maybe rename setSource* ..  to update* ... These should actually be friendly!
-	public void setSourceColor(Color c) {
-		_textRepresentation.setColor(c);
-	}
-
-	public void setSourceBorderColor(Color c) {
-		_textRepresentation.setBorderColor(c);
-	}
-
-	public void setSourceFillColor(Color c) {
-		_textRepresentation.setFillColor(c);
-	}
-
-	public void setSourceThickness(float newThickness, boolean setConnected) {
- 		_textRepresentation.setThickness(newThickness, setConnected);
-	}
-
-	public void setSourceData(List<String> data) {
-		_textRepresentation.setData(data);
-	}
-
-	protected Point getOrigin() {
-		return _d1.getPosition(); // NOTE FROM BROOK: This flips around ... the origin can be any point 
-	}
-
-	protected Item getFirstCorner() {
-		return _d1;
-	}
-
-	public void setAnchorLeft(Float anchor) {
-		_anchorLeft = anchor;
-		// Anchor left-edge corners (dots) as well
-		_d1.setAnchorCornerX(anchor,null); 
-		_d4.setAnchorCornerX(anchor,null); 
-
-		if (anchor != null) {
-		    setPositions(_d1, anchor, _d1.getY());
-		    onResized();
-		}
-		
-		// Move X-rayable item as well
-		getCurrentRepresentation().setAnchorLeft(anchor);
-	}
-
-	public void setAnchorRight(Float anchor) {
-		_anchorRight = anchor;
-		// Anchor right-edge corners (dots) as well
-		_d2.setAnchorCornerX(null,anchor); // right
-		_d3.setAnchorCornerX(null,anchor); // right
-
-		if (anchor != null) {
-			setPositions(_d2, FrameGraphics.getMaxFrameSize().width - anchor, _d2.getY());
-			onResized();
-		}
-		
-		if (_anchorLeft == null) {
-			// Prefer having the X-rayable item at anchorLeft position (if defined) over moving to anchorRight
-			getCurrentRepresentation().setAnchorRight(anchor);
-		}
-	}
-	
-	public void setAnchorTop(Float anchor) {
-		_anchorTop = anchor;
-		// Anchor top-edge corners (dots) as well
-		_d1.setAnchorCornerY(anchor,null);
-		_d2.setAnchorCornerY(anchor,null); 
-		
-		if (anchor != null) {
-		    setPositions(_d2, _d2.getX(), anchor);
-		    onResized();
-		}
-    	
-		// Move X-rayable item as well
-		getCurrentRepresentation().setAnchorTop(anchor);
-	}
-
-	public void setAnchorBottom(Float anchor) {
-		_anchorBottom = anchor;
-		// Anchor bottom-edge corners (dots) as well
-		_d3.setAnchorCornerY(null,anchor); 
-		_d4.setAnchorCornerY(null,anchor); 
-		
-		if (anchor != null) {
-		    setPositions(_d3, _d3.getX(), FrameGraphics.getMaxFrameSize().height  - anchor);
-		    onResized();
-		}
-		
-		if (_anchorTop == null) {
-		    // Prefer having the X-rayable item at anchorTop position (if defined) over moving to anchorBottom
-			getCurrentRepresentation().setAnchorBottom(anchor);
-		}
-	}
-
-
-	public boolean isAnchored() {
-	    return (isAnchoredX()) || (isAnchoredY());
-	}
-
-	public boolean isAnchoredX() {
-		return (_anchorLeft != null) || (_anchorRight != null);
-	}
-
-	public boolean isAnchoredY() {
-		return (_anchorTop != null) || (_anchorBottom != null);
-	}
-	
-	/**
-	 * Call from expeditee for representing the name of the item.
-	 * Override to return custom name.
-	 * 
-	 * Note: Used for the new frame title when creating links for widgets.
-	 * 
-	 * @return
-	 * 		The name representing this widget
-	 */
-	public String getName() {
-		return this.toString();
-	}
-	
-	/**
-	 * Event called when the widget is left clicked while there are items attached to the FreeItems buffer.
-	 * Used to enable expeditee like text-widget interaction for left mouse clicks.
-	 * @return true if event was handled (no pass through), otherwise false.
-	 */
-	public boolean ItemsLeftClickDropped() {
-		return false;
-	}
-	
-	/**
-	 * Event called when the widget is middle clicked while there are items attached to the FreeItems buffer.
-	 * Used to enable expeditee like text-widget interaction for middle mouse clicks.
-	 * @return true if event was handled (no pass through), otherwise false.
-	 */
-	public boolean ItemsMiddleClickDropped() {
-		return false;
-	}
-	
-	/**
-	 * Event called when the widget is left clicked while there are items attached to the FreeItems buffer.
-	 * Used to enable expeditee like text-widget interaction for right mouse clicks
-	 * @return true if event was handled (no pass through), otherwise false.
-	 */
-	public boolean ItemsRightClickDropped() {
-		return false;
-	}
-	
-	/**
-	 * Makes sure we add our KeyListener to every child component,
-	 * since it seems that's the only way to make sure we capture key events in Java
-	 * (without using KeyBindings which seem to only support the keyTyped event)
-	 */
-	@Override
-	public void componentAdded(ContainerEvent e) {
-		if(e == null || e.getChild() == null) {
-			return;
-		}
-		keyListenerToChildren(e.getChild(), true);
-	}
-	
-	@Override
-	public void componentRemoved(ContainerEvent e) {
-		if(e == null || e.getChild() == null) {
-			return;
-		}
-		keyListenerToChildren(e.getChild(), false);
-	}
-	
-	@Override
-    public void keyTyped(KeyEvent e) {
-		
-		int keyCode = e.getKeyCode();
-    	
-    	if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
-    		FrameKeyboardActions.getInstance().keyTyped(e);
-    	}
-    }
-
-	@Override
-    public void keyPressed(KeyEvent e) {
-    	int keyCode = e.getKeyCode();
-    	
-    	if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
-    		FrameKeyboardActions.getInstance().keyPressed(e);
-    	}
-    }
-    
-	@Override
-    public void keyReleased(KeyEvent e) {
-		int keyCode = e.getKeyCode();
-    	
-    	if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
-    		FrameKeyboardActions.getInstance().keyReleased(e);
-    	}
-    }
-	
-	private void keyListenerToChildren(Component parent, boolean add) {
-		List<Component> components = new LinkedList<Component>();
-		components.add(parent);
-		while(!components.isEmpty()) {
-			Component c = components.remove(0);
-			if(c instanceof Container) {
-				components.addAll(Arrays.asList(((Container)c).getComponents()));
-			}
-			if(add && !Arrays.asList(c.getKeyListeners()).contains(this)) {
-				c.addKeyListener(this);
-			} else if (!add && Arrays.asList(c.getKeyListeners()).contains(this)) {
-				c.removeKeyListener(this);
-        	}
-		}
-	}
-	
-	public void onResized() {
-		invalidateSelf();
-    	onBoundsChanged();
-    	layout(_swingComponent);
-	}
-	
-}
