Index: /trunk/src/org/apollo/ApolloSystem.java
===================================================================
--- /trunk/src/org/apollo/ApolloSystem.java	(revision 1101)
+++ /trunk/src/org/apollo/ApolloSystem.java	(revision 1102)
@@ -1,14 +1,8 @@
 package org.apollo;
 
-import java.awt.Image;
-import java.awt.Toolkit;
-import java.awt.event.WindowEvent;
-import java.awt.event.WindowListener;
-import java.net.URL;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
 
-import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
 
@@ -29,11 +23,14 @@
 import org.apollo.widgets.FramePlayer;
 import org.expeditee.actions.Actions;
+import org.expeditee.core.BlockingRunnable;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.EcosystemManager.Ecosystem;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.InputManager.WindowEventListener;
+import org.expeditee.gio.InputManager.WindowEventType;
 import org.expeditee.gui.Browser;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameKeyboardActions;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.settings.UserSettings;
-import org.expeditee.importer.FrameDNDTransferHandler;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -47,9 +44,11 @@
 public final class ApolloSystem {
 	
+	private static final String APOLLO_ICON = "org/apollo/icons/mainicon.png";
+	
 	// TODO: Create actual frames
 	public static final String SYSTEM_FRAMESET_NAME = "apollosystem";
 	public static final String HELP_TOP_FRAMENAME = SYSTEM_FRAMESET_NAME + 2;
 	
-//	 TODO: How to get good results: collection (moteef) and querry
+	// TODO: How to get good results: collection (moteef) and querry
 	// TODO: How to omit indexing on tracks 
 	public static final String HELP_MELODYSEARCH_FRAMENAME = SYSTEM_FRAMESET_NAME + 3; 
@@ -58,84 +57,33 @@
 	public static final String SETTINGS_NAME_TIMELINE_LMARGIN = "timelineleftmargin";
 	
-
-
 	public static boolean useQualityGraphics = true;
-	
-	private ApolloSystem() {
-	}
 
 	private static boolean hasInitialized = false;
 	
+	private ApolloSystem()
+	{
+	}
+	
 	/**
 	 * Initializes Apollo mod for expeditee - prepares all subsystems.
 	 */
-	public static void initialize() {
-		
+	public static void initialize()
+	{
 		if (hasInitialized) return;
 
 		ApolloSystemLog.println("Initializing...");
-		
-		SwingUtilities.invokeLater(new Runnable() {
-			public void run() {
-				
-				 try {
-
-					URL url = ClassLoader.getSystemResource("org/apollo/icons/mainicon.png");
-					
-					if (url != null) {
-						 Image img = Toolkit.getDefaultToolkit().getImage(url);
-						 Browser._theBrowser.setIconImage(img);
-					}
-						
-	
-					 
-				 } catch (Exception e) {
-					 e.printStackTrace();
-				 }
-				 
-				// Ensure that resources are released before the application is closed.
-				Browser._theBrowser.addWindowListener(new WindowListener() {
-		
-					public void windowActivated(WindowEvent e) {
-					}
-		
-					public void windowClosed(WindowEvent e) {
-					}
-		
-					public void windowClosing(WindowEvent e) {
-						ApolloSystem.shutdown();
-					}
-		
-					public void windowDeactivated(WindowEvent e) {
-					}
-		
-					public void windowDeiconified(WindowEvent e) {
-					}
-		
-					public void windowIconified(WindowEvent e) {
-					}
-		
-					public void windowOpened(WindowEvent e) {
-					}
-				
-				});
-				
-				Browser._theBrowser.getContentPane().removeKeyListener(FrameKeyboardActions.getInstance());
-				Browser._theBrowser.removeKeyListener(FrameKeyboardActions.getInstance());
-				
-				Browser._theBrowser.getContentPane().addKeyListener(new AudioFrameKeyboardActions());
-				Browser._theBrowser.addKeyListener(new AudioFrameKeyboardActions());
-				
-				// Filter out some special mouse move cases
-				AudioFrameMouseActions apolloMouseFilter = new AudioFrameMouseActions();
-				Browser._theBrowser.getMouseEventRouter().removeExpediteeMouseMotionListener(
-						FrameMouseActions.getInstance());
-				Browser._theBrowser.getMouseEventRouter().addExpediteeMouseMotionListener(apolloMouseFilter);
-				
-				Browser._theBrowser.getMouseEventRouter().removeExpediteeMouseListener(
-						FrameMouseActions.getInstance());
-				Browser._theBrowser.getMouseEventRouter().addExpediteeMouseListener(apolloMouseFilter);
+
+		// Ensure that resources are released before the application is closed.
+		EcosystemManager.getInputManager().addWindowEventListener(new WindowEventListener() {
+			@Override
+			public void onWindowEvent(WindowEventType type)
+			{
+				if (type != WindowEventType.WINDOW_CLOSED) return;
+				ApolloSystem.shutdown();
 			}
 		});
+		
+		EcosystemManager.getInputManager().registerGestureListener(ApolloGestureActions.getInstance());
+		EcosystemManager.getInputManager().addInputEventToGestureTranslator(new ApolloKBMGestureTranslator());
 		
 		// Set title
@@ -161,6 +109,5 @@
 		
 		// Setup for importing audio
-		FrameDNDTransferHandler.getInstance().addCustomFileImporter(
-				new SampledAudioFileImporter());
+		EcosystemManager.getDragAndDropManager().addCustomFileImporter(new SampledAudioFileImporter());
 
 		ApolloSystemLog.println("  Loading actions and agents...");
@@ -202,6 +149,6 @@
 	 * When invoked, the apollo setting frame is loaded and parsed... setting apollo-specific settings.
 	 */
-	public static void loadSettings() {
-
+	public static void loadSettings()
+	{
 		// Load apollo settings frame from the default profile
 		Frame profile = FrameIO.LoadProfile(UserSettings.DEFAULT_PROFILE_NAME);
@@ -241,5 +188,6 @@
 	}
 	
-	private static Mutable.Integer stripNameValueStringInteger(String namevalue) {
+	private static Mutable.Integer stripNameValueStringInteger(String namevalue)
+	{
 		assert (namevalue != null);
 		int valueIndex = namevalue.indexOf(':') + 1;
@@ -259,6 +207,6 @@
 	 * Releases all resources currently used by the SampledAudioManager.
 	 */
-	public static void shutdown() {
-		
+	public static void shutdown()
+	{
 		ApolloSystemLog.println("Saving banks...");
 		SoundDesk.getInstance().saveMasterMix();
@@ -280,5 +228,6 @@
 	 * 		True if has initialized.
 	 */
-	public static boolean isInitialized() {
+	public static boolean isInitialized()
+	{
 		return hasInitialized;
 	}
@@ -294,13 +243,17 @@
 	 * @param args
 	 */
-	public static void main(String[] args) {
-		
-		try {
-	        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
-	    } 
-	    catch (Exception e) {
-	       e.printStackTrace();
-	       return;
-	    }
+	public static void main(String[] args)
+	{
+		if (Browser.ECOSYSTEM_TYPE == Ecosystem.Swing) {
+			try {
+		        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
+		    } catch (Exception e) {
+		       e.printStackTrace();
+		       return;
+		    }
+		}
+
+		// Window icon must be set before initialisation
+		GraphicsManager.setWindowIcon(APOLLO_ICON);
 		
 		// Run expeditee
@@ -308,6 +261,6 @@
 		
 		// Initialize apollo
-		SwingUtilities.invokeLater(new Runnable() {
-			public void run() {
+		EcosystemManager.getMiscManager().runOnGIOThread(new BlockingRunnable() {
+			public void execute() {
 				ApolloSystem.initialize();
 			}
Index: /trunk/src/org/apollo/ApolloSystemApplet.java
===================================================================
--- /trunk/src/org/apollo/ApolloSystemApplet.java	(revision 1101)
+++ /trunk/src/org/apollo/ApolloSystemApplet.java	(revision 1102)
@@ -3,5 +3,4 @@
 import java.io.File;
 
-import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
Index: /trunk/src/org/apollo/AudioFrameKeyboardActions.java
===================================================================
--- /trunk/src/org/apollo/AudioFrameKeyboardActions.java	(revision 1101)
+++ /trunk/src/org/apollo/AudioFrameKeyboardActions.java	(revision 1102)
@@ -25,5 +25,4 @@
 import org.expeditee.items.Item;
 import org.expeditee.items.Line;
-import org.expeditee.items.Permission;
 import org.expeditee.items.Text;
 import org.expeditee.items.Item.HighlightMode;
Index: /trunk/src/org/apollo/AudioFrameMouseActions.java
===================================================================
--- /trunk/src/org/apollo/AudioFrameMouseActions.java	(revision 1101)
+++ /trunk/src/org/apollo/AudioFrameMouseActions.java	(revision 1102)
@@ -73,6 +73,5 @@
 			FrameMouseActions.MouseY = e.getY();
 			
-		} else if (isSnapOn() &&
-				!FreeItems.getInstance().isEmpty()) { 
+		} else if (isSnapOn() && !FreeItems.getInstance().isEmpty()) { 
 			
 			// Couse movement of free items: Restraining left-most pixel in items
@@ -222,7 +221,7 @@
 					
 					if (firstInitTime == null) {
-						firstInitTime = Mutable.createMutableLong(it.value); // Important to crewate new instance
+						firstInitTime = Mutable.createMutableLong(it.value); // Important to create new instance
 					} else if (it.value < firstInitTime.value) {
-						firstInitTime = Mutable.createMutableLong(it.value); // Important to crewate new instance
+						firstInitTime = Mutable.createMutableLong(it.value); // Important to create new instance
 					}
 				}
Index: /trunk/src/org/apollo/actions/ApolloActions.java
===================================================================
--- /trunk/src/org/apollo/actions/ApolloActions.java	(revision 1101)
+++ /trunk/src/org/apollo/actions/ApolloActions.java	(revision 1102)
@@ -4,7 +4,7 @@
 import org.apollo.widgets.LinkedTrack;
 import org.apollo.widgets.SampleRecorder;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.items.Text;
 
@@ -17,12 +17,13 @@
 public class ApolloActions {
 
-	private ApolloActions() {} // Util construction
+	/** Static-only class. */
+	private ApolloActions()
+	{
+	} 
 	
-	/**
-	 * Attatches a new recorder to the cursor
-	 */
-	public static void spawnRecorder() {
-		
-		Frame target = DisplayIO.getCurrentFrame();
+	/** Attaches a new recorder to the cursor. */
+	public static void spawnRecorder()
+	{
+		Frame target = DisplayController.getCurrentFrame();
 		if (target  == null) return;
 
@@ -30,9 +31,9 @@
 		Text source = new Text(target.getNextItemID());
 		source.setParent(target);
-		source.setPosition(FrameMouseActions.MouseX, FrameMouseActions.MouseY);
+		source.setPosition(DisplayController.getMousePosition());
 		SampleRecorder recWidget = new SampleRecorder(source, null);
 		
 		// Pick it up
-		FrameMouseActions.pickup(recWidget.getItems());
+		StandardGestureActions.pickup(recWidget.getItems());
 	}
 	
@@ -42,5 +43,5 @@
 	public static void spawnLinkedTrack() {
 		
-		Frame target = DisplayIO.getCurrentFrame();
+		Frame target = DisplayController.getCurrentFrame();
 		if (target  == null) return;
 
@@ -48,10 +49,10 @@
 		Text source = new Text(target.getNextItemID());
 		source.setParent(target);
-		source.setPosition(FrameMouseActions.MouseX, FrameMouseActions.MouseY);
+		source.setPosition(DisplayController.getMousePosition());
 		
 		LinkedTrack ltWidget = new LinkedTrack(source, null);
 		
 		// Pick it up
-		FrameMouseActions.pickup(ltWidget.getItems());
+		StandardGestureActions.pickup(ltWidget.getItems());
 	}
 	
@@ -64,8 +65,8 @@
 		// Create the launcher
 		FramePlaybackLauncher launcher = new FramePlaybackLauncher(null);
-		launcher.setPosition(FrameMouseActions.MouseX, FrameMouseActions.MouseY);
+		launcher.setPosition(DisplayController.getMousePosition());
 
 		// Pick it up
-		FrameMouseActions.pickup(launcher);
+		StandardGestureActions.pickup(launcher);
 	}
 	
Index: /trunk/src/org/apollo/agents/MelodySearch.java
===================================================================
--- /trunk/src/org/apollo/agents/MelodySearch.java	(revision 1101)
+++ /trunk/src/org/apollo/agents/MelodySearch.java	(revision 1102)
@@ -1,5 +1,4 @@
 package org.apollo.agents;
 
-import java.awt.Color;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -10,5 +9,4 @@
 
 import javax.sound.sampled.AudioFormat;
-import javax.swing.SwingUtilities;
 
 import org.apollo.ApolloSystem;
@@ -26,12 +24,12 @@
 import org.apollo.widgets.TrackWidgetCommons;
 import org.expeditee.agents.SearchAgent;
+import org.expeditee.core.Colour;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.settings.UserSettings;
 import org.expeditee.settings.folders.FolderSettings;
 import org.expeditee.items.Item;
 import org.expeditee.items.ItemUtils;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.items.widgets.WidgetEdge;
@@ -42,5 +40,5 @@
  * Uses meldex. Thanks David Bainbridge.
  * 
- * The agent runs a querry on the given track widget that launched it.
+ * The agent runs a query on the given track widget that launched it.
  * If the track launches it it does a full search for all tracks on the current frameset.
  * 
@@ -96,5 +94,6 @@
 	 */
 	@Override
-	public boolean initialise(Frame frame, Item item) {
+	public boolean initialise(Frame frame, Item item)
+	{
 		if (!super.initialise(frame, item)) return false;
 		
@@ -104,5 +103,5 @@
 		if (item != null) {
 			
-			InteractiveWidget iw = null;
+			Widget iw = null;
 			
 			if (item instanceof WidgetCorner) {
@@ -162,10 +161,9 @@
 				
 				if (querryMelody == null) { // abort - failed to get audio
-					SwingUtilities.invokeLater(new ExpediteeMessageBayFeedback(
-							"Melody search aborted: Failed to load tracks audio"));
+					overwriteMessage("Melody search aborted: Failed to load tracks audio");
 					_results.addText("Melody search aborted: querry data not good enough to search with", 
-							Color.RED, null, null, false);
+							Colour.RED, null, null, false);
 					_results.addText("Click here for help on melody searches", 
-							new Color(0, 180, 0), ApolloSystem.HELP_MELODYSEARCH_FRAMENAME, null, false);
+							Colour.FromRGB255(0, 180, 0), ApolloSystem.HELP_MELODYSEARCH_FRAMENAME, null, false);
 					
 					_results.save();
@@ -186,9 +184,8 @@
 				
 				if (querryMelody == null) { // abort - failed to get audio
-					SwingUtilities.invokeLater(new ExpediteeMessageBayFeedback(
-							"Melody search aborted: Failed to proccess querry data"));
-					_results.addText("Melody search aborted: querry data not good enough to search with", Color.RED, null, null, false);
+					overwriteMessage("Melody search aborted: Failed to proccess querry data");
+					_results.addText("Melody search aborted: querry data not good enough to search with", Colour.RED, null, null, false);
 					_results.addText("Click here for help on melody searches", 
-							new Color(0, 180, 0), ApolloSystem.HELP_MELODYSEARCH_FRAMENAME, null, false);
+							Colour.FromRGB255(0, 180, 0), ApolloSystem.HELP_MELODYSEARCH_FRAMENAME, null, false);
 					_results.save();
 					return null;
@@ -240,5 +237,5 @@
 					if(!results.isEmpty()) { 
 						_results.addText(frameName + "(" + results.size() + ")", null, frameName, null, false);
-						FrameGraphics.requestRefresh(true);
+						DisplayController.requestRefresh(true);
 					}
 					
@@ -395,7 +392,7 @@
 
 				if (melodyScores.isEmpty() || melodyScores.get(0).getScore() > threshold) {
-					_results.addText("No matches", Color.RED, null, null, false);
+					_results.addText("No matches", Colour.RED, null, null, false);
 					_results.addText("Click here to find out how to improve your melody searches", 
-							new Color(0, 180, 0), ApolloSystem.HELP_MELODYSEARCH_FRAMENAME, null, false);
+							Colour.FromRGB255(0, 180, 0), ApolloSystem.HELP_MELODYSEARCH_FRAMENAME, null, false);
 				} else {
 					
@@ -426,5 +423,5 @@
 			
 			if (_stop) {
-				_results.addText("Search cancelled", Color.RED, null, null, false);
+				_results.addText("Search cancelled", Colour.RED, null, null, false);
 			}
 			
@@ -444,7 +441,4 @@
 		
 	}
-	
-
-	
 	
 	/**
@@ -470,26 +464,3 @@
 
 	}
-	
-	/**
-	 * Safely outputs a message on the messagebay .. if ran on swing thread.
-	 * @author Brook Novak
-	 *
-	 */
-	private class ExpediteeMessageBayFeedback implements Runnable {
-		
-		String feedbackMessage; 
-		
-		public ExpediteeMessageBayFeedback(String feedbackMessage) {
-			assert(feedbackMessage != null);
-			this.feedbackMessage = feedbackMessage;
-		}
-		
-		
-		public void run() {
-			assert(feedbackMessage != null);
-			overwriteMessage(feedbackMessage);
-		}
-	}
-	
-	
 }
Index: /trunk/src/org/apollo/agents/MelodySearchResult.java
===================================================================
--- /trunk/src/org/apollo/agents/MelodySearchResult.java	(revision 1101)
+++ /trunk/src/org/apollo/agents/MelodySearchResult.java	(revision 1102)
@@ -1,4 +1,3 @@
 package org.apollo.agents;
-
 
 /**
Index: /trunk/src/org/apollo/audio/ApolloSubjectChangedEvent.java
===================================================================
--- /trunk/src/org/apollo/audio/ApolloSubjectChangedEvent.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/ApolloSubjectChangedEvent.java	(revision 1102)
@@ -9,5 +9,7 @@
 public final class ApolloSubjectChangedEvent {
 	
-	private ApolloSubjectChangedEvent() {}
+	private ApolloSubjectChangedEvent()
+	{
+	}
 
 	public static final int INPUT_MIXER = 1;
Index: /trunk/src/org/apollo/audio/AudioFormatNotSupportedException.java
===================================================================
--- /trunk/src/org/apollo/audio/AudioFormatNotSupportedException.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/AudioFormatNotSupportedException.java	(revision 1102)
@@ -6,16 +6,20 @@
  * @author Brook Novak
  */
-public class AudioFormatNotSupportedException extends Exception {
+public class AudioFormatNotSupportedException extends Exception
+{
 	protected static final long serialVersionUID = 0L;
 	
-	public AudioFormatNotSupportedException() {
+	public AudioFormatNotSupportedException()
+	{
 		super();
 	}
 	
-	public AudioFormatNotSupportedException(String message) {
+	public AudioFormatNotSupportedException(String message)
+	{
 		super(message);
 	}
 	
-	public AudioFormatNotSupportedException(String message, Exception inner) {
+	public AudioFormatNotSupportedException(String message, Exception inner)
+	{
 		super(message, inner);
 	}
Index: /trunk/src/org/apollo/audio/Metronome.java
===================================================================
--- /trunk/src/org/apollo/audio/Metronome.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/Metronome.java	(revision 1102)
@@ -20,5 +20,6 @@
  *
  */
-public class Metronome extends AbstractSubject {
+public class Metronome extends AbstractSubject
+{
 	
 	private Receiver receiver = null;
Index: /trunk/src/org/apollo/audio/RecordManager.java
===================================================================
--- /trunk/src/org/apollo/audio/RecordManager.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/RecordManager.java	(revision 1102)
@@ -19,6 +19,6 @@
  *
  */
-public class RecordManager extends AbstractSubject  {
-
+public class RecordManager extends AbstractSubject
+{
 	private AudioCaptureThread captureThread = null;
 
Index: /trunk/src/org/apollo/audio/TrackSequence.java
===================================================================
--- /trunk/src/org/apollo/audio/TrackSequence.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/TrackSequence.java	(revision 1102)
@@ -16,5 +16,5 @@
  *
  */
-public final class TrackSequence extends AbstractSubject implements Comparable {
+public final class TrackSequence extends AbstractSubject implements Comparable<TrackSequence> {
 
 	/** FRIENDLY: ONLY TO BE ACCESSED BY AUDIO MIXER. */
@@ -159,11 +159,9 @@
 	 * Order ascending by initiation frame
 	 */
-	public final int compareTo(Object o) {
-		TrackSequence other = (TrackSequence)o; // throws class cast exception
-	
+	public final int compareTo(TrackSequence other)
+	{
 		int cmp = (new Long(initiationFrame)).compareTo(other.initiationFrame);
 
 		if (cmp == 0) {
-			
 			return (new Integer(hashCode()).compareTo(other.hashCode()));
 		}
Index: /trunk/src/org/apollo/audio/structure/AudioStructureModel.java
===================================================================
--- /trunk/src/org/apollo/audio/structure/AudioStructureModel.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/structure/AudioStructureModel.java	(revision 1102)
@@ -3,5 +3,4 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -14,5 +13,4 @@
 
 import javax.sound.sampled.UnsupportedAudioFileException;
-import javax.swing.SwingUtilities;
 
 import org.apollo.audio.ApolloSubjectChangedEvent;
@@ -27,20 +25,20 @@
 import org.apollo.widgets.SampledTrack;
 import org.apollo.widgets.TrackWidgetCommons;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.BlockingRunnable;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.settings.UserSettings;
 import org.expeditee.io.Conversion;
 import org.expeditee.items.ItemUtils;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.settings.folders.FolderSettings;
 
 /**
- * A thread safe model of the heirarchical structure of a track graph...
+ * A thread safe model of the hierarchical structure of a track graph...
  * abstracted from Expeditee frames and audio widgets.
  * 
- * The track widgets notifty this model for keeping the structure consistent with
- * expeditees data.
+ * The track widgets notify this model for keeping the structure consistent with
+ * Expeditee's data.
  * 
  * 
@@ -199,6 +197,6 @@
 		NewGraphCommitor commit = new NewGraphCommitor(rootODFrame, newGraph);
 		try {
-			SwingUtilities.invokeAndWait(commit);
-		} catch (InvocationTargetException e) {
+			EcosystemManager.getMiscManager().runOnGIOThread(commit);
+		} catch (Exception e) {
 			e.printStackTrace();
 			assert(false);
@@ -264,6 +262,6 @@
 		
 		try {
-			SwingUtilities.invokeAndWait(cacheFetch);
-		} catch (InvocationTargetException e) {
+			EcosystemManager.getMiscManager().runOnGIOThread(cacheFetch);
+		} catch (Exception e) {
 			e.printStackTrace();
 			assert(false);
@@ -562,5 +560,5 @@
 	 *
 	 */
-	private class ExpediteeCachedTrackInfoFetcher implements Runnable
+	private class ExpediteeCachedTrackInfoFetcher extends BlockingRunnable
 	{
 		private String rootFrameName;
@@ -578,5 +576,5 @@
 		}
 		
-		public void run()
+		public void execute()
 		{
 			assert(rootFrameName != null);
@@ -584,7 +582,7 @@
 			// Check if the current frame
 			Frame rootFrame = null;
-			if (DisplayIO.getCurrentFrame() != null && DisplayIO.getCurrentFrame().getName() != null
-					&& DisplayIO.getCurrentFrame().getName().equals(rootFrameName)) {
-				rootFrame = DisplayIO.getCurrentFrame();
+			if (DisplayController.getCurrentFrame() != null && DisplayController.getCurrentFrame().getName() != null
+					&& DisplayController.getCurrentFrame().getName().equals(rootFrameName)) {
+				rootFrame = DisplayController.getCurrentFrame();
 			} else {
 				// Check if in cache
@@ -597,5 +595,5 @@
 				linkedTracks =  new HashMap<String, LinkedTrackModelData>();
 				
-				for (InteractiveWidget iw : rootFrame.getInteractiveWidgets()) {
+				for (Widget iw : rootFrame.getInteractiveWidgets()) {
 					
 					if (iw instanceof SampledTrack) {
@@ -668,5 +666,5 @@
 	 *
 	 */
-	private class NewGraphCommitor implements Runnable
+	private class NewGraphCommitor extends BlockingRunnable
 	{
 		private final OverdubbedFrame rootODFrame;
@@ -687,5 +685,5 @@
 		}
 		
-		public void run()
+		public void execute()
 		{
 			
@@ -1083,5 +1081,5 @@
 		synchronized(sharedResourceLocker) { // IMPORTANT: Must wait for new graphs to be added to the shared resources
 
-			if (FrameGraphics.isXRayMode()) { // discard whole model
+			if (DisplayController.isXRayMode()) { // discard whole model
 
 				// Neccessary because if the user goes into xray then moves to a new frame
@@ -1422,5 +1420,5 @@
 
 	
-			if (FrameGraphics.isXRayMode()) { // discard whole model
+			if (DisplayController.isXRayMode()) { // discard whole model
 
 				// Neccessary because if the user goes into xray then moves to a new frame
@@ -1610,7 +1608,7 @@
 						
 						try {
-							SwingUtilities.invokeAndWait(new Runnable() {
+							EcosystemManager.getMiscManager().runOnGIOThread(new BlockingRunnable() {
 								
-								public void run() { // on swing thread
+								public void execute() { // on swing thread
 
 									synchronized(sharedResourceLocker) {
@@ -1672,5 +1670,5 @@
 								}
 							});
-						} catch (InvocationTargetException e) {
+						} catch (Exception e) {
 							e.printStackTrace();
 							assert(false);
Index: /trunk/src/org/apollo/audio/util/MultiTrackPlaybackController.java
===================================================================
--- /trunk/src/org/apollo/audio/util/MultiTrackPlaybackController.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/util/MultiTrackPlaybackController.java	(revision 1102)
@@ -9,5 +9,4 @@
 
 import javax.sound.sampled.LineUnavailableException;
-import javax.swing.SwingUtilities;
 
 import org.apollo.audio.ApolloPlaybackMixer;
@@ -31,11 +30,12 @@
 import org.apollo.util.TrackModelHandler;
 import org.apollo.util.TrackModelLoadManager;
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.DisplayIOObserver;
-
+import org.expeditee.core.BlockingRunnable;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.DisplayObserver;
 
 public class MultiTrackPlaybackController 
 	extends AbstractSubject 
-	implements TrackModelHandler, Observer, DisplayIOObserver {
+	implements TrackModelHandler, Observer, DisplayObserver {
 	
 	/** Can be a framename or virtual filename (e.g. from a linked track) */
@@ -91,5 +91,5 @@
 		// After a certain amount of frame changes since the last multi playback has occured
 		// the cached track models are freed to stop consuming all the memory.
-		DisplayIO.addDisplayIOObserver(this);
+		DisplayController.addDisplayObserver(this);
 		
 		// For whenever a track sequence is created - must observe the created track sequences...
@@ -295,7 +295,7 @@
 	 */
 	public void frameChanged() {
-		if (hasTrackCacheExpired() || isPlaying() || isLoading() || DisplayIO.getCurrentFrame() == null) return; // already expired - or is playing - so don't expire!
-		
-		String currentFrameName = DisplayIO.getCurrentFrame().getName();
+		if (hasTrackCacheExpired() || isPlaying() || isLoading() || DisplayController.getCurrentFrame() == null) return; // already expired - or is playing - so don't expire!
+		
+		String currentFrameName = DisplayController.getCurrentFrame().getName();
 		
 		// Free track group every so often.. 
@@ -785,5 +785,5 @@
 			final int id1 = id; 
 			final Object state1 = state;
-			SwingUtilities.invokeLater(new Runnable() {
+			EcosystemManager.getMiscManager().runOnGIOThread(new Runnable() {
 				public void run() {
 					synchronized(listeners1) {
@@ -919,5 +919,5 @@
 	
 				try {
-					SwingUtilities.invokeAndWait(absTrackGraphRetreiver);
+					EcosystemManager.getMiscManager().runOnGIOThread(absTrackGraphRetreiver);
 				} catch (Exception e) {
 					notifyListeners(loadListeners, MultitrackLoadListener.LOAD_FAILED_GENERIC, e, true);
@@ -1095,5 +1095,5 @@
 
 			// Must commence on the swing thread
-			SwingUtilities.invokeLater(new MultiTrackPlaybackCommencer());
+			EcosystemManager.getMiscManager().runOnGIOThread(new MultiTrackPlaybackCommencer());
 		}
 		
@@ -1154,5 +1154,5 @@
 		 * @author Brook Novak
 		 */
-		private class ABSTrackGraphRetreiver implements Runnable {
+		private class ABSTrackGraphRetreiver extends BlockingRunnable {
 			
 			private String masterMixID;
@@ -1165,5 +1165,5 @@
 			}
 			
-			public void run() {
+			public void execute() {
 				assert(rootODFrame != null);
 				assert(masterMixID != null);
Index: /trunk/src/org/apollo/audio/util/PlaybackClock.java
===================================================================
--- /trunk/src/org/apollo/audio/util/PlaybackClock.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/util/PlaybackClock.java	(revision 1102)
@@ -10,5 +10,5 @@
 import org.apollo.mvc.SubjectChangedEvent;
 import org.apollo.util.AudioMath;
-import org.expeditee.gui.FrameGraphics;
+import org.expeditee.gui.DisplayController;
 
 /**
@@ -161,5 +161,5 @@
 					// Do a repaint is something was listening
 					if (shouldRepaint) {
-						FrameGraphics.requestRefresh(true); // later - should not congest AWT queue
+						DisplayController.requestRefresh(true); // later - should not congest AWT queue
 					}
 					
Index: /trunk/src/org/apollo/audio/util/Timeline.java
===================================================================
--- /trunk/src/org/apollo/audio/util/Timeline.java	(revision 1101)
+++ /trunk/src/org/apollo/audio/util/Timeline.java	(revision 1102)
@@ -6,11 +6,11 @@
  * 
  * <ul>
- * 		<li>The initation point: This is the smallest initiation time 
- * 			<b>(not neccessarily zero)</b> in the frame - at its X pixel.
+ * 		<li>The initiation point: This is the smallest initiation time 
+ * 			<b>(not necessarily zero)</b> in the frame - at its X pixel.
  * 		<li>The end point: This is how long the frame runs for - and the
  * 			x-pixel position of the last played track in the frame.
  * </ul>
  * 
- * They are simple imutable objects thus are not kept consistant with model.
+ * They are simple immutable objects thus are not kept consistent with model.
  * 
  * @author Brook Novak
Index: /trunk/src/org/apollo/gui/ApolloColorIndexedModels.java
===================================================================
--- /trunk/src/org/apollo/gui/ApolloColorIndexedModels.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/ApolloColorIndexedModels.java	(revision 1102)
@@ -1,32 +1,29 @@
 package org.apollo.gui;
 
-import java.awt.Color;
-import java.awt.image.IndexColorModel;
+import org.expeditee.core.Colour;
 
 public class ApolloColorIndexedModels {
 	
-	public static final Color KEY_COLOR = new Color(123,58,123,0);
-	private static final int KEY_INDEX = 0; 
+	public static final Colour KEY_COLOR = Colour.FromRGBA255(123,58,123,0);
+	//private static final int KEY_INDEX = 0; 
 	
 	/** Color index model for the track graphs */
-	public static final IndexColorModel graphIndexColorModel;
+	//public static final IndexColorModel graphIndexColorModel;
 
+	public static final Colour WAVEFORM_COLOR = Colour.fromRGB24BitPacked(0x1C5BA3);
+	public static final Colour WAVEFORM_SELECTION_COLOR = Colour.YELLOW;
 	
-	public static final Color WAVEFORM_COLOR = new Color(0x1C5BA3);
-	public static final Color WAVEFORM_SELECTION_COLOR = Color.YELLOW;
+	//private static final int WAVEFORM_INDEX = 1;
+	//private static final int WAVEFORM_SELECTION_INDEX = 2;
 	
-	private static final int WAVEFORM_INDEX = 1;
-	private static final int WAVEFORM_SELECTION_INDEX = 2;
+	//public static final IndexColorModel linkedTrackIndexColorModel;
 	
-	
-	public static final IndexColorModel linkedTrackIndexColorModel;
-	
-	public static final Color TRACK1_COLOR = new Color(0x1C5BA3);
-	public static final Color TRACK2_COLOR = new Color(0x3280B7);
+	public static final Colour TRACK1_COLOR = Colour.fromRGB24BitPacked(0x1C5BA3);
+	public static final Colour TRACK2_COLOR = Colour.fromRGB24BitPacked(0x3280B7);
 	
 	public static final int TRACK1_INDEX = 1;
 	public static final int TRACK2_INDEX = 2;
 
-	static { // Prepare the global color index model for the graphs
+	/*static { // Prepare the global color index model for the graphs
 
 		// For waveform graphs:
@@ -35,15 +32,15 @@
 		byte[] blues = new byte[256];
 		
-		reds[KEY_INDEX] = (byte)KEY_COLOR.getRed();
-		greens[KEY_INDEX] = (byte)KEY_COLOR.getGreen();
-		blues[KEY_INDEX] = (byte)KEY_COLOR.getBlue();
+		reds[KEY_INDEX] = (byte)KEY_COLOR.getRed255();
+		greens[KEY_INDEX] = (byte)KEY_COLOR.getGreen255();
+		blues[KEY_INDEX] = (byte)KEY_COLOR.getBlue255();
 		
-		reds[WAVEFORM_INDEX] = (byte)WAVEFORM_COLOR.getRed();
-		greens[WAVEFORM_INDEX] = (byte)WAVEFORM_COLOR.getGreen();
-		blues[WAVEFORM_INDEX] = (byte)WAVEFORM_COLOR.getBlue();
+		reds[WAVEFORM_INDEX] = (byte)WAVEFORM_COLOR.getRed255();
+		greens[WAVEFORM_INDEX] = (byte)WAVEFORM_COLOR.getGreen255();
+		blues[WAVEFORM_INDEX] = (byte)WAVEFORM_COLOR.getBlue255();
 		
-		reds[WAVEFORM_SELECTION_INDEX] = (byte)WAVEFORM_SELECTION_COLOR.getRed();
-		greens[WAVEFORM_SELECTION_INDEX] = (byte)WAVEFORM_SELECTION_COLOR.getGreen();
-		blues[WAVEFORM_SELECTION_INDEX] = (byte)WAVEFORM_SELECTION_COLOR.getBlue();
+		reds[WAVEFORM_SELECTION_INDEX] = (byte)WAVEFORM_SELECTION_COLOR.getRed255();
+		greens[WAVEFORM_SELECTION_INDEX] = (byte)WAVEFORM_SELECTION_COLOR.getGreen255();
+		blues[WAVEFORM_SELECTION_INDEX] = (byte)WAVEFORM_SELECTION_COLOR.getBlue255();
 		
 		graphIndexColorModel = new IndexColorModel(8, 256, reds, greens, blues, KEY_INDEX);
@@ -55,22 +52,18 @@
 		blues = new byte[256];
 		
-		reds[KEY_INDEX] = (byte)KEY_COLOR.getRed();
-		greens[KEY_INDEX] = (byte)KEY_COLOR.getGreen();
-		blues[KEY_INDEX] = (byte)KEY_COLOR.getBlue();
+		reds[KEY_INDEX] = (byte)KEY_COLOR.getRed255();
+		greens[KEY_INDEX] = (byte)KEY_COLOR.getGreen255();
+		blues[KEY_INDEX] = (byte)KEY_COLOR.getBlue255();
 		
-		reds[TRACK1_INDEX] = (byte)TRACK1_COLOR.getRed();
-		greens[TRACK1_INDEX] = (byte)TRACK1_COLOR.getGreen();
-		blues[TRACK1_INDEX] = (byte)TRACK1_COLOR.getBlue();
+		reds[TRACK1_INDEX] = (byte)TRACK1_COLOR.getRed255();
+		greens[TRACK1_INDEX] = (byte)TRACK1_COLOR.getGreen255();
+		blues[TRACK1_INDEX] = (byte)TRACK1_COLOR.getBlue255();
 		
-		reds[TRACK2_INDEX] = (byte)TRACK2_COLOR.getRed();
-		greens[TRACK2_INDEX] = (byte)TRACK2_COLOR.getGreen();
-		blues[TRACK2_INDEX] = (byte)TRACK2_COLOR.getBlue();
+		reds[TRACK2_INDEX] = (byte)TRACK2_COLOR.getRed255();
+		greens[TRACK2_INDEX] = (byte)TRACK2_COLOR.getGreen255();
+		blues[TRACK2_INDEX] = (byte)TRACK2_COLOR.getBlue255();
 		
 		linkedTrackIndexColorModel = new IndexColorModel(8, 256, reds, greens, blues, KEY_INDEX);
 		
-	}
-	
-	
-	
-	
+	}*/
 }
Index: /trunk/src/org/apollo/gui/DualPeakTroughWaveFormRenderer.java
===================================================================
--- /trunk/src/org/apollo/gui/DualPeakTroughWaveFormRenderer.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/DualPeakTroughWaveFormRenderer.java	(revision 1102)
@@ -30,9 +30,9 @@
 	 * 			If audioformat is not supported. See SampledAudioManager.isFormatSupportedForPlayback
 	 */
-	public DualPeakTroughWaveFormRenderer(AudioFormat audioFormat) {
+	public DualPeakTroughWaveFormRenderer(AudioFormat audioFormat)
+	{
 		if (audioFormat == null) throw new NullPointerException("audioFormat");
 		
-		if (!SampledAudioManager.getInstance().isFormatSupportedForPlayback(audioFormat)) 
-			throw new IllegalArgumentException();
+		if (!SampledAudioManager.getInstance().isFormatSupportedForPlayback(audioFormat)) throw new IllegalArgumentException();
 
 		sampleSize = audioFormat.getSampleSizeInBits();
@@ -70,5 +70,6 @@
 	 * 		interleaves in rendering order)
 	 */
-	public float[] getSampleAmplitudes(byte[] audioBytes, int startFrame, int frameLength, int aggregationSize) {
+	public float[] getSampleAmplitudes(byte[] audioBytes, int startFrame, int frameLength, int aggregationSize)
+	{
 		assert(audioBytes != null);
 		assert(startFrame >= 0);
@@ -77,7 +78,5 @@
 		int aggregationCount = frameLength / aggregationSize;
 		
-		float[] amplitudes = (aggregationSize == 1) ? 
-			new float[aggregationCount] :
-				new float[aggregationCount * 2];
+		float[] amplitudes = (aggregationSize == 1) ? new float[aggregationCount] : new float[aggregationCount * 2];
 		
 		if (sampleSize == 16) {
Index: /trunk/src/org/apollo/gui/EditableSampledTrackGraphView.java
===================================================================
--- /trunk/src/org/apollo/gui/EditableSampledTrackGraphView.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/EditableSampledTrackGraphView.java	(revision 1102)
@@ -1,9 +1,7 @@
 package org.apollo.gui;
 
-import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Point;
-import java.awt.Rectangle;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
@@ -23,9 +21,12 @@
 import org.apollo.util.TrackNameCreator;
 import org.apollo.widgets.SampledTrack;
+import org.expeditee.core.Colour;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FreeItems;
 import org.expeditee.items.Item;
@@ -52,6 +53,6 @@
 	private boolean selectAllOnDoubleClick = false;
 
-	public static final Color SELECTION_BACKING_COLOR_SELECT_ONLY = Color.BLACK;
-	private static final Color SELECTION_BACKING_COLOR_SELECT_AND_COPY = Color.GREEN;
+	public static final Colour SELECTION_BACKING_COLOR_SELECT_ONLY = Colour.BLACK;
+	private static final Colour SELECTION_BACKING_COLOR_SELECT_AND_COPY = Colour.GREEN;
 
 	private static final int SELECTION_MODE_SELECT_ONLY = 1;
@@ -215,5 +216,5 @@
 			}
 			
-			FrameGraphics.refresh(true);
+			DisplayController.requestRefresh(true);
 			
 		}
@@ -289,5 +290,5 @@
 			assert(copiedAudioRegion != null);
 			
-			Frame targetFrame = DisplayIO.getCurrentFrame();
+			Frame targetFrame = DisplayController.getCurrentFrame();
 			if (targetFrame != null) {
 				
@@ -307,18 +308,18 @@
 				assert(Browser._theBrowser != null);
 				
-				// A workround for getting the widget into fre space centered on cursor
+				// A workaround for getting the widget into free space centred on cursor
 				Point p = e.getLocationOnScreen();
-				SwingUtilities.convertPointFromScreen(p, Browser._theBrowser.getContentPane());
+				SwingUtilities.convertPointFromScreen(p, SwingMiscManager.getIfUsingSwingGraphicsManager().getContentPane());
 				twidget.setPosition(p.x - (twidget.getWidth() / 2), p.y - (twidget.getHeight() / 2));
 
 				for (Item i : twidget.getItems()) {
-					i.setOffset(new Point(
-							(i.getX() - DisplayIO.getMouseX()) + (twidget.getWidth() / 2), 
-							(i.getY() - FrameMouseActions.getY()) + (twidget.getHeight() / 2)
-						));
+					i.setOffset(SwingConversions.fromSwingPoint(new Point(
+							(i.getX() - DisplayController.getMouseX()) + (twidget.getWidth() / 2), 
+							(i.getY() - DisplayController.getMouseY()) + (twidget.getHeight() / 2)
+						)));
 				}
 				
 				// Put the new widget into free space
-				FrameMouseActions.pickup(twidget.getItems());
+				StandardGestureActions.pickup(twidget.getItems());
 
 			}
@@ -399,5 +400,6 @@
 	
 	@Override
-	public void paint(Graphics g) {
+	public void paint(Graphics g)
+	{
 		super.paint(g);
 
@@ -416,10 +418,6 @@
 			}
 			
-			g.setColor(Color.RED);
-			g.drawLine(
-					x, 
-					0, 
-					x,
-					getHeight());
+			g.setColor(SwingConversions.toSwingColor(Colour.RED));
+			g.drawLine(x, 0, x, getHeight());
 			
 		}
@@ -432,8 +430,13 @@
 	private void paintLock(Graphics g) {
 		if (isPlaying()) {
-			IconRepository.getIcon("lock.png").paintIcon(null,
+			/*IconRepository.getIcon("lock.png").paintIcon(null,
 					g, 
 					getWidth() - LOCK_ICON_CORNER_OFFSET, 
-					LOCK_ICON_CORNER_OFFSET - 16);
+					LOCK_ICON_CORNER_OFFSET - 16);*/
+			
+			g.drawImage(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(IconRepository.getIcon("lock.png")), 
+					getWidth() - LOCK_ICON_CORNER_OFFSET, 
+					LOCK_ICON_CORNER_OFFSET - 16,
+					null);
 		}
 	}
@@ -442,5 +445,5 @@
 		Point exp = getExpediteePoint();
 		if (exp != null) {
-			FrameGraphics.invalidateArea(new Rectangle(
+			DisplayController.invalidateArea(new AxisAlignedBoxBounds(
 					exp.x + getWidth() - LOCK_ICON_CORNER_OFFSET, 
 					exp.y + LOCK_ICON_CORNER_OFFSET  - 16, 
@@ -505,5 +508,6 @@
 			
 			color =  (selectionMode == SELECTION_MODE_SELECT_ONLY) ?
-					SELECTION_BACKING_COLOR_SELECT_ONLY : SELECTION_BACKING_COLOR_SELECT_AND_COPY;
+						SwingConversions.toSwingColor(SELECTION_BACKING_COLOR_SELECT_ONLY) :
+						SwingConversions.toSwingColor(SELECTION_BACKING_COLOR_SELECT_AND_COPY);
 			super.paint(g);
 		}
Index: /trunk/src/org/apollo/gui/ExpandedTrackManager.java
===================================================================
--- /trunk/src/org/apollo/gui/ExpandedTrackManager.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/ExpandedTrackManager.java	(revision 1102)
@@ -2,16 +2,14 @@
 
 import java.awt.Dimension;
+import java.awt.Graphics2D;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
-import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
 import java.util.LinkedList;
 
 import javax.swing.JButton;
 import javax.swing.JLabel;
-import javax.swing.SwingUtilities;
+import javax.swing.JPanel;
 
 import org.apollo.audio.SampledTrackModel;
@@ -22,9 +20,15 @@
 import org.apollo.util.TrackModelHandler;
 import org.apollo.util.TrackModelLoadManager;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.InputManager.WindowEventListener;
+import org.expeditee.gio.InputManager.WindowEventType;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.MessageBay;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Popup;
 import org.expeditee.gui.PopupManager;
+import org.expeditee.gui.PopupManager.ExpandShrinkAnimator;
 
 /**
@@ -40,54 +44,38 @@
 	
 	/** All epxanded tracks ... either in all in view or all selected ... to be viewed */
-	private LinkedList<ExpandedTrackPopup> expandedTracks = new LinkedList<ExpandedTrackPopup> (); // SHARED Model data
+	private LinkedList<ExpandedTrackPopup> expandedTracks = new LinkedList<ExpandedTrackPopup>(); // SHARED Model data
 
 	private MultiTrackExpansionPopup trackSelectionPopup = new MultiTrackExpansionPopup();
 	
 	private static ExpandedTrackManager instance = new ExpandedTrackManager();
-	private ExpandedTrackManager() {
-		
+	
+	private ExpandedTrackManager()
+	{
 		// Keep view centered to browser size
-		SwingUtilities.invokeLater(new Runnable() {
-			public void run() {
-
-				// Keep expanded view centered to the browser window
-				if (Browser._theBrowser != null) {
-					Browser._theBrowser.addComponentListener(new ComponentListener() {
-
-						public void componentHidden(ComponentEvent e) {
-						}
-
-						public void componentMoved(ComponentEvent e) {
-						}
-
-						public void componentResized(ComponentEvent e) {
-							
-							if (PopupManager.getInstance().isShowing(trackSelectionPopup)) {
-								// User currently selecting..
-								trackSelectionPopup.setLocation(
-										(Browser._theBrowser.getWidth() / 2) - (trackSelectionPopup.getWidth() / 2), 0);
-								
-							} else { // expanded views might be showing
-								
-								// Fails with Maximizing of window on some systems... swing
-								// bug!! really anoying
-								updateLayout();
-	
-							}
-	
-						}
-
-						public void componentShown(ComponentEvent e) {
-						}
-						
-					});
+		EcosystemManager.getInputManager().addWindowEventListener(new WindowEventListener()
+		{
+			@Override
+			public void onWindowEvent(WindowEventType type)
+			{
+				if (type != WindowEventType.WINDOW_RESIZED) return;
+				if (PopupManager.getInstance().isShowing(trackSelectionPopup)) {
+					// User currently selecting..
+					trackSelectionPopup.setLocation((EcosystemManager.getGraphicsManager().getWindowSize().getWidth() - trackSelectionPopup.getFullBounds().getWidth()) / 2, 0);
+					
+				} else { // expanded views might be showing
+					
+					// Fails with maximising of window on some systems... swing
+					// bug!! really annoying
+					updateLayout();
+
 				}
-				
-			}
+			}
+			
 		});
 		
-		// Registewr for (indirectly) handling track models
+		// Register for (indirectly) handling track models
 		TrackModelLoadManager.getInstance().addTrackModelHandler(this);
 
+		PopupManager.getInstance().add(trackSelectionPopup);
 	}
 	
@@ -162,10 +150,6 @@
 	 * 		If trackModel or trackMix or trackSourceFrameName or localFilename is null.
 	 */
-	public boolean addTrackToSelection(
-			SampledTrackModel track, 
-			String trackSourceFrameName,
-			Rectangle animationSource,
-			TrackMixSubject mix) {
-		
+	public boolean addTrackToSelection(SampledTrackModel track, String trackSourceFrameName, AxisAlignedBoxBounds animationSource, TrackMixSubject mix)
+	{
 		assert(track != null);
 		assert(Browser._theBrowser != null);
@@ -174,6 +158,5 @@
 		synchronized(expandedTracks) {
 	
-			if (expandedTracks.size() < MAX_EXPANDED_TRACK_SIZE 
-					&& !isTrackInExpansionSelection(track)) {
+			if (expandedTracks.size() < MAX_EXPANDED_TRACK_SIZE && !isTrackInExpansionSelection(track)) {
 				
 				ExpandedTrackPopup.giveToExpandedTrackManager(
@@ -183,36 +166,17 @@
 						0,
 						track.getFrameCount()); /** @see #receiveExpandedTrackPopup */
-	
-				Rectangle trackSelectionPopupBounds = null;
 				
 				// Ensure that the trackSelectionPopup is not already showing / animated to show
 				if (!PopupManager.getInstance().isShowing(trackSelectionPopup)) {
 					
-					trackSelectionPopupBounds = new Rectangle(
-							(Browser._theBrowser.getWidth() / 2 ) - (trackSelectionPopup.getWidth() / 2),
-							0, 
-							trackSelectionPopup.getWidth(), 
-							trackSelectionPopup.getHeight());
+					trackSelectionPopup.setLocation((DisplayController.getFramePaintArea().getWidth() - trackSelectionPopup.getFullBounds().getWidth()) / 2, 0);
 					
 					// Creep from above
-					PopupManager.getInstance().showPopup(
-							trackSelectionPopup,
-							trackSelectionPopupBounds.getLocation(),
-							null,
-							PopupManager.getInstance().new ExpandShrinkAnimator(
-									trackSelectionPopupBounds,
-									null));
-					
-				} else {
-					trackSelectionPopup.repaint();
+					trackSelectionPopup.show();
 				}
 				
 				// Animate a fake popup expanding into the trackSelectionPopup from the given source if not null
 				if (animationSource != null) {
-					
-					PopupManager.getInstance().doPureAnimation(PopupManager.getInstance().new ExpandShrinkAnimator(
-							animationSource, null), 
-							(trackSelectionPopupBounds == null) ?
-									trackSelectionPopup.getBounds() : trackSelectionPopupBounds);
+					((ExpandShrinkAnimator) trackSelectionPopup.getAnimator()).setInitialBounds(animationSource);
 				}
 				
@@ -253,11 +217,6 @@
 	 * 
 	 */
-	public void expandSingleTrack(
-			SampledTrackModel track, 
-			Rectangle animationSource, 
-			TrackMixSubject mix,
-			String trackSourceFrameName,
-			int frameStart,
-			int frameLength) {
+	public void expandSingleTrack(SampledTrackModel track, AxisAlignedBoxBounds animationSource, TrackMixSubject mix, String trackSourceFrameName, int frameStart, int frameLength)
+	{
 		assert(animationSource != null);
 		assert(track != null);
@@ -265,6 +224,7 @@
 		synchronized(expandedTracks) {
 			// Hide all expandedTracks that are currently showing
-			while (!expandedTracks.isEmpty())
-				PopupManager.getInstance().hidePopup(expandedTracks.getFirst());
+			for (ExpandedTrackPopup expandedTrack : expandedTracks) {
+				expandedTrack.hide();
+			}
 		}
 
@@ -315,10 +275,10 @@
 	}
 	
-	private void cancelSelection() {
-		
+	private void cancelSelection()
+	{
 		hideTrackSelectionPopup();
 		
 		// Remove from selection
-		LinkedList<? extends ExpandedTrackPopup> old = (LinkedList<? extends ExpandedTrackPopup>)expandedTracks.clone();
+		LinkedList<? extends ExpandedTrackPopup> old = (LinkedList<? extends ExpandedTrackPopup>) expandedTracks.clone();
 		
 		synchronized(expandedTracks) {
@@ -341,5 +301,6 @@
 	 * 		A tracks ExpandedTrackPopup if one exists.
 	 */
-	private ExpandedTrackPopup getExpandedTrackPopup(SampledTrackModel track) {
+	private ExpandedTrackPopup getExpandedTrackPopup(SampledTrackModel track)
+	{
 		assert(track != null);
 		
@@ -362,5 +323,6 @@
 	 * 		True if the track is expanded - or is selected to be expanded..
 	 */
-	public boolean isTrackInExpansionSelection(SampledTrackModel track) {
+	public boolean isTrackInExpansionSelection(SampledTrackModel track)
+	{
 		assert(track != null);
 		return getExpandedTrackPopup(track) != null;
@@ -371,5 +333,6 @@
 	 * 			True if at least 1 expanded track is showing - or is selected to show.
 	 */
-	public boolean doesExpandedTrackExist() {
+	public boolean doesExpandedTrackExist()
+	{
 		synchronized(expandedTracks) {
 			return expandedTracks.size() > 0;
@@ -377,5 +340,6 @@
 	}
 	
-	public boolean isAnyExpandedTrackVisible() {
+	public boolean isAnyExpandedTrackVisible()
+	{
 		for (ExpandedTrackPopup xtp : expandedTracks) {
 			if (PopupManager.getInstance().isShowing(xtp)) return true;
@@ -389,10 +353,11 @@
 	 *
 	 */
-	public void showSelection() {
+	public void showSelection()
+	{
 		expandTracks(null);
 	}
 	
 	/**
-	 * Returns immediatly if there are no tracks selected. Only expands if the popup is not already expanded.
+	 * Returns immediately if there are no tracks selected. Only expands if the popup is not already expanded.
 	 * 
 	 * @param directAnimSource
@@ -401,6 +366,6 @@
 	 * 		a widget).
 	 */
-	private void expandTracks(Rectangle directAnimSource) {
-
+	private void expandTracks(AxisAlignedBoxBounds directAnimSource)
+	{
 		synchronized(expandedTracks) {
 			
@@ -418,12 +383,7 @@
 			for (ExpandedTrackPopup xtp : expandedTracks) {
 	
-				// Note: returns immediatly if already showing
-				PopupManager.getInstance().showPopup(
-						xtp, 
-						xtp.getLocation(), 
-						null,
-						PopupManager.getInstance().new ExpandShrinkAnimator(
-								directAnimSource,
-								null));
+				// Note: returns immediately if already showing
+				((ExpandShrinkAnimator) xtp.getAnimator()).setInitialBounds(directAnimSource);
+				xtp.show();
 			
 			}
@@ -435,9 +395,7 @@
 	}
 	
-	private void hideTrackSelectionPopup() {
-		PopupManager.getInstance().hidePopup(
-				trackSelectionPopup, PopupManager.getInstance().new ExpandShrinkAnimator(
-						new Rectangle((Browser._theBrowser.getWidth() / 2 ) - (trackSelectionPopup.getWidth() / 2),
-								0, trackSelectionPopup.getWidth(), trackSelectionPopup.getHeight()), null));
+	private void hideTrackSelectionPopup()
+	{
+		trackSelectionPopup.hide();
 	}
 	
@@ -446,9 +404,8 @@
 	 * current state of the window.
 	 */
-	private void updateLayout() {
-		
-		synchronized(expandedTracks) {
-				
-	
+	private void updateLayout()
+	{
+		synchronized(expandedTracks) {
+
 			if (expandedTracks.isEmpty()) return;
 			
@@ -456,9 +413,9 @@
 			assert(Browser._theBrowser != null);
 		
-			int cpWidth = Browser._theBrowser.getContentPane().getWidth();
-			int cpHeight = Browser._theBrowser.getContentPane().getHeight();
-			if (!FrameGraphics.isAudienceMode()) { // if message bay is showing - the remove the height
-				
-				cpHeight -= MessageBay.MESSAGE_BUFFER_HEIGHT;
+			int cpWidth = DisplayController.getFramePaintArea().getWidth();
+			int cpHeight = DisplayController.getFramePaintArea().getHeight();
+			if (!DisplayController.isAudienceMode()) { // if message bay is showing - the remove the height
+				
+				cpHeight -= DisplayController.getMessageBayPaintArea().getHeight();
 				
 			}
@@ -504,5 +461,6 @@
 	 * Global Track model re-use .... can be called from any thread
 	 */
-	public SampledTrackModel getSharedSampledTrackModel(String localfilename) {
+	public SampledTrackModel getSharedSampledTrackModel(String localfilename)
+	{
 		synchronized(expandedTracks) {
 			for (ExpandedTrackPopup xtp : expandedTracks) {
@@ -521,6 +479,7 @@
 	 *
 	 */
-	private class MultiTrackExpansionPopup extends Popup implements ActionListener {
-		
+	private class MultiTrackExpansionPopup extends Popup implements ActionListener
+	{
+		private JPanel panel;
 		private JButton expandButton;
 		private JButton cancelButton;
@@ -528,19 +487,22 @@
 		private JLabel selected2;
 		private JLabel selectedMore;
-
-		private static final long serialVersionUID = 1L;
+		
 		//private final Color BACK_COLOR = SampledTrackGraphViewPort.ZOOM_BACKING_COLOR_NORMAL;
 		
-		MultiTrackExpansionPopup() {
-			super(new GridBagLayout());
-			setSize(260, 80);
-			super.setAudoHide(false);
-			
-			expandButton = new JButton(IconRepository.getIcon("expand.png"));
+		MultiTrackExpansionPopup()
+		{
+			super(new ExpandShrinkAnimator());
+			
+			panel = new JPanel(new GridBagLayout());
+			panel.setSize(260, 80);
+			
+			expandButton = new JButton();
+			SwingMiscManager.setJButtonIcon(expandButton, IconRepository.getIcon("expand.png"));
 			expandButton.addActionListener(this);
 			expandButton.setPreferredSize(new Dimension(40, 40));
 			expandButton.setToolTipText("Expand selection");
 			
-			cancelButton = new JButton(IconRepository.getIcon("close.png"));
+			cancelButton = new JButton();
+			SwingMiscManager.setJButtonIcon(cancelButton, IconRepository.getIcon("close.png"));
 			cancelButton.addActionListener(this);
 			cancelButton.setPreferredSize(new Dimension(40, 40));
@@ -563,5 +525,5 @@
 			c.gridy = 0;
 			c.fill = GridBagConstraints.CENTER;
-			add(expandButton, c);
+			panel.add(expandButton, c);
 			
 			c = new GridBagConstraints();
@@ -569,5 +531,5 @@
 			c.gridy = 0;
 			c.fill = GridBagConstraints.CENTER;
-			add(cancelButton, c);
+			panel.add(cancelButton, c);
 			
 			c = new GridBagConstraints();
@@ -576,5 +538,5 @@
 			c.gridwidth = 2;
 			c.fill = GridBagConstraints.CENTER;
-			add(selected1, c);
+			panel.add(selected1, c);
 			
 			c = new GridBagConstraints();
@@ -583,5 +545,5 @@
 			c.gridwidth = 2;
 			c.fill = GridBagConstraints.CENTER;
-			add(selected2, c);
+			panel.add(selected2, c);
 			
 			c = new GridBagConstraints();
@@ -591,10 +553,14 @@
 			c.gridheight = 2;
 			c.fill = GridBagConstraints.CENTER;
-			add(selectedMore, c);
-
-		}
-		
-		public void onTrackSelectionChanged() {
-			
+			panel.add(selectedMore, c);
+		}
+		
+		public void setLocation(int x, int y)
+		{
+			panel.setLocation(x, y);
+		}
+		
+		public void onTrackSelectionChanged()
+		{
 			synchronized(expandedTracks) {
 					
@@ -628,5 +594,6 @@
 		}
 
-		public void actionPerformed(ActionEvent e) {
+		public void actionPerformed(ActionEvent e)
+		{
 			if (e.getSource() == expandButton) {
 				showSelection();
@@ -635,9 +602,28 @@
 			}
 		}
-		
-		
-
-	}
-	
-	
+
+		@Override
+		protected void paintInternal()
+		{
+			Graphics2D g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
+			
+			panel.paint(g);
+		}
+
+		@Override
+		public AxisAlignedBoxBounds getFullBounds()
+		{
+			return SwingConversions.fromSwingRectangle(panel.getBounds());
+		}
+
+		@Override
+		public void onHide()
+		{
+		}
+
+		@Override
+		public void onShow()
+		{
+		}
+	}
 }
Index: /trunk/src/org/apollo/gui/ExpandedTrackPopup.java
===================================================================
--- /trunk/src/org/apollo/gui/ExpandedTrackPopup.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/ExpandedTrackPopup.java	(revision 1102)
@@ -2,24 +2,16 @@
 
 import java.awt.BorderLayout;
-import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Event;
 import java.awt.Font;
-import java.awt.Graphics;
+import java.awt.Graphics2D;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Insets;
 import java.awt.Point;
-import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
 
 import javax.sound.sampled.LineUnavailableException;
-import javax.swing.Icon;
 import javax.swing.JButton;
 import javax.swing.JPanel;
@@ -45,13 +37,19 @@
 import org.apollo.util.AudioMath;
 import org.apollo.widgets.TrackWidgetCommons;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.input.InputEvent;
+import org.expeditee.gio.input.InputEventListener;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.FrameGraphics;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Popup;
-import org.expeditee.gui.PopupManager;
-
-public class ExpandedTrackPopup extends Popup implements ActionListener, Observer {
-	
-	private static final long serialVersionUID = 1L;
-	
+import org.expeditee.gui.PopupManager.ExpandShrinkAnimator;
+
+public class ExpandedTrackPopup extends Popup implements ActionListener, Observer
+{
 	/** The observed subject. Can never be null */
 	private SampledTrackModel trackModel; // immutable
@@ -61,4 +59,5 @@
 	private TrackMixSubject trackMix; // immutable
 
+	private JPanel panel;
 	private JButton playPauseButton;
 	private JButton stopButton;
@@ -106,7 +105,10 @@
 			String trackSourceFrameName,
 			int frameStart,
-			int frameLength) {
-		super(new BorderLayout());
+			int frameLength)
+	{
+		super(new ExpandShrinkAnimator());
 		super.setConsumeBackClick(true);
+		
+		panel = new JPanel(new BorderLayout());
 		
 		if (trackModel == null) throw new NullPointerException("trackModel");
@@ -121,5 +123,5 @@
 		playPauseButton = new JButton();
 		playPauseButton.addActionListener(this);
-		playPauseButton.setIcon(IconRepository.getIcon("play.png"));
+		SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("play.png"));
 		playPauseButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		playPauseButton.setToolTipText("Play selection / Pause");
@@ -128,5 +130,5 @@
 		stopButton.setEnabled(false);
 		stopButton.addActionListener(this);
-		stopButton.setIcon(IconRepository.getIcon("stop.png"));
+		SwingMiscManager.setJButtonIcon(stopButton, IconRepository.getIcon("stop.png"));
 		stopButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		stopButton.setToolTipText("Stop playback");
@@ -134,5 +136,5 @@
 		rewindButton = new JButton();
 		rewindButton.addActionListener(this);
-		rewindButton.setIcon(IconRepository.getIcon("rewind.png"));
+		SwingMiscManager.setJButtonIcon(rewindButton, IconRepository.getIcon("rewind.png"));
 		rewindButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		rewindButton.setToolTipText("Rewind to start");
@@ -140,5 +142,5 @@
 		// Icon changes
 		muteButton = new JToggleButton();
-		muteButton.setSelectedIcon(IconRepository.getIcon("volmute.png"));
+		SwingMiscManager.setJButtonIcon(muteButton, IconRepository.getIcon("volmute.png"));
 		muteButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		muteButton.setToolTipText("Toggle mute");
@@ -153,6 +155,6 @@
 		
 		soloButton = new JToggleButton();
-		soloButton.setIcon(IconRepository.getIcon("solo.png"));
-		soloButton.setSelectedIcon(IconRepository.getIcon("soloon.png"));
+		SwingMiscManager.setJButtonIcon(soloButton, IconRepository.getIcon("solo.png"));
+		SwingMiscManager.setJButtonSelectedIcon(soloButton, IconRepository.getIcon("soloon.png"));
 		soloButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		soloButton.setToolTipText("Toggle solo");
@@ -170,5 +172,5 @@
 		closeButton = new JButton();
 		closeButton.addActionListener(this);
-		closeButton.setIcon(IconRepository.getIcon("close.png"));
+		SwingMiscManager.setJButtonIcon(closeButton, IconRepository.getIcon("close.png"));
 		closeButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		closeButton.setToolTipText("Close");
@@ -216,86 +218,9 @@
 		nameLabelParent = new JPanel();
 		
-		nameLabelParent.addMouseListener(new MouseListener() {
-
-			public void mouseClicked(MouseEvent e) {
-				if (nameLabel != null) {
-					if (nameLabel.onMouseClicked(e)) {
-						e.consume();
-						return;
-					}
-				}
-			}
-
-			public void mouseEntered(MouseEvent e) {
-			}
-
-			public void mouseExited(MouseEvent e) {
-			}
-
-			public void mousePressed(MouseEvent e) {
-				if (nameLabel != null) {
-					if (nameLabel.onMousePressed(e)) {
-						e.consume();
-					}
-				}
-			}
-
-			public void mouseReleased(MouseEvent e) {
-				if (nameLabel != null) {
-					if (nameLabel.onMouseReleased(e)) {
-						e.consume();
-					}
-				}
-			}
-		
-		});
-		
-		nameLabelParent.addMouseMotionListener(new MouseMotionListener() {
-
-			public void mouseDragged(MouseEvent e) {
-				if (nameLabel != null) {
-					if (nameLabel.onMouseDragged(e)) {
-						e.consume();
-					}
-				}
-			}
-
-			public void mouseMoved(MouseEvent e) {
-				if (nameLabel != null) {
-					nameLabel.onMouseMoved(e, nameLabelParent);
-				}
-			}
-
-		});
-		
-		nameLabelParent.addKeyListener(new KeyListener() {
-
-			public void keyPressed(KeyEvent e) {
-				if (nameLabel != null) {
-					if (nameLabel.onKeyPressed(e, nameLabelParent)) {
-						e.consume();
-					}
-				}
-			}
-
-			public void keyReleased(KeyEvent e) {
-				if (nameLabel != null) {
-					if (nameLabel.onKeyReleased(e, nameLabelParent)) {
-						e.consume();
-					}
-				}
-
-			}
-
-			public void keyTyped(KeyEvent e) {
-			}
-			
-		});
-		
-		nameLabel = new EmulatedTextItem(nameLabelParent, new Point(10, 25));
-		nameLabel.setFontStyle(Font.BOLD);
+		nameLabel = new EmulatedTextItem(trackModel.getName(), SwingConversions.fromSwingPoint(new Point(10, 25)));
+		nameLabel.setFontStyle(SwingConversions.fromSwingFontStyle(Font.BOLD));
 		nameLabel.setFontSize(16);
-		nameLabel.setBackgroundColor(Color.WHITE);	
-		nameLabel.setText(trackModel.getName()); 
+		nameLabel.setBackgroundColor(Colour.WHITE);
+		nameLabel.gainFocus();
 
 		nameLabel.addTextChangeListener(new TextChangeListener() { //  a little bit loopy!
@@ -373,6 +298,6 @@
 		toolBarPanel.add(closeButton, c);
 		
-		this.add(toolBarPanel, BorderLayout.NORTH);
-		this.add(splitPane, BorderLayout.CENTER);
+		panel.add(toolBarPanel, BorderLayout.NORTH);
+		panel.add(splitPane, BorderLayout.CENTER);
 		
 		// Observe track model
@@ -430,13 +355,8 @@
 		ExpandedTrackManager.getInstance().receiveExpandedTrackPopup(xtp);
 	}
-
+	
 	@Override
-	public void onShowing() {
-
-	}
-	
-	@Override
-	public void onShow() {
-		
+	public void onShow()
+	{
 		if (splitPane.getHeight() < 140) {
 			splitPane.setDividerLocation(splitPane.getHeight() - 30);
@@ -456,10 +376,11 @@
 		// Invalidate full frame for shading
 		if (Browser._theBrowser != null) {
-			FrameGraphics.refresh(false);
+			DisplayController.requestRefresh(false);
 		}
 	}
 
 	@Override
-	public void onHide() {
+	public void onHide()
+	{
 		ExpandedTrackManager.getInstance().expandedTrackPopupHidden(this);
 		releaseMemory(); // get rid of buffer etc..
@@ -470,22 +391,22 @@
 		// Invalidate full frame for shading
 		if (Browser._theBrowser != null) {
-			FrameGraphics.refresh(false);
+			DisplayController.requestRefresh(false);
 		}
 	}
 	
-	
-
-
 	@Override
-	public void paint(Graphics g) {
-		super.paint(g);
-		
-		g.translate(-getX(), -getY());
-		nameLabel.paint(g);
-		g.translate(getX(), getY());
-		
-	}
-
-	public void actionPerformed(ActionEvent e) {
+	public void paintInternal()
+	{
+		Graphics2D g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
+		
+		panel.paint(g);
+		
+		g.translate(-getFullBounds().getMinX(), -getFullBounds().getMinY());
+		nameLabel.paint();
+		g.translate(getFullBounds().getMinX(), getFullBounds().getMinY());
+	}
+
+	public void actionPerformed(ActionEvent e)
+	{
 		if (trackModel == null) return;
 		
@@ -587,8 +508,5 @@
 			// If there are more expanded tracks showing then the ExpandedTrackManager
 			// will automatically re-layout the remaing views.
-			PopupManager.getInstance().hidePopup(this, 
-					PopupManager.getInstance().new ExpandShrinkAnimator(
-					new Rectangle(0, getY(), 1, getHeight()),
-							Color.LIGHT_GRAY));
+			hide();
 			
 		}
@@ -660,5 +578,5 @@
 			stopButton.setEnabled(true);
 			rewindButton.setEnabled(false);
-			playPauseButton.setIcon(IconRepository.getIcon("pause.png"));
+			SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("pause.png"));
 
 			setBorderThickness(TrackWidgetCommons.PLAYING_TRACK_EDGE_THICKNESS);
@@ -670,5 +588,5 @@
 			rewindButton.setEnabled(true);
 			stopButton.setEnabled(false);
-			playPauseButton.setIcon(IconRepository.getIcon("play.png"));
+			SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("play.png"));
 			
 			// Note:
@@ -810,7 +728,7 @@
 		
 		// Get border color currently used
-		Color oldC = getBorderColor();
-		
-		Color newC = TrackWidgetCommons.getBorderColor(
+		Colour oldC = getBorderColor();
+		
+		Colour newC = TrackWidgetCommons.getBorderColor(
 				SoundDesk.getInstance().isSolo(trackMix.getChannelID()), 
 				trackMix.isMuted());
@@ -828,5 +746,5 @@
 	private void updateButtonGUI() {
 		
-		Icon newIcon = null;
+		Image newIcon = null;
 		if (volumeSlider.getValue() <= 25) 
 				newIcon = IconRepository.getIcon("vol25.png");
@@ -838,5 +756,5 @@
 				newIcon = IconRepository.getIcon("vol100.png");
 		
-		muteButton.setIcon(newIcon);
+		SwingMiscManager.setJButtonIcon(muteButton, newIcon);
 	}
 
@@ -846,8 +764,20 @@
 	 * 		Never null.
 	 */
-	public String getTrackSourceFrameName() {
+	public String getTrackSourceFrameName()
+	{
 		return trackSourceFrameName;
 	}
 	
+	public void setBounds(int x, int y, int width, int height)
+	{
+		panel.setBounds(x, y, width, height);
+	}
+
+	@Override
+	public AxisAlignedBoxBounds getFullBounds()
+	{
+		return SwingConversions.fromSwingRectangle(panel.getBounds());
+	}
+	
 	
 }
Index: /trunk/src/org/apollo/gui/FastAlphaEffect.java
===================================================================
--- /trunk/src/org/apollo/gui/FastAlphaEffect.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/FastAlphaEffect.java	(revision 1102)
@@ -60,10 +60,12 @@
 			int x, int y, 
 			int width, int height,
-			int rgb) {
+			int rgb)
+	{
 		
-		if (raster == null)
+		if (raster == null) {
 			throw new NullPointerException("raster");
-		else if (colorModel == null)
+		} else if (colorModel == null) {
 			throw new NullPointerException("raster");
+		}
 		
 		int endcol = x + width;
Index: /trunk/src/org/apollo/gui/FrameLayoutDaemon.java
===================================================================
--- /trunk/src/org/apollo/gui/FrameLayoutDaemon.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/FrameLayoutDaemon.java	(revision 1102)
@@ -1,15 +1,8 @@
 package org.apollo.gui;
 
-import java.awt.Point;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
-import java.awt.event.MouseEvent;
 import java.io.File;
-import java.lang.reflect.InvocationTargetException;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
-
-import javax.swing.SwingUtilities;
 
 import org.apollo.audio.ApolloSubjectChangedEvent;
@@ -30,14 +23,16 @@
 import org.apollo.widgets.LinkedTrack;
 import org.apollo.widgets.SampledTrack;
-import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.DisplayIOObserver;
+import org.expeditee.core.Point;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.InputManager.WindowEventListener;
+import org.expeditee.gio.InputManager.WindowEventType;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.DisplayObserver;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FreeItems;
-import org.expeditee.gui.MouseEventRouter;
 import org.expeditee.items.Item;
 import org.expeditee.items.ItemUtils;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.items.widgets.WidgetEdge;
@@ -46,5 +41,5 @@
  * A daemon that lays out overdubbed frames.
  * 
- * It is a singletone. Also it is a subject which raises empty events whenever
+ * It is a singleton. Also it is a subject which raises empty events whenever
  * a new timeline is created.
  * 
@@ -52,5 +47,5 @@
  *
  */
-public class FrameLayoutDaemon extends AbstractSubject implements Observer, DisplayIOObserver {
+public class FrameLayoutDaemon extends AbstractSubject implements Observer, DisplayObserver {
 	
 	/** The frame that should not be layout out at any point in time. */
@@ -98,30 +93,12 @@
 		daemon.start();
 		AudioStructureModel.getInstance().addObserver(this);
-		DisplayIO.addDisplayIOObserver(this);
-		
-		// Listen for resize events
-		SwingUtilities.invokeLater(new Runnable() {
-			public void run() {
-
-				// Keep expanded view centered to the browser window
-				if (Browser._theBrowser != null) {
-					Browser._theBrowser.addComponentListener(new ComponentListener() {
-
-						public void componentHidden(ComponentEvent e) {
-						}
-
-						public void componentMoved(ComponentEvent e) {
-						}
-
-						public void componentResized(ComponentEvent e) {
-							forceRecheck();
-						}
-
-						public void componentShown(ComponentEvent e) {
-						}
-						
-					});
-				}
-				
+		DisplayController.addDisplayObserver(this);
+		
+		EcosystemManager.getInputManager().addWindowEventListener(new WindowEventListener()
+		{
+			@Override
+			public void onWindowEvent(WindowEventType type)
+			{
+				if (type == WindowEventType.WINDOW_RESIZED) forceRecheck();
 			}
 		});
@@ -321,5 +298,5 @@
 				// Note that accessing expeditee model in another thread --
 				// Being real careful not to do anything unsafe
-				Frame currentFrame = DisplayIO.getCurrentFrame();
+				Frame currentFrame = DisplayController.getCurrentFrame();
 				if (currentFrame == null) continue;
 
@@ -340,9 +317,7 @@
 				
 				try {
-					SwingUtilities.invokeAndWait(trackFormatter);
-				} catch (InterruptedException e) {
+					EcosystemManager.getMiscManager().runOnGIOThread(trackFormatter);
+				} catch (Throwable e) {
 					e.printStackTrace();
-				} catch (InvocationTargetException e) {
-					e.printStackTrace();
 				}
 				
@@ -359,6 +334,6 @@
 				assert(toFormat != null);
 				
-				// To late?
-				if (toFormat != DisplayIO.getCurrentFrame()) return;
+				// Too late?
+				if (toFormat != DisplayController.getCurrentFrame()) return;
 				
 				boolean supressSpatialLayout = suspendedFrame == toFormat;
@@ -370,7 +345,7 @@
 				boolean hasRunningTime = false; // A flag set to true if there is actual audio to [lay
 				
-				Map<InteractiveWidget, AbstractTrackGraphNode> widgetsToFormat = new HashMap<InteractiveWidget, AbstractTrackGraphNode>();
-	
-				for (InteractiveWidget iw : toFormat.getInteractiveWidgets()) {
+				Map<Widget, AbstractTrackGraphNode> widgetsToFormat = new HashMap<Widget, AbstractTrackGraphNode>();
+	
+				for (Widget iw : toFormat.getInteractiveWidgets()) {
 					
 					AbstractTrackGraphNode abinf = null;
@@ -429,7 +404,5 @@
 				
 				// Anything to format?
-				if (!hasRunningTime || 
-						widgetsToFormat.isEmpty() || 
-						longestEndTime == firstInitiationTime) {
+				if (!hasRunningTime || widgetsToFormat.isEmpty() || longestEndTime == firstInitiationTime) {
 					
 					// NOTE: longestEndTime == firstInitiationTime indicates linked tracks 
@@ -450,5 +423,5 @@
 					// Ensure that left most pixel is at a reasonable position
 					if (!supressSpatialLayout && (initiationXPixel < 0 ||
-							(initiationXPixel > Browser._theBrowser.getWidth() && Browser._theBrowser.getWidth() > leftMargin))) {
+							(initiationXPixel > DisplayController.getFramePaintArea().getWidth() && DisplayController.getFramePaintArea().getWidth() > leftMargin))) {
 						initiationXPixel = leftMargin;
 					} else if (!supressSpatialLayout && initiationXPixel > LAYOUT_MAX_INITIATION_PIXEL) {
@@ -459,5 +432,5 @@
 						timelineWidth = rightMostPixel - initiationXPixel;
 					} else {
-						timelineWidth = Browser._theBrowser.getWidth() - initiationXPixel - rightMargin;
+						timelineWidth = DisplayController.getFramePaintArea().getWidth() - initiationXPixel - rightMargin;
 					}
 					
@@ -483,5 +456,5 @@
 				if (!supressSpatialLayout) {
 					
-					for (InteractiveWidget iw : widgetsToFormat.keySet()) {
+					for (Widget iw : widgetsToFormat.keySet()) {
 						
 						AbstractTrackGraphNode atgi = widgetsToFormat.get(iw);
@@ -545,5 +518,5 @@
 			
 				Item i = FreeItems.getItemAttachedToCursor();
-				InteractiveWidget freespaceTrackToFormat = null;
+				Widget freespaceTrackToFormat = null;
 				if (i != null && i instanceof WidgetEdge) {
 					freespaceTrackToFormat = ((WidgetEdge)i).getWidgetSource();
@@ -573,6 +546,7 @@
 					if (width > 0) {
 						
-						if (width > (Browser._theBrowser.getWidth() - (2 * FREE_SPACE_MARGINS)))
-							width = Browser._theBrowser.getWidth() - (2 * FREE_SPACE_MARGINS);
+						if (width > (DisplayController.getFramePaintArea().getWidth() - (2 * FREE_SPACE_MARGINS))) {
+							width = DisplayController.getFramePaintArea().getWidth() - (2 * FREE_SPACE_MARGINS);
+						}
 
 						freespaceTrackToFormat.setSize(
@@ -582,16 +556,12 @@
 						
 						// Keep the floating track on the cursor
-						MouseEvent me = MouseEventRouter.getCurrentMouseEvent();
-						Point containerPoint = SwingUtilities.convertPoint(me.getComponent(), me.getPoint(), Browser._theBrowser.getContentPane());
-						
+						Point containerPoint = EcosystemManager.getInputManager().getCursorPosition();
+						
+						// If due to resize the track is not longer over the cursor then just center it.
 						if (!ItemUtils.expandRectangle(freespaceTrackToFormat.getBounds(), 20).contains(containerPoint)) {
-							// If due to resize the track is not longer over the cursor then just center it.
 							int offsetX = width / 2; 
 							int offsetY = freespaceTrackToFormat.getHeight() / 2;
-							freespaceTrackToFormat.setPosition(
-									containerPoint.x - offsetX, 
-									containerPoint.y - offsetY);
-							FrameMouseActions.resetOffset();
-		
+							freespaceTrackToFormat.setPosition(containerPoint.x - offsetX, containerPoint.y - offsetY);
+							StandardGestureActions.resetOffset();
 						}
 						
@@ -756,5 +726,5 @@
 
 		// Look for all track widgets
-		for (InteractiveWidget iw : frame.getInteractiveWidgets()) {
+		for (Widget iw : frame.getInteractiveWidgets()) {
 			
 			if (iw instanceof SampledTrack) {
@@ -928,5 +898,5 @@
 	public static long inferCurrentTotalMSTime() {
 		
-		Frame currentFrame = DisplayIO.getCurrentFrame();
+		Frame currentFrame = DisplayController.getCurrentFrame();
 		String currentFrameName = (currentFrame != null) ? currentFrame.getName() : null;
 		
Index: /trunk/src/org/apollo/gui/FramePlaybackBarRenderer.java
===================================================================
--- /trunk/src/org/apollo/gui/FramePlaybackBarRenderer.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/FramePlaybackBarRenderer.java	(revision 1102)
@@ -1,13 +1,6 @@
 package org.apollo.gui;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.Stroke;
 import java.util.LinkedList;
 import java.util.List;
-
-import javax.swing.SwingUtilities;
 
 import org.apollo.audio.ApolloPlaybackMixer;
@@ -23,8 +16,12 @@
 import org.apollo.util.AudioMath;
 import org.apollo.widgets.FramePlayer;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 
 /**
@@ -50,6 +47,6 @@
 	
 	private static final int BAR_STROKE_THICKNESS = 2;
-	private static final Stroke BAR_STROKE = new BasicStroke(BAR_STROKE_THICKNESS);
-	private static final Color BAR_COLOR = Color.DARK_GRAY;
+	private static final Stroke BAR_STROKE = new Stroke(BAR_STROKE_THICKNESS);
+	private static final Colour BAR_COLOR = Colour.DARK_GREY;
 	
 	private static FramePlaybackBarRenderer instance = new FramePlaybackBarRenderer();
@@ -121,5 +118,5 @@
 			}
 			
-			FrameGraphics.refresh(true);
+			DisplayController.requestRefresh(true);
 			
 			
@@ -132,5 +129,5 @@
 			currentMSPosition = -1;
 			pixelPositions.clear();
-			FrameGraphics.refresh(true);
+			DisplayController.requestRefresh(true);
 			
 			break;
@@ -140,29 +137,30 @@
 	}
 	
-	private void invalidate() {
+	private void invalidate()
+	{
 		if (Browser._theBrowser == null) return;
 		
-		int height = Browser._theBrowser.getHeight();
+		int height = EcosystemManager.getGraphicsManager().getWindowSize().getHeight();
 		
 		for (Integer n : pixelPositions) {
-			FrameGraphics.invalidateArea(new Rectangle(n - 1, 0, BAR_STROKE_THICKNESS + 2, height));
-		}
-	}
-	
-	public void paint(Graphics2D g) {
+			DisplayController.invalidateArea(new AxisAlignedBoxBounds(n - 1, 0, BAR_STROKE_THICKNESS + 2, height));
+		}
+	}
+	
+	public void paint()
+	{
 		if (Browser._theBrowser == null) return;
 		
-		Frame currentFrame = DisplayIO.getCurrentFrame();
+		Frame currentFrame = DisplayController.getCurrentFrame();
 		
 		if (currentFrame == null || currentFrame.getName() == null || pixelPositionsParent == null ||
 				!currentFrame.getName().equals(pixelPositionsParent)) return;
 		
-		int height = Browser._theBrowser.getHeight();
-		
-		g.setColor(BAR_COLOR);
-		g.setStroke(BAR_STROKE);
+		int height = EcosystemManager.getGraphicsManager().getWindowSize().getHeight();
+		
+		GraphicsManager gm = EcosystemManager.getGraphicsManager();
 		
 		for (Integer n : pixelPositions) {
-			g.drawLine(n, 0, n, height);
+			gm.drawLine(n, 0, n, height, BAR_COLOR, BAR_STROKE);
 		}
 	}
@@ -193,5 +191,5 @@
 		// Notes: the clock will queue a refresh for the frame after this
 		// event proccesses ... 
-		SwingUtilities.invokeLater(updator);
+		EcosystemManager.getMiscManager().runOnGIOThread(updator);
 	}
 	
@@ -201,10 +199,11 @@
 	 * @author Brook Novak
 	 */
-	private class PlaybackFrameBarUpdator implements Runnable {
+	private class PlaybackFrameBarUpdator implements Runnable
+	{
 		public void run() {
 			
 			if (currentMSPosition == -1 || currentTimeline == null) return;
 			
-			Frame currentFrame = DisplayIO.getCurrentFrame();
+			Frame currentFrame = DisplayController.getCurrentFrame();
 			
 			if (currentFrame == null || currentFrame.getName() == null) return;
Index: /trunk/src/org/apollo/gui/FrameRenderPasses.java
===================================================================
--- /trunk/src/org/apollo/gui/FrameRenderPasses.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/FrameRenderPasses.java	(revision 1102)
@@ -1,16 +1,7 @@
 package org.apollo.gui;
 
-import java.awt.Color;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.geom.Area;
-import java.awt.geom.Rectangle2D;
 import java.util.LinkedList;
 
-import org.apollo.AudioFrameKeyboardActions;
-import org.apollo.AudioFrameMouseActions;
+import org.apollo.ApolloGestureActions;
 import org.apollo.audio.util.Timeline;
 import org.apollo.items.FramePlaybackLauncher;
@@ -19,11 +10,23 @@
 import org.apollo.widgets.LinkedTrack;
 import org.apollo.widgets.SampledTrack;
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.TextLayout;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.input.KBMInputEvent.Key;
+import org.expeditee.gio.input.StandardInputEventListeners;
 import org.expeditee.gui.Browser;
 import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FreeItems;
 import org.expeditee.gui.FrameGraphics.FrameRenderPass;
 import org.expeditee.items.Item;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.items.widgets.WidgetEdge;
@@ -31,5 +34,5 @@
 /**
  * All final effects rendered here - to give extra feedback to the user and simply to make
- * it more apealing.
+ * it more appealing.
  * @author Brook Novak
  *
@@ -37,6 +40,6 @@
 public class FrameRenderPasses implements FrameRenderPass {
 	
-	private static final Color SHADED_EXPANDED_BACKING_COLOR = new Color(80, 80, 80, 140);
-	private static final Color Y_HELPER_LINES_COLOR = Color.DARK_GRAY;
+	private static final Colour SHADED_EXPANDED_BACKING_COLOR = Colour.FromRGBA255(80, 80, 80, 140);
+	private static final Colour Y_HELPER_LINES_COLOR = Colour.DARK_GREY;
 	private static final Stroke Y_HELPER_LINES_STROKE = OverdubbedFrameTimeAxis.TRACK_TIMELINE_STROKE;
 	
@@ -48,15 +51,21 @@
 	private boolean shouldDrawFullscreenHelpers = false;
 	
-	private FrameRenderPasses() {
+	private FrameRenderPasses()
+	{
 		FrameGraphics.addFrameRenderPass(this);
 	}
 	
-	public static FrameRenderPasses getInstance() {
+	public static FrameRenderPasses getInstance()
+	{
 		return instance;
 	}
 
-	public void paintFinalPass(Graphics g) {
+	public void paintFinalPass()
+	{
 		if (Browser._theBrowser == null) return;
-		int frameHeight = Browser._theBrowser.getContentPane().getHeight();
+		
+		GraphicsManager gm = EcosystemManager.getGraphicsManager();
+		
+		int frameHeight = EcosystemManager.getGraphicsManager().getWindowSize().getHeight();
 		if (ExpandedTrackManager.getInstance().isAnyExpandedTrackVisible()
 				&& !FreeItems.getInstance().isEmpty()) {
@@ -67,5 +76,5 @@
 			for (Item i : FreeItems.getInstance()) {
 				if (i instanceof WidgetCorner) {
-					InteractiveWidget iw = ((WidgetCorner)i).getWidgetSource();
+					Widget iw = ((WidgetCorner)i).getWidgetSource();
 					
 					if (iw != null && iw instanceof SampledTrack) {
@@ -84,8 +93,7 @@
 			if (toPaint != null) {
 				for (SampledTrack trackWidget : toPaint) {
-					if (g.getClip() == null
-							|| g.getClip().intersects(trackWidget.getComponant().getBounds()))
-					trackWidget.paintInFreeSpace(g, true);
-					
+					if (gm.peekClip() == null || gm.peekClip().isNotClipped() || (!gm.peekClip().isFullyClipped() && gm.peekClip().getBounds().intersects(trackWidget.getBounds()))) {
+						trackWidget.paintInFreeSpace(true);
+					}
 				}
 			}
@@ -93,26 +101,24 @@
 		} 
 		
-		OverdubbedFrameTimeAxis.getInstance().paint(g);
+		OverdubbedFrameTimeAxis.getInstance().paint();
 		
 		TimeAxis timeAxis = OverdubbedFrameTimeAxis.getInstance().getTimeAxis();	
 		Timeline lastTimeline = OverdubbedFrameTimeAxis.getInstance().getLastTimeline();
 		
-		FramePlaybackBarRenderer.getInstance().paint((Graphics2D)g);
+		FramePlaybackBarRenderer.getInstance().paint();
 
 		if (timeHelperLinesToPaint != null && timeAxis != null && lastTimeline != null) {
 
-			Rectangle r = OverdubbedFrameTimeAxis.getInstance().getCurrentTimelineArea();
+			AxisAlignedBoxBounds r = OverdubbedFrameTimeAxis.getInstance().getCurrentTimelineArea();
 			
 			// Draw helper bar and text
 			for (Integer x : timeHelperLinesToPaint) {
 				
-				((Graphics2D)g).setStroke(OverdubbedFrameTimeAxis.TRACK_TIMELINE_STROKE);
-				g.setColor(Color.RED);
-				
-				if (shouldDrawFullscreenHelpers) 
-					g.drawLine(x, 0, x, frameHeight);
-				else 
-					g.drawLine(x, r.y, x, r.y + r.height);
-									
+				if (shouldDrawFullscreenHelpers) {
+					gm.drawLine(new Point(x, 0), new Point(x, frameHeight), Colour.RED, OverdubbedFrameTimeAxis.TRACK_TIMELINE_STROKE);
+				} else {
+					gm.drawLine(new Point(x, r.getMinY()), new Point(x, r.getMinY() + r.getHeight()), Colour.RED, OverdubbedFrameTimeAxis.TRACK_TIMELINE_STROKE);
+				}
+				
 				long ms = lastTimeline.getMSTimeAtX(x) - lastTimeline.getFirstInitiationTime();
 
@@ -120,24 +126,16 @@
 				if (ms < 0) label = "-" + label;
 				
-				FontMetrics fm   = g.getFontMetrics(SampledTrackGraphViewPort.TIME_HELPER_FONT);
-				Rectangle2D rect = fm.getStringBounds(label, g);
+				//FontMetrics fm   = g.getFontMetrics(SampledTrackGraphViewPort.TIME_HELPER_FONT);
+				//Rectangle2D rect = fm.getStringBounds(label, g);
+				TextLayout layout = EcosystemManager.getTextLayoutManager().layoutStringSimple(label, SampledTrackGraphViewPort.TIME_HELPER_FONT);
+				AxisAlignedBoxBounds rect = layout.getPixelBounds(0, 0);
 				int labelWidth  = (int)(rect.getWidth());
 				int labelHeight  = (int)(rect.getHeight());
 				
-				int y = r.y + (r.height / 2) - ((labelHeight + 4) / 2);
-				
-
-				g.setColor(SampledTrackGraphViewPort.TIME_HELPER_COLOR);
-				g.fillRect(x + 2,  y, labelWidth + 3, labelHeight + 4);
-	
-				g.setColor(SampledTrackGraphViewPort.TIME_HELPER_BORDERCOLOR);
-				((Graphics2D)g).setStroke(SampledTrackGraphViewPort.ZOOM_BACKING_BORDER_STROKE);
-				g.fillRect(x + 2,  y, labelWidth + 3, labelHeight + 4);
-
-				g.setFont(SampledTrackGraphViewPort.TIME_HELPER_FONT);
-				g.setColor(Color.BLACK);
-				g.drawString(label, x + 4, y + labelHeight);
-				
-				
+				int y = r.getMinY() + (r.getHeight() / 2) - ((labelHeight + 4) / 2);
+				
+				gm.drawRectangle(new Point(x + 2,  y), new Dimension(labelWidth + 3, labelHeight + 4), 0.0, new Fill(SampledTrackGraphViewPort.TIME_HELPER_COLOR), SampledTrackGraphViewPort.TIME_HELPER_BORDERCOLOR, SampledTrackGraphViewPort.ZOOM_BACKING_BORDER_STROKE, null);
+
+				gm.drawTextLayout(layout, new Point(x + 4, y + labelHeight), Colour.BLACK);
 			}
 		
@@ -146,36 +144,26 @@
 //		 Draw Y helper
 		if (yAxisTimelineHelperToPaint != null) {
-
-			((Graphics2D)g).setStroke(Y_HELPER_LINES_STROKE);
-			g.setColor(Y_HELPER_LINES_COLOR);
-
-			g.drawLine(
-					0, 
-					yAxisTimelineHelperToPaint.value, 
-					Browser._theBrowser.getContentPane().getWidth(), 
-					yAxisTimelineHelperToPaint.value);
-			
-		}
-		
-	
-	}
-
-	public void paintPreLayeredPanePass(Graphics g) {
+			gm.drawLine(0, yAxisTimelineHelperToPaint.value, EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), yAxisTimelineHelperToPaint.value, Y_HELPER_LINES_COLOR, Y_HELPER_LINES_STROKE);
+		}
+		
+	
+	}
+
+	public void paintPreLayeredPanePass()
+	{
 		if (Browser._theBrowser == null) return;
 		
 		if (ExpandedTrackManager.getInstance().isAnyExpandedTrackVisible()) {
-			
-			g.setColor(SHADED_EXPANDED_BACKING_COLOR);
-			g.fillRect(0, 0, 
-					Browser._theBrowser.getContentPane().getWidth(), 
-					Browser._theBrowser.getContentPane().getHeight());
-		}
-		
-	}
-
-	public Area paintStarted(Area currentClip) {
+			Dimension windowSize = EcosystemManager.getGraphicsManager().getWindowSize();
+			EcosystemManager.getGraphicsManager().drawRectangle(Point.ORIGIN, windowSize, 0.0, new Fill(SHADED_EXPANDED_BACKING_COLOR), null, null, null);
+		}
+		
+	}
+
+	public Clip paintStarted(Clip currentClip)
+	{
 		if (Browser._theBrowser == null) return currentClip;
 
-		LinkedList<InteractiveWidget> seen = null;
+		LinkedList<Widget> seen = null;
 		
 		//boolean idDirty = false;
@@ -189,18 +177,18 @@
 		timeHelperLinesToPaint = null;
 		yAxisTimelineHelperToPaint = null;
-		shouldDrawFullscreenHelpers = AudioFrameKeyboardActions.isControlDown() || 
-			(AudioFrameKeyboardActions.isShiftDown() && !FreeItems.getInstance().isEmpty());
+		shouldDrawFullscreenHelpers = StandardInputEventListeners.kbmStateListener.isKeyDown(Key.CTRL) || 
+			(StandardInputEventListeners.kbmStateListener.isKeyDown(Key.SHIFT) && !FreeItems.getInstance().isEmpty());
 
 		// Get free tracks and paint line helpers
-		if (!FreeItems.getInstance().isEmpty() || FrameMouseActions.getlastHighlightedItem() != null) {
+		if (!FreeItems.getInstance().isEmpty() || StandardGestureActions.getlastHighlightedItem() != null) {
 
 			LinkedList<Item> possibles = new LinkedList<Item>(FreeItems.getInstance());
-			if (FreeItems.getInstance().isEmpty() &&
-					FrameMouseActions.getlastHighlightedItem() != null)
-				possibles.add(FrameMouseActions.getlastHighlightedItem());
+			if (FreeItems.getInstance().isEmpty() && StandardGestureActions.getlastHighlightedItem() != null) {
+				possibles.add(StandardGestureActions.getlastHighlightedItem());
+			}
 			
 			for (Item i : possibles) {
 				
-				InteractiveWidget iw = null;
+				Widget iw = null;
 				
 				if (i instanceof WidgetCorner) {
@@ -216,5 +204,5 @@
 						
 						if (seen == null) {
-							seen = new LinkedList<InteractiveWidget>();
+							seen = new LinkedList<Widget>();
 						} else if (seen.contains(iw)) {
 							continue;
@@ -235,5 +223,5 @@
 		} 
 		
-		if ((AudioFrameMouseActions.isYAxisRestictionOn() || AudioFrameMouseActions.isSnapOn()) 
+		if ((ApolloGestureActions.isYAxisRestictionOn() || ApolloGestureActions.isSnapOn()) 
 			&& !FreeItems.getInstance().isEmpty()) {
 			
@@ -255,31 +243,27 @@
 	}
 	
-	private void invalidateHelperLines(Area currentClip) {
-		if (currentClip != null) {
-			
-			if (timeHelperLinesToPaint != null && !timeHelperLinesToPaint.isEmpty()) {
-				currentClip.add(new Area(OverdubbedFrameTimeAxis.getInstance().getCurrentTimelineArea()));
-				if (shouldDrawFullscreenHelpers) {
-					int fsHeight = Browser._theBrowser.getContentPane().getHeight();
-					for (Integer n : timeHelperLinesToPaint) {
-						currentClip.add(new Area(new Rectangle(n - 1, 0, 3, fsHeight)));
-					}
-				}
-			}
-			
-			if (yAxisTimelineHelperToPaint != null && shouldDrawFullscreenHelpers) {
-
-				currentClip.add(new Area(new Rectangle(
-						0, 
-						yAxisTimelineHelperToPaint.value - 1, 
-						Browser._theBrowser.getContentPane().getWidth(), 
-						3)));
-			
-			}
-		}
-	}
-	
-	
-	
-
+	private void invalidateHelperLines(Clip currentClip)
+	{
+		if (currentClip == null) return;
+		
+		if (timeHelperLinesToPaint != null && !timeHelperLinesToPaint.isEmpty()) {
+			currentClip.includeBounds(OverdubbedFrameTimeAxis.getInstance().getCurrentTimelineArea().clone());
+			if (shouldDrawFullscreenHelpers) {
+				int fsHeight = EcosystemManager.getGraphicsManager().getWindowSize().getHeight();
+				for (Integer n : timeHelperLinesToPaint) {
+					currentClip.includeBounds(new AxisAlignedBoxBounds(n - 1, 0, 3, fsHeight));
+				}
+			}
+		}
+		
+		if (yAxisTimelineHelperToPaint != null && shouldDrawFullscreenHelpers) {
+
+			currentClip.includeBounds(new AxisAlignedBoxBounds(
+					0, 
+					yAxisTimelineHelperToPaint.value - 1, 
+					EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), 
+					3));
+		
+		}
+	}
 }
Index: /trunk/src/org/apollo/gui/OverdubbedFrameTimeAxis.java
===================================================================
--- /trunk/src/org/apollo/gui/OverdubbedFrameTimeAxis.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/OverdubbedFrameTimeAxis.java	(revision 1102)
@@ -1,14 +1,3 @@
 package org.apollo.gui;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
-
-import javax.swing.SwingUtilities;
 
 import org.apollo.audio.util.Timeline;
@@ -16,8 +5,16 @@
 import org.apollo.mvc.Subject;
 import org.apollo.mvc.SubjectChangedEvent;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.InputManager.WindowEventListener;
+import org.expeditee.gio.InputManager.WindowEventType;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.MessageBay;
+import org.expeditee.gui.DisplayController;
 
 /**
@@ -30,5 +27,5 @@
 
 	private TimeAxis timeAxis = null;
-	private Rectangle lastInvalidated;
+	private AxisAlignedBoxBounds lastInvalidated;
 	private Timeline lastTimeline = null;
 
@@ -36,11 +33,10 @@
 
 	private static final int GLOBAL_TIMELINE_HEIGHT = 30;
-	private static final Color GLOBAL_TIMELINE_BACKCOLOR = new Color(220, 220, 220, 100);
-	private static final Color GLOBAL_EMPTY_TIMELINE_BACKCOLOR = new Color(240, 240, 240, 100);
+	private static final Colour GLOBAL_TIMELINE_BACKCOLOR = Colour.FromRGBA255(220, 220, 220, 100);
+	private static final Colour GLOBAL_EMPTY_TIMELINE_BACKCOLOR = Colour.FromRGBA255(240, 240, 240, 100);
 	
-	public static final Stroke TRACK_TIMELINE_STROKE = new BasicStroke(
-			1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0.0f, new float[] { 5.0f, 5.0f }, 0.0f);
+	public static final Stroke TRACK_TIMELINE_STROKE = new Stroke(1.0f, Stroke.CAP.SQUARE, Stroke.JOIN.BEVEL, new float[] { 5.0f, 5.0f }, 0.0f);
 	
-	private static final Stroke TIMELINE_BORDER_STROKE = new BasicStroke(1.0f);
+	private static final Stroke TIMELINE_BORDER_STROKE = new Stroke(1.0f);
 			
 	/**
@@ -54,27 +50,10 @@
 		
 		// Listen for resize events
-		SwingUtilities.invokeLater(new Runnable() {
-			public void run() {
-
-				// Keep expanded view centered to the browser window
-				if (Browser._theBrowser != null) {
-					Browser._theBrowser.addComponentListener(new ComponentListener() {
-
-						public void componentHidden(ComponentEvent e) {
-						}
-
-						public void componentMoved(ComponentEvent e) {
-						}
-
-						public void componentResized(ComponentEvent e) {
-							updateAxis();
-						}
-
-						public void componentShown(ComponentEvent e) {
-						}
-						
-					});
-				}
-				
+		EcosystemManager.getInputManager().addWindowEventListener(new WindowEventListener()
+		{
+			@Override
+			public void onWindowEvent(WindowEventType type)
+			{
+				if (type == WindowEventType.WINDOW_RESIZED) updateAxis();
 			}
 		});
@@ -113,14 +92,14 @@
 		lastTimeline = FrameLayoutDaemon.getInstance().getLastComputedTimeline();
 		if (lastTimeline == null || 
-			FrameLayoutDaemon.getInstance().getTimelineOwner() != DisplayIO.getCurrentFrame()) {
+			FrameLayoutDaemon.getInstance().getTimelineOwner() != DisplayController.getCurrentFrame()) {
 			
 			// The frame layout daemon only lays out frames once - unless the user rearranges tracks
 			// on a frame then the daemon we re-calc the timeline... thus a timeline must be infferred
 			
-			lastTimeline = FrameLayoutDaemon.inferTimeline(DisplayIO.getCurrentFrame());
+			lastTimeline = FrameLayoutDaemon.inferTimeline(DisplayController.getCurrentFrame());
 			
 			if (lastTimeline == null) { // no widgets
 				if (timeAxis != null && lastInvalidated != null) {
-					FrameGraphics.invalidateArea(lastInvalidated); // old position
+					DisplayController.invalidateArea(lastInvalidated); // old position
 				}
 				
@@ -141,51 +120,49 @@
 
 		
-		Rectangle newBounds = getCurrentTimelineArea();
+		AxisAlignedBoxBounds newBounds = getCurrentTimelineArea();
 		if (lastInvalidated != null && !lastInvalidated.equals(newBounds)) {
-			FrameGraphics.invalidateArea(lastInvalidated); // old position
+			DisplayController.invalidateArea(lastInvalidated); // old position
 		}
 		
-		FrameGraphics.invalidateArea(newBounds);
+		DisplayController.invalidateArea(newBounds);
 		
 		lastInvalidated = newBounds;
 		
-		FrameGraphics.refresh(true);
+		DisplayController.requestRefresh(true);
 		
 	}
 
-	public Rectangle getCurrentTimelineArea() {
+	public AxisAlignedBoxBounds getCurrentTimelineArea()
+	{
 		assert(Browser._theBrowser != null);
-		int y = Browser._theBrowser.getContentPane().getHeight() - GLOBAL_TIMELINE_HEIGHT;
-		if (!FrameGraphics.isAudienceMode()) {
-			y -= MessageBay.MESSAGE_BUFFER_HEIGHT;
+		int y = EcosystemManager.getGraphicsManager().getWindowSize().getHeight() - GLOBAL_TIMELINE_HEIGHT;
+		if (!DisplayController.isAudienceMode()) {
+			y -= DisplayController.getMessageBayPaintArea().getHeight();
 		}
 		
 		if (y < 0) y = 0;
 
-		return new Rectangle(0, y, Browser._theBrowser.getContentPane().getWidth(), GLOBAL_TIMELINE_HEIGHT);
+		return new AxisAlignedBoxBounds(0, y, EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), GLOBAL_TIMELINE_HEIGHT);
 	}
 	
 
-	public void paint(Graphics g) {
+	public void paint()
+	{
 		if (Browser._theBrowser == null) return;
 
 		if (timeAxis != null && lastTimeline != null) {
 		
-			Rectangle r = getCurrentTimelineArea();
-
-			g.setColor(GLOBAL_EMPTY_TIMELINE_BACKCOLOR);
-			g.fillRect(0, r.y, Browser._theBrowser.getContentPane().getWidth(), r.height);
+			GraphicsManager gm = EcosystemManager.getGraphicsManager();
 			
-			timeAxis.paint(g, 
+			AxisAlignedBoxBounds r = getCurrentTimelineArea();
+			gm.drawRectangle(new Point(0, r.getMinY()), new Dimension(EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), r.getHeight()), 0.0, new Fill(GLOBAL_EMPTY_TIMELINE_BACKCOLOR), null, null, null);
+			
+			timeAxis.paint( 
 					lastTimeline.getInitiationXPixel(),
-					r.y,
-					r.height, 
+					r.getMinY(),
+					r.getHeight(), 
 					GLOBAL_TIMELINE_BACKCOLOR);
 			
-			
-			g.setColor(Color.DARK_GRAY);
-			
-			((Graphics2D)g).setStroke(TIMELINE_BORDER_STROKE);
-			g.drawLine(0, r.y, Browser._theBrowser.getContentPane().getWidth(), r.y);
+			gm.drawLine(new Point(0, r.getMinY()), new Point(EcosystemManager.getGraphicsManager().getWindowSize().getWidth(), r.getMinY()), Colour.DARK_GREY, TIMELINE_BORDER_STROKE);
 	
 		}
Index: /trunk/src/org/apollo/gui/PlaybackControlPopup.java
===================================================================
--- /trunk/src/org/apollo/gui/PlaybackControlPopup.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/PlaybackControlPopup.java	(revision 1102)
@@ -2,4 +2,5 @@
 
 import java.awt.Dimension;
+import java.awt.Graphics2D;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
@@ -8,6 +9,6 @@
 import java.awt.event.ActionListener;
 
-import javax.swing.Icon;
 import javax.swing.JButton;
+import javax.swing.JPanel;
 import javax.swing.JSlider;
 import javax.swing.JToggleButton;
@@ -16,5 +17,10 @@
 
 import org.apollo.io.IconRepository;
+import org.expeditee.core.Image;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Popup;
+import org.expeditee.gui.PopupManager.ExpandShrinkAnimator;
 
 /**
@@ -25,6 +31,7 @@
  *
  */
-public abstract class PlaybackControlPopup extends Popup implements ActionListener {
-
+public abstract class PlaybackControlPopup extends Popup implements ActionListener
+{
+	public JPanel panel;
 	public JButton playPauseButton;
 	public JButton stopButton;
@@ -39,11 +46,14 @@
 	private static final int BUTTON_SIZE = 40;
 	
-	protected PlaybackControlPopup() {
-		super(new GridBagLayout());
+	protected PlaybackControlPopup()
+	{
+		super(new ExpandShrinkAnimator());
+		
+		panel = new JPanel(new GridBagLayout());
 		
 		playPauseButton = new JButton();
 		playPauseButton.setActionCommand("playpause");
 		playPauseButton.addActionListener(this);
-		playPauseButton.setIcon(IconRepository.getIcon("play.png"));
+		SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("play.png"));
 		playPauseButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		playPauseButton.setToolTipText("Play selection / Pause");
@@ -53,5 +63,5 @@
 		stopButton.addActionListener(this);
 		stopButton.setActionCommand("stop");
-		stopButton.setIcon(IconRepository.getIcon("stop.png"));
+		SwingMiscManager.setJButtonIcon(stopButton, IconRepository.getIcon("stop.png"));
 		stopButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		stopButton.setToolTipText("Stop playback");
@@ -60,5 +70,5 @@
 		rewindButton.addActionListener(this);
 		rewindButton.setActionCommand("rewind");
-		rewindButton.setIcon(IconRepository.getIcon("rewind.png"));
+		SwingMiscManager.setJButtonIcon(rewindButton, IconRepository.getIcon("rewind.png"));
 		rewindButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		rewindButton.setToolTipText("Rewind to start");
@@ -66,5 +76,5 @@
 		// Icon changes
 		muteButton = new JToggleButton();
-		muteButton.setSelectedIcon(IconRepository.getIcon("volmute.png"));
+		SwingMiscManager.setJButtonSelectedIcon(muteButton, IconRepository.getIcon("volmute.png"));
 		muteButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		muteButton.setToolTipText("Toggle mute");
@@ -78,6 +88,6 @@
 		
 		soloButton = new JToggleButton();
-		soloButton.setIcon(IconRepository.getIcon("solo.png"));
-		soloButton.setSelectedIcon(IconRepository.getIcon("soloon.png"));
+		SwingMiscManager.setJButtonIcon(soloButton, IconRepository.getIcon("solo.png"));
+		SwingMiscManager.setJButtonSelectedIcon(soloButton, IconRepository.getIcon("soloon.png"));
 		soloButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		soloButton.setToolTipText("Toggle solo");
@@ -115,5 +125,5 @@
 		c.gridy = 0;
 		c.fill = GridBagConstraints.BOTH;
-		add(playPauseButton, c);
+		panel.add(playPauseButton, c);
 		
 		c = new GridBagConstraints();
@@ -121,5 +131,5 @@
 		c.gridy = 0;
 		c.fill = GridBagConstraints.BOTH;
-		add(stopButton, c);
+		panel.add(stopButton, c);
 		
 		c = new GridBagConstraints();
@@ -127,5 +137,5 @@
 		c.gridy = 0;
 		c.fill = GridBagConstraints.BOTH;
-		add(rewindButton, c);
+		panel.add(rewindButton, c);
 		
 		c = new GridBagConstraints();
@@ -133,5 +143,5 @@
 		c.gridy = 0;
 		c.fill = GridBagConstraints.BOTH;
-		add(soloButton, c);
+		panel.add(soloButton, c);
 		
 		c = new GridBagConstraints();
@@ -139,5 +149,5 @@
 		c.gridy = 0;
 		c.fill = GridBagConstraints.BOTH;
-		add(muteButton, c);
+		panel.add(muteButton, c);
 		
 		c = new GridBagConstraints();
@@ -146,5 +156,5 @@
 		c.fill = GridBagConstraints.BOTH;
 		c.insets = new Insets(0,VOLUME_SPACING,0,VOLUME_SPACING);
-		add(volumeSlider, c);
+		panel.add(volumeSlider, c);
 		
 		c = new GridBagConstraints();
@@ -152,5 +162,5 @@
 		c.gridy = 0;
 		c.fill = GridBagConstraints.BOTH;
-		add(miscButton, c);
+		panel.add(miscButton, c);
 		
 //
@@ -201,7 +211,7 @@
 //		this.setSize(BUTTON_SIZE * 4, BUTTON_SIZE * 2);
 		
-		this.setSize(BUTTON_SIZE * 8, BUTTON_SIZE);
-		
-		this.doLayout();
+		panel.setSize(BUTTON_SIZE * 8, BUTTON_SIZE);
+		
+		panel.doLayout();
 		
 	}
@@ -213,5 +223,5 @@
 	private void updateButtonGUI() {
 		
-		Icon newIcon = null;
+		Image newIcon = null;
 		if (volumeSlider.getValue() <= 25) 
 				newIcon = IconRepository.getIcon("vol25.png");
@@ -223,8 +233,24 @@
 				newIcon = IconRepository.getIcon("vol100.png");
 		
-		muteButton.setIcon(newIcon);
-	}
-
-
+		SwingMiscManager.setJButtonIcon(muteButton, newIcon);
+	}
+	
+	@Override
+	protected void paintInternal()
+	{
+		Graphics2D g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
+		AxisAlignedBoxBounds bounds = getBounds();
+		
+		g.translate(bounds.getMinX(), bounds.getMinY());
+		panel.paint(g);
+		g.translate(-bounds.getMinX(), -bounds.getMinY());
+	}
+
+	@Override
+	public AxisAlignedBoxBounds getFullBounds()
+	{
+		return SwingConversions.fromSwingRectangle(panel.getBounds());
+	}
+	
 	public abstract void actionPerformed(ActionEvent e);
 	
Index: /trunk/src/org/apollo/gui/SampledTrackGraphView.java
===================================================================
--- /trunk/src/org/apollo/gui/SampledTrackGraphView.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/SampledTrackGraphView.java	(revision 1102)
@@ -1,4 +1,5 @@
 package org.apollo.gui;
 
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Event;
@@ -10,8 +11,6 @@
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.Stroke;
 import java.awt.event.ComponentEvent;
 import java.awt.event.ComponentListener;
-import java.awt.image.BufferedImage;
 import java.util.LinkedList;
 import java.util.List;
@@ -31,6 +30,10 @@
 import org.apollo.mvc.Subject;
 import org.apollo.mvc.SubjectChangedEvent;
+import org.expeditee.core.Image;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.FrameGraphics;
+import org.expeditee.gui.DisplayController;
 
 /**
@@ -59,5 +62,5 @@
 
 	private WaveFormRenderProccessingUnit.WaveFormRenderTask renderTask = null;
-	private BufferedImage backBuffer = null; // Shared resource
+	private Image backBuffer = null; // Shared resource
 	private int bufferWidth = -1; // cached from backBuffer - so don't have to lock
 	private int bufferHeight = -1; // cached from backBuffer - so don't have to lock
@@ -67,5 +70,5 @@
 	private int timescaleFrameLength = 0; // in frames
 	
-	private final Font RENDER_MESSAGE_FONT = new Font("Arial", Font.ITALIC | Font.BOLD, 14);
+	private final Font RENDER_MESSAGE_FONT = new Font("Arial", Font.BOLD | Font.ITALIC, 14);
 	
 	private boolean alwaysFullViewOn = false;
@@ -80,5 +83,5 @@
 	
 	/** The stroke used for drawing graph bars. E.G: The selection Start bar. */
-	public static final Stroke GRAPH_BAR_STROKE = Strokes.SOLID_1;
+	public static final BasicStroke GRAPH_BAR_STROKE = SwingConversions.toSwingStroke(Strokes.SOLID_1);
 	public static final int GRAPH_BAR_NWIDTH = 1;
 	
@@ -139,5 +142,5 @@
 				this, 
 				0, 0, 
-				Browser._theBrowser.getContentPane());
+				SwingMiscManager.getIfUsingSwingGraphicsManager().getContentPane());
 	}
 	
@@ -339,5 +342,5 @@
 				
 				if (x >= 0 && x <= viewWidth) { // is the playback position in view?
-					FrameGraphics.invalidateArea(new Rectangle(
+					DisplayController.invalidateArea(new AxisAlignedBoxBounds(
 						x + expediteePosition.x, 
 						expediteePosition.y, 
@@ -356,5 +359,5 @@
 				
 				if (x >= 0 && x <= viewWidth) { // is the playback position in view?
-					FrameGraphics.invalidateArea(new Rectangle(
+					DisplayController.invalidateArea(new AxisAlignedBoxBounds(
 						x + expediteePosition.x , 
 						expediteePosition.y, 
@@ -565,5 +568,5 @@
 		
 		renderTask = null; // must be on swing thread because could be painting
-		if (backBuffer != null) backBuffer.flush();
+		if (backBuffer != null) backBuffer.releaseImage();
 		backBuffer = null; // must be on swing thread because could be painting
 	}
@@ -605,9 +608,10 @@
 				
 				// Create new sized buffer
-				backBuffer = new BufferedImage(
+				backBuffer = Image.createImage(width, height);
+/*				backBuffer = new BufferedImage(
 						width, 
 						height,
 						BufferedImage.TYPE_BYTE_INDEXED,
-						ApolloColorIndexedModels.graphIndexColorModel);
+						ApolloColorIndexedModels.graphIndexColorModel);*/
 			}
 		}
@@ -624,5 +628,5 @@
 				);
 		
-		// Wait for invalidation recomendation messages
+		// Wait for invalidation recommendation messages
 		renderTask.addObserver(this);
 
@@ -693,9 +697,9 @@
 				synchronized(backBuffer) {
 	
-					g.drawImage(backBuffer, 
+					g.drawImage(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(backBuffer), 
 							0, 
 							0, 
 							getWidth(), 
-							getHeight(), 
+							getHeight(),
 							null);
 					
@@ -709,9 +713,9 @@
 				// No need to synchronize waveformBuffer because there is no thread accessing it,
 				// and a new render thread is always created on this thread.
-				g.drawImage(backBuffer, 
+				g.drawImage(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(backBuffer),
 						0, 
 						0, 
 						getWidth(), 
-						getHeight(), 
+						getHeight(),
 						null);
 				
@@ -919,9 +923,11 @@
 	 *
 	 */
-	public interface EffecientInvalidator {
+	public interface EffecientInvalidator
+	{
 		public void onGraphDirty(SampledTrackGraphView graph, Rectangle dirty);
 	}
 
-	public Color getBackColor() {
+	public Color getBackColor()
+	{
 		return backColor;
 	}
@@ -935,5 +941,6 @@
 	 * 	
 	 */
-	public void setBackColor(Color backColor, Color highlights) {
+	public void setBackColor(Color backColor, Color highlights)
+	{
 		setBackColor(backColor, highlights, true);
 	}
@@ -949,5 +956,6 @@
 	 * 		Doesnt invalidate if the color has not changed.
 	 */
-	public void setBackColor(Color backColor, Color highlights, boolean invalidate) {
+	public void setBackColor(Color backColor, Color highlights, boolean invalidate)
+	{
 		if (backColor == null) throw new NullPointerException("backColor");
 		if (this.backColor != backColor || backColorHighlights != highlights) {
Index: /trunk/src/org/apollo/gui/SampledTrackGraphViewPort.java
===================================================================
--- /trunk/src/org/apollo/gui/SampledTrackGraphViewPort.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/SampledTrackGraphViewPort.java	(revision 1102)
@@ -1,11 +1,7 @@
 package org.apollo.gui;
 
-import java.awt.Color;
 import java.awt.Event;
-import java.awt.Font;
-import java.awt.FontMetrics;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
-import java.awt.Stroke;
 import java.awt.event.ComponentEvent;
 import java.awt.event.ComponentListener;
@@ -17,6 +13,4 @@
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
 import java.util.LinkedList;
 import java.util.List;
@@ -27,5 +21,12 @@
 import org.apollo.mvc.SubjectChangedEvent;
 import org.apollo.util.AudioMath;
-import org.expeditee.gui.Browser;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Font;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.TextLayout;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 
 public class SampledTrackGraphViewPort extends SampledTrackGraphView
@@ -43,12 +44,12 @@
 	private static final int ZOOM_ADJUSTMENT_MODE_MODIFYZOOM = 3;
 	
-	public static final Color ZOOM_BACKING_COLOR_NORMAL = new Color(251, 255, 168);
-	private static final Color ZOOM_BACKING_COLOR_HIGHLIGHT = new Color(255, 255, 224);
-	private static final Color ZOOM_BACKING_BORDER_COLOR = new Color(215, 219, 144);
+	public static final Colour ZOOM_BACKING_COLOR_NORMAL = Colour.FromRGB255(251, 255, 168);
+	private static final Colour ZOOM_BACKING_COLOR_HIGHLIGHT = Colour.FromRGB255(255, 255, 224);
+	private static final Colour ZOOM_BACKING_BORDER_COLOR = Colour.FromRGB255(215, 219, 144);
 	public static final Stroke ZOOM_BACKING_BORDER_STROKE = Strokes.SOLID_1;
 	
-	public static final Font TIME_HELPER_FONT = new Font("Arial", Font.PLAIN, 12);
-	public static final Color TIME_HELPER_COLOR = new Color(132, 175, 201);
-	public static final Color TIME_HELPER_BORDERCOLOR = new Color(111, 146, 168);
+	public static final Font TIME_HELPER_FONT = new Font("Arial", Font.Style.PLAIN, 12);
+	public static final Colour TIME_HELPER_COLOR = Colour.FromRGB255(132, 175, 201);
+	public static final Colour TIME_HELPER_BORDERCOLOR = Colour.FromRGB255(111, 146, 168);
 	
 	// displays the current zoom or the new zoom-selection
@@ -67,8 +68,9 @@
 	private List<ZoomChangeListener> zoomChangeListeners = new LinkedList<ZoomChangeListener>();
 
-	public SampledTrackGraphViewPort() {
+	public SampledTrackGraphViewPort()
+	{
 		super();
 		
-		setBackColor(new Color(250, 250, 250), new Color(230, 230, 230));
+		setBackColor(SwingConversions.toSwingColor(Colour.FromRGB255(250, 250, 250)), SwingConversions.toSwingColor(Colour.FromRGB255(230, 230, 230)));
 		setAlwaysFullView(true);
 
@@ -531,10 +533,9 @@
 		void paint(Graphics g) {
 			
-			color =  (zoomAdjustmentMode == ZOOM_ADJUSTMENT_MODE_NONE) ?
-					ZOOM_BACKING_COLOR_NORMAL : ZOOM_BACKING_COLOR_HIGHLIGHT;
+			color = SwingConversions.toSwingColor((zoomAdjustmentMode == ZOOM_ADJUSTMENT_MODE_NONE) ? ZOOM_BACKING_COLOR_NORMAL : ZOOM_BACKING_COLOR_HIGHLIGHT);
 			super.paint(g);
 			
-			g.setColor(ZOOM_BACKING_BORDER_COLOR);
-			((Graphics2D)g).setStroke(ZOOM_BACKING_BORDER_STROKE);
+			g.setColor(SwingConversions.toSwingColor(ZOOM_BACKING_BORDER_COLOR));
+			((Graphics2D)g).setStroke(SwingConversions.toSwingStroke(ZOOM_BACKING_BORDER_STROKE));
 			g.drawLine(left, 0, left, getHeight());
 			g.drawLine(left + width, 0, left + width, getHeight());
@@ -542,20 +543,20 @@
 		}
 		
-		void postPaint(Graphics g) {
-			// Paint little helper labels when ajusting view port
-			if (startTimeHelpLabel != null && endTimeHelpLabel != null &&
-					zoomAdjustmentMode != ZOOM_ADJUSTMENT_MODE_NONE) {
-				
-				g.setColor(TIME_HELPER_COLOR);
+		void postPaint(Graphics g)
+		{
+			// Paint little helper labels when adjusting view port
+			if (startTimeHelpLabel != null && endTimeHelpLabel != null && zoomAdjustmentMode != ZOOM_ADJUSTMENT_MODE_NONE) {
+				
+				g.setColor(SwingConversions.toSwingColor(TIME_HELPER_COLOR));
 				g.fillRect(labelStartX - 2, labelStartY - labelHeight + 2, labelWidth + 3, labelHeight);
 				g.fillRect(labelEndX - 2, labelEndY  - labelHeight + 2, labelWidth + 3, labelHeight);
 				
-				g.setColor(TIME_HELPER_BORDERCOLOR);
-				((Graphics2D)g).setStroke(ZOOM_BACKING_BORDER_STROKE);
+				g.setColor(SwingConversions.toSwingColor(TIME_HELPER_BORDERCOLOR));
+				((Graphics2D)g).setStroke(SwingConversions.toSwingStroke(ZOOM_BACKING_BORDER_STROKE));
 				g.drawRect(labelStartX - 2, labelStartY - labelHeight + 2, labelWidth + 3, labelHeight);
 				g.drawRect(labelEndX - 2, labelEndY  - labelHeight + 2, labelWidth + 3, labelHeight);
 
-				g.setFont(TIME_HELPER_FONT);
-				g.setColor(Color.BLACK);
+				g.setFont(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(TIME_HELPER_FONT));
+				g.setColor(SwingConversions.toSwingColor(Colour.BLACK));
 				g.drawString(startTimeHelpLabel, labelStartX, labelStartY);
 				g.drawString(endTimeHelpLabel, labelEndX, labelEndY);
@@ -603,13 +604,15 @@
 				
 				// Create a temp graphics for centered label positioning
-				if (Browser._theBrowser != null && Browser._theBrowser.g != null) {
+				/*if (Browser._theBrowser != null && Browser._theBrowser.g != null) {
 					g = Browser._theBrowser.g.create();
 				} else {
 					g = new BufferedImage(1,1,BufferedImage.TYPE_BYTE_INDEXED).getGraphics();
-				}
+				}*/
 		
 				// Position labels
-				FontMetrics fm   = g.getFontMetrics(TIME_HELPER_FONT);
-				Rectangle2D rect = fm.getStringBounds(startTimeHelpLabel, g);
+				//FontMetrics fm   = g.getFontMetrics(TIME_HELPER_FONT);
+				//Rectangle2D rect = fm.getStringBounds(startTimeHelpLabel, g);
+				TextLayout layout = EcosystemManager.getTextLayoutManager().layoutStringSimple(startTimeHelpLabel, TIME_HELPER_FONT);
+				AxisAlignedBoxBounds rect = layout.getPixelBounds(0, 0);
 				
 				labelWidth = (int)rect.getWidth();
Index: /trunk/src/org/apollo/gui/Strokes.java
===================================================================
--- /trunk/src/org/apollo/gui/Strokes.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/Strokes.java	(revision 1102)
@@ -1,6 +1,5 @@
 package org.apollo.gui;
 
-import java.awt.BasicStroke;
-import java.awt.Stroke;
+import org.expeditee.core.Stroke;
 
 public class Strokes {
@@ -9,6 +8,6 @@
 	}
 	
-	public static final Stroke SOLID_1 = new BasicStroke(1.0f);
-	public static final Stroke SOLID_2 = new BasicStroke(2.0f);
+	public static final Stroke SOLID_1 = new Stroke(1.0f);
+	public static final Stroke SOLID_2 = new Stroke(2.0f);
 	
 }
Index: /trunk/src/org/apollo/gui/TimeAxis.java
===================================================================
--- /trunk/src/org/apollo/gui/TimeAxis.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/TimeAxis.java	(revision 1102)
@@ -1,17 +1,18 @@
 package org.apollo.gui;
 
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.GradientPaint;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Stroke;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
 import java.util.LinkedList;
 
 import org.apollo.ApolloSystem;
-import org.expeditee.gui.Browser;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Font;
+import org.expeditee.core.GradientFill;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.TextLayout;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.swing.SwingConversions;
 
 /**
@@ -23,11 +24,9 @@
 public class TimeAxis {
 	
-	private static final long serialVersionUID = 1L;
-	
-	public static final Font TIME_BAR_FONT = new Font("Arial", Font.PLAIN, 14);
+	public static final Font TIME_BAR_FONT = new Font("Arial", Font.Style.PLAIN, 14);
 	private static final Stroke TICK_STROKE = Strokes.SOLID_1;
 	
-	private static final Color MAJOR_TICK_COLOR = Color.BLACK;
-	private static final Color MINOR_TICK_COLOR = new Color(0.4f, 0.4f, 0.4f);
+	private static final Colour MAJOR_TICK_COLOR = Colour.BLACK;
+	private static final Colour MINOR_TICK_COLOR = new Colour(0.4f, 0.4f, 0.4f);
 	
 	private static final int DESIRED_MAJOR_TICK_PIXEL_SPACING = 100;
@@ -43,5 +42,6 @@
 	private long totalTrackMSLength = 0;
 
-	public TimeAxis() {
+	public TimeAxis()
+	{
 	}
 
@@ -51,5 +51,6 @@
 			long timeLengthSamples,
 			long totalTrackMSLength, 
-			int width) {
+			int width)
+	{
 
 		assert(width > 0);
@@ -146,40 +147,20 @@
 		LinkedList<Integer> majorTickLabelPositions = new LinkedList<Integer>();
 	
-		Graphics g = null;
-		try {
-		
-			
-			// Create a temp graphics for centered label positioning
-			if (Browser._theBrowser != null && Browser._theBrowser.g != null) {
-				g = Browser._theBrowser.g.create();
-			} else {
-				g = new BufferedImage(1,1,BufferedImage.TYPE_BYTE_INDEXED).getGraphics();
-			}
-			
-			do {
-	
-				majorTickPositions.add(new Integer((int)currentTickX));
-
-				String label = createSpecificTimeLabel((long)currentTickTime, timeAggregation);
-				
-				majorTickLabels.add(label);
-
-				// Center label
-				FontMetrics fm   = g.getFontMetrics(TIME_BAR_FONT);
-				Rectangle2D rect = fm.getStringBounds(label, g);
-				int textWidth  = (int)(rect.getWidth());
-				
-				majorTickLabelPositions.add(new Integer((int)currentTickX - (textWidth >> 1)));
-
-				currentTickX += majorTickPixelSpacing;
-				currentTickTime += timeAggregation;
-	
-			} while (currentTickX < width);
-
-			
-		} finally {
-			if (g != null)
-				g.dispose();
-		}
+		do {
+			majorTickPositions.add(new Integer((int)currentTickX));
+
+			String label = createSpecificTimeLabel((long)currentTickTime, timeAggregation);
+			
+			majorTickLabels.add(label);
+
+			// Center label
+			int textWidth = EcosystemManager.getTextLayoutManager().layoutStringSimple(label, TIME_BAR_FONT).getPixelBounds(0, 0).getWidth();
+			
+			majorTickLabelPositions.add(new Integer((int)currentTickX - (textWidth >> 1)));
+
+			currentTickX += majorTickPixelSpacing;
+			currentTickTime += timeAggregation;
+			
+		} while (currentTickX < width);
 		
 		this.majorTickLabels = majorTickLabels.toArray(new String[0]);
@@ -227,6 +208,6 @@
 	
 	
-	public String createSpecificTimeLabel(long atTime, double timeAggregation) {
-
+	public String createSpecificTimeLabel(long atTime, double timeAggregation)
+	{
 		Long min = null;
 		Long sec = null;
@@ -261,6 +242,6 @@
 	}
 	
-	public static String createTimeLabel(Long min, Long sec, Long ms) {
-		
+	public static String createTimeLabel(Long min, Long sec, Long ms)
+	{
 		if (min == null && sec == null && ms != null) {
 			return ms + "ms";
@@ -314,5 +295,5 @@
 	}
 	
-	public void paint(Graphics g, int x, int y, int height, Color backgroundColor) {
+	public void paint(int x, int y, int height, Colour backgroundColor) {
 		
 		int majorTickHeight = height / 2;
@@ -320,52 +301,42 @@
 
 		// Draw backing
+		Fill backingFill;
 		if (ApolloSystem.useQualityGraphics) {
-			
-			GradientPaint gp = new GradientPaint(
-					x + (width / 2), y + (int)(height * 0.5), backgroundColor,
-					x + (width / 2), y, SampledTrackGraphView.DEFAULT_BACKGROUND_HIGHTLIGHTS_COLOR);
-			((Graphics2D)g).setPaint(gp);
-			
+			backingFill = new GradientFill(backgroundColor, new Point(x + (width / 2), y + (int)(height * 0.5)), SwingConversions.fromSwingColor(SampledTrackGraphView.DEFAULT_BACKGROUND_HIGHTLIGHTS_COLOR), new Point(x + (width / 2), y));
 		} else {
-			g.setColor(backgroundColor);
-		}
-		
-		g.fillRect(x, y, width, height);
-		
-		g.setFont(TIME_BAR_FONT);
+			backingFill = new Fill(backgroundColor);
+		}
+		
+		GraphicsManager gm = EcosystemManager.getGraphicsManager();
+		
+		gm.drawRectangle(new Point(x, y), new Dimension(width, height), 0.0, backingFill, null, null, null);
 		
 		if (majorTickXPositions != null) {
-
-			((Graphics2D)g).setStroke(TICK_STROKE);
-			
-			g.setColor(MAJOR_TICK_COLOR);
 			// Draw Major ticks and labels
 			for (int i = 0; i < majorTickLabels.length; i++) {
 				
 				// Label
-				g.drawString(
+				gm.drawString(
 						majorTickLabels[i], 
-						x + majorTickLabelXPositions[i], 
-						y + height - 2);
+						new Point(x + majorTickLabelXPositions[i], y + height - 2),
+						TIME_BAR_FONT,
+						MAJOR_TICK_COLOR);
 				
 				// Tick
-				g.drawLine(
-						x + majorTickXPositions[i], 
+				gm.drawLine(x + majorTickXPositions[i], 
 						y, 
 						x + majorTickXPositions[i], 
-						y + majorTickHeight);
+						y + majorTickHeight, MAJOR_TICK_COLOR, TICK_STROKE);
 				
 			}
-			
-			g.setColor(MINOR_TICK_COLOR);
 			
 			// Draw minor ticks
 			if (minorTickXPositions != null) {
 				for (int tx : minorTickXPositions) {
-					g.drawLine(
+					gm.drawLine(
 							x + tx, 
 							y, 
 							x + tx, 
-							y + minorTickHeight);
+							y + minorTickHeight, MINOR_TICK_COLOR, TICK_STROKE);
 				}
 			}
@@ -373,20 +344,15 @@
 		} else if (alternateLabel != null) {
 			
-			g.setColor(Color.BLACK);
-			
-			FontMetrics fm   = g.getFontMetrics(TIME_BAR_FONT);
-			Rectangle2D rect = fm.getStringBounds(alternateLabel, g);
-			int textWidth  = (int)(rect.getWidth());
-			
-			g.drawString(
-					alternateLabel, 
-					x + ((width >> 1) - (textWidth >> 1)), 
-					y + (height - 2));
-
-		}
-		
-	}
-
-	public int getWidth() {
+			TextLayout layout = EcosystemManager.getTextLayoutManager().layoutStringSimple(alternateLabel, TIME_BAR_FONT);
+
+			int textWidth  = layout.getPixelBounds(0, 0).getWidth();
+			gm.drawTextLayout(layout, new Point(x + ((width >> 1) - (textWidth >> 1)), y + (height - 2)), Colour.BLACK);
+			
+		}
+		
+	}
+
+	public int getWidth()
+	{
 		return width;
 	}
Index: /trunk/src/org/apollo/gui/TimeAxisPanel.java
===================================================================
--- /trunk/src/org/apollo/gui/TimeAxisPanel.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/TimeAxisPanel.java	(revision 1102)
@@ -12,4 +12,5 @@
 
 import org.apollo.util.AudioMath;
+import org.expeditee.gio.swing.SwingConversions;
 
 /**
@@ -30,5 +31,6 @@
 	private TimeAxis timeAxis = new TimeAxis();
 	
-	public TimeAxisPanel(SampledTrackGraphView graph) {
+	public TimeAxisPanel(SampledTrackGraphView graph)
+	{
 		assert (graph != null);
 		
@@ -37,19 +39,22 @@
 		
 		// Auto-adjust scale when component resizes.
-		this.addComponentListener(new ComponentListener() {
-
-			public void componentHidden(ComponentEvent e) {
+		this.addComponentListener(new ComponentListener()
+		{
+			public void componentHidden(ComponentEvent e)
+			{
 			}
 
-			public void componentMoved(ComponentEvent e) {
+			public void componentMoved(ComponentEvent e)
+			{
 			}
 
-			public void componentResized(ComponentEvent e) {
+			public void componentResized(ComponentEvent e)
+			{
 				updateAxis();
 			}
 
-			public void componentShown(ComponentEvent e) {
+			public void componentShown(ComponentEvent e)
+			{
 			}
-		
 		});
 		
@@ -58,25 +63,22 @@
 	
 
-	public void timelineChanged(Event e) {
+	public void timelineChanged(Event e)
+	{
 		 updateAxis();
 	}
 	
 
-	private void updateAxis() {
-		
+	private void updateAxis()
+	{
 		// Is track model even set yet?
-		if (observedSubject.getSampledTrackModel() == null ||
-				getWidth() == 0) return;
+		if (observedSubject.getSampledTrackModel() == null || getWidth() == 0) return;
 		
 		AudioFormat format = observedSubject.getSampledTrackModel().getFormat();
 		
-		long startTimeMS = AudioMath.framesToMilliseconds(
-				observedSubject.getTimeScaleStart(), format);
+		long startTimeMS = AudioMath.framesToMilliseconds(observedSubject.getTimeScaleStart(), format);
 		
-		long timeLengthMS = AudioMath.framesToMilliseconds(
-				observedSubject.getTimeScaleLength(), format);
+		long timeLengthMS = AudioMath.framesToMilliseconds(observedSubject.getTimeScaleLength(), format);
 		
-		long totalTrackMSLength = AudioMath.framesToMilliseconds(
-				observedSubject.getSampledTrackModel().getFrameCount(), format);
+		long totalTrackMSLength = AudioMath.framesToMilliseconds(observedSubject.getSampledTrackModel().getFrameCount(), format);
 		
 		timeAxis.setAxis(
@@ -92,6 +94,7 @@
 	
 	@Override
-	public void paint(Graphics g) {
-		timeAxis.paint(g, 0, 0, getHeight(), getBackground());
+	public void paint(Graphics g)
+	{
+		timeAxis.paint(0, 0, getHeight(), SwingConversions.fromSwingColor(getBackground()));
 	}
 
Index: /trunk/src/org/apollo/gui/TimelineChangeListener.java
===================================================================
--- /trunk/src/org/apollo/gui/TimelineChangeListener.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/TimelineChangeListener.java	(revision 1102)
@@ -3,5 +3,6 @@
 import java.awt.Event;
 
-public interface TimelineChangeListener {
+public interface TimelineChangeListener
+{
 	void timelineChanged(Event e);
 }
Index: /trunk/src/org/apollo/gui/VolumeControlButton.java
===================================================================
--- /trunk/src/org/apollo/gui/VolumeControlButton.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/VolumeControlButton.java	(revision 1102)
@@ -1,10 +1,8 @@
 package org.apollo.gui;
 
-import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Insets;
-import java.awt.Point;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -12,6 +10,6 @@
 import java.util.List;
 
-import javax.swing.Icon;
 import javax.swing.JButton;
+import javax.swing.JPanel;
 import javax.swing.JSlider;
 import javax.swing.event.ChangeEvent;
@@ -19,6 +17,12 @@
 
 import org.apollo.io.IconRepository;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Popup;
 import org.expeditee.gui.PopupManager;
+import org.expeditee.gui.PopupManager.ExpandShrinkAnimator;
 
 /**
@@ -40,6 +44,6 @@
 	private String volumeTag;
 	
-	private Color SELECTED_BACKCOLOR = Color.GRAY;
-	private Color UNSELECTED_BACKCOLOR = null;
+	private Colour SELECTED_BACKCOLOR = Colour.GRAY;
+	private Colour UNSELECTED_BACKCOLOR = null;
 	
 	private static final int VOL_ADJUSTMENT = 10;
@@ -52,9 +56,10 @@
 	 * 		E.G. "Master Volume".
 	 */
-	public VolumeControlButton(String volumeTag) {
+	public VolumeControlButton(String volumeTag)
+	{
 		super();
-		UNSELECTED_BACKCOLOR = getBackground();
+		UNSELECTED_BACKCOLOR = SwingConversions.fromSwingColor(getBackground());
 		vcPopup = new VolumeControlPopup();
-		vcPopup.setVisible(false);
+		PopupManager.getInstance().add(vcPopup);
 		this.volumeTag = volumeTag;
 		toggleSelectionState(false);
@@ -68,10 +73,12 @@
 	 * @param listener
 	 */
-	public void addVolumeChangeListener(ChangeListener listener) {
+	public void addVolumeChangeListener(ChangeListener listener)
+	{
 		assert(listener != null);
 		changeListeners.add(listener);
 	}
 	
-	private void fireVolumeChanged() {
+	private void fireVolumeChanged()
+	{
 		for (ChangeListener a : changeListeners) {
 			a.stateChanged(new ChangeEvent(this));
@@ -79,7 +86,11 @@
 	}
 
-	private void toggleSelectionState(boolean selected) {
-		if (selected) setBackground(SELECTED_BACKCOLOR);
-		else setBackground(UNSELECTED_BACKCOLOR);
+	private void toggleSelectionState(boolean selected)
+	{
+		if (selected) {
+			setBackground(SwingConversions.toSwingColor(SELECTED_BACKCOLOR));
+		} else {
+			setBackground(SwingConversions.toSwingColor(UNSELECTED_BACKCOLOR));
+		}
 	}
 	
@@ -89,17 +100,12 @@
 	 */
 	@Override
-	protected void fireActionPerformed(ActionEvent event) {
+	protected void fireActionPerformed(ActionEvent event)
+	{
 		super.fireActionPerformed(event);
 		
-		if (!vcPopup.isVisible()) { // show popup
-			
+		if (!vcPopup.isShowing()) { // show popup
 			vcPopup.showPopup();
-
 		} else { // hide popup
-
-			PopupManager.getInstance().hidePopup(vcPopup, 
-					PopupManager.getInstance().new ExpandShrinkAnimator(
-							VolumeControlButton.this.getBounds(),
-							Color.LIGHT_GRAY));
+			vcPopup.hide();
 		}
 	}
@@ -133,5 +139,6 @@
 	 * @return
 	 */
-	public void setMuted(boolean mute) {
+	public void setMuted(boolean mute)
+	{
 		muted = mute;
 		updateButtonGUI();
@@ -139,7 +146,7 @@
 		
 
-	private void updateButtonGUI() {
-		
-		Icon newIcon;
+	private void updateButtonGUI()
+	{
+		Image newIcon;
 		if(muted)  
 				newIcon = IconRepository.getIcon("volmute.png");
@@ -153,13 +160,18 @@
 				newIcon = IconRepository.getIcon("vol100.png");
 
-		if (newIcon != getIcon()) setIcon(newIcon);
+		if (newIcon != getIcon()) SwingMiscManager.setJButtonIcon(this, newIcon);
 		
 		if (muted) {
-			if (volumeTag != null) setToolTipText(volumeTag + ": Muted");
-			else setToolTipText("Muted");
-		}
-		else {
-			if (volumeTag != null) setToolTipText(volumeTag + ": " + volumeValue + "%");
-			else setToolTipText(volumeValue + "%");
+			if (volumeTag != null) {
+				setToolTipText(volumeTag + ": Muted");
+			} else {
+				setToolTipText("Muted");
+			}
+		} else {
+			if (volumeTag != null) {
+				setToolTipText(volumeTag + ": " + volumeValue + "%");
+			} else {
+				setToolTipText(volumeValue + "%");
+			}
 		}
 	}
@@ -169,5 +181,6 @@
 	 * @return The volume value of the gui
 	 */
-	public int getVolumeValue() {
+	public int getVolumeValue()
+	{
 		return volumeValue;
 	}
@@ -178,12 +191,12 @@
 	 * @return The mute value of the gui
 	 */
-	public boolean getMuteValue() {
+	public boolean getMuteValue()
+	{
 		return muted;
 	}
 
-	private class VolumeControlPopup extends Popup {
-		
-		private static final long serialVersionUID = 1L;
-	
+	private class VolumeControlPopup extends Popup
+	{
+		private JPanel panel;
 		private JSlider volumeSlider;
 		private JButton increaseButton;
@@ -193,6 +206,9 @@
 		 * Constructor.
 		 */
-		public VolumeControlPopup() {
-			super();
+		public VolumeControlPopup()
+		{
+			super(new ExpandShrinkAnimator());
+			
+			panel = new JPanel();
 
 			volumeSlider = new JSlider(JSlider.VERTICAL);
@@ -226,5 +242,6 @@
 		}
 		
-		private void onIncrementVolume() {
+		private void onIncrementVolume()
+		{
 			if (setVolumeValue(volumeValue + VOL_ADJUSTMENT)) {
 				fireVolumeChanged();
@@ -232,5 +249,6 @@
 		}
 		
-		private void onDeincrementVolume() {
+		private void onDeincrementVolume()
+		{
 			if (setVolumeValue(volumeValue - VOL_ADJUSTMENT)) {
 				fireVolumeChanged();
@@ -238,5 +256,6 @@
 		}
 		
-		private void onVolumeSliderChanged() {
+		private void onVolumeSliderChanged()
+		{
 			if (setVolumeValue(volumeSlider.getValue())) {
 				fireVolumeChanged();
@@ -244,5 +263,6 @@
 		}
 		
-		private void updatePopupGUI() {
+		private void updatePopupGUI()
+		{
 			volumeSlider.setValue(volumeValue);
 			increaseButton.setEnabled(volumeValue < 100);
@@ -250,7 +270,7 @@
 		}
 		
-		private void prepLayout() {
-			
-			if (this.getComponents().length == 0) {
+		private void prepLayout()
+		{
+			if (panel.getComponents().length == 0) {
 				
 				final int INNER_SPACING = 0;
@@ -286,5 +306,5 @@
 				c.insets = new Insets(OUTER_SPACING,OUTER_SPACING,INNER_SPACING,OUTER_SPACING);
 				c.ipady = YPAD;
-				this.add(increaseButton, c);
+				panel.add(increaseButton, c);
 				
 				c = new GridBagConstraints();
@@ -294,5 +314,5 @@
 				c.insets = new Insets(INNER_SPACING,OUTER_SPACING,INNER_SPACING,OUTER_SPACING);
 				c.ipady = YPAD;
-				this.add(volumeSlider, c);
+				panel.add(volumeSlider, c);
 				
 				c = new GridBagConstraints();
@@ -302,16 +322,46 @@
 				c.insets = new Insets(INNER_SPACING,OUTER_SPACING,OUTER_SPACING,OUTER_SPACING);
 				c.ipady = YPAD;
-				this.add(decreaseButton, c);
-				
-				setSize(targetWidth, volumeSlider.getHeight() + (2 * buttonSizes.height) 
-						+ (2 * OUTER_SPACING));
-				this.doLayout();
-			}
-
-		}
-		
-		private void showPopup() {
+				panel.add(decreaseButton, c);
+				
+				setSize(targetWidth, volumeSlider.getHeight() + (2 * buttonSizes.height) + (2 * OUTER_SPACING));
+				panel.doLayout();
+			}
+
+		}
+		
+		private void showPopup()
+		{
 			prepLayout();
-
+			show();
+		}
+
+		@Override
+		public void onHide() {
+			// Toggle state = volume popup showing
+			toggleSelectionState(false);
+		}
+
+		@Override
+		public void onShow() {
+			// Toggle state = volume popup showing
+			toggleSelectionState(true);
+		}
+
+		@Override
+		public boolean shouldConsumeBackClick()
+		{
+			return true;
+		}
+
+		@Override
+		protected void paintInternal()
+		{
+			// TODO Auto-generated method stub
+			
+		}
+
+		@Override
+		public AxisAlignedBoxBounds getFullBounds()
+		{
 			// Determine where popup should show
 			int x = VolumeControlButton.this.getX();
@@ -321,34 +371,7 @@
 				y = VolumeControlButton.this.getY() + VolumeControlButton.this.getHeight() + 2;
 			}
-
-			PopupManager.getInstance().showPopup(
-					this, 
-					new Point(x, y), 
-					VolumeControlButton.this,
-					PopupManager.getInstance().new ExpandShrinkAnimator(
-							VolumeControlButton.this.getBounds(),
-							Color.LIGHT_GRAY));
-		}
-
-		@Override
-		public void onHide() {
-			// Toggle state = volume popup showing
-			toggleSelectionState(false);
-		}
-
-		@Override
-		public void onShow() {
-			// Toggle state = volume popup showing
-			toggleSelectionState(true);
-		}
-
-		@Override
-		public boolean shouldConsumeBackClick() {
-			return true;
-		}
-		
-		
-		
-	}
-
+			
+			return new AxisAlignedBoxBounds(x, y, VolumeControlButton.this.getBounds().width, VolumeControlButton.this.getBounds().height);
+		}
+	}
 }
Index: /trunk/src/org/apollo/gui/WaveFormRenderProccessingUnit.java
===================================================================
--- /trunk/src/org/apollo/gui/WaveFormRenderProccessingUnit.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/WaveFormRenderProccessingUnit.java	(revision 1102)
@@ -2,5 +2,4 @@
 
 import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
 import java.util.LinkedList;
 
@@ -10,4 +9,7 @@
 import org.apollo.mvc.AbstractSubject;
 import org.apollo.mvc.SubjectChangedEvent;
+import org.expeditee.core.Image;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 
 public class WaveFormRenderProccessingUnit {
@@ -176,10 +178,10 @@
 					bufferWidth = currentTask.imageBuffer.getWidth();
 					
-					g = currentTask.imageBuffer.createGraphics();
-	
-					g.setStroke(Strokes.SOLID_1);
+					g = SwingMiscManager.getIfUsingSwingImageManager().getImageGraphics(currentTask.imageBuffer);
+	
+					g.setStroke(SwingConversions.toSwingStroke(Strokes.SOLID_1));
 
 					// Clear the buffer with transparent pixels
-					g.setBackground(ApolloColorIndexedModels.KEY_COLOR);
+					g.setBackground(SwingConversions.toSwingColor(ApolloColorIndexedModels.KEY_COLOR));
 					g.clearRect(0, 0, bufferWidth, currentTask.imageBuffer.getHeight());
 					
@@ -233,5 +235,5 @@
 					synchronized(currentTask.imageBuffer) { 
 						
-						g.setColor(ApolloColorIndexedModels.WAVEFORM_COLOR);
+						g.setColor(SwingConversions.toSwingColor(ApolloColorIndexedModels.WAVEFORM_COLOR));
 						
 						if (aggregationSize == 1) {
@@ -344,5 +346,5 @@
 		private static final int STATE_STOPPED = 3;
 		
-		private BufferedImage imageBuffer; // nullified when stopped.
+		private Image imageBuffer; // nullified when stopped.
 		private byte[] audioBytes; // nullified when stopped. - Arrays (not contents) are immutable so no need to worry about threading issues with indexes
 		private final int startFrame;
@@ -352,5 +354,5 @@
 		
 		public WaveFormRenderTask(
-				BufferedImage imageBuffer, 
+				Image imageBuffer, 
 				byte[] audioBytes, 
 				AudioFormat format,
Index: /trunk/src/org/apollo/gui/WaveFormRenderer.java
===================================================================
--- /trunk/src/org/apollo/gui/WaveFormRenderer.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/WaveFormRenderer.java	(revision 1102)
@@ -13,5 +13,5 @@
 	 * 
 	 * A single height is calculated for one or more frames, which is specified by the
-	 * aggregationSize. The way in which waveforms are rendered is implementation dependant.
+	 * aggregationSize. The way in which waveforms are rendered is implementation dependent.
 	 * 
 	 * @param audioBytes
@@ -22,8 +22,8 @@
 	 * 
 	 * @param frameLength
-	 * 		The amount of frames to consider for rendering.
+	 * 		The number of frames to consider for rendering.
 	 * 
 	 * @param aggregationSize
-	 * 		The amout of frames to aggregate.
+	 * 		The amount of frames to aggregate.
 	 * 
 	 * @return 
Index: /trunk/src/org/apollo/gui/ZoomChangeListener.java
===================================================================
--- /trunk/src/org/apollo/gui/ZoomChangeListener.java	(revision 1101)
+++ /trunk/src/org/apollo/gui/ZoomChangeListener.java	(revision 1102)
@@ -3,5 +3,6 @@
 import java.awt.Event;
 
-public interface ZoomChangeListener {
+public interface ZoomChangeListener
+{
 	void zoomChanged(Event e);
 }
Index: /trunk/src/org/apollo/io/AudioIO.java
===================================================================
--- /trunk/src/org/apollo/io/AudioIO.java	(revision 1101)
+++ /trunk/src/org/apollo/io/AudioIO.java	(revision 1102)
@@ -167,8 +167,5 @@
 		if (!sourceFormat.getEncoding().toString().startsWith("PCM")) {
 			
-			AudioFormat.Encoding conversionEncoding = 
-				(sourceFormat.getSampleSizeInBits() == 8) ?
-				AudioFormat.Encoding.PCM_UNSIGNED :
-				AudioFormat.Encoding.PCM_SIGNED;
+			AudioFormat.Encoding conversionEncoding = (sourceFormat.getSampleSizeInBits() == 8) ? AudioFormat.Encoding.PCM_UNSIGNED : AudioFormat.Encoding.PCM_SIGNED;
 			
 			aisConverter = AudioSystem.getAudioInputStream(conversionEncoding, aisConverter);
Index: /trunk/src/org/apollo/io/IconRepository.java
===================================================================
--- /trunk/src/org/apollo/io/IconRepository.java	(revision 1101)
+++ /trunk/src/org/apollo/io/IconRepository.java	(revision 1102)
@@ -1,18 +1,16 @@
 package org.apollo.io;
 
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.image.BufferedImage;
 import java.net.URL;
 import java.util.HashMap;
 
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-
 import org.apollo.gui.Strokes;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
+import org.expeditee.core.Line;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
 
 /**
- * An icon provider. Only loads icons once and when they are requested (somple proxy approach).
+ * An icon provider. Only loads icons once and when they are requested (simple proxy approach).
  * 
  * @author Brook Novak
@@ -21,27 +19,33 @@
 public final class IconRepository {
 	
-	private static HashMap<String, Icon> _loadedIcons = new HashMap<String, Icon>();
-	private static Icon missingIcon = null;
+	private static HashMap<String, Image> _loadedIcons = new HashMap<String, Image>();
+	
+	private static Image missingIcon = null;
 
-	private IconRepository() {}
+	private IconRepository()
+	{
+	}
 	
-	private static Icon getMissingIcon() {
-		
+	private static Image getMissingIcon()
+	{
 		if (missingIcon == null) {
 			
-			Image image = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
-			Graphics2D g = (Graphics2D)image.getGraphics();
+			Image image = EcosystemManager.getImageManager().createImage(16, 16, false);
 			
-			g.setStroke(Strokes.SOLID_2);
+			GraphicsManager g = EcosystemManager.getGraphicsManager();
 			
-			// White square with X
-			g.setColor(Color.WHITE);
-			g.fillRect(0, 0, 16, 16);
+			g.pushDrawingSurface(image);
 			
-			g.setColor(Color.RED);
-			g.drawLine(0, 0, 16, 16);
-			g.drawLine(0, 16, 16, 0);
+			g.clear(Colour.WHITE);
+
+			Line l1 = new Line(0, 0, 16, 16);
+			Line l2 = new Line(0, 16, 16, 0);
+
+			g.drawLine(l1, Colour.RED, Strokes.SOLID_2);
+			g.drawLine(l2, Colour.RED, Strokes.SOLID_2);
 			
-			missingIcon = new ImageIcon(image);
+			g.popDrawingSurface();
+			
+			missingIcon = image;
 		}
 			
@@ -54,23 +58,20 @@
 	 * @return
 	 */
-	public static Icon getIcon(String name) {
-		Icon icon = _loadedIcons.get(name);
+	public static Image getIcon(String name)
+	{
+		Image icon = _loadedIcons.get(name);
 		
 		if (icon == null) {
 			try {
-			        URL url;
+				URL url;
 				ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 				if (classLoader!=null) {
 				    // Applet friendly
 				    url = classLoader.getResource("org/apollo/assets/icons/" + name);
-				}
-				else {
+				} else {
 				    url = ClassLoader.getSystemResource("org/apollo/assets/icons/" + name);
 				}
 
-				if (url != null) {
-					icon = new ImageIcon(url);
-				}
-				
+				if (url != null) icon = Image.getImage(url);
 			} catch (Exception e) {
 				e.printStackTrace();
Index: /trunk/src/org/apollo/io/SampledAudioFileImporter.java
===================================================================
--- /trunk/src/org/apollo/io/SampledAudioFileImporter.java	(revision 1101)
+++ /trunk/src/org/apollo/io/SampledAudioFileImporter.java	(revision 1102)
@@ -1,10 +1,10 @@
 package org.apollo.io;
 
-import java.awt.Point;
 import java.io.File;
 import java.io.IOException;
 
 import org.apollo.widgets.SampledTrack;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Point;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.importer.FileImporter;
 import org.expeditee.items.Item;
@@ -18,17 +18,16 @@
 public class SampledAudioFileImporter implements FileImporter {
 
-	public Item importFile(File f, Point location) throws IOException {
-
-		if (location == null || !AudioIO.canImportFile(f) ||
-				DisplayIO.getCurrentFrame() == null) return null;
+	public Item importFile(File f, Point location) throws IOException
+	{
+		if (location == null || !AudioIO.canImportFile(f) || DisplayController.getCurrentFrame() == null) return null;
 		
 		SampledTrack trackWidget = SampledTrack.createFromFile(
 				f,
-				DisplayIO.getCurrentFrame(), 
+				DisplayController.getCurrentFrame(), 
 				location.x, 
 				location.y);
 		
 		// Add the sampled track widget to the current frame
-		DisplayIO.getCurrentFrame().addAllItems(trackWidget.getItems());
+		DisplayController.getCurrentFrame().addAllItems(trackWidget.getItems());
 		
 		return trackWidget.getSource(); // Don't allow for other importers to deal with this file
Index: /trunk/src/org/apollo/items/EmulatedTextItem.java
===================================================================
--- /trunk/src/org/apollo/items/EmulatedTextItem.java	(revision 1101)
+++ /trunk/src/org/apollo/items/EmulatedTextItem.java	(revision 1102)
@@ -1,16 +1,4 @@
 package org.apollo.items;
 
-import java.awt.AWTException;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Cursor;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.IllegalComponentStateException;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Robot;
-import java.awt.Shape;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
@@ -18,18 +6,19 @@
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
-import java.awt.geom.Area;
-import java.awt.geom.Point2D;
 import java.util.LinkedList;
 import java.util.List;
 
-import javax.swing.JComponent;
-import javax.swing.SwingUtilities;
-
-import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Cursor;
+import org.expeditee.core.Font;
+import org.expeditee.core.Point;
+import org.expeditee.core.EnforcedClipStack.EnforcedClipKey;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.FrameMouseActions;
-import org.expeditee.gui.MouseEventRouter;
 import org.expeditee.gui.Popup;
 import org.expeditee.gui.PopupManager;
@@ -38,5 +27,4 @@
 
 /**
- * 
  * Its a terrible hack - but it will do.
  * 
@@ -44,26 +32,12 @@
  *
  */
-public class EmulatedTextItem {
-
-	private static final long serialVersionUID = 1L;
-	
-	private static Robot robot;
-
+public class EmulatedTextItem
+{
 	private List<TextChangeListener> textChangeListeners = new LinkedList<TextChangeListener>();
 	
 	private RestrictedTextItem emulatedSource;
 	private LabelEditPopup popup = null;
-	private JComponent parentComponant = null;
-	private Point masterOffset;
-	
-	private static final Font DEFAULT_FONT = new Font("Serif-Plain", Font.PLAIN, 12);
-	
-	static {
-		try {
-			robot = new Robot();
-		} catch (AWTException e) {
-			e.printStackTrace();
-		}
-	}
+	
+	private static final Font DEFAULT_FONT = new Font("Serif-Plain", Font.Style.PLAIN, 12);
 	
 	/**
@@ -77,25 +51,37 @@
 	 * 		Must not be null.
 	 */
-	public EmulatedTextItem(JComponent parent, Point offset) {
-		assert(parent != null);
-		assert(offset != null);
-		
-		parentComponant = parent;
-		masterOffset = offset;
+	public EmulatedTextItem(String text, Point position)
+	{
+		assert(position != null);
+		
 		emulatedSource = new RestrictedTextItem();
-		emulatedSource.setPosition(parent.getX() + offset.x, parent.getY() + offset.y);
+		emulatedSource.setPosition(position);
 		emulatedSource.setFont(DEFAULT_FONT);
-
-	}
-	
-	
-	public void setFontStyle(int style) {
-		emulatedSource.setFont(emulatedSource.getFont().deriveFont(style));
-	}
-	
-	public void setFontSize(float size) {
+		emulatedSource.setText(text);
+		
+		popup = new LabelEditPopup();
+		PopupManager.getInstance().add(popup);
+	}
+	
+	@Override
+	public void finalize()
+	{
+		PopupManager.getInstance().remove(popup);
+	}
+	
+	public void setFontStyle(Font.Style style)
+	{
+		emulatedSource.setFont(emulatedSource.getFont().clone().setStyle(style));
+	}
+	
+	public void setFontSize(float size)
+	{
 		emulatedSource.setSize(size);
 	}
 	
+	public void setPosition(Point position)
+	{
+		emulatedSource.setPosition(position);
+	}
 	
 	/**
@@ -107,21 +93,14 @@
 	 * 		True if the event is over the emulated item.
 	 */
-	private boolean isOnEmulatedText(MouseEvent swingME) {
-		if (swingME == null) return false;
-		Point p = convertToExpediteeSpace(swingME.getLocationOnScreen());
+	private boolean isOnEmulatedText()
+	{
+		Point p = EcosystemManager.getInputManager().getCursorPosition();
+		
 		return isOnEmulatedText(p.x, p.y);
 	}
 	
-	private boolean isOnEmulatedText(int expX, int expY) {
+	private boolean isOnEmulatedText(int expX, int expY)
+	{
 		return emulatedSource.contains(expX, expY);
-	}
-	
-	private Point convertToExpediteeSpace(Point screenPos) {
-		assert(screenPos != null);
-		
-		Point expPoint = new Point(0, 0);
-		SwingUtilities.convertPointToScreen(expPoint, Browser._theBrowser.getContentPane());
-		
-		return new Point(screenPos.x - expPoint.x, screenPos.y - expPoint.y);
 	}
 	
@@ -132,88 +111,48 @@
 	 * @param parent
 	 */
-	public boolean onMouseMoved(MouseEvent e, Component parent) {
-
-		if (isOnEmulatedText(e)) {
+	public boolean onMouseMoved(MouseEvent e)
+	{
+		if (isOnEmulatedText()) {
 			
 			if (emulatedSource.getHighlightMode() != HighlightMode.Normal) {
 				emulatedSource.setHighlightMode(HighlightMode.Normal);
+				emulatedSource.setHighlightColorToDefault();
 				repaint();
 			}
 			
-			if (parent != popup && 
-					(emulatedSource.getBoundsWidth() + masterOffset.x) > (parent.getWidth() - 10)) { // have some give to transition over widget edge
-				if (popup == null) {
-					popup = new LabelEditPopup();
-				}
-				
-				int x = (emulatedSource.getPolygon() == null) ? parent.getX() + masterOffset.x : emulatedSource.getPolygon().getBounds().x;
-				int y = (emulatedSource.getPolygon() == null) ? parent.getY() + masterOffset.y : emulatedSource.getPolygon().getBounds().y;
-				x -= 2;
-				y -= 2;
-
-				if (!PopupManager.getInstance().isShowing(popup)) {
-					PopupManager.getInstance().showPopup(
-							popup, 
-							new Point(x, y), 
-							popup);  
-				}
-				
-			}
-			
 			return true;
-			
 		} else {
-			
 			lostFocus();
-
 		}
 		
 		return false;
-		
-	}
-	
-	/**
-	 * 
-	 * @param e
-	 * 
-	 * @param parent
-	 */
-	public boolean onKeyPressed(KeyEvent e, Component parent) {
-
-		MouseEvent currentME = MouseEventRouter.getCurrentMouseEvent();
-		
-		if (currentME == null) return false;
-		
-		Point p = convertToExpediteeSpace(currentME.getLocationOnScreen());
+	}
+	
+	public boolean onKeyTyped(KeyEvent e)
+	{
+		Point p = EcosystemManager.getInputManager().getCursorPosition();
 
 		// If so and the event really comes from its parent ...
-		if (currentME.getComponent() == parent && 
-				(isOnEmulatedText(p.x, p.y))) {
-			
-			int yOffset = (parent == popup) ? -6 : -6;
-			
-			Browser._theBrowser.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+		if (isOnEmulatedText(p.x, p.y)) {
+			
+			int yOffset = -6;
+			
+			EcosystemManager.getGraphicsManager().setCursor(new Cursor(Cursor.CursorType.TEXT));
 
 			// If a alphanumeric text entry...
-			if (!e.isActionKey() && 
-					(Character.isLetterOrDigit(e.getKeyChar()) || 
-							(e.getKeyChar() == KeyEvent.VK_BACK_SPACE && !emulatedSource.isEmpty()) ||
-							(e.getKeyChar() == KeyEvent.VK_DELETE && !emulatedSource.isEmpty()) ||
-							e.getKeyChar() == KeyEvent.VK_SPACE ||
-							e.getKeyChar() == KeyEvent.VK_UNDERSCORE) ||
-							e.getKeyChar() == KeyEvent.VK_AMPERSAND ||
-							e.getKeyChar() == KeyEvent.VK_OPEN_BRACKET ||
-							e.getKeyChar() == KeyEvent.VK_CLOSE_BRACKET ||
-							e.getKeyChar() == KeyEvent.VK_MINUS) {
-
-
-				Rectangle[] oldArea = emulatedSource.getDrawingArea();
-				int oldWidth = emulatedSource.getBoundsWidth();
-				
+			if (!e.isActionKey() &&
+					Character.isLetterOrDigit(e.getKeyChar()) || 
+					(e.getKeyChar() == Text.BACKSPACE_CHARACTER && !emulatedSource.isEmpty()) ||
+					(e.getKeyChar() == Text.DELETE_CHARACTER && !emulatedSource.isEmpty()) ||
+					e.getKeyChar() == ' ' ||
+					e.getKeyChar() == '_' ||
+					e.getKeyChar() == '&' ||
+					e.getKeyChar() == '(' ||
+					e.getKeyChar() == ')' ||
+					e.getKeyChar() == '-'
+				)
+			{
 				// Insert the text according to the current mouse position
-				Point2D.Float newMouse = emulatedSource.insertChar(
-						e.getKeyChar(), 
-						p.x, 
-						p.y);
+				Point newMouse = emulatedSource.insertChar(e.getKeyChar(), p.x, p.y);
 				
 				List<String> lines = emulatedSource.getTextList();
@@ -225,33 +164,8 @@
 				fireTextChanged();
 
-				// Move "cursured mouse"
+				// Move "cursored mouse"
 				if (newMouse != null) {
-					Point bloc = Browser._theBrowser.getContentPane().getLocationOnScreen();
-					robot.mouseMove(bloc.x + (int)newMouse.x, bloc.y + (int)newMouse.y + yOffset);
+					EcosystemManager.getInputManager().setCursorPosition(new Point((int) newMouse.x, (int) newMouse.y + yOffset));
 				}
-				
-				// Invalidate emulated item if not in popup (popup will naturally handle invalidation)
-				if (parent != popup) {
-
-					if (oldWidth > emulatedSource.getBoundsWidth()) {
-						for (Rectangle r : oldArea) 
-							FrameGraphics.invalidateArea(r);
-					}
-					
-					repaint();
-
-				}
-				
-			} else if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_RIGHT) {
-				
-				Point2D.Float newMouse = emulatedSource.moveCursor(
-						(e.getKeyCode() == KeyEvent.VK_LEFT) ? Text.LEFT : Text.RIGHT, 
-						(float)p.getX(), (float)p.getY(), false, false);
-				
-				if (newMouse != null) {
-					Point bloc = Browser._theBrowser.getContentPane().getLocationOnScreen();
-					robot.mouseMove(bloc.x + (int)newMouse.x, bloc.y + (int)newMouse.y + yOffset);
-				}
-
 			}
 			
@@ -274,17 +188,58 @@
 	 * @param parent
 	 */
-	public boolean onKeyReleased(KeyEvent e, Component parent) {
-		return isOnEmulatedText(MouseEventRouter.getCurrentMouseEvent());
-		
-	}
-	
-	
-	public boolean onMouseReleased(MouseEvent e) {
-		
-		Point p = convertToExpediteeSpace(e.getLocationOnScreen());
+	public boolean onKeyPressed(KeyEvent e)
+	{
+		Point p = EcosystemManager.getInputManager().getCursorPosition();
 
 		// If so and the event really comes from its parent ...
 		if (isOnEmulatedText(p.x, p.y)) {
 			
+			int yOffset = -6;
+			
+			EcosystemManager.getGraphicsManager().setCursor(new Cursor(Cursor.CursorType.TEXT));
+
+			// If a alphanumeric text entry...
+			if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_RIGHT) {
+				
+				Point newMouse = emulatedSource.moveCursor(
+						(e.getKeyCode() == KeyEvent.VK_LEFT) ? Text.LEFT : Text.RIGHT, 
+						(float)p.getX(), (float)p.getY(), false, false);
+				
+				if (newMouse != null) {
+					EcosystemManager.getInputManager().setCursorPosition(new Point((int) newMouse.x, (int) newMouse.y + yOffset));
+				}
+
+			}
+			
+			if (emulatedSource.hasSelection()) {
+				emulatedSource.clearSelection();
+				repaint();
+			}
+			
+			return true;
+			
+		}
+		
+		return false;
+	}
+	
+	/**
+	 * 
+	 * @param e
+	 * 
+	 * @param parent
+	 */
+	public boolean onKeyReleased(KeyEvent e)
+	{
+		return isOnEmulatedText();
+	}
+	
+	
+	public boolean onMouseReleased(MouseEvent e)
+	{
+		Point p = EcosystemManager.getInputManager().getCursorPosition();
+
+		// If so and the event really comes from its parent ...
+		if (isOnEmulatedText(p.x, p.y)) {
 			
 			String toMoveIntoFreespace = null;
@@ -292,8 +247,5 @@
 			if (e.getButton() == MouseEvent.BUTTON1) {
 				// LINK
-			} else if (e.getButton() == MouseEvent.BUTTON2 && 
-					emulatedSource.hasSelection() && 
-					!emulatedSource.isEmpty() &&
-					emulatedSource.selectionMouseButton == MouseEvent.BUTTON2) {
+			} else if (e.getButton() == MouseEvent.BUTTON2 && emulatedSource.hasSelection() && !emulatedSource.isEmpty()) {
 	
 				invalidate();
@@ -301,8 +253,5 @@
 				toMoveIntoFreespace = emulatedSource.cutSelectedText();
 				
-			} else if (e.getButton() == MouseEvent.BUTTON3 && 
-					emulatedSource.hasSelection() && 
-					!emulatedSource.isEmpty() &&
-					emulatedSource.selectionMouseButton == MouseEvent.BUTTON3) {
+			} else if (e.getButton() == MouseEvent.BUTTON3 && emulatedSource.hasSelection() && !emulatedSource.isEmpty()) {
 				toMoveIntoFreespace = emulatedSource.copySelectedText();
 				
@@ -315,10 +264,10 @@
 			if (toMoveIntoFreespace != null) {
 				
-				Frame target = DisplayIO.getCurrentFrame();
+				Frame target = DisplayController.getCurrentFrame();
 				if (target != null) {
 					Text selectionCopy = new Text(target.getNextItemID(), toMoveIntoFreespace);
 					selectionCopy.setPosition(p.x, p.y);
 					selectionCopy.setSize(emulatedSource.getSize());
-					FrameMouseActions.pickup(selectionCopy);
+					StandardGestureActions.pickup(selectionCopy);
 					lostFocus();
 				}
@@ -336,7 +285,7 @@
 	}
 	
-	public boolean onMousePressed(MouseEvent e) {
-
-		Point p = convertToExpediteeSpace(e.getLocationOnScreen());
+	public boolean onMousePressed(MouseEvent e)
+	{
+		Point p = EcosystemManager.getInputManager().getCursorPosition();
 
 		// If so and the event really comes from its parent ...
@@ -354,15 +303,17 @@
 	}
 	
-	public boolean onMouseClicked(MouseEvent e) {
-		return isOnEmulatedText(e);
-	}
-	public boolean onMouseDragged(MouseEvent e) {
-
-		Point p = convertToExpediteeSpace(e.getLocationOnScreen());
+	public boolean onMouseClicked(MouseEvent e)
+	{
+		return isOnEmulatedText();
+	}
+	
+	public boolean onMouseDragged(MouseEvent e)
+	{
+		Point p = EcosystemManager.getInputManager().getCursorPosition();
 
 		// If so and the event really comes from its parent ...
 		if (isOnEmulatedText(p.x, p.y)) {
 
-			Browser._theBrowser.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+			EcosystemManager.getGraphicsManager().setCursor(new Cursor(Cursor.CursorType.TEXT));
 			
 			emulatedSource.setSelectionEnd(p.x, p.y);
@@ -375,12 +326,20 @@
 	}
 	
-	public void addTextChangeListener(TextChangeListener listener) {
+	public void addTextChangeListener(TextChangeListener listener)
+	{
 		assert(listener != null);
-		if (!textChangeListeners.contains(listener))
-			textChangeListeners.add(listener);
-	}
-	
-	public void lostFocus() {
-		Browser._theBrowser.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+		if (!textChangeListeners.contains(listener)) textChangeListeners.add(listener);
+	}
+	
+	public void gainFocus()
+	{
+		if (popup != null && !PopupManager.getInstance().isShowing(popup)) {
+			popup.show();
+		}
+	}
+	
+	public void lostFocus()
+	{
+		EcosystemManager.getGraphicsManager().setCursor(new Cursor(Cursor.CursorType.DEFAULT));
 		
 		boolean dirty = false;
@@ -392,10 +351,10 @@
 		if (emulatedSource.getHighlightMode() != HighlightMode.None) {
 			emulatedSource.setHighlightMode(HighlightMode.None);
+			emulatedSource.setHighlightColorToDefault();
 			dirty = true;
 		}
 
-		if (popup != null &&
-				PopupManager.getInstance().isShowing(popup)) {
-			PopupManager.getInstance().hidePopup(popup);
+		if (popup != null && PopupManager.getInstance().isShowing(popup)) {
+			popup.hide();
 		}
 		
@@ -410,5 +369,6 @@
 	 * 		Null is allowed
 	 */
-	public void setText(String text) {
+	public void setText(String text)
+	{
 		if (text == null) text = "";
 		
@@ -424,110 +384,46 @@
 	}
 	
-	public String getText() {
+	public String getText()
+	{
 		return emulatedSource.getText();
 	}
 	
-	private void fireTextChanged() {
-		
-		for (TextChangeListener listener : textChangeListeners)
+	private void fireTextChanged()
+	{
+		for (TextChangeListener listener : textChangeListeners) {
 			listener.onTextChanged(this, this.emulatedSource.getText());
-		
-	}
-
-	public void setBackgroundColor(Color c) {
+		}
+	}
+
+	public void setBackgroundColor(Colour c)
+	{
 		emulatedSource.setBackgroundColor(c);
 	}
 	
-	private void repaint() {
-
+	private void repaint()
+	{
 		if (popup != null && PopupManager.getInstance().isShowing(popup)) {
 			popup.invalidateAppearance();
-			FrameGraphics.refresh(true);
+			DisplayController.requestRefresh(true);
 		} else {
 			invalidate();
-			FrameGraphics.refresh(true);
-		}
-	}
-	
-	private void invalidate() {
-		for (Rectangle r : emulatedSource.getDrawingArea()) 
-			FrameGraphics.invalidateArea(r);
-	}
-
-	public void paint(Graphics g) {
-		
-		if ((popup != null && PopupManager.getInstance().isShowing(popup)) ||
-				!parentComponant.isShowing())
-			return;
-		
-		Point pos;
-		try {
-		pos = this.convertToExpediteeSpace(parentComponant.getLocationOnScreen());
-		} catch (Exception e) {
-			e.printStackTrace();
-			return;
-		}
-
-		paint(	g, 
-				pos.x + masterOffset.x, 
-				pos.y + masterOffset.y, 
-				parentComponant.getWidth() - masterOffset.x);
-	}
-	
-	private void paint(Graphics g, int parentX, int parentY, int maxWidth) {
-
-		if (Browser._theBrowser == null) return;
-		
-		/*int xoffset = (emulatedSource.getLink() == null) ? 6 : 18;
-		int yoffset = emulatedSource.getBoundsHeight() - 3;
-		parentX += xoffset;
-		parentY += yoffset;*/
-		
-		// Set the emulated position according to the parent position - the parent position
-		// can be from the popup or the actual parent componant
-		if (emulatedSource.getX() != parentX || emulatedSource.getY() != parentY)
-			emulatedSource.setPosition(parentX, parentY);
-
-		Shape saveClip = g.getClip();
-		
-		if (maxWidth > 0) {
-			
-			Area clip = FrameGraphics.getCurrentClip();
-
-			Area tmpClip = (clip != null) ? clip : 
-				new Area(new Rectangle(0, 0, 
-						Browser._theBrowser.getContentPane().getWidth(), 
-						Browser._theBrowser.getContentPane().getHeight()));
-			
-		/*	tmpClip.intersect(new Area(new Rectangle(0, 0,
-					parentX + maxWidth - xoffset, Browser._theBrowser.getContentPane().getHeight()
-			)));*/
-			
-			tmpClip.intersect(new Area(new Rectangle(0, 0,
-					parentX + maxWidth, Browser._theBrowser.getContentPane().getHeight()
-			)));
-	
-			// No intersection
-			if (!tmpClip.isEmpty()) 
-				g.setClip(tmpClip);
-		
-		}
-		
-		emulatedSource.paint((Graphics2D)g);
-		
-		// Restore
-		if (maxWidth > 0) {
-			g.setClip(saveClip);
-		}
-		
-		// Restore emulated position for consuming mouse movements
-		try {
-		Point pos = this.convertToExpediteeSpace(parentComponant.getLocationOnScreen());
-		emulatedSource.setPosition(
-				pos.x + masterOffset.x, 
-				pos.y + masterOffset.y);
-		} catch (IllegalComponentStateException ex) { // Cannot fix this .. this whole class needs revising
-			ex.printStackTrace();
-		}
+			DisplayController.requestRefresh(true);
+		}
+	}
+	
+	private void invalidate()
+	{
+		DisplayController.invalidateArea(emulatedSource.getDrawingArea());
+	}
+	
+	public void paint()
+	{
+		GraphicsManager gm = EcosystemManager.getGraphicsManager();
+
+		EnforcedClipKey key = gm.pushClip(new Clip(emulatedSource.getDrawingArea()));
+		
+		emulatedSource.paint();
+
+		gm.popClip(key);
 	}
 	
@@ -537,114 +433,133 @@
 	}
 	
-	private class LabelEditPopup extends Popup implements KeyListener, MouseListener, MouseMotionListener {
-		
-		private static final long serialVersionUID = 1L;
-		
-		LabelEditPopup() {
-			super.setAudoHide(true);
+	private class LabelEditPopup extends Popup implements KeyListener, MouseListener, MouseMotionListener
+	{
+		LabelEditPopup()
+		{
+			super(null); // No animation (instant show/hide)
 			super.setConsumeBackClick(false);
 			super.setBorderThickness(0);
-			
-			updateSize();
-			
-			addKeyListener(this);
-			addMouseListener(this);
-			addMouseMotionListener(this);
-		}
-		
-		public void updateSize() {
-			setSize(emulatedSource.getBoundsWidth() + 4, emulatedSource.getBoundsHeight() + 4);
-		}
-	
-
-		public void keyPressed(KeyEvent e) {
-			onKeyPressed(e, LabelEditPopup.this);
-			updateSize();
-		}
-
-		public void keyReleased(KeyEvent e) {
-		}
-		
-
-		public void keyTyped(KeyEvent e) {
-		}
-		
-		
-		public void mouseClicked(MouseEvent e) {
-		}
-
-		public void mouseEntered(MouseEvent e) {
-		}
-
-		public void mouseExited(MouseEvent e) {
-		}
-
-		public void mousePressed(MouseEvent e) {
-			onMousePressed(e);
-		}
-
-		public void mouseReleased(MouseEvent e) {
-			onMouseReleased(e);
-			updateSize();
-		}
-		
-
-		public void mouseDragged(MouseEvent e) {
-			onMouseDragged(e);
-		}
-
-		public void mouseMoved(MouseEvent e) {
-
-		}
-
-		@Override
-		public void onHide() {
-			super.onHide();
-		}
-	
-		@Override
-		public void onShow() {
-			super.onShow();
-		}
-		
-		
-
-		@Override
-		public void paint(Graphics g) {
-			
-			EmulatedTextItem.this.paint(g, 7, 16, -1);
-
-		}
-	
-	}
-	
-	private class RestrictedTextItem extends Text {
-		
-		private Color selectionColor = null;
-		private int selectionMouseButton = -1;
-		
-		RestrictedTextItem() {
+		}
+
+		@Override
+		public void onHide()
+		{
+		}
+	
+		@Override
+		public void onShow()
+		{
+		}
+		
+		@Override
+		public void paintInternal()
+		{
+			EmulatedTextItem.this.paint();
+		}
+
+		@Override
+		public AxisAlignedBoxBounds getFullBounds()
+		{
+			return emulatedSource.getDrawingArea();
+		}
+
+		@Override
+		public void mouseDragged(MouseEvent e)
+		{
+			boolean consume = onMouseDragged(e);
+			if (consume) e.consume();
+		}
+
+		@Override
+		public void mouseMoved(MouseEvent e)
+		{
+			boolean consume = onMouseMoved(e);
+			if (consume) e.consume();
+		}
+
+		@Override
+		public void mouseClicked(MouseEvent e)
+		{
+			boolean consume = onMouseClicked(e);
+			if (consume) e.consume();
+		}
+
+		@Override
+		public void mousePressed(MouseEvent e)
+		{
+			boolean consume = onMousePressed(e);
+			if (consume) e.consume();
+		}
+
+		@Override
+		public void mouseReleased(MouseEvent e)
+		{
+			boolean consume = onMouseReleased(e);
+			if (consume) e.consume();
+		}
+
+		@Override
+		public void mouseEntered(MouseEvent e)
+		{
+			// Not required
+		}
+
+		@Override
+		public void mouseExited(MouseEvent e)
+		{
+			// Not required
+		}
+
+		@Override
+		public void keyTyped(KeyEvent e)
+		{
+			boolean consume = onKeyTyped(e);
+			if (consume) e.consume();
+		}
+
+		@Override
+		public void keyPressed(KeyEvent e)
+		{
+			boolean consume = onKeyPressed(e);
+			if (consume) e.consume();
+		}
+
+		@Override
+		public void keyReleased(KeyEvent e)
+		{
+			boolean consume = onKeyReleased(e);
+			if (consume) e.consume();
+		}
+	
+	}
+	
+	private class RestrictedTextItem extends Text
+	{
+		private Colour selectionColor = null;
+		
+		RestrictedTextItem()
+		{
 			super(1);
 		}
 		
-		private void updateSelection(int mouseButton) {
-			selectionColor = super.getSelectionColor(mouseButton);
-			selectionMouseButton = mouseButton;
-		}
-
-		public void setSelectionStart(float mouseX, float mouseY, int mouseButton) {
+		private void updateSelection()
+		{
+			selectionColor = super.getSelectionColour();
+		}
+
+		public void setSelectionStart(float mouseX, float mouseY, int mouseButton)
+		{
 			super.setSelectionStart(mouseX, mouseY);
-			updateSelection(mouseButton);
-		}
-		
-		
-
-		@Override
-		protected Color getSelectionColor(int mouseButton) {
-			
-			if (selectionColor != null)
+			updateSelection();
+		}
+		
+		@Override
+		public Colour getSelectionColour()
+		{
+			if (selectionColor != null) {
 				return selectionColor;
-			
-			else return super.getSelectionColor(mouseButton);
+			} else {
+				return super.getSelectionColour();
+			}
 
 		}
Index: /trunk/src/org/apollo/items/FramePlaybackLauncher.java
===================================================================
--- /trunk/src/org/apollo/items/FramePlaybackLauncher.java	(revision 1101)
+++ /trunk/src/org/apollo/items/FramePlaybackLauncher.java	(revision 1102)
@@ -1,10 +1,3 @@
 package org.apollo.items;
-
-import java.awt.Color;
-import java.awt.GradientPaint;
-import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.Polygon;
-import java.awt.Stroke;
 
 import org.apollo.ApolloSystem;
@@ -24,6 +17,16 @@
 import org.apollo.util.ODFrameHeirarchyFetcher.ODFrameReceiver;
 import org.apollo.widgets.FramePlayer;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.GradientFill;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.Bounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -43,8 +46,8 @@
 	private static int WIDTH = 80;
 	private static int HEIGHT = 80;
-	private static Stroke BORDER_STOKE = Strokes.SOLID_1;
-	
-	private static final Color BASE_COLOR = new Color(60, 148, 255);
-	private static final Color HIGHLIGHT_COLOR = new Color(253, 255, 201);
+	private static Stroke BORDER_STROKE = Strokes.SOLID_1;
+	
+	private static final Colour BASE_COLOR = Colour.FromRGB255(60, 148, 255);
+	private static final Colour HIGHLIGHT_COLOR = Colour.FromRGB255(253, 255, 201);
 	
 	private String frameToPlay = null;
@@ -74,28 +77,27 @@
 
 	@Override
-	public void paint(Graphics2D g) {
+	public void paint()
+	{
 		if (Browser._theBrowser == null) return;
 		
-		Paint restore = g.getPaint();
-		
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		
+		Fill fill = null;
 		if (ApolloSystem.useQualityGraphics) {
-			GradientPaint gp = new GradientPaint(
-					_x + (WIDTH / 2), _y, HIGHLIGHT_COLOR,
-					_x + (WIDTH / 2), _y + HEIGHT - (HEIGHT / 5), BASE_COLOR);
-			g.setPaint(gp);
+			Point fromPoint = new Point(_x + (WIDTH / 2), _y);
+			Point toPoint = new Point(_x + (WIDTH / 2), _y + HEIGHT - (HEIGHT / 5));
+			fill = new GradientFill(HIGHLIGHT_COLOR, fromPoint, BASE_COLOR, toPoint);
 		} else {
-			g.setColor(BASE_COLOR);
-		}
-		
-		g.fillRect((int)_x, (int)_y, WIDTH, HEIGHT);
-		
-		g.setPaint(restore);
-		
-		g.setColor(Color.BLACK);
-		g.setStroke(BORDER_STOKE);
-		g.drawRect((int)_x, (int)_y, WIDTH, HEIGHT);
-		
-		IconRepository.getIcon("frameplay.png").paintIcon(
-				Browser._theBrowser.getContentPane(), g, getX() + 25, getY() + 25);
+			fill = new Fill(BASE_COLOR);
+		}
+
+		Point topLeft = new Point((int)_x, (int)_y);
+		Dimension size = new Dimension(WIDTH, HEIGHT);
+		g.drawRectangle(topLeft, size, 0.0, fill, Colour.BLACK, BORDER_STROKE, null);
+		
+		/*IconRepository.getIcon("frameplay.png").paintIcon(
+				Browser._theBrowser.getContentPane(), g, getX() + 25, getY() + 25);*/
+		
+		g.drawImage(IconRepository.getIcon("frameplay.png"), new Point(getX() + 25, getY() + 25));
 		
 	}
@@ -117,16 +119,7 @@
 
 	@Override
-	public void updatePolygon() {
-		
-		_poly = new Polygon();
-
-		int x = (int)_x;
-		int y = (int)_y;
-		
-		_poly.addPoint(x, y);
-		_poly.addPoint(x + WIDTH, y);
-		_poly.addPoint(x + WIDTH, y + HEIGHT);
-		_poly.addPoint(x, y + HEIGHT);
-
+	public Bounds updateBounds()
+	{
+		return new AxisAlignedBoxBounds((int) _x, (int) _y, WIDTH, HEIGHT);
 	}
 
@@ -148,19 +141,19 @@
 	}
 	
-	private void selfDestruct() {
-		
+	private void selfDestruct()
+	{
 		Frame parent = getParent();
 		parent.removeItem(this);
 		
-		if (DisplayIO.getCurrentFrame() == null) return;
+		if (DisplayController.getCurrentFrame() == null) return;
 		
 		Frame audioFrame = null;
 		
 		// Flag as null if frame to play is actually current frame
-		if (frameToPlay != null && frameToPlay.equals(DisplayIO.getCurrentFrame().getName()))
+		if (frameToPlay != null && frameToPlay.equals(DisplayController.getCurrentFrame().getName()))
 			frameToPlay = null;
 		
 		if (frameToPlay == null) {
-			audioFrame = DisplayIO.getCurrentFrame();
+			audioFrame = DisplayController.getCurrentFrame();
 		} else {
 			audioFrame = FrameIO.LoadFrame(frameToPlay);
@@ -199,5 +192,5 @@
 			} else {
 				// Fetch the audio graph for the frame
-				GraphReceiver receiver = new GraphReceiver(DisplayIO.getCurrentFrame());
+				GraphReceiver receiver = new GraphReceiver(DisplayController.getCurrentFrame());
 				ODFrameHeirarchyFetcher.getInstance().doFetch(audioFrame.getName(), receiver);
 				// The callback will later begin playback
@@ -257,5 +250,5 @@
 				// Thus the start frame will be hence taken as a percentage of the whole frame
 				
-				float percent = _x / Browser._theBrowser.getContentPane().getWidth();
+				float percent = _x / EcosystemManager.getGraphicsManager().getWindowSize().getWidth();
 				if (percent < 0) percent = 0;
 				if (percent > 1) percent = 1;
Index: /trunk/src/org/apollo/items/RecordOverdubLauncher.java
===================================================================
--- /trunk/src/org/apollo/items/RecordOverdubLauncher.java	(revision 1101)
+++ /trunk/src/org/apollo/items/RecordOverdubLauncher.java	(revision 1102)
@@ -1,10 +1,3 @@
 package org.apollo.items;
-
-import java.awt.Color;
-import java.awt.GradientPaint;
-import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.Polygon;
-import java.awt.Stroke;
 
 import org.apollo.ApolloSystem;
@@ -12,6 +5,16 @@
 import org.apollo.io.IconRepository;
 import org.apollo.widgets.SampleRecorder;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.GradientFill;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.Bounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.Item;
@@ -23,9 +26,9 @@
 		private static int WIDTH = 80;
 		private static int HEIGHT = 80;
-		private static Stroke BORDER_STOKE = Strokes.SOLID_1;
+		private static Stroke BORDER_STROKE = Strokes.SOLID_1;
 		private int countdown;
 		
-		private static final Color BASE_COLOR = new Color(255, 100, 100);
-		private static final Color HIGHLIGHT_COLOR = new Color(253, 255, 201);
+		private static final Colour BASE_COLOR = Colour.FromRGB255(255, 100, 100);
+		private static final Colour HIGHLIGHT_COLOR = Colour.FromRGB255(253, 255, 201);
 		
 		public RecordOverdubLauncher(int countdown) {
@@ -49,28 +52,26 @@
 
 		@Override
-		public void paint(Graphics2D g) {
+		public void paint() {
 			if (Browser._theBrowser == null) return;
 			
-			Paint restore = g.getPaint();
+			GraphicsManager g = EcosystemManager.getGraphicsManager();
 			
+			Fill fill = null;
 			if (ApolloSystem.useQualityGraphics) {
-				GradientPaint gp = new GradientPaint(
-						_x + (WIDTH / 2), _y, HIGHLIGHT_COLOR,
-						_x + (WIDTH / 2), _y + HEIGHT - (HEIGHT / 5), BASE_COLOR);
-				g.setPaint(gp);
+				Point fromPoint = new Point(_x + (WIDTH / 2), _y);
+				Point toPoint = new Point(_x + (WIDTH / 2), _y + HEIGHT - (HEIGHT / 5));
+				fill = new GradientFill(HIGHLIGHT_COLOR, fromPoint, BASE_COLOR, toPoint);
 			} else {
-				g.setColor(BASE_COLOR);
+				fill = new Fill(BASE_COLOR);
 			}
 			
-			g.fillRect((int)_x, (int)_y, WIDTH, HEIGHT);
+			Point topLeft = new Point((int)_x, (int)_y);
+			Dimension size = new Dimension(WIDTH, HEIGHT);
+			g.drawRectangle(topLeft, size, 0.0, fill, Colour.BLACK, BORDER_STROKE, null);
 			
-			g.setPaint(restore);
+			/*IconRepository.getIcon("recordplay.png").paintIcon(
+					Browser._theBrowser.getContentPane(), g, getX() + 25, getY() + 25);*/
 			
-			g.setColor(Color.BLACK);
-			g.setStroke(BORDER_STOKE);
-			g.drawRect((int)_x, (int)_y, WIDTH, HEIGHT);
-			
-			IconRepository.getIcon("recordplay.png").paintIcon(
-					Browser._theBrowser.getContentPane(), g, getX() + 25, getY() + 25);
+			g.drawImage(IconRepository.getIcon("recordplay.png"), new Point(getX() + 25, getY() + 25));
 			
 		}
@@ -92,16 +93,7 @@
 
 		@Override
-		public void updatePolygon() {
-			
-			_poly = new Polygon();
-
-			int x = (int)_x;
-			int y = (int)_y;
-			
-			_poly.addPoint(x, y);
-			_poly.addPoint(x + WIDTH, y);
-			_poly.addPoint(x + WIDTH, y + HEIGHT);
-			_poly.addPoint(x, y + HEIGHT);
-
+		public Bounds updateBounds()
+		{
+			return new AxisAlignedBoxBounds((int) _x, (int) _y, WIDTH, HEIGHT);
 		}
 
@@ -128,5 +120,5 @@
 			parent.removeItem(this);
 			
-			Frame currentFrame = DisplayIO.getCurrentFrame();
+			Frame currentFrame = DisplayController.getCurrentFrame();
 			
 			if (currentFrame != null) {
Index: /trunk/src/org/apollo/meldex/PitchTracker.java
===================================================================
--- /trunk/src/org/apollo/meldex/PitchTracker.java	(revision 1101)
+++ /trunk/src/org/apollo/meldex/PitchTracker.java	(revision 1102)
@@ -3,5 +3,4 @@
 import java.util.ArrayList;
 
-@SuppressWarnings("unchecked") // code in java 1.4
 public class PitchTracker
 {
@@ -14,5 +13,5 @@
 
     // The pitch data
-    ArrayList pitchData;
+    ArrayList<PitchValue> pitchData;
 
     // Our lovely Pitch Period Estimators
@@ -26,5 +25,5 @@
 
 
-    public ArrayList process(byte[] rawData, int rawLength, int rawSampleRate)
+    public ArrayList<PitchValue> process(byte[] rawData, int rawLength, int rawSampleRate)
     {
 	// Save the sample rate of the loaded sample
@@ -32,5 +31,5 @@
 
 	// Allocate a new pitch data array to store our pitch values
-	pitchData = new ArrayList();
+	pitchData = new ArrayList<PitchValue>();
 
 	// Reset our 6 pitch period estimators
Index: /trunk/src/org/apollo/meldex/PitchValue.java
===================================================================
--- /trunk/src/org/apollo/meldex/PitchValue.java	(revision 1101)
+++ /trunk/src/org/apollo/meldex/PitchValue.java	(revision 1102)
@@ -11,6 +11,6 @@
     public PitchValue(double per, int pos)
     {
-	period = per;
-	position = pos;
+		period = per;
+		position = pos;
     }
 }
Index: /trunk/src/org/apollo/meldex/RogTrack.java
===================================================================
--- /trunk/src/org/apollo/meldex/RogTrack.java	(revision 1101)
+++ /trunk/src/org/apollo/meldex/RogTrack.java	(revision 1102)
@@ -1,12 +1,12 @@
 package org.apollo.meldex;
-
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.ArrayList;
-import javax.swing.JOptionPane;
-
-@SuppressWarnings("unchecked") // code in java 1.4
+
+import org.expeditee.gio.EcosystemManager;
+
 public class RogTrack
 {
@@ -20,5 +20,5 @@
 
     // Data representing the track events
-    ArrayList trackData = new ArrayList();
+    ArrayList<RogTrackEvent> trackData = new ArrayList<RogTrackEvent>();
 
 
@@ -217,5 +217,5 @@
 	int track_len = trackData.size();
 
-	ArrayList filtered_td = new ArrayList();
+	ArrayList<RogTrackEvent> filtered_td = new ArrayList<RogTrackEvent>();
 
 	for (int i = 0; i < track_len; i++) {
@@ -235,5 +235,5 @@
 	}
 
-	ArrayList me_list = new ArrayList();
+	ArrayList<MelodyEvent> me_list = new ArrayList<MelodyEvent>();
 
 	for (int i = 0; i < filtered_track_len-1; i++) {
@@ -283,25 +283,34 @@
     public boolean loadFromFile(File rogFile)
     {
-	try {
-	    // Open the file with a FileInputStream, ready for parsing
-	    FileInputStream fileIn = new FileInputStream(rogFile);
-
-	    // Get the number of bytes in the file
-	    int rogLength = fileIn.available();
-
-	    // Create a buffer to store the file, and read the file into it
-	    byte[] rogData = new byte[rogLength];
-	    fileIn.read(rogData, 0, rogLength);
-
-	    // Parse the .rog file
-	    parseFile(rogData, rogLength);
-	}
-	catch (Exception ex) {
-	    JOptionPane.showMessageDialog(null, "Exception occurred reading file.\n\n" + ex);
-	    return false;
-	}
-
-	// File loaded successfully
-	return true;
+    	boolean success = true;
+    	FileInputStream fileIn = null;
+		try {
+		    // Open the file with a FileInputStream, ready for parsing
+		    fileIn = new FileInputStream(rogFile);
+	
+		    // Get the number of bytes in the file
+		    int rogLength = fileIn.available();
+	
+		    // Create a buffer to store the file, and read the file into it
+		    byte[] rogData = new byte[rogLength];
+		    fileIn.read(rogData, 0, rogLength);
+	
+		    // Parse the .rog file
+		    parseFile(rogData, rogLength);
+		} catch (Exception ex) {
+			EcosystemManager.getGraphicsManager().showDialog("Exception", "Exception occurred reading file.\n\n" + ex);
+			success = false;
+		} finally {
+			if (fileIn != null) {
+				try {
+					fileIn.close();
+				} catch (IOException e) {
+					// If an IO exception occurs when closing the file, just sweep it under the rug
+				}
+			}
+		}
+	
+		// File loaded successfully
+		return success;
     }
 
@@ -406,5 +415,5 @@
 	    // Check that the noteName is valid
 	    if (noteName < 'A' || noteName > 'G') {
-		JOptionPane.showMessageDialog(null, "Parsing error - check that the Rog file is valid.");
+		EcosystemManager.getGraphicsManager().showDialog("Exception", "Parsing error - check that the Rog file is valid.");
 		return;
 	    }
@@ -497,5 +506,5 @@
 	}
 	catch (Exception ex) {
-	    JOptionPane.showMessageDialog(null, "Exception occurred writing to file.\n\n" + ex);
+	    EcosystemManager.getGraphicsManager().showDialog("Exception", "Exception occurred writing to file.\n\n" + ex);
 	    return false;
 	}
Index: /trunk/src/org/apollo/meldex/StandardisedMelody.java
===================================================================
--- /trunk/src/org/apollo/meldex/StandardisedMelody.java	(revision 1101)
+++ /trunk/src/org/apollo/meldex/StandardisedMelody.java	(revision 1102)
@@ -93,5 +93,9 @@
 
 	    // Read the melody from the melody file
-	    return (StandardisedMelody) melodyFileStream.readObject();
+	    StandardisedMelody standardisedMelody = (StandardisedMelody) melodyFileStream.readObject();
+	    
+	    melodyFileStream.close();
+	    
+	    return standardisedMelody;
 
     }
Index: /trunk/src/org/apollo/meldex/Transcriber.java
===================================================================
--- /trunk/src/org/apollo/meldex/Transcriber.java	(revision 1101)
+++ /trunk/src/org/apollo/meldex/Transcriber.java	(revision 1102)
@@ -4,5 +4,4 @@
 import java.util.ArrayList;
 
-@SuppressWarnings("unchecked") // code in java 1.4
 public class Transcriber
 {
@@ -255,5 +254,5 @@
     {
 	// Pitch track the note
-	ArrayList pitchData = pitchTracker.process(data, length, sampleRate);
+	ArrayList<PitchValue> pitchData = pitchTracker.process(data, length, sampleRate);
 
 	// Average the pitch data
@@ -265,13 +264,13 @@
 
 
-    private int averagePitchData(ArrayList pitchData)
+    private int averagePitchData(ArrayList<PitchValue> pitchData)
     {
 	// Loop through the pitch values...
 	int i = 0, k = 0;
 	while (i < (pitchData.size() - 1)) {
-	    int startPos = ((PitchValue) pitchData.get(i)).position;
-	    double period = ((PitchValue) pitchData.get(i)).period;
+	    int startPos = pitchData.get(i).position;
+	    double period = pitchData.get(i).period;
 	    double averagePeriod = period;
-	    double runningPeriod = ((PitchValue) pitchData.get(i+1)).position - startPos;
+	    double runningPeriod = pitchData.get(i+1).position - startPos;
 	    double numPeriods = runningPeriod / period;
 
@@ -280,6 +279,6 @@
 	    while ((i+j) < (pitchData.size() - 1)) {
 		// Get the next pitch estimate
-		period = ((PitchValue) pitchData.get(i+j)).period;
-		int position = ((PitchValue) pitchData.get(i+j)).position;
+		period = pitchData.get(i+j).period;
+		int position = pitchData.get(i+j).position;
 
 		// Make sure that this period is covered by the average so far
@@ -289,5 +288,5 @@
 
 		// Stop if we have covered more than 20 msec
-		int nextPos = ((PitchValue) pitchData.get(i+j+1)).position;
+		int nextPos = pitchData.get(i+j+1).position;
 		// if ((nextPos - startPos) >= 445) {  // !! PURE-ROG !!
 		if ((nextPos - startPos) >= (sampleRate * 0.02)) {
@@ -315,5 +314,5 @@
 
 
-    private int calculateHistogram(ArrayList data, int length)
+    private int calculateHistogram(ArrayList<PitchValue> data, int length)
     {
 	// This probably shouldn't be a constant
@@ -328,7 +327,7 @@
 	// Calculate the histogram data
 	for (int i = 0; i < (length - 1); i++) {
-	    double period = ((PitchValue) data.get(i)).period;
-	    double position = ((PitchValue) data.get(i)).position;
-	    double periodLength = ((PitchValue) data.get(i+1)).position - position;
+	    double period = data.get(i).period;
+	    double position = data.get(i).position;
+	    double periodLength = data.get(i+1).position - position;
 
 	    // We only need to do this if the pitch does not equal zero
Index: /trunk/src/org/apollo/meldex/WavSample.java
===================================================================
--- /trunk/src/org/apollo/meldex/WavSample.java	(revision 1101)
+++ /trunk/src/org/apollo/meldex/WavSample.java	(revision 1102)
@@ -8,7 +8,7 @@
 import javax.sound.sampled.AudioInputStream;
 import javax.sound.sampled.AudioSystem;
-import javax.swing.JOptionPane;
-
-@SuppressWarnings("unchecked") // code in java 1.4
+
+import org.expeditee.gio.EcosystemManager;
+
 public class WavSample
 {
@@ -68,5 +68,5 @@
 	}
 	catch (Exception ex) {
-	    JOptionPane.showMessageDialog(null, "Exception occurred creating sample.\n\n" + ex);
+	    EcosystemManager.getGraphicsManager().showDialog("Exception", "Exception occurred creating sample.\n\n" + ex);
 	    return false;
 	}
@@ -90,5 +90,5 @@
 	    }
 	    catch (Exception ex) {
-		JOptionPane.showMessageDialog(null, "Exception occurred reloading sample.\n\n" + ex);
+	    EcosystemManager.getGraphicsManager().showDialog("Exception", "Exception occurred reloading sample.\n\n" + ex);
 		return false;
 	    }
@@ -101,5 +101,5 @@
 	    }
 	    catch (Exception ex) {
-		JOptionPane.showMessageDialog(null, "Exception occurred resetting audio stream.\n\n" + ex);
+	    EcosystemManager.getGraphicsManager().showDialog("Exception", "Exception occurred resetting audio stream.\n\n" + ex);
 		return false;
 	    }
@@ -172,5 +172,5 @@
 	if (format.getSampleSizeInBits() == 8) {
 	    if (format.getEncoding().equals(AudioFormat.Encoding.PCM_SIGNED)) {
-		JOptionPane.showMessageDialog(null, "Oops! Internal Error: Unexpected audio format (signed 8-bit).");
+	    EcosystemManager.getGraphicsManager().showDialog("Exception", "Oops! Internal Error: Unexpected audio format (signed 8-bit).");
 		return null;
 	    }
@@ -178,5 +178,5 @@
 	if (format.getSampleSizeInBits() == 16) {
 	    if (format.getEncoding().equals(AudioFormat.Encoding.PCM_UNSIGNED)) {
-		JOptionPane.showMessageDialog(null, "Oops! Internal Error: Unexpected audio format (unsigned 16-bit).");
+	    EcosystemManager.getGraphicsManager().showDialog("Exception", "Oops! Internal Error: Unexpected audio format (unsigned 16-bit).");
 		return null;
 	    }
@@ -188,5 +188,5 @@
 
 	// Create a new list to store the standardised sample values
-	ArrayList stdTemp = new ArrayList();
+	ArrayList<Integer> stdTemp = new ArrayList<Integer>();
 
 	// Simply pick values from the sample at the frequency specified
@@ -218,36 +218,36 @@
 
 
-    private static ArrayList toStandardEndian(AudioFormat format, ArrayList inData)
-    {
-	// Endian details do not apply to 8-bit samples, so no conversion needed
-	if (format.getSampleSizeInBits() == 8) {
-	    return inData;
-	}
-
-	// Create a new list to store the results
-	ArrayList outData = new ArrayList();
-
-	// Simply convert each number in the sample to the endian form for the current system
-	for (int i = 0; i < inData.size(); i += 2) {
-
-	    int MSB, LSB;
-	    if (format.isBigEndian()) {
-		MSB = ((Integer) inData.get(i)).intValue();    // First byte is MSB (high order)
-		LSB = ((Integer) inData.get(i+1)).intValue();  // Second byte is LSB (low order)
-	    }
-	    else {
-		LSB = ((Integer) inData.get(i)).intValue();    // First byte is LSB (low order)
-		MSB = ((Integer) inData.get(i+1)).intValue();  // Second byte is MSB (high order)
-	    }
-
-	    int val = (MSB << 8) + (LSB & 255);
-	    outData.add(new Integer(val));
-	}
-
-	return outData;
-    }
-
-
-    private static ArrayList toUnsignedValues(AudioFormat format, ArrayList inData)
+    private static ArrayList<Integer> toStandardEndian(AudioFormat format, ArrayList<Integer> inData)
+    {
+		// Endian details do not apply to 8-bit samples, so no conversion needed
+		if (format.getSampleSizeInBits() == 8) {
+		    return inData;
+		}
+	
+		// Create a new list to store the results
+		ArrayList<Integer> outData = new ArrayList<Integer>();
+	
+		// Simply convert each number in the sample to the endian form for the current system
+		for (int i = 0; i < inData.size(); i += 2) {
+	
+		    int MSB, LSB;
+		    if (format.isBigEndian()) {
+			MSB = ((Integer) inData.get(i)).intValue();    // First byte is MSB (high order)
+			LSB = ((Integer) inData.get(i+1)).intValue();  // Second byte is LSB (low order)
+		    }
+		    else {
+			LSB = ((Integer) inData.get(i)).intValue();    // First byte is LSB (low order)
+			MSB = ((Integer) inData.get(i+1)).intValue();  // Second byte is MSB (high order)
+		    }
+	
+		    int val = (MSB << 8) + (LSB & 255);
+		    outData.add(new Integer(val));
+		}
+	
+		return outData;
+    }
+
+
+    private static ArrayList<Integer> toUnsignedValues(AudioFormat format, ArrayList<Integer> inData)
     {
 	// PCM_UNSIGNED samples are what we want, so no conversion needed
@@ -257,5 +257,5 @@
 
 	// Create a new list to store the results
-	ArrayList outData = new ArrayList();
+	ArrayList<Integer> outData = new ArrayList<Integer>();
 
 	// Simply convert each signed number in the sample to an unsigned value
@@ -275,5 +275,5 @@
 
 
-    private static ArrayList to8bit(AudioFormat format, ArrayList inData)
+    private static ArrayList<Integer> to8bit(AudioFormat format, ArrayList<Integer> inData)
     {
 	// 8-bit data is what we want, so no conversion necessary
@@ -283,5 +283,5 @@
 
 	// Create a new list to store the results
-	ArrayList outData = new ArrayList();
+	ArrayList<Integer> outData = new ArrayList<Integer>();
 
 	// Simply reduce each value in the sample to an 8-bit value
@@ -298,5 +298,5 @@
 
 
-    private static ArrayList toMono(AudioFormat format, ArrayList inData)
+    private static ArrayList<Integer> toMono(AudioFormat format, ArrayList<Integer> inData)
     {
 	// Mono-channel data is what we want, so no conversion necessary
@@ -306,5 +306,5 @@
 
 	// Create a new list to store the results
-	ArrayList outData = new ArrayList();
+	ArrayList<Integer> outData = new ArrayList<Integer>();
 
 	// Simply average all of the channels for each frame
@@ -362,10 +362,10 @@
 	try {
 	    if (AudioSystem.write(audioData, AudioFileFormat.Type.WAVE, outFile) == -1) {
-		JOptionPane.showMessageDialog(null, "Problem occurred writing to file.");
+	    EcosystemManager.getGraphicsManager().showDialog("Exception", "Problem occurred writing to file.");
 		return false;
 	    }
 	}
 	catch (Exception ex) {
-	    JOptionPane.showMessageDialog(null, "Exception occurred saving file.\n\n" + ex);
+	    EcosystemManager.getGraphicsManager().showDialog("Exception", "Exception occurred saving file.\n\n" + ex);
 	    return false;
 	}
Index: /trunk/src/org/apollo/mvc/AbstractSubject.java
===================================================================
--- /trunk/src/org/apollo/mvc/AbstractSubject.java	(revision 1101)
+++ /trunk/src/org/apollo/mvc/AbstractSubject.java	(revision 1102)
@@ -4,5 +4,5 @@
 import java.util.Set;
 
-import javax.swing.SwingUtilities;
+import org.expeditee.gio.EcosystemManager;
 
 /**
@@ -66,5 +66,5 @@
 	protected final void fireSubjectChangedLaterOnSwingThread(final SubjectChangedEvent event) {
 		
-		SwingUtilities.invokeLater(new Runnable() {
+		EcosystemManager.getMiscManager().runOnGIOThread(new Runnable() {
 			public void run() {
 				fireSubjectChanged(event);
Index: /trunk/src/org/apollo/mvc/SwingEventQueue.java
===================================================================
--- /trunk/src/org/apollo/mvc/SwingEventQueue.java	(revision 1101)
+++ /trunk/src/org/apollo/mvc/SwingEventQueue.java	(revision 1102)
@@ -4,10 +4,10 @@
 import java.util.Queue;
 
-import javax.swing.SwingUtilities;
+import org.expeditee.gio.EcosystemManager;
 
 /**
  * If your observer needs to reacts to events on the swing thread (i.e. interacting with swing
  * objects somewhere in the event) and the observed subject raised events on other threads,
- * this class thunnels all events into the swing thread and ensures that they are raised in
+ * this class tunnels all events into the swing thread and ensures that they are raised in
  * the swing thread (thread safety!).
  * 
@@ -26,5 +26,5 @@
 	/**
 	 * COnstructor.
-	 * @param target The SwingThreadedObserver instance to thunnel events to on the swing thread.
+	 * @param target The SwingThreadedObserver instance to tunnel events to on the swing thread.
 	 */
 	public SwingEventQueue(SwingThreadedObserver target) {
@@ -44,5 +44,5 @@
 			eventQueue.add(new QueudEvent(source, event));
 		}
-		SwingUtilities.invokeLater(eventProccessor);
+		EcosystemManager.getMiscManager().runOnGIOThread(eventProccessor);
 	}
 
Index: /trunk/src/org/apollo/util/AudioPurger.java
===================================================================
--- /trunk/src/org/apollo/util/AudioPurger.java	(revision 1101)
+++ /trunk/src/org/apollo/util/AudioPurger.java	(revision 1102)
@@ -10,5 +10,4 @@
 import org.apollo.io.AudioPathManager;
 import org.apollo.widgets.SampledTrack;
-import org.expeditee.settings.UserSettings;
 import org.expeditee.settings.folders.FolderSettings;
 import org.expeditee.items.ItemUtils;
Index: /trunk/src/org/apollo/util/ExpediteeFileTextSearch.java
===================================================================
--- /trunk/src/org/apollo/util/ExpediteeFileTextSearch.java	(revision 1101)
+++ /trunk/src/org/apollo/util/ExpediteeFileTextSearch.java	(revision 1102)
@@ -1,5 +1,4 @@
 package org.apollo.util;
 
-import java.awt.Point;
 import java.io.BufferedReader;
 import java.io.FileNotFoundException;
@@ -8,4 +7,6 @@
 import java.util.LinkedList;
 import java.util.List;
+
+import org.expeditee.core.Point;
 
 /**
Index: /trunk/src/org/apollo/util/ODFrameHeirarchyFetcher.java
===================================================================
--- /trunk/src/org/apollo/util/ODFrameHeirarchyFetcher.java	(revision 1101)
+++ /trunk/src/org/apollo/util/ODFrameHeirarchyFetcher.java	(revision 1102)
@@ -3,10 +3,9 @@
 import java.util.LinkedList;
 import java.util.Queue;
-
-import javax.swing.SwingUtilities;
 
 import org.apollo.audio.structure.OverdubbedFrame;
 import org.apollo.audio.structure.TrackGraphLoopException;
 import org.apollo.audio.structure.AudioStructureModel;
+import org.expeditee.gio.EcosystemManager;
 import org.expeditee.gui.FrameIO;
 
@@ -139,6 +138,6 @@
 				} 
 				
-				// Run result notiofaction for this request on swing thread
-				SwingUtilities.invokeLater(request);
+				// Run result notification for this request on swing thread
+				EcosystemManager.getMiscManager().runOnGIOThread(request);
 				
 			}
Index: /trunk/src/org/apollo/util/PopupReaper.java
===================================================================
--- /trunk/src/org/apollo/util/PopupReaper.java	(revision 1101)
+++ /trunk/src/org/apollo/util/PopupReaper.java	(revision 1102)
@@ -13,5 +13,5 @@
 import javax.swing.SwingUtilities;
 
-import org.expeditee.gui.MouseEventRouter;
+import org.expeditee.gio.swing.MouseEventRouter;
 import org.expeditee.gui.Popup;
 import org.expeditee.gui.PopupManager;
@@ -19,11 +19,11 @@
 
 /**
- * Yet another daemon .. whos job is to hide popups after their lifetimes have passed
+ * Yet another daemon .. whose job is to hide popups after their lifetimes have passed
  * 
  * @author Brook Novak
  */
 
-public class PopupReaper {
-	
+public class PopupReaper
+{
 	private Map<Popup, TemporaryPopup> tempPopups = new HashMap<Popup, TemporaryPopup>();// SHARED RESOURCE - the locker
 
@@ -31,7 +31,11 @@
 	
 	private static PopupReaper instance = new PopupReaper();
-	private PopupReaper() {
-	}
-	public  static PopupReaper getInstance() {
+	
+	private PopupReaper()
+	{
+	}
+	
+	public  static PopupReaper getInstance()
+	{
 		return instance;
 	}
@@ -62,5 +66,6 @@
 	 * 
 	 */
-	public void initPopupLifetime(Popup p, PopupAnimator hideAnimation, int lifetime) {
+	public void initPopupLifetime(Popup p, PopupAnimator hideAnimation, int lifetime)
+	{
 		if (p == null) throw new NullPointerException("p");
 		if (lifetime < 0) throw new IllegalArgumentException("lifetime < 0");
@@ -87,9 +92,5 @@
 				reaper.interrupt();
 			}
-			
-
-			
-		}
-		
+		}
 	}
 	
@@ -115,5 +116,6 @@
 	 * 
 	 */
-	public boolean revivePopup(Popup p, int lifetime) {
+	public boolean revivePopup(Popup p, int lifetime)
+	{
 		if (p == null) throw new NullPointerException("p");
 		if (lifetime < 0) throw new IllegalArgumentException("lifetime < 0");
@@ -134,7 +136,8 @@
 
 	
-	private class ReapDaemon extends Thread {
-		
-		ReapDaemon() {
+	private class ReapDaemon extends Thread
+	{
+		ReapDaemon()
+		{
 			super("Popup Reaper");
 			super.setPriority(Thread.MIN_PRIORITY);
@@ -142,6 +145,6 @@
 		}
 	
-		public void run() {
-			
+		public void run()
+		{
 			while (true) {
 			
@@ -166,6 +169,6 @@
 		 * 		A Positive wait time, or a negative for nothing to to wait on.
 		 */
-		private long reap() {
-
+		private long reap()
+		{
 			Collection<TemporaryPopup> snapshot;
 			
@@ -226,10 +229,11 @@
 	 *
 	 */
-	private class DoHide implements Runnable {
-		
+	private class DoHide implements Runnable
+	{
 		private TemporaryPopup tempPopup;
 		public boolean didHide = false;
 		
-		public DoHide(TemporaryPopup tempPopup) {
+		public DoHide(TemporaryPopup tempPopup)
+		{
 			this.tempPopup = tempPopup;
 		}
@@ -244,5 +248,6 @@
 		 * 		True if screenPoint is over c.
 		 */
-		private boolean isPointInComponant(Component c, Point screenPoint) {
+		private boolean isPointInComponant(Component c, Point screenPoint)
+		{
 			assert(c != null);
 			assert(screenPoint != null);
@@ -257,17 +262,15 @@
 		}
 	
-		public void run() {
+		public void run()
+		{
 			assert(tempPopup != null);
 			
 			MouseEvent me = MouseEventRouter.getCurrentMouseEvent();
 			if (me != null) {
-				
-				if (isPointInComponant(tempPopup.popup, me.getLocationOnScreen()))
-					return;
+				if (isPointInComponant(tempPopup.popup, me.getLocationOnScreen())) return;
 				
 				Component invoker = PopupManager.getInstance().getInvoker(tempPopup.popup);
-				if (invoker != null && isPointInComponant(invoker, me.getLocationOnScreen()))
-					return;
-				
+				
+				if (invoker != null && isPointInComponant(invoker, me.getLocationOnScreen())) return;
 			}
 
@@ -289,6 +292,6 @@
 	 *
 	 */
-	private class TemporaryPopup implements Comparable {
-
+	private class TemporaryPopup implements Comparable<TemporaryPopup>
+	{
 		private Popup popup;
 		private PopupAnimator hideAnim;
@@ -310,5 +313,6 @@
 		 *
 		 */
-		public TemporaryPopup(Popup popup, PopupAnimator anim, int lifetime) {
+		public TemporaryPopup(Popup popup, PopupAnimator anim, int lifetime)
+		{
 			assert(popup != null);
 			assert(lifetime >= 0);
@@ -320,5 +324,6 @@
 		}
 
-		public void setNewLifetime(int lifetime) {
+		public void setNewLifetime(int lifetime)
+		{
 			assert(lifetime >= 0);
 			this.lifetime = lifetime;
@@ -326,9 +331,11 @@
 		}
 		
-		public void resetLifetime() {
+		public void resetLifetime()
+		{
 			setNewLifetime(lifetime);
 		}
 		
-		public long getDelay() {
+		public long getDelay()
+		{
 			return destructionTime - System.currentTimeMillis();
 		}
@@ -337,13 +344,11 @@
 		 * {@inheritDoc}
 		 */
-		public int compareTo(Object o) {
-			
-			long dt2 = ((TemporaryPopup)o).destructionTime;
-			
-			if (destructionTime < dt2)
-		         return -1;
-			
-		      if (destructionTime > dt2)
-		         return 1;
+		public int compareTo(TemporaryPopup o)
+		{
+			long dt2 = o.destructionTime;
+			
+			if (destructionTime < dt2) return -1;
+			
+		    if (destructionTime > dt2) return 1;
 		      
 			return 0;
Index: /trunk/src/org/apollo/util/ProbeDaemon.java
===================================================================
--- /trunk/src/org/apollo/util/ProbeDaemon.java	(revision 1101)
+++ /trunk/src/org/apollo/util/ProbeDaemon.java	(revision 1102)
@@ -7,5 +7,5 @@
 import org.apollo.audio.util.Timeline;
 import org.apollo.gui.FrameLayoutDaemon;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 
 public class ProbeDaemon extends Thread {
@@ -46,5 +46,5 @@
 			String timeline = "none";
 			Timeline tl = FrameLayoutDaemon.getInstance().getLastComputedTimeline();
-			if (tl != null && DisplayIO.getCurrentFrame() == FrameLayoutDaemon.getInstance().getTimelineOwner()) {
+			if (tl != null && DisplayController.getCurrentFrame() == FrameLayoutDaemon.getInstance().getTimelineOwner()) {
 				timeline = tl.toString();
 			}
Index: /trunk/src/org/apollo/util/TextItemSearchResult.java
===================================================================
--- /trunk/src/org/apollo/util/TextItemSearchResult.java	(revision 1101)
+++ /trunk/src/org/apollo/util/TextItemSearchResult.java	(revision 1102)
@@ -1,6 +1,7 @@
 package org.apollo.util;
 
-import java.awt.Point;
 import java.util.List;
+
+import org.expeditee.core.Point;
 /**
  * Represents a single mutable search result.
Index: /trunk/src/org/apollo/util/TrackModelLoadManager.java
===================================================================
--- /trunk/src/org/apollo/util/TrackModelLoadManager.java	(revision 1101)
+++ /trunk/src/org/apollo/util/TrackModelLoadManager.java	(revision 1102)
@@ -3,10 +3,8 @@
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
 import java.util.HashSet;
 import java.util.Set;
 
 import javax.sound.sampled.UnsupportedAudioFileException;
-import javax.swing.SwingUtilities;
 
 import org.apollo.audio.SampledTrackModel;
@@ -14,4 +12,6 @@
 import org.apollo.io.LoadedAudioData;
 import org.apollo.mvc.Observer;
+import org.expeditee.core.BlockingRunnable;
+import org.expeditee.gio.EcosystemManager;
 import org.expeditee.items.widgets.HeavyDutyInteractiveWidget;
 import org.expeditee.items.widgets.WidgetCacheManager;
@@ -124,8 +124,6 @@
 			
 			try {
-				SwingUtilities.invokeAndWait(locator);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			} catch (InvocationTargetException e) {
+				EcosystemManager.getMiscManager().runOnGIOThread(locator);
+			} catch (Exception e) {
 				e.printStackTrace();
 			}
@@ -166,5 +164,5 @@
 	 * Look in expeditee memory - this should be quick - will hold up the user
 	 */
-	private class CachedTrackModelLocator implements Runnable
+	private class CachedTrackModelLocator extends BlockingRunnable
 	{
 		private String localfileName;
@@ -176,5 +174,5 @@
 		}
 		
-		public void run() {
+		public void execute() {
 		
 			// Exploit knowledge that all SampledTrack are Cached HDW
Index: /trunk/src/org/apollo/widgets/AudioConfiguration.java
===================================================================
--- /trunk/src/org/apollo/widgets/AudioConfiguration.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/AudioConfiguration.java	(revision 1102)
@@ -31,11 +31,11 @@
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
-
-public class AudioConfiguration extends InteractiveWidget implements Observer {
+import org.expeditee.items.widgets.SwingWidget;
+
+public class AudioConfiguration extends SwingWidget implements Observer {
 	
 	private static MixerItem[] inputMixerItems = null;
 
-	private JComboBox inputMixureCombo;
+	private JComboBox<MixerItem> inputMixureCombo;
 	private JSlider masterVolumeSlider;
 	private JCheckBox masterMuteCheckBox;
@@ -48,5 +48,5 @@
 		Font descFont = new Font("Arial", Font.PLAIN, 12);
 
-		inputMixureCombo = new JComboBox(getInputMixerItems());
+		inputMixureCombo = new JComboBox<MixerItem>(getInputMixerItems());
 		
 		inputMixureCombo.addActionListener( new ActionListener() {
Index: /trunk/src/org/apollo/widgets/FramePlayer.java
===================================================================
--- /trunk/src/org/apollo/widgets/FramePlayer.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/FramePlayer.java	(revision 1102)
@@ -1,5 +1,4 @@
 package org.apollo.widgets;
 
-import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.GridBagConstraints;
@@ -21,5 +20,4 @@
 import javax.swing.ComboBoxModel;
 import javax.swing.DefaultComboBoxModel;
-import javax.swing.Icon;
 import javax.swing.JButton;
 import javax.swing.JComboBox;
@@ -45,13 +43,15 @@
 import org.apollo.util.ApolloSystemLog;
 import org.apollo.util.AudioMath;
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.DisplayIOObserver;
-import org.expeditee.gui.FrameGraphics;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.swing.SwingMiscManager;
+import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.DisplayObserver;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.MessageBay;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.SwingWidget;
 
 /**
@@ -61,6 +61,6 @@
  *
  */
-public class FramePlayer extends InteractiveWidget 
-	implements Observer, MultitrackLoadListener, ActionListener, DisplayIOObserver {
+public class FramePlayer extends SwingWidget 
+	implements Observer, MultitrackLoadListener, ActionListener, DisplayObserver {
 
 	private static final int BUTTON_SIZE = 40;
@@ -73,5 +73,5 @@
 	private JButton rewindButton;
 	private JButton playLauncherButton;
-	private JComboBox frameSelection;
+	private JComboBox<String> frameSelection;
 	private JToggleButton muteButton;
 	private JSlider volumeSlider;
@@ -86,5 +86,5 @@
 	public static String FRAME_PLAYERMASTER_CHANNEL_ID = "#$frameplayer#master$";
 	
-	private static final Color LOADING_BORDER_COLOR = new Color(22, 205, 5);
+	private static final Colour LOADING_BORDER_COLOR = Colour.FromRGB255(22, 205, 5);
 	//private static final Color FAILED_MESSAGE_COLOR = Color.RED;
 	//private static final Font MESSAGE_FONT = TrackWidgetCommons.FREESPACE_TRACKNAME_FONT;
@@ -180,5 +180,5 @@
 		playPauseButton = new JButton();
 		playPauseButton.addActionListener(this);
-		playPauseButton.setIcon(IconRepository.getIcon("play.png"));
+		SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("play.png"));
 		playPauseButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		playPauseButton.setToolTipText("Play selection / Pause");
@@ -187,5 +187,5 @@
 		stopButton.setEnabled(false);
 		stopButton.addActionListener(this);
-		stopButton.setIcon(IconRepository.getIcon("stop.png"));
+		SwingMiscManager.setJButtonIcon(stopButton, IconRepository.getIcon("stop.png"));
 		stopButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		stopButton.setToolTipText("Stop playback");
@@ -193,5 +193,5 @@
 		rewindButton = new JButton();
 		rewindButton.addActionListener(this);
-		rewindButton.setIcon(IconRepository.getIcon("rewind.png"));
+		SwingMiscManager.setJButtonIcon(rewindButton, IconRepository.getIcon("rewind.png"));
 		rewindButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		rewindButton.setToolTipText("Rewind to start");
@@ -199,5 +199,5 @@
 		// Icon changes
 		muteButton = new JToggleButton();
-		muteButton.setSelectedIcon(IconRepository.getIcon("volmute.png"));
+		SwingMiscManager.setJButtonIcon(muteButton, IconRepository.getIcon("volmute.png"));
 		muteButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		muteButton.setToolTipText("Toggle mute");
@@ -212,5 +212,5 @@
 		playLauncherButton = new JButton();
 		playLauncherButton.addActionListener(this);
-		playLauncherButton.setIcon(IconRepository.getIcon("frameplay.png"));
+		SwingMiscManager.setJButtonIcon(playLauncherButton, IconRepository.getIcon("frameplay.png"));
 		playLauncherButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
 		playLauncherButton.setToolTipText("Play from a specific position");
@@ -231,5 +231,5 @@
 		volumeSlider.setPreferredSize(new Dimension((3 * BUTTON_SIZE) - (2 * VOLUME_SPACING), BUTTON_SIZE));
 
-		frameSelection = new JComboBox();
+		frameSelection = new JComboBox<String>();
 		frameSelection.setEditable(true);
 		frameSelection.setPreferredSize(new Dimension(4 * BUTTON_SIZE, BUTTON_SIZE));
@@ -304,5 +304,5 @@
 			stopButton.setEnabled(false);
 			playPauseButton.setEnabled(true);
-			playPauseButton.setIcon(IconRepository.getIcon("play.png"));
+			SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("play.png"));
 			playLauncherButton.setEnabled(true);
 
@@ -323,5 +323,5 @@
 			playLauncherButton.setEnabled(true);
 			playPauseButton.setEnabled(true);
-			playPauseButton.setIcon(IconRepository.getIcon("pause.png"));
+			SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("pause.png"));
 
 			setWidgetEdgeThickness(TrackWidgetCommons.PLAYING_TRACK_EDGE_THICKNESS);
@@ -336,5 +336,5 @@
 		
 		invalidateSelf();
-		FrameGraphics.refresh(true);
+		DisplayController.requestRefresh(true);
 	}
 	
@@ -361,5 +361,5 @@
 			MultiTrackPlaybackController.getInstance().addObserver(this); // the core!
 			masterMix.addObserver(this);
-			DisplayIO.addDisplayIOObserver(this);
+			DisplayController.addDisplayObserver(this);
 		
 			// Evaluate the state of this add set the state accordingly
@@ -405,5 +405,5 @@
 			
 			// Remove observers
-			DisplayIO.removeDisplayIOObserver(this);
+			DisplayController.removeDisplayObserver(this);
 			SoundDesk.getInstance().removeObserver(this);
 			MultiTrackPlaybackController.getInstance().removeObserver(this);
@@ -544,10 +544,10 @@
 		if ((frameSelection.getSelectedItem() != null && frameSelection.getSelectedItem().equals(CURRENT_FRAME_SPECIFIER))
 				|| frameSelection.getSelectedItem() == null)
-			return DisplayIO.getCurrentFrame().getName();
+			return DisplayController.getCurrentFrame().getName();
 		
 		String frameSpecifier = (String)frameSelection.getSelectedItem();
 		
 		if (frameSpecifier.isEmpty()) {
-			return DisplayIO.getCurrentFrame().getName();
+			return DisplayController.getCurrentFrame().getName();
 		}
 		
@@ -671,12 +671,12 @@
 			
 			String target = getSelectedFrameName();
-			if (target == DisplayIO.getCurrentFrame().getName()) target = null;
+			if (target == DisplayController.getCurrentFrame().getName()) target = null;
 			
 			// Create the launcher
 			FramePlaybackLauncher launcher = new FramePlaybackLauncher(target);
-			launcher.setPosition(FrameMouseActions.MouseX, FrameMouseActions.MouseY);
+			launcher.setPosition(DisplayController.getMousePosition());
 
 			// Pick it up
-			FrameMouseActions.pickup(launcher);
+			StandardGestureActions.pickup(launcher);
 		}
 		
@@ -687,6 +687,6 @@
 		
 		// Get border color currently used
-		Color oldC = getSource().getBorderColor();
-		Color newC = null;
+		Colour oldC = getSource().getBorderColor();
+		Colour newC = null;
 		
 		if (this.state == PLAYBACK_LOADING) {
@@ -714,5 +714,5 @@
 	private void updateButtonGUI() {
 		
-		Icon newIcon = null;
+		Image newIcon = null;
 		if (volumeSlider.getValue() <= 25) 
 				newIcon = IconRepository.getIcon("vol25.png");
@@ -724,5 +724,5 @@
 				newIcon = IconRepository.getIcon("vol100.png");
 		
-		muteButton.setIcon(newIcon);
+		SwingMiscManager.setJButtonIcon(muteButton, newIcon);
 	}
 	
@@ -783,5 +783,5 @@
 		
 		// Place last visited frames
-		List<String> history = DisplayIO.getUnmodifiableVisitedList();
+		List<String> history = DisplayController.getUnmodifiableVisitedList();
 		
 		for (int i = history.size() - 1; i >= 0; i--) {
@@ -802,5 +802,5 @@
 		}
 		
-	    ComboBoxModel model = new DefaultComboBoxModel(orderedModelData.toArray());
+	    ComboBoxModel<String> model = new DefaultComboBoxModel<String>((String[]) orderedModelData.toArray());
 	    
 	    // Remove helper tags from model data
Index: /trunk/src/org/apollo/widgets/LinkedTrack.java
===================================================================
--- /trunk/src/org/apollo/widgets/LinkedTrack.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/LinkedTrack.java	(revision 1102)
@@ -1,6 +1,4 @@
 package org.apollo.widgets;
 
-import java.awt.Color;
-import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.GradientPaint;
@@ -8,8 +6,5 @@
 import java.awt.Graphics2D;
 import java.awt.Paint;
-import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.Stroke;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -19,5 +14,4 @@
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
-import java.awt.geom.Area;
 import java.awt.geom.Rectangle2D;
 import java.util.LinkedList;
@@ -29,7 +23,7 @@
 import javax.swing.SwingUtilities;
 
+import org.apollo.ApolloGestureActions;
+import org.apollo.ApolloKBMGestureTranslator;
 import org.apollo.ApolloSystem;
-import org.apollo.AudioFrameKeyboardActions;
-import org.apollo.AudioFrameMouseActions;
 import org.apollo.audio.ApolloSubjectChangedEvent;
 import org.apollo.audio.SampledAudioManager;
@@ -62,23 +56,37 @@
 import org.apollo.util.Mutable;
 import org.apollo.util.ODFrameHeirarchyFetcher;
-import org.apollo.util.PopupReaper;
 import org.apollo.util.StringEx;
 import org.apollo.util.ODFrameHeirarchyFetcher.ODFrameReceiver;
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.EnforcedClipStack.EnforcedClipKey;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Font;
+import org.expeditee.core.Line;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.TextLayout;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.TextLayoutManager;
+import org.expeditee.gio.swing.MouseEventRouter;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
-import org.expeditee.gui.MouseEventRouter;
 import org.expeditee.gui.PopupManager;
 import org.expeditee.items.Item;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
 import org.expeditee.items.widgets.InteractiveWidgetInitialisationFailedException;
 import org.expeditee.items.widgets.InteractiveWidgetNotAvailableException;
-
-public class LinkedTrack extends InteractiveWidget implements ODFrameReceiver, Observer, MultitrackLoadListener, PlaybackClockListener {
+import org.expeditee.items.widgets.SwingWidget;
+import org.expeditee.items.widgets.Widget;
+
+public class LinkedTrack extends SwingWidget implements ODFrameReceiver, Observer, MultitrackLoadListener, PlaybackClockListener {
 	
 	private String virtualFilename; // immutable 
@@ -92,5 +100,4 @@
 	
 	private PlaybackPopup playbackControlPopup = null;
-
 
 	// private SoundDeskPopup soundDeskPopup = null;
@@ -116,22 +123,22 @@
 	private String abortMessage = null;
 	
-	private static final Color FAILED_MESSAGE_COLOR = Color.RED;
+	private static final Colour FAILED_MESSAGE_COLOR = Colour.RED;
 	private static final Font MESSAGE_FONT = TrackWidgetCommons.FREESPACE_TRACKNAME_FONT;
-	private static final Font HELPER_FONT = new Font("Arial", Font.BOLD, 12);
-	
-	private static final Color[] TRACK_COLOR_WHEEL = { 
-							new Color(66, 145, 255), 
-							new Color(255, 163, 33), 
-							new Color(155, 227, 48), 
+	private static final Font HELPER_FONT = new Font("Arial", Font.Style.BOLD, 12);
+	
+	private static final Colour[] TRACK_COLOR_WHEEL = { 
+							Colour.FromRGB255(66, 145, 255), 
+							Colour.FromRGB255(255, 163, 33), 
+							Colour.FromRGB255(155, 227, 48)
 						};
-	private static final Color TRACK_LOAD_COLOR = Color.BLACK;
-	private static final Color TRACK_FAIL_COLOR = Color.RED;
-	
-	private static final Color SELECTION_COLOR = new Color(0,0,0,100);
+	private static final Colour TRACK_LOAD_COLOR = Colour.BLACK;
+	private static final Colour TRACK_FAIL_COLOR = Colour.RED;
+	
+	private static final Colour SELECTION_COLOR = Colour.FromRGBA255(0,0,0,100);
 
 	private static final Stroke TRACK_BORDER = Strokes.SOLID_1;
 	private static final Stroke TRACK_SELECTED_BORDER = Strokes.SOLID_2;
-	private static final Color TRACK_BORDER_COLOR = Color.BLACK;
-	private static final Color TRACK_SELECTED_BORDER_COLOR = new Color(253, 255, 201);
+	private static final Colour TRACK_BORDER_COLOR = Colour.BLACK;
+	private static final Colour TRACK_SELECTED_BORDER_COLOR = Colour.FromRGB255(253, 255, 201);
 	
 	
@@ -154,5 +161,6 @@
 	 * @param args
 	 */
-	public LinkedTrack(Text source, String[] args) {
+	public LinkedTrack(Text source, String[] args)
+	{
 		super(source, new JPanel(), 
 				100, -1, 
@@ -187,6 +195,6 @@
 		playbackControlPopup = new PlaybackPopup();
 		
-		nameLabel = new EmulatedTextItem(_swingComponent, new Point(10, 20));
-		nameLabel.setBackgroundColor(Color.WHITE);	
+		nameLabel = new EmulatedTextItem("", new Point(10, 20));
+		nameLabel.setBackgroundColor(Colour.WHITE);	
 		
 		String metaName = getStrippedDataString(TrackWidgetCommons.META_NAME_TAG);
@@ -210,8 +218,4 @@
 			public void keyPressed(KeyEvent e) {
 				if ((state != PLAYING && state != STOPPED) || e.isControlDown()) return;
-				if (nameLabel.onKeyPressed(e, _swingComponent)) {
-					e.consume();
-					return;
-				}
 			}
 
@@ -219,12 +223,13 @@
 				if ((state != PLAYING && state != STOPPED)) return;
 				else if (e.isControlDown()) {
-					if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_RIGHT) {
-						AudioFrameKeyboardActions.adjustInitationTime(LinkedTrack.this, e.getKeyCode() == KeyEvent.VK_LEFT);
-					} else if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN) {
-						AudioFrameKeyboardActions.adjustVerticlePosition(LinkedTrack.this, e.getKeyCode() == KeyEvent.VK_UP);
+					if (e.getKeyCode() == KeyEvent.VK_LEFT) {
+						ApolloGestureActions.adjustInitiationTime(LinkedTrack.this, -ApolloKBMGestureTranslator.TRACK_WIDGET_TIMELINE_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
+						ApolloGestureActions.adjustInitiationTime(LinkedTrack.this, ApolloKBMGestureTranslator.TRACK_WIDGET_TIMELINE_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_UP) {
+						ApolloGestureActions.adjustVerticalPosition(LinkedTrack.this, -ApolloKBMGestureTranslator.TRACK_WIDGET_VERTICAL_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
+						ApolloGestureActions.adjustVerticalPosition(LinkedTrack.this, ApolloKBMGestureTranslator.TRACK_WIDGET_VERTICAL_ADJUSTMENT);
 					}
-				} else if (nameLabel.onKeyReleased(e, _swingComponent)) {
-					e.consume();
-					return;
 				}
 			}
@@ -234,5 +239,4 @@
 			
 		});
-		
 		
 		updateBorderColor();
@@ -346,5 +350,5 @@
 			playbackControlPopup.stopButton.setEnabled(false);
 			playbackControlPopup.playPauseButton.setEnabled(true);
-			playbackControlPopup.playPauseButton.setIcon(IconRepository.getIcon("play.png"));
+			SwingMiscManager.setJButtonIcon(playbackControlPopup.playPauseButton, IconRepository.getIcon("play.png"));
 		
 
@@ -363,5 +367,5 @@
 			playbackControlPopup.rewindButton.setEnabled(false);
 			playbackControlPopup.playPauseButton.setEnabled(true);
-			playbackControlPopup.playPauseButton.setIcon(IconRepository.getIcon("pause.png"));
+			SwingMiscManager.setJButtonIcon(playbackControlPopup.playPauseButton, IconRepository.getIcon("pause.png"));
 
 			setWidgetEdgeThickness(TrackWidgetCommons.PLAYING_TRACK_EDGE_THICKNESS);
@@ -408,5 +412,5 @@
 		
 		invalidateSelf();
-		FrameGraphics.refresh(true);
+		DisplayController.requestRefresh(true);
 	}
 	
@@ -528,5 +532,5 @@
 			for (Track t : tracks) setTrackState(t, TRACKSTATE_READY);
 			invalidateSelf();
-			FrameGraphics.refresh(true);
+			DisplayController.requestRefresh(true);
 			break;
 		case MultitrackLoadListener.LOAD_FAILED_BAD_GRAPH:
@@ -552,5 +556,5 @@
 			setTrackState((String) state, TRACKSTATE_READY);
 			invalidateSelf();
-			FrameGraphics.refresh(true);
+			DisplayController.requestRefresh(true);
 			break;
 
@@ -611,5 +615,5 @@
 	 */
 	@Override
-	public InteractiveWidget copy() 
+	public Widget copy() 
 		throws InteractiveWidgetNotAvailableException, InteractiveWidgetInitialisationFailedException {
 		
@@ -632,5 +636,5 @@
 		source.setData(data);
 		
-		return InteractiveWidget.createWidget((Text)source);
+		return Widget.createWidget((Text)source);
 
 	}
@@ -640,5 +644,6 @@
 	 */
 	@Override
-	protected void onParentStateChanged(int eventType) {
+	protected void onParentStateChanged(int eventType)
+	{
 		super.onParentStateChanged(eventType);
 		
@@ -667,5 +672,5 @@
 				boolean inferInitTime = true;
 	
-				if (AudioFrameMouseActions.isYAxisRestictionOn()) {
+				if (ApolloGestureActions.isYAxisRestictionOn()) {
 					Mutable.Long ms = getInitiationTimeFromMeta();
 					if (ms != null) {
@@ -683,7 +688,7 @@
 				
 				// Also must not set initiation time if the frame is simply being displayed
-				inferInitTime &= 
-					(AudioFrameMouseActions.isMouseAnchoring() || AudioFrameMouseActions.isMouseStamping());
-
+				//inferInitTime &= (AudioFrameMouseActions.isMouseAnchoring() || AudioFrameMouseActions.isMouseStamping());
+				inferInitTime &= (eventType == ItemParentStateChangedEvent.EVENT_TYPE_ADDED);
+				
 				if (inferInitTime) {
 					initTime = Mutable.createMutableLong(FrameLayoutDaemon.getInstance().getMSAtX(getX(), parent));
@@ -731,5 +736,5 @@
 			if (MouseEventRouter.getCurrentMouseEvent() != null &&
 					MouseEventRouter.getCurrentMouseEvent().getButton() == MouseEvent.BUTTON2) {
-				Frame suspended = DisplayIO.getCurrentFrame();
+				Frame suspended = DisplayController.getCurrentFrame();
 				if (suspended != null) {
 					FrameLayoutDaemon.getInstance().suspendLayout(suspended, this);
@@ -755,5 +760,5 @@
 				public void run() {
 					invalidateSelf();
-					FrameGraphics.refresh(true);
+					DisplayController.requestRefresh(true);
 				}
 			}); // NOTE TO REPEAT: Pick up a linked track and delete it directly from freespace
@@ -946,29 +951,18 @@
 	 */
 	@Override
-	public void paint(Graphics g) {
+	public void paintSwingWidget(Graphics2D gm) {
 		
 		if (Browser._theBrowser == null) return;
 		
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		
 		// Ensure that load bar or any text doesn't spill over widgets invalidation area
-		Area clip = FrameGraphics.getCurrentClip();
-		
-		Shape clipBackUp = g.getClip();
-		
-		Area tmpClip = (clip != null) ? clip : 
-			new Area(new Rectangle(0, 0, 
-					Browser._theBrowser.getContentPane().getWidth(), 
-					Browser._theBrowser.getContentPane().getHeight()));
-		
-		tmpClip.intersect(new Area(getBounds()));
-
-		if (tmpClip.isEmpty()) return;
-
-		g.setClip(tmpClip);
+		EnforcedClipKey clipKey = g.pushClip(new Clip(getBounds()));
 		
 		// Paint backing
-		g.setColor(SampledTrackGraphView.DEFAULT_BACKGROUND_COLOR);
-		g.fillRect(getX(), getY(), getWidth(), getHeight());
+		g.drawRectangle(getBounds(), 0.0, new Fill(SwingConversions.fromSwingColor(SampledTrackGraphView.DEFAULT_BACKGROUND_COLOR)), null, null, null);
 		
 		String centralizedMessage = null;
+		Colour colour = null;
 
 		// Render according to the currently widget state
@@ -978,24 +972,20 @@
 
 		case FAILED_STATE: 
+			centralizedMessage = failMessage;
+			assert(failMessage != null);
+			colour = FAILED_MESSAGE_COLOR;
+			break;
 		case EMPTY_STATE:
+			if (getLink() == null) {
+				centralizedMessage = "Click to create";
+			} else {
+				centralizedMessage = "Nothing to play";
+			}
+			
+			colour = Colour.DARK_GREY;
+			break;
 		case LOADING_TRACK_GRAPH:
-			
-			if (state == FAILED_STATE) {
-				centralizedMessage = failMessage;
-				assert(failMessage != null);
-				g.setColor(FAILED_MESSAGE_COLOR);
-			} else if (state == LOADING_TRACK_GRAPH){
-				centralizedMessage = "Loading...";
-				g.setColor(Color.DARK_GRAY);
-			} else { // empty
-				if (getLink() == null) {
-					centralizedMessage = "Click to create";
-				} else {
-					centralizedMessage = "Nothing to play";
-				}
-				
-				g.setColor(Color.DARK_GRAY);
-			}
-
+			centralizedMessage = "Loading...";
+			colour = Colour.DARK_GREY;
 			break;
 			
@@ -1008,12 +998,12 @@
 
 			for (Track track : tracks) {
-				track.paintTrackArea((Graphics2D)g, x, y);
+				track.paintTrackArea(x, y);
 				if (track.isSelected) {
 					selected = track;
 				} else {
-					track.paintTrackBorder(g, x, y);
+					track.paintTrackBorder(x, y);
 					
 					if (track.area.height > 15) { // don't clutter up busy linked tracks
-						drawTrackName(track, g, Color.DARK_GRAY);
+						drawTrackName(track, Colour.DARK_GREY);
 					}
 	
@@ -1025,6 +1015,6 @@
 			// the selected border is drawn last
 			if (selected != null) {
-				selected.paintTrackBorder(g, x, y);
-				drawTrackName(selected, g, Color.BLACK);
+				selected.paintTrackBorder(x, y);
+				drawTrackName(selected, Colour.BLACK);
 			}
 
@@ -1038,5 +1028,5 @@
 				
 				centralizedMessage = "Loading dubs...";
-				g.setColor(Color.BLACK);
+				colour = Colour.BLACK;
 				
 			} else {
@@ -1045,13 +1035,11 @@
 				int selLeftX = XatFrame(selectionStart);
 				if (selectionLength > 1) {
-					g.setColor(SELECTION_COLOR);
-					g.fillRect(	getX() + selLeftX, 
-								getY(), 
-								XatFrame(selectionStart + selectionLength) - selLeftX, 
-								getHeight());
+					colour = SELECTION_COLOR;
+					AxisAlignedBoxBounds b = new AxisAlignedBoxBounds(	getX() + selLeftX, 
+							getY(), 
+							XatFrame(selectionStart + selectionLength) - selLeftX, 
+							getHeight());
+					g.drawRectangle(b, 0.0, new Fill(colour), null, null, null);
 				}
-				
-				// Draw selection start bar
-				((Graphics2D)g).setStroke(SampledTrackGraphView.GRAPH_BAR_STROKE);
 				
 				// Note that if the start line is near the edges of the panel it can be concealed - thus
@@ -1063,11 +1051,11 @@
 					x = getWidth() - 1;
 				}
-				
-				g.setColor(Color.RED);
-				g.drawLine(
+				colour = Colour.RED;
+				Line l = new Line(
 						x, 
 						getY(), 
 						x,
 						getY() + getHeight());
+				g.drawLine(l, colour, SwingConversions.fromSwingStroke(SampledTrackGraphView.GRAPH_BAR_STROKE));
 	
 				
@@ -1076,14 +1064,11 @@
 					
 					x = XatFrame(currentPlaybackFramePosition) + getX();
-					
-					((Graphics2D)g).setStroke(SampledTrackGraphView.GRAPH_BAR_STROKE);
-					g.setColor(SampledTrackGraphView.PLAYBACK_BAR_COLOR);
-					g.drawLine(x, getY(), x, getY() + getHeight());
+					colour = SwingConversions.fromSwingColor(SampledTrackGraphView.PLAYBACK_BAR_COLOR);
+					Line l2 = new Line(x, getY(), x, getY() + getHeight());
+					g.drawLine(l2, colour, SwingConversions.fromSwingStroke(SampledTrackGraphView.GRAPH_BAR_STROKE));
 				
 				}
 			
 			}
-			
-
 			
 			break;
@@ -1094,21 +1079,24 @@
 		if (centralizedMessage != null) {
 
-			FontMetrics fm   = g.getFontMetrics(MESSAGE_FONT);
-			Rectangle2D rect = fm.getStringBounds(centralizedMessage, g);
+			TextLayoutManager t = EcosystemManager.getTextLayoutManager();
+			
+			TextLayout layout = t.layoutString(centralizedMessage, MESSAGE_FONT, Point.ORIGIN, null, Integer.MAX_VALUE, 0, true, false).get(0);
+			
+			AxisAlignedBoxBounds layoutBounds = layout.getPixelBounds(0, 0);
 
 			// Calc centered position
-			int x = getX() + ((getWidth() / 2) - (int)(rect.getWidth() / 2));
-			int y = getY() + ((getHeight() / 2) + (int)(rect.getHeight() / 2) - 4);
+			int x = getX() + ((getWidth() / 2) - (int)(layoutBounds.getWidth() / 2));
+			int y = getY() + ((getHeight() / 2) + (int)(layoutBounds.getHeight() / 2) - 4);
 			
 			// Draw text
-			g.setFont(MESSAGE_FONT);
-			g.drawString(centralizedMessage, x, y);
+			g.drawTextLayout(layout, new Point(x, y), colour);
 			
 			// Draw add icon if waiting for a link
 			if (getLink() == null) {
-				IconRepository.getIcon("goto.png").paintIcon(null,
+				/*IconRepository.getIcon("goto.png").paintIcon(null,
 						g, 
 						x - 34, 
-						getY() + (getHeight() / 2) - 12);
+						getY() + (getHeight() / 2) - 12);*/
+				g.drawImage(IconRepository.getIcon("goto.png"), new Point(x - 34, getY() + (getHeight() / 2) - 12));
 			}
 				
@@ -1116,15 +1104,14 @@
 
 		// Paint name label over everything
-		if (state != NOT_INITIALIZED && state != FAILED_STATE && state != EMPTY_STATE)
-			nameLabel.paint(g);
-		
-		g.setClip(clipBackUp);
-		
-		super.paintLink((Graphics2D)g);
-
-	}
-	
-	private void drawTrackName(Track track, Graphics g, Color textColor) {
-
+		if (state != NOT_INITIALIZED && state != FAILED_STATE && state != EMPTY_STATE) nameLabel.paint();
+		
+		g.popClip(clipKey);
+
+	}
+	
+	private void drawTrackName(Track track, Colour textColor)
+	{
+		Graphics2D g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
+		
 		// Draw helper message for user to give meaningful information of what they
 		// are actually highlighting
@@ -1133,5 +1120,5 @@
 		helperMessage = helperMessage + " (" + track.getParentFrameName() +  ")";
 		
-		FontMetrics fm   = g.getFontMetrics(HELPER_FONT);
+		FontMetrics fm   = g.getFontMetrics(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(HELPER_FONT));
 		Rectangle2D rect = fm.getStringBounds(helperMessage, g);
 
@@ -1149,6 +1136,6 @@
 		
 		// Draw text
-		g.setColor(textColor);
-		g.setFont(HELPER_FONT);
+		g.setColor(SwingConversions.toSwingColor(textColor));
+		g.setFont(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(HELPER_FONT));
 		g.drawString(helperMessage, xoff, yoff);
 
@@ -1156,15 +1143,14 @@
 	
 	@Override
-	protected void paintInFreeSpace(Graphics g) {
-
-		super.paintInFreeSpace(g);
-
-		Shape clipBackUp = g.getClip();
-		Rectangle tmpClip = (clipBackUp != null) ? clipBackUp.getBounds() : 
-			new Rectangle(0, 0, 
-					Browser._theBrowser.getContentPane().getWidth(), 
-					Browser._theBrowser.getContentPane().getHeight());
-			
-		g.setClip(tmpClip.intersection(getBounds()));
+	protected void paintInFreeSpace()
+	{
+		super.paintInFreeSpace();
+		
+		// Draw the name of the track
+		
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+
+		// Ensure that load bar or any text doesn't spill over widgets invalidation area
+		EnforcedClipKey clipKey = g.pushClip(new Clip(getBounds()));
 	
 		// Draw the name
@@ -1173,21 +1159,18 @@
 			name = "Unnamed";
 		}
-
-		g.setFont(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT);
-		g.setColor(TrackWidgetCommons.FREESPACE_TRACKNAME_TEXT_COLOR);
-		
-		// Center track name
-		FontMetrics fm   = g.getFontMetrics(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT);
-		Rectangle2D rect = fm.getStringBounds(name, g);
-		
-		g.drawString(
-				name, 
-				this.getX() + (int)((getWidth() - rect.getWidth()) / 2), 
-				this.getY() + (int)((getHeight() - rect.getHeight()) / 2) + (int)rect.getHeight()
-				);
-		
-		g.setClip(clipBackUp);
-	
-
+		
+		List<TextLayout> layouts = EcosystemManager.getTextLayoutManager().layoutString(name, TrackWidgetCommons.FREESPACE_TRACKNAME_FONT, getBounds().getTopLeft(), null, getBounds().getWidth(), 0, true, false);
+
+		// Centre the track name
+		int lineYDelta = 0;
+		for (TextLayout layout : layouts) {
+			AxisAlignedBoxBounds bounds = layout.getPixelBounds(getBounds().getMinX(), getBounds().getMinY() + lineYDelta);
+			int centreXOffset = (getBounds().getWidth() - bounds.getWidth()) / 2;
+			bounds.translate(centreXOffset, 0);
+			g.drawTextLayout(layout, bounds.getTopLeft(), TrackWidgetCommons.FREESPACE_TRACKNAME_TEXT_COLOR);
+			lineYDelta += bounds.getHeight();
+		}
+		
+		g.popClip(clipKey);
 	}
 
@@ -1205,5 +1188,5 @@
 				x = XatFrame(currentPlaybackFramePosition);
 				
-				FrameGraphics.invalidateArea(new Rectangle(
+				DisplayController.invalidateArea(new AxisAlignedBoxBounds(
 					x + offsetX, 
 					offsetY, 
@@ -1220,5 +1203,5 @@
 				x = XatFrame(currentPlaybackFramePosition);
 		
-				FrameGraphics.invalidateArea(new Rectangle(
+				DisplayController.invalidateArea(new AxisAlignedBoxBounds(
 						x + offsetX , 
 						offsetY, 
@@ -1462,7 +1445,7 @@
 		
 		// Get border color currently used
-		Color oldC = getSource().getBorderColor();
-		
-		Color newC = TrackWidgetCommons.getBorderColor(
+		Colour oldC = getSource().getBorderColor();
+		
+		Colour newC = TrackWidgetCommons.getBorderColor(
 				SoundDesk.getInstance().isSolo(masterMix.getChannelID()), 
 						masterMix.isMuted());
@@ -1518,29 +1501,27 @@
 	 *
 	 */
-	private class PlaybackPopup extends PlaybackControlPopup {
-
-		private static final long serialVersionUID = 1L;
-		
+	private class PlaybackPopup extends PlaybackControlPopup
+	{
 		public PlaybackPopup() {
 			miscButton.setActionCommand("goto");
-			miscButton.setIcon(IconRepository.getIcon("goto.png"));
+			SwingMiscManager.setJButtonIcon(miscButton, IconRepository.getIcon("goto.png"));
 			miscButton.setToolTipText("Goto linked frame");
 		}
 
 		@Override
-		public void onHide() {
-			super.onHide();
+		public void onHide()
+		{
 		}
 
 		@Override
-		public void onShow() {
-			super.onShow();
+		public void onShow()
+		{
 			updateVolume((int)(100 * masterMix.getVolume()));
 			updateMute(masterMix.isMuted());
 			updateSolo(SoundDesk.getInstance().isSolo(masterMix.getChannelID()));
 		}
-
-		public void actionPerformed(ActionEvent e) {
-			
+		
+		public void actionPerformed(ActionEvent e)
+		{
 			if (e.getSource() == miscButton) {
 				
@@ -1670,5 +1651,5 @@
 				currentPlaybackFramePosition = -1;
 				setSelection(0, 0); // invalidates
-				FrameGraphics.refresh(true);
+				DisplayController.requestRefresh(true);
 				
 			}
@@ -1691,7 +1672,8 @@
 	}
 	
-	private class MouseActions implements MouseListener, MouseMotionListener {
-
-		public void mouseClicked(MouseEvent e) {
+	private class MouseActions implements MouseListener, MouseMotionListener
+	{
+		public void mouseClicked(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 			
@@ -1705,18 +1687,18 @@
 		}
 
-
-		public void mouseEntered(MouseEvent e) {
+		public void mouseEntered(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 		}
 
 
-		public void mouseExited(MouseEvent e) {
+		public void mouseExited(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
-			
-		}
-
-
-		public void mousePressed(MouseEvent e) {
-			
+		}
+
+
+		public void mousePressed(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 			
@@ -1732,13 +1714,11 @@
 			setSelection(frameAtX(selectionStartX), 1);
 			
-			FrameGraphics.refresh(true);
-		}
-
-
-		public void mouseReleased(MouseEvent e) {
-			
-
+			DisplayController.requestRefresh(true);
+		}
+
+
+		public void mouseReleased(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
-			
 			
 			// Was the release a simple click
@@ -1765,11 +1745,9 @@
 				return;
 			}
-
-			
-		}
-		
-
-		public void mouseDragged(MouseEvent e) {
-			
+		}
+		
+
+		public void mouseDragged(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 			
@@ -1800,15 +1778,15 @@
 			}
 			
-			FrameGraphics.refresh(true);
-		}
-
-		public void mouseMoved(MouseEvent e) {
+			DisplayController.requestRefresh(true);
+		}
+
+		public void mouseMoved(MouseEvent e)
+		{
 			assert(state != EMPTY_STATE);
 			
 			if (state != PLAYING && state != STOPPED) return;
 
-			if (nameLabel.onMouseMoved(e, _swingComponent)) {
-				e.consume();
-				return;
+			if (nameLabel != null) {
+				nameLabel.gainFocus();
 			}
 
@@ -1822,39 +1800,27 @@
 				
 				// Get rid of all popups
-				PopupManager.getInstance().hideAutohidePopups();
-				
-				Rectangle animationSource = _swingComponent.getBounds();
+				PopupManager.getInstance().hideAutoHidePopups();
+				
+				AxisAlignedBoxBounds animationSource = SwingConversions.fromSwingRectangle(_swingComponent.getBounds());
 				
 				// Determine where popup should show
 				int x = LinkedTrack.this.getX();
-				int y = LinkedTrack.this.getY() - playbackControlPopup.getHeight() - 2; // by default show above
+				int y = LinkedTrack.this.getY() - playbackControlPopup.getFullBounds().getHeight() - 2; // by default show above
 				
 				// I get sick.dizzy from the popup expanding from the whole thing...
-				animationSource.height = 1;
-				animationSource.width = Math.min(animationSource.width, playbackControlPopup.getWidth());
+				animationSource.getSize().height = 1;
+				animationSource.getSize().width = Math.min(animationSource.getWidth(), playbackControlPopup.getFullBounds().getWidth());
 				
 				if (y < 0) {
 					y = LinkedTrack.this.getY() + LinkedTrack.this.getHeight() + 2;
-					animationSource.y = y - 2;
+					animationSource.getTopLeft().y = y - 2;
 				} 
 
 				// Animate the popup
-				PopupManager.getInstance().showPopup(
-						playbackControlPopup, 
-						new Point(x, y), 
-						_swingComponent,
-						PopupManager.getInstance().new ExpandShrinkAnimator(
-								animationSource,
-								Color.LIGHT_GRAY));
-				
-				PopupReaper.getInstance().initPopupLifetime(
-						playbackControlPopup, 
-						PopupManager.getInstance().new ExpandShrinkAnimator(
-								animationSource,
-								Color.LIGHT_GRAY), 
-								TrackWidgetCommons.POPUP_LIFETIME);
-				
+				playbackControlPopup.getAutoHideTime().setLifetime(TrackWidgetCommons.POPUP_LIFETIME);
+				PopupManager.getInstance().add(playbackControlPopup);
+				playbackControlPopup.show();
 			} else {
-				PopupReaper.getInstance().revivePopup(playbackControlPopup, TrackWidgetCommons.POPUP_LIFETIME);
+				playbackControlPopup.show();
 			}
 			
@@ -1878,5 +1844,5 @@
 			if (shouldInvalidate) {
 				invalidateSelf();
-				FrameGraphics.refresh(true);
+				DisplayController.requestRefresh(true);
 			}
 		}
@@ -1888,11 +1854,11 @@
 	 * @author Brook Novak
 	 */
-	private class Track {
-		
+	private class Track
+	{
 		private AbsoluteTrackNode absNode; // immutable. Never null
 		
 		private Rectangle area;
 		
-		private Color baseColor;
+		private Colour baseColor;
 		
 		boolean isSelected = false;
@@ -1900,10 +1866,12 @@
 		private int state = TRACKSTATE_READY;
 		
-		Track(AbsoluteTrackNode absNode) {
+		Track(AbsoluteTrackNode absNode)
+		{
 			assert(absNode != null);
 			this.absNode = absNode;
 		}
 		
-		public String getChannelID() {
+		public String getChannelID()
+		{
 			return absNode.getChannelID();
 		}
@@ -1929,12 +1897,14 @@
 		}
 		
-		public void paintTrackArea(Graphics2D g, int x, int y) {
+		public void paintTrackArea(int x, int y)
+		{
+			Graphics2D g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
 			
 			if (state == TRACKSTATE_LOADING && LinkedTrack.this.state == PLAYBACK_LOADING) {
-				g.setColor(TRACK_LOAD_COLOR);
+				g.setColor(SwingConversions.toSwingColor(TRACK_LOAD_COLOR));
 			} else if (state == TRACKSTATE_FAILED) {
-				g.setColor(TRACK_FAIL_COLOR);
+				g.setColor(SwingConversions.toSwingColor(TRACK_FAIL_COLOR));
 			} else {
-				g.setColor(baseColor);
+				g.setColor(SwingConversions.toSwingColor(baseColor));
 			}
 			
@@ -1943,10 +1913,10 @@
 
 				GradientPaint gp = new GradientPaint(
-						(int) (area.x + x + (area.width / 2)), area.y + y + (int)(area.height * 0.8), baseColor,
-						(int) (area.x + x + (area.width / 2)), area.y + y, TRACK_SELECTED_BORDER_COLOR);
+						(int) (area.x + x + (area.width / 2)), area.y + y + (int)(area.height * 0.8), SwingConversions.toSwingColor(baseColor),
+						(int) (area.x + x + (area.width / 2)), area.y + y, SwingConversions.toSwingColor(TRACK_SELECTED_BORDER_COLOR));
 				g.setPaint(gp);
 			}
 			
-			// Draw a filled rect - represented a track in the heirarchy
+			// Draw a filled rect - represented a track in the hierarchy
 			g.fillRect(area.x + x, area.y + y, area.width, area.height);
 			
@@ -1957,12 +1927,14 @@
 		}
 		
-		public void paintTrackBorder(Graphics g, int x, int y) {
+		public void paintTrackBorder(int x, int y)
+		{
+			Graphics g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
 			
 			if (isSelected) {
-				g.setColor(TRACK_SELECTED_BORDER_COLOR);
-				((Graphics2D)g).setStroke(TRACK_SELECTED_BORDER);
+				g.setColor(SwingConversions.toSwingColor(TRACK_SELECTED_BORDER_COLOR));
+				((Graphics2D)g).setStroke(SwingConversions.toSwingStroke(TRACK_SELECTED_BORDER));
 			} else {
-				g.setColor(TRACK_BORDER_COLOR);
-				((Graphics2D)g).setStroke(TRACK_BORDER); // todo muted colors etc...
+				g.setColor(SwingConversions.toSwingColor(TRACK_BORDER_COLOR));
+				((Graphics2D)g).setStroke(SwingConversions.toSwingStroke(TRACK_BORDER)); // todo muted colors etc...
 			}
 			
@@ -1972,4 +1944,5 @@
 	}
 	
+	// TODO: Why not? cts16
 	@Override
 	public boolean isWidgetEdgeThicknessAdjustable() {
Index: /trunk/src/org/apollo/widgets/MasterVolume.java
===================================================================
--- /trunk/src/org/apollo/widgets/MasterVolume.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/MasterVolume.java	(revision 1102)
@@ -12,5 +12,5 @@
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.SwingWidget;
 
 /**
@@ -20,5 +20,5 @@
  *
  */
-public class MasterVolume extends InteractiveWidget implements Observer {
+public class MasterVolume extends SwingWidget implements Observer {
 	
 	private VolumeControlButton vcButton;
Index: /trunk/src/org/apollo/widgets/MetronomePlayer.java
===================================================================
--- /trunk/src/org/apollo/widgets/MetronomePlayer.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/MetronomePlayer.java	(revision 1102)
@@ -21,7 +21,8 @@
 import org.apollo.mvc.Subject;
 import org.apollo.mvc.SubjectChangedEvent;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.SwingWidget;
 
 /**
@@ -33,10 +34,10 @@
  *
  */
-public class MetronomePlayer extends InteractiveWidget implements Observer {
+public class MetronomePlayer extends SwingWidget implements Observer {
 	
 	private JLabel tempoLabel;
 	private JSlider bpmSlider;
 	private JButton startStopButton;
-	private JComboBox beatsPerMeasureCombo;
+	private JComboBox<String> beatsPerMeasureCombo;
 	private JCheckBox enabledCheckbox;
 	private boolean interfaceIsUpdating = false;
@@ -84,5 +85,5 @@
 		});
 
-		beatsPerMeasureCombo = new JComboBox(new String[]{"1", "2", "3", "4", "5", "6", "7", "8"});
+		beatsPerMeasureCombo = new JComboBox<String>(new String[]{"1", "2", "3", "4", "5", "6", "7", "8"});
 		beatsPerMeasureCombo.setPreferredSize(new Dimension(60, 25));
 		beatsPerMeasureCombo.setEditable(false);
@@ -133,9 +134,9 @@
 			
 			if (Metronome.getInstance().isPlaying()) {
-				startStopButton.setIcon(IconRepository.getIcon("metrostop.png"));
+				SwingMiscManager.setJButtonIcon(startStopButton, IconRepository.getIcon("metrostop.png"));
 				setWidgetEdgeThickness(TrackWidgetCommons.PLAYING_TRACK_EDGE_THICKNESS);
 	
 			} else {
-				startStopButton.setIcon(IconRepository.getIcon("metroplay.png"));
+				SwingMiscManager.setJButtonIcon(startStopButton, IconRepository.getIcon("metroplay.png"));
 				setWidgetEdgeThickness(TrackWidgetCommons.STOPPED_TRACK_EDGE_THICKNESS);
 			}
Index: /trunk/src/org/apollo/widgets/SampleRecorder.java
===================================================================
--- /trunk/src/org/apollo/widgets/SampleRecorder.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/SampleRecorder.java	(revision 1102)
@@ -1,5 +1,4 @@
 package org.apollo.widgets;
 
-import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.FontMetrics;
@@ -49,11 +48,13 @@
 import org.apollo.util.ApolloSystemLog;
 import org.apollo.util.TrackNameCreator;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.SwingWidget;
 
 /**
@@ -63,6 +64,5 @@
  *
  */
-public class SampleRecorder extends InteractiveWidget 
-	implements ActionListener, Observer, MultitrackLoadListener {
+public class SampleRecorder extends SwingWidget implements ActionListener, Observer, MultitrackLoadListener {
 	
 	private enum WidgetState {
@@ -105,6 +105,6 @@
 	private final static int MAX_COUNTDOWN_TIME = 60;
 	
-	private static final Color GRAPH_BACKCOLOR = Color.BLACK;
-	private static final Color GRAPH_WAVECOLOR = Color.GREEN;
+	private static final Colour GRAPH_BACKCOLOR = Colour.BLACK;
+	private static final Colour GRAPH_WAVECOLOR = Colour.GREEN;
 	
 	private final static int RENDER_POINTS_PER_SECOND = 20; // how many points to render each second
@@ -112,9 +112,11 @@
 	private final static String COUNTDOWN_META = "countdown=";
 	
-	public SampleRecorder(Text source, String[] args) {
+	public SampleRecorder(Text source, String[] args)
+	{
 		this(source, args, false);
 	}
 	
-	public SampleRecorder(Text source, String[] args, boolean isTemporary) {
+	public SampleRecorder(Text source, String[] args, boolean isTemporary)
+	{
 		super(source, new JPanel(new GridBagLayout()),
 				AnimatedSampleGraph.GRAPH_WIDTH + (2 * HORO_SPACING), 
@@ -132,15 +134,15 @@
 		// Create gui layout
 		recordButton = new JButton();
-		recordButton.setIcon(IconRepository.getIcon("record.png"));
+		SwingMiscManager.setJButtonIcon(recordButton, IconRepository.getIcon("record.png"));
 		recordButton.addActionListener(this);
 		recordButton.setPreferredSize(new Dimension(AnimatedSampleGraph.GRAPH_WIDTH / 2, BUTTON_HEIGHT));
 		
 		recordSynchedButton = new JButton();
-		recordSynchedButton.setIcon(IconRepository.getIcon("recordplay.png"));
+		SwingMiscManager.setJButtonIcon(recordSynchedButton, IconRepository.getIcon("recordplay.png"));
 		recordSynchedButton.addActionListener(this);
 		recordSynchedButton.setPreferredSize(new Dimension(AnimatedSampleGraph.GRAPH_WIDTH / 2, BUTTON_HEIGHT));
 
 		stopButton = new JButton();
-		stopButton.setIcon(IconRepository.getIcon("stop.png"));
+		SwingMiscManager.setJButtonIcon(stopButton, IconRepository.getIcon("stop.png"));
 		stopButton.addActionListener(this);
 		stopButton.setPreferredSize(new Dimension(AnimatedSampleGraph.GRAPH_WIDTH, BUTTON_HEIGHT));
@@ -303,7 +305,7 @@
 	
 				sampleGraph.alternateText = Integer.toString(countDown);
-				sampleGraph.alternateTextColor = (countDown > 3) ? Color.WHITE : Color.RED;
+				sampleGraph.alternateTextColor = (countDown > 3) ? Colour.WHITE : Colour.RED;
 				sampleGraph.invalidateGraph();
-				FrameGraphics.refresh(true);
+				DisplayController.requestRefresh(true);
 				
 				countdownThread = new CountDownTimer(countDown);
@@ -373,5 +375,5 @@
 					 Frame targetFrame = getParentFrame();
 					 if (targetFrame == null) {
-						 targetFrame = DisplayIO.getCurrentFrame();
+						 targetFrame = DisplayController.getCurrentFrame();
 					 }
 					 
@@ -398,5 +400,5 @@
 					 } else {
 						 
-						 FrameMouseActions.pickup(trackWidget.getItems());
+						 StandardGestureActions.pickup(trackWidget.getItems());
 							
 						// Reset the state
@@ -602,5 +604,5 @@
 			assert (state == WidgetState.Ready);
 			
-			Frame target = DisplayIO.getCurrentFrame();
+			Frame target = DisplayController.getCurrentFrame();
 			if (target  == null) return;
 
@@ -608,8 +610,8 @@
 			
 			RecordOverdubLauncher launcher = new RecordOverdubLauncher((Integer)countDownSpinner.getValue());
-			launcher.setPosition(FrameMouseActions.MouseX, FrameMouseActions.MouseY);
+			launcher.setPosition(DisplayController.getMousePosition());
 
 			// Pick it up
-			FrameMouseActions.pickup(launcher);
+			StandardGestureActions.pickup(launcher);
 			
 		}
@@ -757,5 +759,5 @@
 			setState(WidgetState.LoadingPlayback, "Loading tracks...");
 			
-			Frame currentFrame = DisplayIO.getCurrentFrame();
+			Frame currentFrame = DisplayController.getCurrentFrame();
 			if (currentFrame == null || currentFrame.getName() == null) {
 				
@@ -843,10 +845,10 @@
 		
 		private String alternateText = null;
-		private Color alternateTextColor = Color.WHITE;
+		private Colour alternateTextColor = Colour.WHITE;
 
 		AnimatedSampleGraph() {
 			imageBuffer = new BufferedImage(GRAPH_WIDTH, GRAPH_HEIGHT, BufferedImage.TYPE_INT_RGB);
 			imageGraphics = (Graphics2D)imageBuffer.getGraphics();
-			imageGraphics.setColor(GRAPH_BACKCOLOR);
+			imageGraphics.setColor(SwingConversions.toSwingColor(GRAPH_BACKCOLOR));
 			imageGraphics.fillRect(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
 			setPreferredSize(new Dimension(GRAPH_WIDTH, GRAPH_HEIGHT));
@@ -857,5 +859,5 @@
 		 */
 		public void clear() {
-			imageGraphics.setColor(GRAPH_BACKCOLOR);
+			imageGraphics.setColor(SwingConversions.toSwingColor(GRAPH_BACKCOLOR));
 			imageGraphics.fillRect(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
 			invalidateGraph();
@@ -867,12 +869,12 @@
 			if (alternateText != null) {
 				
-				g.setColor(Color.BLACK);
+				g.setColor(SwingConversions.toSwingColor(Colour.BLACK));
 				g.fillRect(0, 0, getWidth(), getHeight());
 				
-				g.setFont(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT);
-				g.setColor(alternateTextColor);
+				g.setFont(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT));
+				g.setColor(SwingConversions.toSwingColor(alternateTextColor));
 				
 				// Center track name
-				FontMetrics fm   = g.getFontMetrics(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT);
+				FontMetrics fm   = g.getFontMetrics(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT));
 				Rectangle2D rect = fm.getStringBounds(alternateText, g);
 				
@@ -907,9 +909,9 @@
 			
 			// Render backcolor
-			imageGraphics.setColor(GRAPH_BACKCOLOR);
+			imageGraphics.setColor(SwingConversions.toSwingColor(GRAPH_BACKCOLOR));
 			imageGraphics.fillRect(GRAPH_WIDTH - pixelWidth, 0, pixelWidth, GRAPH_HEIGHT);
 			
 			// Render wave forms from lastSampleHeight
-			imageGraphics.setColor(GRAPH_WAVECOLOR);
+			imageGraphics.setColor(SwingConversions.toSwingColor(GRAPH_WAVECOLOR));
 			int currentPixelX = GRAPH_WIDTH - pixelWidth;
 
@@ -933,6 +935,6 @@
 	        Rectangle dirty = this.getBounds();
 	        dirty.translate(SampleRecorder.this.getX(), SampleRecorder.this.getY());
-	        FrameGraphics.invalidateArea(dirty); 
-	        FrameGraphics.refresh(true); 
+	        DisplayController.invalidateArea(SwingConversions.fromSwingRectangle(dirty)); 
+	        DisplayController.requestRefresh(true); 
 	        
 		}
@@ -979,7 +981,7 @@
 							sampleGraph.alternateText = Integer.toString(currentCountdown);
 							sampleGraph.alternateTextColor = (currentCountdown > 3) ?
-										Color.WHITE : Color.RED;
+										Colour.WHITE : Colour.RED;
 							sampleGraph.invalidateGraph();
-							FrameGraphics.refresh(true);
+							DisplayController.requestRefresh(true);
 						}
 					});
Index: /trunk/src/org/apollo/widgets/SampledTrack.java
===================================================================
--- /trunk/src/org/apollo/widgets/SampledTrack.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/SampledTrack.java	(revision 1102)
@@ -5,8 +5,6 @@
 import java.awt.Graphics;
 import java.awt.Graphics2D;
-import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Shape;
-import java.awt.Stroke;
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
@@ -27,6 +25,6 @@
 import javax.swing.SwingUtilities;
 
-import org.apollo.AudioFrameKeyboardActions;
-import org.apollo.AudioFrameMouseActions;
+import org.apollo.ApolloGestureActions;
+import org.apollo.ApolloKBMGestureTranslator;
 import org.apollo.audio.ApolloPlaybackMixer;
 import org.apollo.audio.ApolloSubjectChangedEvent;
@@ -56,15 +54,19 @@
 import org.apollo.util.AudioMath;
 import org.apollo.util.Mutable;
-import org.apollo.util.PopupReaper;
 import org.apollo.util.TrackModelHandler;
 import org.apollo.util.TrackModelLoadManager;
 import org.apollo.util.TrackNameCreator;
-import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.Util;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.swing.MouseEventRouter;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameMouseActions;
-import org.expeditee.gui.MouseEventRouter;
 import org.expeditee.gui.PopupManager;
 import org.expeditee.items.ItemParentStateChangedEvent;
@@ -72,7 +74,7 @@
 import org.expeditee.items.Text;
 import org.expeditee.items.widgets.HeavyDutyInteractiveWidget;
-import org.expeditee.items.widgets.InteractiveWidget;
 import org.expeditee.items.widgets.InteractiveWidgetInitialisationFailedException;
 import org.expeditee.items.widgets.InteractiveWidgetNotAvailableException;
+import org.expeditee.items.widgets.Widget;
 
 /**
@@ -82,6 +84,5 @@
  *
  */
-public class SampledTrack extends HeavyDutyInteractiveWidget 
-	implements TrackModelHandler, EffecientInvalidator, Observer {
+public class SampledTrack extends HeavyDutyInteractiveWidget implements TrackModelHandler, EffecientInvalidator, Observer {
 
 	/** The observered subject. Can be null */
@@ -115,7 +116,7 @@
 	private static final Stroke FREESPACE_OUTLINING = Strokes.SOLID_2;
 	
-	private static final Color SEMI_TRANSPARENT_FREESPACE_BACKCOLOR = new Color(
+	private static final Colour SEMI_TRANSPARENT_FREESPACE_BACKCOLOR = new Colour(
 			FREESPACE_BACKCOLOR.getRed(), FREESPACE_BACKCOLOR.getGreen(),
-			FREESPACE_BACKCOLOR.getBlue(), 128);
+			FREESPACE_BACKCOLOR.getBlue(), Colour.FromComponent255(128));
 	
 	
@@ -173,4 +174,10 @@
 		initObservers();
 		
+	}
+	
+	@Override
+	public void onMoved()
+	{
+		if (nameLabel != null) nameLabel.setPosition(new Point(getX() + 10, getY() + 20));
 	}
 
@@ -279,5 +286,5 @@
 
 				if (nameLabel != null) {
-					nameLabel.onMouseMoved(e, fulltrackView);
+					nameLabel.gainFocus();
 				}
 				
@@ -291,5 +298,5 @@
 					
 					// Get rid of all popups
-					PopupManager.getInstance().hideAutohidePopups();
+					PopupManager.getInstance().hideAutoHidePopups();
 					
 					Rectangle animationSource = _swingComponent.getBounds();
@@ -297,9 +304,9 @@
 					// Determine where popup should show
 					int x = SampledTrack.this.getX();
-					int y = SampledTrack.this.getY() - playbackControlPopup.getHeight() - 2; // by default show above
+					int y = SampledTrack.this.getY() - playbackControlPopup.getFullBounds().getHeight() - 2; // by default show above
 					
 					// I get sick.dizzy from the popup expanding from the whole thing...
 					animationSource.height = 1;
-					animationSource.width = Math.min(animationSource.width, playbackControlPopup.getWidth());
+					animationSource.width = Math.min(animationSource.width, playbackControlPopup.getFullBounds().getWidth());
 					
 					if (y < 0) {
@@ -309,21 +316,9 @@
 
 					// Animate the popup
-					PopupManager.getInstance().showPopup(
-							playbackControlPopup, 
-							new Point(x, y), 
-							fulltrackView,
-							PopupManager.getInstance().new ExpandShrinkAnimator(
-									animationSource,
-									Color.LIGHT_GRAY));
-					
-					PopupReaper.getInstance().initPopupLifetime(
-							playbackControlPopup, 
-							PopupManager.getInstance().new ExpandShrinkAnimator(
-									animationSource,
-									Color.LIGHT_GRAY), 
-									TrackWidgetCommons.POPUP_LIFETIME);
-					
+					playbackControlPopup.getAutoHideTime().setLifetime(TrackWidgetCommons.POPUP_LIFETIME);
+					PopupManager.getInstance().add(playbackControlPopup);
+					playbackControlPopup.show();
 				} else {
-					PopupReaper.getInstance().revivePopup(playbackControlPopup, TrackWidgetCommons.POPUP_LIFETIME);
+					playbackControlPopup.show();
 				}
 				
@@ -398,23 +393,14 @@
 		fulltrackView.addKeyListener(new KeyListener() {
 
-			public void keyPressed(KeyEvent e) {
-				if (!e.isControlDown() && nameLabel != null) {
-					if (nameLabel.onKeyPressed(e, fulltrackView)) {
-						e.consume();
-					}
-				}
-			}
-
-			public void keyReleased(KeyEvent e) {
-				if (!e.isControlDown() && nameLabel != null) {
-					if (nameLabel.onKeyReleased(e, fulltrackView)) {
-						e.consume();
-					}
-				}
-				
+			public void keyPressed(KeyEvent e)
+			{
+			}
+
+			public void keyReleased(KeyEvent e)
+			{
 				// Toggle pitch-track indexing
 				if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_I) {
 					setShouldOmitIndexAudio(!shouldOmitIndexAudio());
-					FrameGraphics.refresh(true);
+					DisplayController.requestRefresh(true);
 				}
 				
@@ -429,5 +415,5 @@
 				else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_L) {
 
-					Frame current = DisplayIO.getCurrentFrame();
+					Frame current = DisplayController.getCurrentFrame();
 					
 					if (current != null) {
@@ -473,12 +459,18 @@
 					}
 	
-				} else if (e.isControlDown() && 
-						(e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_RIGHT)) {
-					e.consume();
-					AudioFrameKeyboardActions.adjustInitationTime(SampledTrack.this, e.getKeyCode() == KeyEvent.VK_LEFT);
-				} else if (e.isControlDown() && 
-						(e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN)) {
-					e.consume();
-					AudioFrameKeyboardActions.adjustVerticlePosition(SampledTrack.this, e.getKeyCode() == KeyEvent.VK_UP);
+				} else if (e.isControlDown()) {
+					if (e.getKeyCode() == KeyEvent.VK_LEFT) {
+						e.consume();
+						ApolloGestureActions.adjustInitiationTime(SampledTrack.this, -ApolloKBMGestureTranslator.TRACK_WIDGET_TIMELINE_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
+						e.consume();
+						ApolloGestureActions.adjustInitiationTime(SampledTrack.this, ApolloKBMGestureTranslator.TRACK_WIDGET_TIMELINE_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_UP) {
+						e.consume();
+						ApolloGestureActions.adjustVerticalPosition(SampledTrack.this, -ApolloKBMGestureTranslator.TRACK_WIDGET_VERTICAL_ADJUSTMENT);
+					} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
+						e.consume();
+						ApolloGestureActions.adjustVerticalPosition(SampledTrack.this, ApolloKBMGestureTranslator.TRACK_WIDGET_VERTICAL_ADJUSTMENT);
+					}
 				}
 
@@ -490,8 +482,6 @@
 		});
 		
-		
-		
-		nameLabel = new EmulatedTextItem(_swingComponent, new Point(10, 20));
-		nameLabel.setBackgroundColor(Color.WHITE);	
+		nameLabel = new EmulatedTextItem("", (new Point(10, 20)).add(getBounds().getTopLeft()));
+		nameLabel.setBackgroundColor(Colour.WHITE);	
 		
 		String metaName = getStrippedDataString(TrackWidgetCommons.META_NAME_TAG);
@@ -616,5 +606,5 @@
 		Text source = new Text(
 				targetFrame.getNextItemID(),
-				ItemUtils.GetTag(ItemUtils.TAG_IWIDGET) + ":" + formatArgs(args));
+				ItemUtils.GetTag(ItemUtils.TAG_IWIDGET) + ":" + Util.formatArgs(args));
 		
 		source.setParent(targetFrame);
@@ -685,5 +675,5 @@
 	
 	@Override
-	public InteractiveWidget copy() 
+	public Widget copy() 
 		throws InteractiveWidgetNotAvailableException, InteractiveWidgetInitialisationFailedException {
 		
@@ -1119,8 +1109,9 @@
 	}
 
-	public void onGraphDirty(SampledTrackGraphView graph, Rectangle dirty) {
+	public void onGraphDirty(SampledTrackGraphView graph, Rectangle dirty)
+	{
         dirty.translate(getX(), getY() - 1);
-        FrameGraphics.invalidateArea(dirty); 
-        FrameGraphics.refresh(true);
+        DisplayController.invalidateArea(SwingConversions.fromSwingRectangle(dirty)); 
+        DisplayController.requestRefresh(true);
 	}
 
@@ -1131,5 +1122,6 @@
 
 	@Override
-	protected void onSizeChanged() {
+	protected void onSizeChanged()
+	{
 		super.onSizeChanged();
 		// Keep meta as constant as possible for best reults
@@ -1246,9 +1238,12 @@
 
 	@Override
-	public void paintInFreeSpace(Graphics g) {
-		paintInFreeSpace(g, false);
-	}
-	
-	public void paintInFreeSpace(Graphics g, boolean isAtFinalPass) { 
+	public void paintInFreeSpace()
+	{
+		paintInFreeSpace(false);
+	}
+	
+	public void paintInFreeSpace(boolean isAtFinalPass)
+	{
+		Graphics g = SwingMiscManager.getIfUsingSwingGraphicsManager().getCurrentSurface();
 
 		if (isLoaded()) { 
@@ -1270,11 +1265,11 @@
 					
 
-					Point containerPoint = SwingUtilities.convertPoint(me.getComponent(), 
-							new Point(0,0), Browser._theBrowser.getContentPane());
+					Point containerPoint = SwingConversions.fromSwingPoint(SwingUtilities.convertPoint(me.getComponent(), 
+							new java.awt.Point(0,0), SwingMiscManager.getIfUsingSwingGraphicsManager().getContentPane()));
 					
 					Shape clipBackUp = g.getClip();
 					g.setClip(null);
 					
-					g.setColor(Color.ORANGE);
+					g.setColor(SwingConversions.toSwingColor(Colour.ORANGE));
 					((Graphics2D)g).setStroke(EditableSampledTrackGraphView.GRAPH_BAR_STROKE);
 					g.drawLine(
@@ -1284,5 +1279,5 @@
 							containerPoint.y + me.getComponent().getHeight());
 					
-					FrameGraphics.invalidateArea(new Rectangle(
+					DisplayController.invalidateArea(new AxisAlignedBoxBounds(
 							containerPoint.x + me.getX(), 
 							containerPoint.y, 
@@ -1293,10 +1288,10 @@
 					g.setClip(clipBackUp);
 					
-					g.setColor(SEMI_TRANSPARENT_FREESPACE_BACKCOLOR);
+					g.setColor(SwingConversions.toSwingColor(SEMI_TRANSPARENT_FREESPACE_BACKCOLOR));
 					g.fillRect(getX(), getY(), getWidth(), getHeight());
 					
 					if (isAtFinalPass) { // final pass does not draw the borders... so must manually draw them
-						g.setColor(Color.BLACK);
-						((Graphics2D)g).setStroke(FREESPACE_OUTLINING);
+						g.setColor(SwingConversions.toSwingColor(Colour.BLACK));
+						((Graphics2D)g).setStroke(SwingConversions.toSwingStroke(FREESPACE_OUTLINING));
 						g.drawRect(getX(), getY(), getWidth(), getHeight());
 					}
@@ -1311,5 +1306,5 @@
 		}
 		
-		super.paintInFreeSpace(g);
+		super.paintInFreeSpace();
 		
 		if (isLoaded()) {
@@ -1318,8 +1313,8 @@
 			Rectangle tmpClip = (clipBackUp != null) ? clipBackUp.getBounds() : 
 				new Rectangle(0, 0, 
-						Browser._theBrowser.getContentPane().getWidth(), 
-						Browser._theBrowser.getContentPane().getHeight());
-				
-			g.setClip(tmpClip.intersection(getBounds()));
+						SwingMiscManager.getIfUsingSwingGraphicsManager().getContentPane().getWidth(), 
+						SwingMiscManager.getIfUsingSwingGraphicsManager().getContentPane().getHeight());
+				
+			g.setClip(tmpClip.intersection(SwingConversions.toSwingRectangle(getBounds())));
 		
 			// Draw the name
@@ -1327,9 +1322,9 @@
 			if (name == null) name = "Unnamed";
 
-			g.setFont(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT);
-			g.setColor(TrackWidgetCommons.FREESPACE_TRACKNAME_TEXT_COLOR);
+			g.setFont(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT));
+			g.setColor(SwingConversions.toSwingColor(TrackWidgetCommons.FREESPACE_TRACKNAME_TEXT_COLOR));
 			
 			// Center track name
-			FontMetrics fm   = g.getFontMetrics(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT);
+			FontMetrics fm   = g.getFontMetrics(SwingMiscManager.getIfUsingSwingFontManager().getInternalFont(TrackWidgetCommons.FREESPACE_TRACKNAME_FONT));
 			Rectangle2D rect = fm.getStringBounds(name, g);
 			
@@ -1349,9 +1344,10 @@
 
 	@Override
-	public void paint(Graphics g) {
-		super.paint(g);
+	public void paintHeavyDutyWidget(Graphics2D g)
+	{
+		super.paintHeavyDutyWidget(g);
 		
 		if (isLoaded() && nameLabel != null) {
-			nameLabel.paint(g);
+			nameLabel.paint();
 			
 			if (shouldOmitIndexAudio()) {
@@ -1360,9 +1356,13 @@
 						-20 : 0;
 				
-				IconRepository.getIcon("omitindexed.png").paintIcon(
+				/*IconRepository.getIcon("omitindexed.png").paintIcon(
 						_swingComponent, 
 						g, 
 						getX() + getWidth() - EditableSampledTrackGraphView.LOCK_ICON_CORNER_OFFSET + shiftOffset, 
-						getY() + EditableSampledTrackGraphView.LOCK_ICON_CORNER_OFFSET - 16);
+						getY() + EditableSampledTrackGraphView.LOCK_ICON_CORNER_OFFSET - 16);*/
+				
+				g.drawImage(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(IconRepository.getIcon("omitindexed.png")),
+						getX() + getWidth() - EditableSampledTrackGraphView.LOCK_ICON_CORNER_OFFSET + shiftOffset, 
+						getY() + EditableSampledTrackGraphView.LOCK_ICON_CORNER_OFFSET - 16, null);
 				
 			}
@@ -1404,5 +1404,5 @@
 						boolean inferInitTime = true;
 						
-						if (AudioFrameMouseActions.isYAxisRestictionOn()) {
+						if (ApolloGestureActions.isYAxisRestictionOn()) {
 							Mutable.Long ms = getInitiationTimeFromMeta();
 							if (ms != null) {
@@ -1417,7 +1417,8 @@
 						}
 						
-						inferInitTime &= 
-							(AudioFrameMouseActions.isMouseAnchoring() || AudioFrameMouseActions.isMouseStamping());
-
+						// Also must not set initiation time if the frame is simply being displayed
+						//inferInitTime &= (AudioFrameMouseActions.isMouseAnchoring() || AudioFrameMouseActions.isMouseStamping());
+						inferInitTime &= (eventType == ItemParentStateChangedEvent.EVENT_TYPE_ADDED);
+						
 						if (inferInitTime) 
 							initTime = Mutable.createMutableLong(FrameLayoutDaemon.getInstance().getMSAtX(getX(), parent));
@@ -1499,5 +1500,5 @@
 						MouseEventRouter.getCurrentMouseEvent().getButton() == MouseEvent.BUTTON2 &&
 						MouseEventRouter.getCurrentMouseEvent() != lastInsertME) {
-					Frame suspended = DisplayIO.getCurrentFrame();
+					Frame suspended = DisplayController.getCurrentFrame();
 					if (suspended != null) {
 						FrameLayoutDaemon.getInstance().suspendLayout(suspended, this);
@@ -1682,7 +1683,7 @@
 		
 		// Get border color currently used
-		Color oldC = getSource().getBorderColor();
-		
-		Color newC = TrackWidgetCommons.getBorderColor(
+		Colour oldC = getSource().getBorderColor();
+		
+		Colour newC = TrackWidgetCommons.getBorderColor(
 				SoundDesk.getInstance().isSolo(trackMix.getChannelID()), 
 				trackMix.isMuted());
@@ -1772,5 +1773,5 @@
 				// Build the new neighbouring widget
 				Frame target = getParentFrame();
-				if (target == null) target = DisplayIO.getCurrentFrame();
+				if (target == null) target = DisplayController.getCurrentFrame();
 				
 				// Determine init time
@@ -1811,5 +1812,5 @@
 							trackMix);
 					
-					FrameMouseActions.pickup(extractedTrack.getItems());
+					StandardGestureActions.pickup(extractedTrack.getItems());
 					
 				}
@@ -1840,5 +1841,5 @@
 						trackModel,
 						pfname,
-						_swingComponent.getBounds(),
+						SwingConversions.fromSwingRectangle(_swingComponent.getBounds()),
 						trackMix);
 
@@ -1846,5 +1847,5 @@
 
 				// Get rid of all popups
-				PopupManager.getInstance().hideAutohidePopups();
+				PopupManager.getInstance().hideAutoHidePopups();
 				
 				int start = trackModel.getSelectionStart();
@@ -1859,5 +1860,5 @@
 				ExpandedTrackManager.getInstance().expandSingleTrack(
 						trackModel, 
-						_swingComponent.getBounds(),
+						SwingConversions.fromSwingRectangle(_swingComponent.getBounds()),
 						trackMix,
 						pfname,
@@ -1882,19 +1883,16 @@
 	 *
 	 */
-	private class PlaybackPopup extends PlaybackControlPopup implements Observer {
-
-		private static final long serialVersionUID = 1L;
-		
-		public PlaybackPopup() {
+	private class PlaybackPopup extends PlaybackControlPopup implements Observer
+	{
+		public PlaybackPopup()
+		{
 			miscButton.setActionCommand("expand");
-			miscButton.setIcon(IconRepository.getIcon("expand.png"));
+			SwingMiscManager.setJButtonIcon(miscButton, IconRepository.getIcon("expand.png"));
 			miscButton.setToolTipText("Expand");
-
 		}
 
 		@Override
-		public void onHide() {
-			super.onHide();
-			
+		public void onHide()
+		{
 			// Listen for volume or mute changed events
 			trackMix.removeObserver(this);
@@ -1905,6 +1903,6 @@
 
 		@Override
-		public void onShow() {
-			super.onShow();
+		public void onShow()
+		{
 			// Listen for volume or mute changed events
 			trackMix.addObserver(this);
@@ -2016,9 +2014,11 @@
 		}
 		
-		public Subject getObservedSubject() {
+		public Subject getObservedSubject()
+		{
 			return null;
 		}
 
-		public void setObservedSubject(Subject parent) {
+		public void setObservedSubject(Subject parent)
+		{
 		}
 
@@ -2026,6 +2026,6 @@
 		 * Receives events from the track model OR from the observed track sequence.
 		 */
-		public void modelChanged(Subject source, SubjectChangedEvent event) {
-
+		public void modelChanged(Subject source, SubjectChangedEvent event)
+		{
 			// Synch GUI with track state
 			switch (event.getID()) {
@@ -2049,5 +2049,5 @@
 				stopButton.setEnabled(true);
 				rewindButton.setEnabled(false);
-				playPauseButton.setIcon(IconRepository.getIcon("pause.png"));
+				SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("pause.png"));
 				
 				invalidateStateIcons();
@@ -2063,5 +2063,5 @@
 				rewindButton.setEnabled(true);
 				stopButton.setEnabled(false);
-				playPauseButton.setIcon(IconRepository.getIcon("play.png"));
+				SwingMiscManager.setJButtonIcon(playPauseButton, IconRepository.getIcon("play.png"));
 				
 				// Note:
@@ -2109,28 +2109,28 @@
 
 		@Override
-		protected void volumeChanged() {
+		protected void volumeChanged()
+		{
 			trackMix.setVolume(((float)volumeSlider.getValue()) / 100.0f);
 		}
 
 		@Override
-		protected void muteChanged() {
+		protected void muteChanged()
+		{
 			trackMix.setMuted(muteButton.isSelected());
 		}
 
 		@Override
-		protected void soloChanged() {
+		protected void soloChanged()
+		{
 			SoundDesk.getInstance().setSoloIDPrefix(soloButton.isSelected() ?
 					trackMix.getChannelID() : null
 					);
 		}
-		
 	}
 
 	@Override
-	public boolean isWidgetEdgeThicknessAdjustable() {
+	public boolean isWidgetEdgeThicknessAdjustable()
+	{
 		return false;
 	}
-	
-	
-	
 }
Index: /trunk/src/org/apollo/widgets/SearchRecorder.java
===================================================================
--- /trunk/src/org/apollo/widgets/SearchRecorder.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/SearchRecorder.java	(revision 1102)
@@ -30,11 +30,12 @@
 import org.apollo.util.ApolloSystemLog;
 import org.expeditee.actions.Actions;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gio.swing.SwingMiscManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
-
-public class SearchRecorder extends InteractiveWidget 
+import org.expeditee.items.widgets.SwingWidget;
+
+public class SearchRecorder extends SwingWidget 
 	implements ActionListener, Observer {
 	
@@ -68,5 +69,5 @@
 		// Create gui layout
 		recordButton = new JButton();
-		recordButton.setIcon(IconRepository.getIcon("searchmel.png"));
+		SwingMiscManager.setJButtonIcon(recordButton, IconRepository.getIcon("searchmel.png"));
 		recordButton.setToolTipText("Search for audio from live recording");
 		recordButton.addActionListener(this);
@@ -74,5 +75,5 @@
 
 		commitButton = new JButton();
-		commitButton.setIcon(IconRepository.getIcon("commitquery.png"));
+		SwingMiscManager.setJButtonIcon(commitButton, IconRepository.getIcon("commitquery.png"));
 		commitButton.addActionListener(this);
 		commitButton.setToolTipText("GO!");
@@ -82,5 +83,5 @@
 		cancelButton = new JButton();
 		cancelButton.setToolTipText("Cancel");
-		cancelButton.setIcon(IconRepository.getIcon("cancel.png"));
+		SwingMiscManager.setJButtonIcon(cancelButton, IconRepository.getIcon("cancel.png"));
 		cancelButton.addActionListener(this);
 		cancelButton.setPreferredSize(new Dimension(BUTTON_SIZE, BUTTON_SIZE));
@@ -384,5 +385,5 @@
 			if (hasExplicityStopped) {
 				
-				Frame sourceFrame = DisplayIO.getCurrentFrame();
+				Frame sourceFrame = DisplayController.getCurrentFrame();
 				
 				 if (sourceFrame != null &&
Index: /trunk/src/org/apollo/widgets/TrackWidgetCommons.java
===================================================================
--- /trunk/src/org/apollo/widgets/TrackWidgetCommons.java	(revision 1101)
+++ /trunk/src/org/apollo/widgets/TrackWidgetCommons.java	(revision 1102)
@@ -1,9 +1,12 @@
 package org.apollo.widgets;
 
-import java.awt.Color;
-import java.awt.Font;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Font;
 
 public final class TrackWidgetCommons {
-	private TrackWidgetCommons() {
+	
+	/** Static-only class. */
+	private TrackWidgetCommons()
+	{
 	}
 	
@@ -17,13 +20,13 @@
 	public static final int CACHE_DEPTH = 1;
 	
-	public static final Color FREESPACE_TRACKNAME_TEXT_COLOR = Color.WHITE;
-	public static final Font FREESPACE_TRACKNAME_FONT = new Font("Arial", Font.BOLD, 20);
+	public static final Colour FREESPACE_TRACKNAME_TEXT_COLOR = Colour.WHITE;
+	public static final Font FREESPACE_TRACKNAME_FONT = new Font("Arial", Font.Style.BOLD, 20);
 	
 	public static final int POPUP_LIFETIME = 1500;
 	
-	public static final Color STANDARD_TRACK_EDGE_COLOR = Color.BLACK;
-	public static final Color MUTED_TRACK_EDGE_COLOR = Color.GRAY;
-	public static final Color SOLO_TRACK_EDGE_COLOR = Color.RED;
-	public static final Color MUTED_SOLO_TRACK_EDGE_COLOR = new Color(255, 168, 168);
+	public static final Colour STANDARD_TRACK_EDGE_COLOR = Colour.BLACK;
+	public static final Colour MUTED_TRACK_EDGE_COLOR = Colour.GREY;
+	public static final Colour SOLO_TRACK_EDGE_COLOR = Colour.RED;
+	public static final Colour MUTED_SOLO_TRACK_EDGE_COLOR = Colour.FromRGB255(255, 168, 168);
 	
 	public static final float STOPPED_TRACK_EDGE_THICKNESS = 1.0f;
@@ -31,7 +34,7 @@
 	
 
-	public static Color getBorderColor(boolean isSolo, boolean isMuted) {
+	public static Colour getBorderColor(boolean isSolo, boolean isMuted) {
 		
-		Color newC = null;
+		Colour newC = null;
 		
 		if (isSolo && isMuted) {
Index: /trunk/src/org/expeditee/actions/Actions.java
===================================================================
--- /trunk/src/org/expeditee/actions/Actions.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Actions.java	(revision 1102)
@@ -19,6 +19,4 @@
 package org.expeditee.actions;
 
-import java.awt.GraphicsEnvironment;
-import java.io.Serializable;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -26,5 +24,4 @@
 import java.rmi.UnexpectedException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
@@ -35,7 +32,7 @@
 
 import org.expeditee.agents.Agent;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
 import org.expeditee.gui.FrameUtils;
@@ -217,7 +214,7 @@
 	 *         actions.
 	 */
-	public static Collection<String> Init() {
-
-		Collection<String> warnings = new LinkedList<String>();
+	public static List<String> Init() {
+
+		List<String> warnings = new LinkedList<String>();
 		List<Class<?>> classes;
 
@@ -436,5 +433,5 @@
 		// 	loose changes
 		if (firstCanditate.getDeclaringClass().getName().equals(NAVIGATIONS_CLASS)) {
-			FrameIO.SaveFrame(DisplayIO.getCurrentFrame());
+			FrameIO.SaveFrame(DisplayController.getCurrentFrame());
 		}
 		final List<Method> canditates = new LinkedList<Method>();
@@ -825,5 +822,5 @@
 					+ nameWithCorrectCase + "'");
 		}
-		FrameGraphics.refresh(false);
+		DisplayController.requestRefresh(false);
 	}
 
@@ -1031,7 +1028,5 @@
 	private static void initFonts() {
 		if (_Fonts.size() == 0) {
-			String[] availableFonts = GraphicsEnvironment
-					.getLocalGraphicsEnvironment()
-					.getAvailableFontFamilyNames();
+			String[] availableFonts = EcosystemManager.getFontManager().getRegisteredFontFamilies();
 			for (String s : availableFonts) {
 				_Fonts.put(s.toLowerCase(), s);
Index: /trunk/src/org/expeditee/actions/Debug.java
===================================================================
--- /trunk/src/org/expeditee/actions/Debug.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Debug.java	(revision 1102)
@@ -21,5 +21,5 @@
 import java.util.List;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Constraint;
 import org.expeditee.items.Item;
@@ -38,5 +38,5 @@
 	 */
 	public static void ShowConstraints() {
-		List<Item> items = DisplayIO.getCurrentFrame().getItems();
+		List<Item> items = DisplayController.getCurrentFrame().getItems();
 
 		for (Item i : items)
Index: /trunk/src/org/expeditee/actions/ExploratorySearchActions.java
===================================================================
--- /trunk/src/org/expeditee/actions/ExploratorySearchActions.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/ExploratorySearchActions.java	(revision 1102)
@@ -19,10 +19,11 @@
 package org.expeditee.actions;
 
+import org.expeditee.core.Point;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameKeyboardActions;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FreeItems;
 import org.expeditee.items.Item;
@@ -59,8 +60,8 @@
 			}
 			
-			Text linkToBrowserSession = DisplayIO.getCurrentFrame().addText(FrameMouseActions.getX(), FrameMouseActions.getY(), " - Web Browser Session", null);
-			linkToBrowserSession.setParent(DisplayIO.getCurrentFrame());
-			FrameKeyboardActions.AddDate(linkToBrowserSession);
-			FrameMouseActions.pickup(linkToBrowserSession);
+			Text linkToBrowserSession = DisplayController.getCurrentFrame().addText(DisplayController.getMouseX(), DisplayController.getMouseY(), " - Web Browser Session", null);
+			linkToBrowserSession.setParent(DisplayController.getCurrentFrame());
+			Text.AddDate(linkToBrowserSession);
+			StandardGestureActions.pickup(linkToBrowserSession);
 			
 			// Create new frame
@@ -75,6 +76,6 @@
 			// Add web browser active overlay and @old
 			Text t = (Text) frame.addText(-150, 50, "@ao: 2", null, "overlayset2");
-			t.setAnchorRight(-100.0f);
-			t.setAnchorTop(50.0f);
+			t.setAnchorRight(-100);
+			t.setAnchorTop(50);
 			t = (Text) frame.addText(-150, 50, "@old", null);
 			t.setFamily("Roboto Condensed");
@@ -84,6 +85,6 @@
 			t.setJustification(Justification.right);
 			t.setLinkMark(false);
-			t.setAnchorLeft(9.0f);
-			t.setAnchorBottom(114.0f);
+			t.setAnchorLeft(9);
+			t.setAnchorBottom(114);
 			
 			Text wt;
@@ -101,6 +102,6 @@
 						+ ("--anchorLeft " + (lm + ExploratorySearchSettings.BROWSER_HORZ_OFFSET) + " --anchorRight " + rm + " --anchorTop " 
 						+ (ExploratorySearchSettings.BROWSER_VERT_OFFSET + tm) + " --anchorBottom " + bm + " ")
-						+ (Browser._theBrowser.getContentPane().getWidth() - ExploratorySearchSettings.BROWSER_HORZ_OFFSET - lm - rm) + " " 
-						+ (Browser._theBrowser.getContentPane().getHeight() - ExploratorySearchSettings.BROWSER_VERT_OFFSET - tm - bm) + " : " + url, null);
+						+ (EcosystemManager.getGraphicsManager().getWindowSize().getWidth() - ExploratorySearchSettings.BROWSER_HORZ_OFFSET - lm - rm) + " " 
+						+ (EcosystemManager.getGraphicsManager().getWindowSize().getHeight() - ExploratorySearchSettings.BROWSER_VERT_OFFSET - tm - bm) + " : " + url, null);
 			} else {
 				wt = frame.addText(ExploratorySearchSettings.BROWSER_HORZ_OFFSET + lm, ExploratorySearchSettings.BROWSER_VERT_OFFSET + tm,
@@ -122,8 +123,9 @@
 		// Replace any text item on cursor with link to a new mindmap
 		FreeItems.getInstance().clear();
-		Text text = DisplayIO.getCurrentFrame().addText(FrameMouseActions.getX(), FrameMouseActions.getY(), " - Mindmap Session", null);
-		text.setParent(DisplayIO.getCurrentFrame());
-		FrameKeyboardActions.AddDate(text);
-		FrameMouseActions.pickup(text);
+		Point cursorPos = DisplayController.getMousePosition();
+		Text text = DisplayController.getCurrentFrame().addText(cursorPos.getX(), cursorPos.getY(), " - Mindmap Session", null);
+		text.setParent(DisplayController.getCurrentFrame());
+		Text.AddDate(text);
+		StandardGestureActions.pickup(text);
 		Frame frame = FrameIO.CreateNewFrame(text);
 		text.setLink("" + frame.getNumber());
@@ -132,6 +134,6 @@
 		frame.removeAllItems(frame.getItems());
 		Text t = (Text) frame.addText(-150, 50, "@ao: 2", null, "overlayset3");
-		t.setAnchorLeft(-150.0f);
-		t.setAnchorTop(50.0f);
+		t.setAnchorLeft(-150);
+		t.setAnchorTop(50);
 		t = (Text) frame.addText(-150, 50, "@old", null);
 		t.setFamily("Roboto Condensed");
@@ -141,6 +143,6 @@
 		t.setJustification(Justification.right);
 		t.setLinkMark(false);
-		t.setAnchorLeft(9.0f);
-		t.setAnchorBottom(114.0f);
+		t.setAnchorLeft(9);
+		t.setAnchorBottom(114);
 		
 		FrameIO.SaveFrame(frame);
@@ -168,7 +170,8 @@
 			}
 			
-			Text linkToBrowserSession = DisplayIO.getCurrentFrame().addText(FrameMouseActions.getX(), FrameMouseActions.getY(), url, null);
-			linkToBrowserSession.setParent(DisplayIO.getCurrentFrame());
-			FrameMouseActions.pickup(linkToBrowserSession);
+			Point cursorPos = DisplayController.getMousePosition();
+			Text linkToBrowserSession = DisplayController.getCurrentFrame().addText(cursorPos.getX(), cursorPos.getY(), url, null);
+			linkToBrowserSession.setParent(DisplayController.getCurrentFrame());
+			StandardGestureActions.pickup(linkToBrowserSession);
 			
 			// Create new frame
@@ -183,6 +186,6 @@
 			// Add web browser active overlay and @old
 			Text t = (Text) frame.addText(-150, 50, "@ao: 2", null, "overlayset2");
-			t.setAnchorLeft(-150.0f);
-			t.setAnchorTop(50.0f);
+			t.setAnchorLeft(-150);
+			t.setAnchorTop(50);
 			t = (Text) frame.addText(-150, 50, "@old", null);
 			t.setFamily("Roboto Condensed");
@@ -192,6 +195,6 @@
 			t.setJustification(Justification.right);
 			t.setLinkMark(false);
-			t.setAnchorLeft(9.0f);
-			t.setAnchorBottom(114.0f);
+			t.setAnchorLeft(9);
+			t.setAnchorBottom(114);
 			
 			Text wt;
@@ -209,6 +212,6 @@
 						+ ("--anchorLeft " + (lm + ExploratorySearchSettings.BROWSER_HORZ_OFFSET) + " --anchorRight " + rm + " --anchorTop " 
 						+ (ExploratorySearchSettings.BROWSER_VERT_OFFSET + tm) + " --anchorBottom " + bm + " ")
-						+ (Browser._theBrowser.getContentPane().getWidth() - ExploratorySearchSettings.BROWSER_HORZ_OFFSET - lm - rm) + " " 
-						+ (Browser._theBrowser.getContentPane().getHeight() - ExploratorySearchSettings.BROWSER_VERT_OFFSET - tm - bm) + " : " + url, null);
+						+ (EcosystemManager.getGraphicsManager().getWindowSize().getWidth() - ExploratorySearchSettings.BROWSER_HORZ_OFFSET - lm - rm) + " " 
+						+ (EcosystemManager.getGraphicsManager().getWindowSize().getHeight() - ExploratorySearchSettings.BROWSER_VERT_OFFSET - tm - bm) + " : " + url, null);
 			} else {
 				wt = frame.addText(ExploratorySearchSettings.BROWSER_HORZ_OFFSET + lm, ExploratorySearchSettings.BROWSER_VERT_OFFSET + tm,
Index: /trunk/src/org/expeditee/actions/GreenstoneActions.java
===================================================================
--- /trunk/src/org/expeditee/actions/GreenstoneActions.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/GreenstoneActions.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -25,4 +24,5 @@
 
 import org.expeditee.agents.SearchGreenstone;
+import org.expeditee.core.Colour;
 import org.expeditee.greenstone.ResultDocument;
 import org.expeditee.gui.AttributeValuePair;
@@ -134,5 +134,5 @@
 			}
 		}
-		MessageBay.displayMessage("Feedback complete", null, Color.green
+		MessageBay.displayMessage("Feedback complete", null, Colour.GREEN
 				.darker(), true, null);
 	}
Index: /trunk/src/org/expeditee/actions/Help.java
===================================================================
--- /trunk/src/org/expeditee/actions/Help.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Help.java	(revision 1102)
@@ -25,7 +25,7 @@
 import java.util.List;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -77,7 +77,7 @@
 		});
 
-		Frame current = DisplayIO.getCurrentFrame();
-		float x = FrameMouseActions.MouseX;
-		float y = FrameMouseActions.MouseY;
+		Frame current = DisplayController.getCurrentFrame();
+		float x = DisplayController.getFloatMouseX();
+		float y = DisplayController.getFloatMouseY();
 
 		// Do case sensitive comparison
Index: /trunk/src/org/expeditee/actions/IDE.java
===================================================================
--- /trunk/src/org/expeditee/actions/IDE.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/IDE.java	(revision 1102)
@@ -19,11 +19,9 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.InputStreamReader;
 
 import org.expeditee.agents.WriteTree;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -37,5 +35,5 @@
 		int exitVal = 0; // default's to status OK
 		
-		Frame source = DisplayIO.getCurrentFrame();
+		Frame source = DisplayController.getCurrentFrame();
 		String title = source.getTitleItem().getText();
 		String[] tokens = title.split("\\s+");
@@ -72,5 +70,5 @@
 				}
 				else {
-					MessageBay.displayMessage("Compiled " + fileName, Color.darkGray);
+					MessageBay.displayMessage("Compiled " + fileName, Colour.DARK_GREY);
 				}
 			} catch (Exception e) {
@@ -101,5 +99,5 @@
 	
 	public static void RunClass() {
-		Frame source = DisplayIO.getCurrentFrame();
+		Frame source = DisplayController.getCurrentFrame();
 		String className = getClassName(source);
 		try {
Index: /trunk/src/org/expeditee/actions/Javascript.java
===================================================================
--- /trunk/src/org/expeditee/actions/Javascript.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Javascript.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
 import java.util.LinkedList;
 import java.util.List;
@@ -26,7 +25,7 @@
 import org.expeditee.agents.Agent;
 import org.expeditee.agents.DefaultAgent;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
 import org.expeditee.gui.MessageBay;
@@ -75,5 +74,5 @@
 	private static int _stepPause = -1;
 
-	private static Color _stepColor;
+	private static Colour _stepColor;
 
 	private static boolean _nextStatement;
@@ -93,5 +92,5 @@
 	//Have changed parameters, so it takes an Item, not just a Text item.
 	private static void RunJavascriptFrame(Frame frame, Item current,
-			boolean acceptKeyboardInput, boolean step, int pause, Color color) {
+			boolean acceptKeyboardInput, boolean step, int pause, Colour color) {
 		try {
 			if (current != null) {
@@ -101,5 +100,5 @@
 				 */
 				// DisplayIO.addToBack(current.getParent());
-				DisplayIO.addToBack(DisplayIO.getCurrentFrame());
+				DisplayController.addToBack(DisplayController.getCurrentFrame());
 			} else {
 				/* TODO we should not have to pass an item just to run a frame! */
@@ -108,7 +107,7 @@
 			}
 
-			_stepColor = color == null ? Color.green : color;
-			_stepColor = new Color(_stepColor.getRed(), _stepColor.getGreen(),
-					_stepColor.getBlue(), 50);
+			_stepColor = color == null ? Colour.GREEN : color;
+			_stepColor = new Colour(_stepColor.getRed(), _stepColor.getGreen(),
+					_stepColor.getBlue(), Colour.FromComponent255(50));
 			_stepPause = pause;
 			_step = step;
@@ -168,5 +167,5 @@
 		FrameUtils.DisplayFrame(item.getParent().getName(), true, true);
 		item.setHighlightMode(HighlightMode.Normal);
-		item.setHighlightColor(Color.CYAN);
+		item.setHighlightColor(Colour.CYAN);
 		FrameIO.SaveFrame(item.getParent());
 	}
@@ -192,8 +191,8 @@
 
 		if (_step) {
-			if (child != DisplayIO.getCurrentFrame()) {
-				DisplayIO.setCurrentFrame(child, true);
-			}
-			DisplayIO.addToBack(child);
+			if (child != DisplayController.getCurrentFrame()) {
+				DisplayController.setCurrentFrame(child, true);
+			}
+			DisplayController.addToBack(child);
 		}
 
@@ -216,5 +215,5 @@
 			AgentStats.ItemExecuted();
 			try {
-				Color oldColor = item.getBackgroundColor();
+				Colour oldColor = item.getBackgroundColor();
 				if (_step) {
 					pause(item);
@@ -226,4 +225,5 @@
 					} else {
 						item.setHighlightMode(Item.HighlightMode.None);
+						item.setHighlightColorToDefault();
 					}
 				}
@@ -233,5 +233,5 @@
 							&& lastItemStatus != Status.FalseIf) {
 						if (_step) {
-							DisplayIO.removeFromBack();
+							DisplayController.removeFromBack();
 						}
 						return lastItemStatus;
@@ -257,7 +257,7 @@
 
 		if (_step) {
-			DisplayIO.removeFromBack();
-			if (DisplayIO.getCurrentFrame() != current.getParent())
-				DisplayIO.setCurrentFrame(current.getParent(), true);
+			DisplayController.removeFromBack();
+			if (DisplayController.getCurrentFrame() != current.getParent())
+				DisplayController.setCurrentFrame(current.getParent(), true);
 		}
 
@@ -276,15 +276,16 @@
 			return;
 
-		Color oldColor = item.getBackgroundColor();
+		Colour oldColor = item.getBackgroundColor();
 		item.setBackgroundColor(_stepColor);
 		item.setHighlightMode(Item.HighlightMode.None);
+		item.setHighlightColorToDefault();
 
 		// Make sure we are on the frame with this item
 		Frame parent = item.getParentOrCurrentFrame();
-		if (!parent.equals(DisplayIO.getCurrentFrame())) {
-			DisplayIO.setCurrentFrame(parent, true);
-		}
-
-		FrameGraphics.Repaint();
+		if (!parent.equals(DisplayController.getCurrentFrame())) {
+			DisplayController.setCurrentFrame(parent, true);
+		}
+
+		DisplayController.requestRefresh(true);
 
 		int timeRemaining;
@@ -297,5 +298,5 @@
 			if (_stop) {
 				item.setBackgroundColor(oldColor);
-				item.setHighlightMode(HighlightMode.Normal, _stepColor);
+				item.setHighlightModeAndColour(HighlightMode.Normal, _stepColor);
 				throw new Exception("Program terminated");
 			}
@@ -388,5 +389,5 @@
 		_programsRunning++;
 		AgentStats.reset();
-		MessageBay.displayMessage("Running Javascript Program ...", Color.BLUE);
+		MessageBay.displayMessage("Running Javascript Program ...", Colour.BLUE);
 	}
 
Index: /trunk/src/org/expeditee/actions/Javascript2.java
===================================================================
--- /trunk/src/org/expeditee/actions/Javascript2.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Javascript2.java	(revision 1102)
@@ -19,25 +19,9 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.script.Bindings;
 import javax.script.Invocable;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import javax.script.SimpleScriptContext;
 
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
-import org.expeditee.io.flowlayout.XGroupItem;
 import org.expeditee.items.Item;
-import org.expeditee.items.ItemUtils;
-import org.expeditee.items.Text;
 
 /**
Index: /trunk/src/org/expeditee/actions/JfxBrowserActions.java
===================================================================
--- /trunk/src/org/expeditee/actions/JfxBrowserActions.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/JfxBrowserActions.java	(revision 1102)
@@ -22,17 +22,13 @@
 import java.io.InputStreamReader;
 import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLEncoder;
 import java.util.ArrayList;
 
-import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.FreeItems;
@@ -42,7 +38,6 @@
 import org.expeditee.items.Picture;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.JfxBrowser;
-import org.expeditee.settings.exploratorysearch.ExploratorySearchSettings;
 import org.expeditee.settings.network.NetworkSettings;
 import org.json.simple.JSONObject;
@@ -83,11 +78,11 @@
 		FreeItems.getInstance().clear();					// remove url text from cursor
 		
-		wt.setParent(DisplayIO.getCurrentFrame());			// set parent of text source for InteractiveWidget.createWidget()
-		wt.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
+		wt.setParent(DisplayController.getCurrentFrame());			// set parent of text source for InteractiveWidget.createWidget()
+		wt.setXY(DisplayController.getMouseX(), DisplayController.getMouseY());
 		
 		// create widget from text item
-		JfxBrowser browser = (JfxBrowser) InteractiveWidget.createWidget(wt);
+		JfxBrowser browser = (JfxBrowser) Widget.createWidget(wt);
 			
-		FrameMouseActions.pickup(browser.getItems());		// attach browser widget to mouse
+		StandardGestureActions.pickup(browser.getItems());		// attach browser widget to mouse
 	}
 	
@@ -109,8 +104,8 @@
 		// If no text with url is passed to action create a new text item with http://www.waikato.ac.nz for a default url
 		if(!FreeItems.textOnlyAttachedToCursor()) {
-			text = DisplayIO.getCurrentFrame().addText(FrameMouseActions.getX(), FrameMouseActions.getY(), 
+			text = DisplayController.getCurrentFrame().addText(DisplayController.getMouseX(), DisplayController.getMouseY(), 
 					NetworkSettings.HomePage.get(), null);
-			text.setParent(DisplayIO.getCurrentFrame());	// set parent of text source for InteractiveWidget.createWidget()
-			FrameMouseActions.pickup(text);					// Attach new text link to cursor
+			text.setParent(DisplayController.getCurrentFrame());	// set parent of text source for InteractiveWidget.createWidget()
+			StandardGestureActions.pickup(text);					// Attach new text link to cursor
 		}
 		
@@ -123,8 +118,8 @@
 		Text wt = frame.addText(0, 0, "@iw: org.expeditee.items.widgets.JfxBrowser " 
 				+ ("--anchorLeft 0 --anchorRight 0 --anchorTop 0 --anchorBottom 0 ")
-				+ Browser._theBrowser.getContentPane().getWidth() +  " " + Browser._theBrowser.getContentPane().getHeight() 
+				+ EcosystemManager.getGraphicsManager().getWindowSize().getWidth() +  " " + EcosystemManager.getGraphicsManager().getWindowSize().getHeight() 
 				+ " : " + text.getText(), null);
 		
-		InteractiveWidget.createWidget(wt);
+		Widget.createWidget(wt);
 		
 		FrameIO.SaveFrame(frame);							// save frame to disk
@@ -179,6 +174,6 @@
 
 		// Create widget via text annotation
-		frame.addText(10, 10, "@iw: org.expeditee.items.widgets.JfxBrowser " + (int) (FrameGraphics.getMaxFrameSize().getWidth() * 0.9) + " "
-				+ (int) (FrameGraphics.getMaxFrameSize().getHeight() * 0.9) + " : " + url, null);
+		frame.addText(10, 10, "@iw: org.expeditee.items.widgets.JfxBrowser " + (int) (DisplayController.getFramePaintArea().getWidth() * 0.9) + " "
+				+ (int) (DisplayController.getFramePaintArea().getHeight() * 0.9) + " : " + url, null);
 
 		FrameIO.SaveFrame(frame);
@@ -294,5 +289,5 @@
 
 					if (!picSource.equals("")) {
-						pic = WebParser.getImageFromUrl(picSource, null, DisplayIO.getCurrentFrame(), 0, 0, 50, null, null,
+						pic = WebParser.getImageFromUrl(picSource, null, DisplayController.getCurrentFrame(), 0, 0, 50, null, null,
 								null, null, null, 0, 0);
 						items.add(pic);
@@ -300,5 +295,5 @@
 					}
 
-					titleItem.setPosition(FrameMouseActions.getPosition());
+					titleItem.setPosition(DisplayController.getMousePosition());
 					mainTextItem.setPosition(titleItem.getX(), titleItem.getY() + titleItem.getBoundsHeight());
 					sourceItem.setPosition(mainTextItem.getX(), mainTextItem.getY() + mainTextItem.getBoundsHeight());
@@ -313,5 +308,5 @@
 					items.add(sourceItem);
 					items.add(ddgLink);
-					FrameMouseActions.pickup(items);
+					StandardGestureActions.pickup(items);
 				} catch (IOException e) {
 					MessageBay.displayMessage("Problem loading results");
Index: /trunk/src/org/expeditee/actions/Mail.java
===================================================================
--- /trunk/src/org/expeditee/actions/Mail.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Mail.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
 import java.util.Collection;
 
@@ -25,9 +24,10 @@
 
 import org.expeditee.agents.mail.MailSession;
+import org.expeditee.core.Colour;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.gui.AttributeValuePair;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameKeyboardActions;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.MessageBay;
 import org.expeditee.items.Item;
@@ -116,5 +116,5 @@
 	public static Text getMailByID(int messageNo) {
 		Text mailItem = MailSession.getInstance().getMail(
-				DisplayIO.getCurrentFrame(), FrameMouseActions.getPosition(),
+				DisplayController.getCurrentFrame(), DisplayController.getMousePosition(),
 				messageNo - 1);
 		// MessageBay.displayMessage(mailItems.size() + " messages read",
@@ -139,6 +139,6 @@
 			int noOfMessages) {
 		Collection<Text> mailItems = MailSession.getInstance().getMail(flag,
-				isPresent, DisplayIO.getCurrentFrame(),
-				FrameMouseActions.getPosition(), noOfMessages);
+				isPresent, DisplayController.getCurrentFrame(),
+				DisplayController.getMousePosition(), noOfMessages);
 		// MessageBay.displayMessage(mailItems.size() + " messages read",
 		// Color.green);
@@ -187,7 +187,7 @@
 
 		reply.setActions(null);
-		FrameMouseActions.tdfc(reply);
-
-		Frame replyFrame = DisplayIO.getCurrentFrame();
+		StandardGestureActions.tdfc(reply);
+
+		Frame replyFrame = DisplayController.getCurrentFrame();
 		String titleText = frame.getTitle();
 		// Add Re on the end if it is not already there
@@ -197,18 +197,17 @@
 		}
 		replyFrame.setTitle(titleText);
-		FrameKeyboardActions.Drop(null, false);
+		StandardGestureActions.Drop(null, false);
 
 		// Add a link to the original message
 		Text original = replyFrame.createNewText("@original");
-		original.setPosition(FrameMouseActions.getPosition());
+		original.setPosition(DisplayController.getMousePosition());
 		original.setLink(frame.getName());
-		FrameKeyboardActions.Drop(original, false);
+		StandardGestureActions.Drop(original, false);
 
 		Text to = replyFrame.createNewText("@to: " + fromAddress);
-		to.setPosition(FrameMouseActions.getPosition());
+		to.setPosition(DisplayController.getMousePosition());
 		to.addAction("MailTree");
-		FrameKeyboardActions.Drop(to, false);
-		DisplayIO.setCursorPosition(FrameMouseActions.MouseX,
-				FrameMouseActions.MouseY + 15);
+		StandardGestureActions.Drop(to, false);
+		DisplayController.setCursorPosition(DisplayController.getMouseX(), DisplayController.getMouseY() + 15);
 	}
 
@@ -216,5 +215,5 @@
 		if (FrameShare.getInstance().sendMessage(message, peerName)) {
 			MessageBay.displayMessage("Sent message to " + peerName,
-					Color.green.darker());
+					Colour.GREEN.darker());
 		} else {
 			MessageBay.errorMessage("Could not find " + peerName);
Index: /trunk/src/org/expeditee/actions/Misc.java
===================================================================
--- /trunk/src/org/expeditee/actions/Misc.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Misc.java	(revision 1102)
@@ -19,9 +19,4 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
-import java.awt.Desktop;
-import java.awt.Image;
-import java.awt.image.BufferedImage;
-import java.awt.image.VolatileImage;
 import java.io.BufferedReader;
 import java.io.File;
@@ -31,6 +26,4 @@
 import java.io.InputStreamReader;
 import java.lang.reflect.Method;
-import java.net.URI;
-import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -39,22 +32,20 @@
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Map.Entry;
-import java.util.Set;
 import java.util.jar.Attributes;
 import java.util.jar.JarFile;
 
-import javax.imageio.ImageIO;
-
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
+import org.expeditee.core.Point;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.gui.AttributeUtils;
-import org.expeditee.gui.Browser;
 import org.expeditee.io.Conversion;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.io.ExpReader;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameKeyboardActions;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.FreeItems;
@@ -63,5 +54,4 @@
 import org.expeditee.gui.Reminders;
 import org.expeditee.gui.TimeKeeper;
-import org.expeditee.importer.FrameDNDTransferHandler;
 import org.expeditee.items.Item;
 import org.expeditee.items.ItemUtils;
@@ -69,5 +59,5 @@
 import org.expeditee.items.Text;
 import org.expeditee.items.XRayable;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.items.widgets.WidgetEdge;
@@ -83,10 +73,8 @@
 import org.nfunk.jep.ParseException;
 
-import com.lowagie.text.Font;
-
 
 
 /**
- * A list of miscellaneous Actions and Actions specific to Expeditee
+ * A list of miscellaneous Actions specific to Expeditee
  * 
  */
@@ -96,6 +84,7 @@
 	 * Causes the system to beep
 	 */
-	public static void beep() {
-		java.awt.Toolkit.getDefaultToolkit().beep();
+	public static void beep()
+	{
+		EcosystemManager.getMiscManager().beep();
 	}
 	
@@ -161,14 +150,9 @@
 	 * Treats a string as a URL and attempts to open it
 	 */
-	public static void openURL(String siteURL){
-		
-		try {
-			URL check = new URL(siteURL);			
-			Desktop.getDesktop().browse(new URI(siteURL));
-			
-		} catch (IOException| URISyntaxException e) {
-		
-			MessageBay.displayMessage("'" + siteURL + "' is not a valid URL");
-		}		
+	public static void openURL(String siteURL)
+	{
+		boolean success = EcosystemManager.getMiscManager().browse(siteURL);
+		
+		if (!success) MessageBay.displayMessage("'" + siteURL + "' is not a valid URL");	
 	}
 	/**
@@ -177,5 +161,5 @@
 	public static void setRestorePoint()
 	{
-		Frame current = DisplayIO.getCurrentFrame();
+		Frame current = DisplayController.getCurrentFrame();
 		current.change();
 		FrameIO.SaveFrameAsRestore(current, true, true);		
@@ -185,9 +169,9 @@
 	 */
 	public static void display() {
-		FrameGraphics.refresh(false);
+		DisplayController.requestRefresh(false);
 	}
 	
 	public static String getWindowSize() {
-		return Browser.getWindows()[0].getSize().toString();
+		return EcosystemManager.getGraphicsManager().getWindowSize().toString();
 	}
 
@@ -205,5 +189,5 @@
 	 */
 	public static void toggleAudienceMode() {
-		FrameGraphics.ToggleAudienceMode();
+		DisplayController.ToggleAudienceMode();
 	}
 
@@ -212,5 +196,5 @@
 	 */
 	public static void toggleTwinFramesMode() {
-		DisplayIO.ToggleTwinFrames();
+		DisplayController.toggleTwinFrames();
 	}
 
@@ -227,5 +211,5 @@
 			for (String action : actions) {
 				if (!action.equalsIgnoreCase("runitem")) {
-					Actions.PerformAction(DisplayIO.getCurrentFrame(), current,
+					Actions.PerformAction(DisplayController.getCurrentFrame(), current,
 							action);
 				}
@@ -249,8 +233,8 @@
 			String deletedFrameName = FrameIO.DeleteFrame(toDelete);
 			if (deletedFrameName != null) {
-				DisplayIO.Back();
+				DisplayController.Back();
 				// Remove any links on the previous frame to the one being
 				// deleted
-				Frame current = DisplayIO.getCurrentFrame();
+				Frame current = DisplayController.getCurrentFrame();
 				for (Item i : current.getItems())
 					if (i.getLink() != null
@@ -312,5 +296,5 @@
 			// copy the item and switch
 			item = item.copy();
-			item.setPosition(DisplayIO.getMouseX(), FrameMouseActions.getY());
+			item.setPosition(DisplayController.getMousePosition());
 		}
 		return item;
@@ -327,6 +311,6 @@
 		Collection<Item> copies = ItemUtils.CopyItems(items);
 		Item first = items.iterator().next();
-		float deltaX = DisplayIO.getMouseX() - first.getX();
-		float deltaY = FrameMouseActions.getY() - first.getY();
+		float deltaX = DisplayController.getMouseX() - first.getX();
+		float deltaY = DisplayController.getMouseY() - first.getY();
 		for (Item i : copies) {
 			if (i.isVisible())
@@ -334,6 +318,6 @@
 			i.setParent(null);
 		}
-		FrameMouseActions.pickup(copies);
-		FrameGraphics.Repaint();
+		StandardGestureActions.pickup(copies);
+		DisplayController.requestRefresh(true);
 	}
 	
@@ -347,10 +331,10 @@
 	 *            The Color to give the Item.
 	 */
-	public static void SetItemBackgroundColor(Item toChange, Color toUse) {
+	public static void SetItemBackgroundColor(Item toChange, Colour toUse) {
 		if (toChange == null)
 			return;
 
 		toChange.setBackgroundColor(toUse);
-		FrameGraphics.Repaint();
+		DisplayController.requestRefresh(true);
 	}
 
@@ -364,10 +348,10 @@
 	 *            The Color to give the Item.
 	 */
-	public static void SetItemColor(Item toChange, Color toUse) {
+	public static void SetItemColor(Item toChange, Colour toUse) {
 		if (toChange == null)
 			return;
 
 		toChange.setColor(toUse);
-		FrameGraphics.Repaint();
+		DisplayController.requestRefresh(true);
 	}
 
@@ -428,16 +412,16 @@
 	public static void attachStatsToCursor(String itemText) {
 		SessionStats.CreatedText();
-		Frame current = DisplayIO.getCurrentFrame();
+		Frame current = DisplayController.getCurrentFrame();
 		Item text = current.getStatsTextItem(itemText);
-		FrameMouseActions.pickup(text);
-		FrameGraphics.Repaint();
+		StandardGestureActions.pickup(text);
+		DisplayController.requestRefresh(true);
 	}
 
 	public static void attachTextToCursor(String itemText) {
 		SessionStats.CreatedText();
-		Frame current = DisplayIO.getCurrentFrame();
+		Frame current = DisplayController.getCurrentFrame();
 		Item text = current.getTextItem(itemText);
-		FrameMouseActions.pickup(text);
-		FrameGraphics.Repaint();
+		StandardGestureActions.pickup(text);
+		DisplayController.requestRefresh(true);
 	}
 	
@@ -494,5 +478,5 @@
 		}
 
-		for (Entry<String, java.awt.Font> entry: Text.FONT_WHEEL_ADDITIONAL_LOOKUP.entrySet()){
+		for (Entry<String, org.expeditee.core.Font> entry: Text.FONT_WHEEL_ADDITIONAL_LOOKUP.entrySet()){
 			
 			String fontName = entry.getKey();
@@ -585,5 +569,5 @@
 	 */
 	public static void jpegFrame() {
-		ImageFrame(DisplayIO.getCurrentFrame().getName(), "JPEG");
+		ImageFrame(DisplayController.getCurrentFrame().getName(), "JPEG");
 	}
 
@@ -610,5 +594,5 @@
 	}
 
-	public static String SaveImage(BufferedImage screen, String format,
+	public static String SaveImage(Image screen, String format,
 			String directory, String fileName) {
 		String suffix = "." + format.toLowerCase();
@@ -633,5 +617,5 @@
 
 			// If the image is successfully written out return the fileName
-			if (ImageIO.write(screen, format, out))
+			if (screen.writeToDisk(format, out))
 				return fileName;
 
@@ -647,21 +631,12 @@
 		Image oldBuffer = frame.getBuffer();
 		frame.setBuffer(null);
-		// Jpeg only works properly with volitile frames
+		// Jpeg only works properly with volatile frames
 		// Png transparency only works with bufferedImage form
-		Image frameBuffer = FrameGraphics.getBuffer(frame, false, format
-				.equalsIgnoreCase("jpeg"));
-		// Make sure overlay stuff doesnt disapear on the frame visible on the
+		Image frameBuffer = FrameGraphics.getFrameImage(frame, null, null, false, format.equalsIgnoreCase("jpeg"));
+		// Make sure overlay stuff doesnt disappear on the frame visible on the
 		// screen
 		frame.setBuffer(oldBuffer);
-		BufferedImage screen = null;
-
-		if (frameBuffer instanceof VolatileImage) {
-			// If its the current frame it will be a volitive image
-			screen = ((VolatileImage) frameBuffer).getSnapshot();
-		} else {
-			assert (frameBuffer instanceof BufferedImage);
-			screen = (BufferedImage) frameBuffer;
-		}
-		return SaveImage(screen, format, directory, frame.getExportFileName());
+		
+		return SaveImage(frameBuffer, format, directory, frame.getExportFileName());
 	}
 
@@ -842,5 +817,5 @@
 		current.setActions(null);
 
-		FrameGraphics.Repaint();
+		DisplayController.requestRefresh(true);
 	}
 
@@ -932,7 +907,7 @@
 				text.setFormula(formulaFullCase);
 				if (text.isFloating()) {
-					text.setPosition(FrameMouseActions.MouseX,
-							FrameMouseActions.MouseY);
-					FrameMouseActions.resetOffset();
+					Point cursorPos = EcosystemManager.getInputManager().getCursorPosition();
+					text.setPosition(cursorPos.x, cursorPos.y);
+					StandardGestureActions.resetOffset();
 				} else {
 					text.getParentOrCurrentFrame().change();
@@ -956,6 +931,6 @@
 	public static void attachToCursor(Item item) {
 		item.setParent(null);
-		FrameMouseActions.pickup(item);
-		FrameGraphics.Repaint();
+		StandardGestureActions.pickup(item);
+		DisplayController.requestRefresh(true);
 	}
 
@@ -965,8 +940,8 @@
 			i.invalidateAll();
 		}
-		FrameMouseActions.pickup(items);
+		StandardGestureActions.pickup(items);
 		// TODO figure out why this isnt repainting stuff immediately
 		// All of text item doesnt repaint until the cursor is moved
-		FrameGraphics.requestRefresh(true);
+		DisplayController.requestRefresh(true);
 	}
 
@@ -980,6 +955,5 @@
 		}
 		try {
-			FrameDNDTransferHandler.getInstance().importFileList(files,
-					FrameMouseActions.getPosition());
+			EcosystemManager.getDragAndDropManager().importFileList(files, EcosystemManager.getInputManager().getCursorPosition());
 		} catch (Exception e) {
 		}
@@ -990,6 +964,5 @@
 		if (file.exists()) {
 			try {
-				FrameDNDTransferHandler.getInstance().importFile(file,
-						FrameMouseActions.getPosition());
+				EcosystemManager.getDragAndDropManager().importFile(file, EcosystemManager.getInputManager().getCursorPosition());
 			} catch (Exception e) {
 				e.printStackTrace();
@@ -1021,11 +994,12 @@
 		}
 
-		float curX = FrameMouseActions.MouseX;
-		float curY = FrameMouseActions.MouseY;
+		Point cursorPos = DisplayController.getMousePosition();
+		float curX = cursorPos.x;
+		float curY = cursorPos.y;
 
 		Collection<Item> newItems = new LinkedList<Item>();
 		Item[] d = new Item[sides];
 		// create dots
-		Frame current = DisplayIO.getCurrentFrame();
+		Frame current = DisplayController.getCurrentFrame();
 		for (int i = 0; i < d.length; i++) {
 			d[i] = current.createDot();
@@ -1053,5 +1027,5 @@
 		}
 
-		Color newColor = item.getColor();
+		Colour newColor = item.getColor();
 		if (newColor != null) {
 			d[0].setColor(item.getColor());
@@ -1068,5 +1042,5 @@
 
 		ItemUtils.EnclosedCheck(newItems);
-		FrameGraphics.refresh(false);
+		DisplayController.requestRefresh(false);
 
 		return d[0];
@@ -1077,14 +1051,9 @@
 	}
 
-	public static void print(String file) {
-		try {
-			if (Browser._theBrowser.isMinimumVersion6()) {
-				if (Desktop.isDesktopSupported()) {
-					Desktop.getDesktop().print(new File(file));
-				}
-			}
-		} catch (Exception e) {
-			MessageBay.errorMessage("Printing error: " + e.getMessage());
-		}
+	public static void print(String file)
+	{	
+		String errorMessage = EcosystemManager.getMiscManager().print(file);
+		
+		if (errorMessage != null) MessageBay.errorMessage("Printing error: " + errorMessage);
 	}
 
@@ -1129,5 +1098,5 @@
 	 * @throws Exception
 	 */
-	public static void startLoboBrowser(Item text) throws Exception {
+/*	public static void startLoboBrowser(Item text) throws Exception {
 		if (!(text instanceof Text)) {
 			MessageBay.errorMessage("Must be a text item.");
@@ -1154,5 +1123,5 @@
 			
 		FrameMouseActions.pickup(browser.getItems());					// attach browser widget to mouse
-	}
+	}*/
 	
 	/**
@@ -1161,9 +1130,11 @@
 	 * @throws Exception
 	 */
-	public static void startLoboBrowserNewFrame(Item text) throws Exception {
+	public static void startLoboBrowserNewFrame(Item text) throws Exception
+	{
 		if (!(text instanceof Text)) {
 			MessageBay.errorMessage("Must be a text item.");
 			return;
 		}
+		
 		if(text.getLink() != null) {											// text item can't already have a link
 			MessageBay.errorMessage("Text item already has link.");
@@ -1176,12 +1147,11 @@
 		FrameUtils.Parse(frame);
 		
-		for(InteractiveWidget iw : frame.getInteractiveWidgets()) {	// may be other widgets on frame
+		for(Widget iw : frame.getInteractiveWidgets()) {	// may be other widgets on frame
 			if(iw instanceof org.expeditee.items.widgets.Browser) {
 				// Set browser to 'full screen'
-				iw.setSize(-1, -1, -1, -1, Browser._theBrowser.getWidth(), Browser._theBrowser.getHeight() 
-						- MessageBay.MESSAGE_BUFFER_HEIGHT - 80);
+				iw.setSize(-1, -1, -1, -1, DisplayController.getFramePaintArea().getWidth(), DisplayController.getFramePaintArea().getHeight() - 80);
 				
 				// If there is a text item attached to cursor use it as url for browser
-				if(FreeItems.textOnlyAttachedToCursor()) {
+				if (FreeItems.textOnlyAttachedToCursor()) {
 					text.setLink("" + frame.getNumber());
 					((org.expeditee.items.widgets.Browser)iw).navigate(text.getText());
@@ -1190,8 +1160,8 @@
 					((org.expeditee.items.widgets.Browser)iw).navigate("http://www.waikato.ac.nz");
 					Text t = new Text("http://www.waikato.ac.nz");
-					t.setParent(DisplayIO.getCurrentFrame());		// set parent of text source for InteractiveWidget.createWidget()
-					t.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
+					t.setParent(DisplayController.getCurrentFrame());		// set parent of text source for InteractiveWidget.createWidget()
+					t.setXY(DisplayController.getFloatMouseX(), DisplayController.getFloatMouseY());
 					t.setLink("" + frame.getNumber());				// link url text to new browser frame
-					FrameMouseActions.pickup(t);					// Attach new text link to cursor
+					StandardGestureActions.pickup(t);					// Attach new text link to cursor
 				}
 			}
@@ -1201,5 +1171,6 @@
 	}
 	
-	private static boolean startWidget(String name) throws Exception {
+	private static boolean startWidget(String name) throws Exception
+	{
 		String fullName = Actions.getClassName(name);
 		if(fullName == null) {
@@ -1210,8 +1181,8 @@
 		FreeItems.getInstance().clear();
 		Text wt = new Text("@iw:" + fullName);							// create new text item for browser widget
-		wt.setParent(DisplayIO.getCurrentFrame());						// set parent of text source for InteractiveWidget.createWidget()
-		wt.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());	// move to the mouse cursor
-		InteractiveWidget widget = InteractiveWidget.createWidget(wt);
-		FrameMouseActions.pickup(widget.getItems());
+		wt.setParent(DisplayController.getCurrentFrame());						// set parent of text source for InteractiveWidget.createWidget()
+		wt.setXY(DisplayController.getMouseX(), DisplayController.getMouseY());	// move to the mouse cursor
+		Widget widget = Widget.createWidget(wt);
+		StandardGestureActions.pickup(widget.getItems());
 		
 		return true;
@@ -1223,5 +1194,5 @@
 		}
 		
-		Actions.PerformAction(DisplayIO.getCurrentFrame(), null, command);
+		Actions.PerformAction(DisplayController.getCurrentFrame(), null, command);
 	}
 	
@@ -1241,5 +1212,5 @@
 		if(name == "action" || name == "agent") {
 			if(args.length() > 0) {
-				Actions.PerformAction(DisplayIO.getCurrentFrame(), null, args);
+				Actions.PerformAction(DisplayController.getCurrentFrame(), null, args);
 			} else {
 				MessageBay.displayMessage("Please specify an action/agent name");
@@ -1324,6 +1295,5 @@
 			if (i instanceof WidgetEdge || i instanceof WidgetCorner) {
 				continue;
-			} 
-			else {
+			} else {
 				int new_x = i.getX();
 				int new_y = i.getY();
@@ -1345,8 +1315,8 @@
 			}
 			// update the polygon, otherwise stuff moves but leaves it's outline behind
-			i.updatePolygon();
-		}
-
-		for (InteractiveWidget iw : frame.getInteractiveWidgets()) {
+			i.invalidateBounds();
+		}
+
+		for (Widget iw : frame.getInteractiveWidgets()) {
 
 			int new_x = iw.getX();
@@ -1368,5 +1338,5 @@
 		frame.change();
 		// redraw everything
-		FrameKeyboardActions.Refresh();
+		StandardGestureActions.Refresh();
 	}
 	
@@ -1505,7 +1475,7 @@
     public static void GitPushFrame() {
 
-	FrameKeyboardActions.Save();
-	
-	Frame current = DisplayIO.getCurrentFrame();
+	StandardGestureActions.Save();
+	
+	Frame current = DisplayController.getCurrentFrame();
 	String userName = UserSettings.ProfileName.get();
 
@@ -1544,5 +1514,5 @@
 
     public static void GitPullFrame() {
-	Frame current = DisplayIO.getCurrentFrame();
+	Frame current = DisplayController.getCurrentFrame();
 
 	List<String> cmd_array = new ArrayList<String>();
@@ -1554,5 +1524,5 @@
 	
 	FrameIO.Reload();
-	FrameKeyboardActions.Refresh();
+	StandardGestureActions.Refresh();
     }
 
Index: /trunk/src/org/expeditee/actions/Navigation.java
===================================================================
--- /trunk/src/org/expeditee/actions/Navigation.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Navigation.java	(revision 1102)
@@ -21,5 +21,5 @@
 import java.util.List;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -49,9 +49,9 @@
 	 */
 	public static void Back() {
-		DisplayIO.Back();
+		DisplayController.Back();
 	}
 
 	public static void Forward() {
-		DisplayIO.Forward();
+		DisplayController.Forward();
 	}
 
@@ -78,5 +78,5 @@
 	public static void GotoZero() {
 		FrameUtils
-				.DisplayFrame(DisplayIO.getCurrentFrame().getFramesetName() + 0);
+				.DisplayFrame(DisplayController.getCurrentFrame().getFramesetName() + 0);
 	}
 
@@ -96,5 +96,5 @@
 	 */
 	public static void Goto(Integer value) {
-		FrameUtils.DisplayFrame(DisplayIO.getCurrentFrame().getFramesetName()
+		FrameUtils.DisplayFrame(DisplayController.getCurrentFrame().getFramesetName()
 				+ value);
 	}
@@ -132,6 +132,6 @@
 	 */
 	public static void Large() {
-		if (DisplayIO.isTwinFramesOn())
-			DisplayIO.ToggleTwinFrames();
+		if (DisplayController.isTwinFramesOn())
+			DisplayController.toggleTwinFrames();
 	}
 
@@ -188,5 +188,5 @@
 
 	public static void NextChild(Frame source) {
-		String back = DisplayIO.peekFromBackUpStack();
+		String back = DisplayController.peekFromBackUpStack();
 		// if there is no parent frame (i.e. the user is on the home frame) //
 		if (back == null) { // No frame was on the Backup stack
@@ -259,6 +259,6 @@
 	// better to say more explicitly/directly what the mode is!!!!
 	public static void Small() {
-		if (!DisplayIO.isTwinFramesOn())
-			DisplayIO.ToggleTwinFrames();
+		if (!DisplayController.isTwinFramesOn())
+			DisplayController.toggleTwinFrames();
 	}
 
Index: /trunk/src/org/expeditee/actions/Python.java
===================================================================
--- /trunk/src/org/expeditee/actions/Python.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Python.java	(revision 1102)
@@ -19,24 +19,11 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
-import java.util.Collection;
-import java.util.LinkedList;
 import java.util.List;
 
-import javax.script.Bindings;
 import javax.script.Invocable;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import javax.script.SimpleScriptContext;
 
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
-import org.expeditee.io.flowlayout.XGroupItem;
 import org.expeditee.items.Item;
-import org.expeditee.items.ItemUtils;
 import org.expeditee.items.Text;
 
Index: /trunk/src/org/expeditee/actions/ScriptBase.java
===================================================================
--- /trunk/src/org/expeditee/actions/ScriptBase.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/ScriptBase.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
 import java.util.Collection;
 import java.util.LinkedList;
@@ -32,4 +31,5 @@
 import javax.script.SimpleScriptContext;
 
+import org.expeditee.core.Colour;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -235,5 +235,5 @@
 	Text errorItem;
 	errorItem = errorFrame.addText(x, y, errorItemLines[cl.line], null);
-	errorItem.setBackgroundColor(Color.RED);
+	errorItem.setBackgroundColor(Colour.RED);
 	for(String line : message.split("[\\n\\r]+")) {
 	    errorItem.setTooltip("text: " + line);
Index: /trunk/src/org/expeditee/actions/Simple.java
===================================================================
--- /trunk/src/org/expeditee/actions/Simple.java	(revision 1101)
+++ /trunk/src/org/expeditee/actions/Simple.java	(revision 1102)
@@ -19,8 +19,5 @@
 package org.expeditee.actions;
 
-import java.awt.Color;
-import java.awt.Point;
-import java.awt.event.InputEvent;
-import java.awt.geom.Point2D;
+//import java.awt.event.InputEvent;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
@@ -47,12 +44,13 @@
 import org.expeditee.agents.SearchTree;
 import org.expeditee.agents.WriteTree;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.gui.AttributeUtils;
 import org.expeditee.gui.AttributeValuePair;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.FreeItems;
@@ -156,5 +154,5 @@
 	private static int _stepPause = -1;
 
-	private static Color _stepColor;
+	private static Colour _stepColor;
 
 	private static boolean _nextStatement;
@@ -173,5 +171,5 @@
 
 	public static void NewSimpleTest() {
-		Frame newSimpleTest = FrameIO.CreateFrame(DisplayIO.getCurrentFrame()
+		Frame newSimpleTest = FrameIO.CreateFrame(DisplayController.getCurrentFrame()
 				.getFramesetName(), "Test", null);
 		List<String> actions = new ArrayList<String>();
@@ -183,5 +181,5 @@
 
 	public static void NextTest() {
-		Frame next = DisplayIO.getCurrentFrame();
+		Frame next = DisplayController.getCurrentFrame();
 		do {
 			next = FrameIO.LoadNext(next);
@@ -191,5 +189,5 @@
 
 	public static void PreviousTest() {
-		Frame prev = DisplayIO.getCurrentFrame();
+		Frame prev = DisplayController.getCurrentFrame();
 		do {
 			prev = FrameIO.LoadPrevious(prev);
@@ -240,7 +238,7 @@
 		int testsFailed = 0;
 
-		FrameIO.SaveFrame(DisplayIO.getCurrentFrame(), false);
+		FrameIO.SaveFrame(DisplayController.getCurrentFrame(), false);
 		MessageBay.displayMessage("Starting test suite: " + _frameset,
-				Color.CYAN);
+				Colour.CYAN);
 
 		// Get the next number in the inf file for the _frameset
@@ -312,9 +310,9 @@
 		// Report the number of test passed and failed
 		MessageBay.displayMessage(
-				"Total tests: " + (testsPassed + testsFailed), Color.CYAN);
+				"Total tests: " + (testsPassed + testsFailed), Colour.CYAN);
 		if (testsPassed > 0)
 			MessageBay.displayMessage("Passed: " + testsPassed, Item.GREEN);
 		if (testsFailed > 0)
-			MessageBay.displayMessage("Failed: " + testsFailed, Color.RED);
+			MessageBay.displayMessage("Failed: " + testsFailed, Colour.RED);
 		// Remove items from the cursor...
 		FreeItems.getInstance().clear();
@@ -350,5 +348,5 @@
 	//Have changed parameters, so it takes an Item, not just a Text item.
 	private static void RunFrame(Frame frame, Item current,
-			boolean acceptKeyboardInput, boolean step, int pause, Color color) {
+			boolean acceptKeyboardInput, boolean step, int pause, Colour color) {
 		try {
 			if (current != null) {
@@ -358,5 +356,5 @@
 				 */
 				// DisplayIO.addToBack(current.getParent());
-				DisplayIO.addToBack(DisplayIO.getCurrentFrame());
+				DisplayController.addToBack(DisplayController.getCurrentFrame());
 			} else {
 				/* TODO we should not have to pass an item just to run a frame! */
@@ -365,7 +363,7 @@
 			}
 
-			_stepColor = color == null ? Color.green : color;
-			_stepColor = new Color(_stepColor.getRed(), _stepColor.getGreen(),
-					_stepColor.getBlue(), 50);
+			_stepColor = color == null ? Colour.GREEN : color;
+			_stepColor = new Colour(_stepColor.getRed(), _stepColor.getGreen(),
+					_stepColor.getBlue(), Colour.FromComponent255(50));
 			_stepPause = pause;
 			_step = step;
@@ -429,5 +427,5 @@
 	 */
 	public static void DebugFrame(Frame frame, Text current, float pause,
-			Color color) {
+			Colour color) {
 		if (isProgramRunning()) {
 			stop();
@@ -454,5 +452,5 @@
 		FrameUtils.DisplayFrame(item.getParent().getName(), true, true);
 		item.setHighlightMode(HighlightMode.Normal);
-		item.setHighlightColor(Color.CYAN);
+		item.setHighlightColor(Colour.CYAN);
 		FrameIO.SaveFrame(item.getParent());
 	}
@@ -499,8 +497,8 @@
 
 		if (_step) {
-			if (child != DisplayIO.getCurrentFrame()) {
-				DisplayIO.setCurrentFrame(child, true);
-			}
-			DisplayIO.addToBack(child);
+			if (child != DisplayController.getCurrentFrame()) {
+				DisplayController.setCurrentFrame(child, true);
+			}
+			DisplayController.addToBack(child);
 		}
 
@@ -524,5 +522,5 @@
 			AgentStats.ItemExecuted();
 			try {
-				Color oldColor = item.getBackgroundColor();
+				Colour oldColor = item.getBackgroundColor();
 				if (_step) {
 					pause(item);
@@ -534,4 +532,5 @@
 					} else {
 						item.setHighlightMode(Item.HighlightMode.None);
+						item.setHighlightColorToDefault();
 					}
 				}
@@ -541,5 +540,5 @@
 							&& lastItemStatus != Status.FalseIf) {
 						if (_step) {
-							DisplayIO.removeFromBack();
+							DisplayController.removeFromBack();
 						}
 						return lastItemStatus;
@@ -565,7 +564,7 @@
 
 		if (_step) {
-			DisplayIO.removeFromBack();
-			if (DisplayIO.getCurrentFrame() != current.getParent())
-				DisplayIO.setCurrentFrame(current.getParent(), true);
+			DisplayController.removeFromBack();
+			if (DisplayController.getCurrentFrame() != current.getParent())
+				DisplayController.setCurrentFrame(current.getParent(), true);
 		}
 
@@ -583,15 +582,16 @@
 			return;
 
-		Color oldColor = item.getBackgroundColor();
+		Colour oldColor = item.getBackgroundColor();
 		item.setBackgroundColor(_stepColor);
 		item.setHighlightMode(Item.HighlightMode.None);
+		item.setHighlightColorToDefault();
 
 		// Make sure we are on the frame with this item
 		Frame parent = item.getParentOrCurrentFrame();
-		if (!parent.equals(DisplayIO.getCurrentFrame())) {
-			DisplayIO.setCurrentFrame(parent, true);
+		if (!parent.equals(DisplayController.getCurrentFrame())) {
+			DisplayController.setCurrentFrame(parent, true);
 		}
 
-		FrameGraphics.Repaint();
+		DisplayController.requestRefresh(true);
 
 		int timeRemaining;
@@ -604,5 +604,5 @@
 			if (_stop) {
 				item.setBackgroundColor(oldColor);
-				item.setHighlightMode(HighlightMode.Normal, _stepColor);
+				item.setHighlightModeAndColour(HighlightMode.Normal, _stepColor);
 				throw new Exception("Program terminated");
 			}
@@ -1125,6 +1125,5 @@
 				// attribute without the value in the same item
 				if (!found && attributeItem != null) {
-					Point2D.Float endPoint = attributeItem
-							.getParagraphEndPosition();
+					Point endPoint = attributeItem.getParagraphEndPosition();
 
 					for (Text text : targetFrame.getTextItems()) {
@@ -1217,6 +1216,6 @@
 					String stringColor = context.getPrimitives().getVariable(
 							tokens[2]).stringValue();
-					item.setBackgroundColor((Color) Conversion.Convert(
-							Color.class, stringColor));
+					item.setBackgroundColor((Colour) Conversion.Convert(
+							Colour.class, stringColor));
 				} else if (tokens[0].equals("setitemcolor")) {
 					assertVariableType(tokens[1], 1, SPointer.itemPrefix);
@@ -1226,5 +1225,5 @@
 					String stringColor = context.getPrimitives().getVariable(
 							tokens[2]).stringValue();
-					item.setColor((Color) Conversion.Convert(Color.class,
+					item.setColor((Colour) Conversion.Convert(Colour.class,
 							stringColor, item.getColor()));
 					
@@ -1377,6 +1376,5 @@
 					// attribute without the value in the same item
 					if (!found && attributeItem != null) {
-						Point2D.Float endPoint = attributeItem
-								.getParagraphEndPosition();
+						Point endPoint = attributeItem.getParagraphEndPosition();
 
 						for (Text text : targetFrame.getTextItems()) {
@@ -1484,5 +1482,5 @@
 					assertVariableType(tokens[1], 1, SPointer.framePrefix);
 
-					Frame currentFrame = DisplayIO.getCurrentFrame();
+					Frame currentFrame = DisplayController.getCurrentFrame();
 					context.getPointers().setObject(tokens[1], currentFrame);
 
@@ -1504,11 +1502,10 @@
 							&& tokens.length > 2) {
 						Text text = (Text) currentItem;
-						int cursorLinePos = text
-								.getLinePosition(FrameMouseActions.getY());
+						int cursorLinePos = text.getLinePosition(DisplayController.getMouseY());
 						context.getPrimitives().setValue(tokens[2],
 								new SInteger(cursorLinePos + 1));
 						if (tokens.length > 3) {
 							int cursorCharPos = text.getCharPosition(
-									cursorLinePos, DisplayIO.getMouseX())
+									cursorLinePos, DisplayController.getMouseX())
 									.getCharIndex();
 							context.getPrimitives().setValue(tokens[3],
@@ -1532,5 +1529,5 @@
                    
                     //no frame specified by user so use current frame.
-                    getFrameName = DisplayIO.getCurrentFrame().getName();
+                    getFrameName = DisplayController.getCurrentFrame().getName();
                     getItem = Misc.getItemContainingData(data, FrameUtils.getFrame(getFrameName));
                 }
@@ -1569,5 +1566,5 @@
 						
 						//no frame specified by user so use current frame.
-						getFrameName = DisplayIO.getCurrentFrame().getName();
+						getFrameName = DisplayController.getCurrentFrame().getName();
 						getItem = Misc.getItemAtPosition(x, y, FrameUtils.getFrame(getFrameName));
 					}
@@ -1662,5 +1659,5 @@
 					assertVariableType(tokens[1], 1, SPointer.itemPrefix);
 					// assertPrimitiveType(tokens[2], 2);
-					Color itemColor = ((Item) context.getPointers()
+					Colour itemColor = ((Item) context.getPointers()
 							.getVariable(tokens[1]).getValue())
 							.getPaintBackgroundColor();
@@ -1672,5 +1669,5 @@
 					assertVariableType(tokens[1], 1, SPointer.itemPrefix);
 					// assertPrimitiveType(tokens[2], 2);
-					Color itemColor = ((Item) context.getPointers()
+					Colour itemColor = ((Item) context.getPointers()
 							.getVariable(tokens[1]).getValue()).getPaintColor();
 					String color = itemColor.getRed() + " "
@@ -1834,5 +1831,5 @@
 			double delay = context.getPrimitives().getDoubleValue(tokens[1]);
 			String s = getMessage(tokens, context, code.toString(), " ", 2);
-			DisplayIO.typeStringDirect(delay, s);
+			DisplayController.typeStringDirect(delay, s);
 		} else if (tokens[0].equals("type") || tokens[0].equals("typenospaces")) {
 
@@ -1840,5 +1837,5 @@
 					.equals("type") ? " " : "", 1);
 
-			DisplayIO.typeStringDirect(0.025, s);
+			DisplayController.typeStringDirect(0.025, s);
 		} else if (tokens[0].equals("runstring")) {
 			String codeText = getMessage(tokens, context, code.toString(), " ",
@@ -1858,5 +1855,5 @@
 				// Process p = Runtime.getRuntime().exec(new String[]{"date",
 				// ">", "test.date"});
-				MessageBay.displayMessage(command, Color.darkGray);
+				MessageBay.displayMessage(command, Colour.DARK_GREY);
 
 				BufferedReader stdInput = new BufferedReader(
@@ -2028,8 +2025,6 @@
 			Item item = (Item) context.getPointers().getVariable(itemVar)
 					.getValue();
-			item
-					.setPosition(FrameMouseActions.MouseX,
-							FrameMouseActions.MouseY);
-			FrameMouseActions.pickup(item);
+			item.setPosition(DisplayController.getMouseX(), DisplayController.getMouseY());
+			StandardGestureActions.pickup(item);
 		} else if (tokens[0].equals("attachstrtocursor")) {
 			String stringVar = DEFAULT_STRING;
@@ -2040,10 +2035,8 @@
 			}
 			String s = context.getPrimitives().getStringValue(stringVar);
-			Frame frame = DisplayIO.getCurrentFrame();
+			Frame frame = DisplayController.getCurrentFrame();
 			Item item = frame.createNewText(s);
-			item
-					.setPosition(FrameMouseActions.MouseX,
-							FrameMouseActions.MouseY);
-			FrameMouseActions.pickup(item);
+			item.setPosition(DisplayController.getMouseX(), DisplayController.getMouseY());
+			StandardGestureActions.pickup(item);
 		} else if (tokens[0].equals("additemtoframe")) {
 			String itemVar = DEFAULT_ITEM;
@@ -2410,5 +2403,5 @@
 						}
 					}
-					DisplayIO.setCurrentFrame(frame, false);
+					DisplayController.setCurrentFrame(frame, false);
 					pause(thisFramesPause);
 
@@ -2629,6 +2622,6 @@
 						tokens[3]) * 1000);
 
-			int initialX = DisplayIO.getMouseX();
-			int initialY = FrameMouseActions.getY();
+			int initialX = DisplayController.getMouseX();
+			int initialY = DisplayController.getMouseY();
 
 			final int timeInterval = 40;
@@ -2643,10 +2636,10 @@
 				Thread.yield();
 				Thread.sleep(timeInterval);
-				DisplayIO.setCursorPosition(newX, newY);
+				DisplayController.setCursorPosition(newX, newY);
 				// DisplayIO.repaint();
 			}
 			// Thread.yield();
 			Thread.sleep(milliseconds % timeInterval);
-			DisplayIO.setCursorPosition(finalX, finalY);
+			DisplayController.setCursorPosition(finalX, finalY);
 		} else if (tokens[0].equals("glideitemto")) {
 			assertMinParametreCount(tokens, 3);
@@ -2686,5 +2679,5 @@
 
 				item.setPosition(newX, newY);
-				FrameGraphics.Repaint();
+				DisplayController.requestRefresh(true);
 			}
 			// Thread.yield();
@@ -2692,7 +2685,7 @@
 			item.setPosition(finalX, finalY);
 			// DisplayIO.setCursorPosition(finalX, finalY);
-			FrameMouseActions.anchor(item);
+			StandardGestureActions.anchor(item);
 			FreeItems.getInstance().clear();
-			FrameGraphics.Repaint();
+			DisplayController.requestRefresh(true);
 			// FrameMouseActions.updateCursor();
 		}
@@ -2740,36 +2733,36 @@
 		} else if (tokens[0].equals("pressleftbutton")) {
 			assertExactParametreCount(tokens, 0);
-			DisplayIO.pressMouse(InputEvent.BUTTON1_MASK);
+			//DisplayIO.pressMouse(InputEvent.BUTTON1_MASK); TODO: Reinstate. cts16
 		} else if (tokens[0].equals("pressmiddlebutton")) {
 			assertExactParametreCount(tokens, 0);
-			DisplayIO.pressMouse(InputEvent.BUTTON2_MASK);
+			//DisplayIO.pressMouse(InputEvent.BUTTON2_MASK); TODO: Reinstate. cts16
 		} else if (tokens[0].equals("pressrightbutton")) {
 			assertExactParametreCount(tokens, 0);
-			DisplayIO.pressMouse(InputEvent.BUTTON3_MASK);
+			//DisplayIO.pressMouse(InputEvent.BUTTON3_MASK); TODO: Reinstate. cts16
 		} else if (tokens[0].equals("releaseleftbutton")) {
 			assertExactParametreCount(tokens, 0);
-			DisplayIO.releaseMouse(InputEvent.BUTTON1_MASK);
+			//DisplayIO.releaseMouse(InputEvent.BUTTON1_MASK); TODO: Reinstate. cts16
 		} else if (tokens[0].equals("releasemiddlebutton")) {
 			assertExactParametreCount(tokens, 0);
-			DisplayIO.releaseMouse(InputEvent.BUTTON2_MASK);
+			//DisplayIO.releaseMouse(InputEvent.BUTTON2_MASK); TODO: Reinstate. cts16
 		} else if (tokens[0].equals("releaserightbutton")) {
 			assertExactParametreCount(tokens, 0);
-			DisplayIO.releaseMouse(InputEvent.BUTTON3_MASK);
+			//DisplayIO.releaseMouse(InputEvent.BUTTON3_MASK); TODO: Reinstate. cts16
 		} else if (tokens[0].equals("clickleftbutton")) {
 			assertExactParametreCount(tokens, 0);
-			FrameMouseActions.leftButton();
+			// FrameMouseActions.leftButton(); TODO: Reinstate. cts16
 			// DisplayIO.clickMouse(InputEvent.BUTTON1_MASK);
 		} else if (tokens[0].equals("clickmiddlebutton")) {
 			assertExactParametreCount(tokens, 0);
-			FrameMouseActions.middleButton();
+			// FrameMouseActions.middleButton(); TODO: Reinstate. cts16
 			// DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
 		} else if (tokens[0].equals("clickrightbutton")) {
 			assertExactParametreCount(tokens, 0);
-			FrameMouseActions.rightButton();
+			// FrameMouseActions.rightButton(); TODO: Reinstate. cts16
 			// DisplayIO.clickMouse(InputEvent.BUTTON3_MASK);
 		} else if (tokens[0].equals("repaint")) {
 			assertExactParametreCount(tokens, 0);
 			// FrameGraphics.Repaint();
-			FrameGraphics.requestRefresh(true);
+			DisplayController.requestRefresh(true);
 		} else if (tokens[0].equals("add")) {
 			assertMaxParametreCount(tokens, 3);
@@ -2931,5 +2924,5 @@
 			int x = (int) context.getPrimitives().getIntegerValue(tokens[1]);
 			int y = (int) context.getPrimitives().getIntegerValue(tokens[2]);
-			DisplayIO.setCursorPosition(x, y);
+			DisplayController.setCursorPosition(x, y);
 			
 			
@@ -2981,5 +2974,5 @@
 
 		if (source == null)
-			source = DisplayIO.getCurrentFrame();
+			source = DisplayController.getCurrentFrame();
 		int lastParam = tokens.length - 1;
 		String resultVarName = null;
@@ -3102,5 +3095,5 @@
 		_programsRunning++;
 		AgentStats.reset();
-		MessageBay.displayMessage("Running SimpleProgram...", Color.BLUE);
+		MessageBay.displayMessage("Running SimpleProgram...", Colour.BLUE);
 	}
 
Index: /trunk/src/org/expeditee/agents/DefaultAgent.java
===================================================================
--- /trunk/src/org/expeditee/agents/DefaultAgent.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/DefaultAgent.java	(revision 1102)
@@ -19,6 +19,6 @@
 package org.expeditee.agents;
 
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.MessageBay;
 import org.expeditee.gui.TimeKeeper;
@@ -128,5 +128,5 @@
 		AGENTS_RUNNING--;
 
-		FrameGraphics.requestRefresh(true);
+		DisplayController.requestRefresh(true);
 		SessionStats.setEnabled(true);
 	}
Index: /trunk/src/org/expeditee/agents/DisplayComet.java
===================================================================
--- /trunk/src/org/expeditee/agents/DisplayComet.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/DisplayComet.java	(revision 1102)
@@ -23,5 +23,5 @@
 import java.util.Stack;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -45,5 +45,5 @@
 		Collection<String> seen = new HashSet<String>();
 
-		DisplayIO.addToBack(frame);
+		DisplayController.addToBack(frame);
 
 		// Goto the end of the comet
@@ -74,5 +74,5 @@
 			if (_stop)
 				return null;
-			DisplayIO.setCurrentFrame(_frameList.pop(), true);
+			DisplayController.setCurrentFrame(_frameList.pop(), true);
 			_frameCount++;
 			pause(_delay);
Index: /trunk/src/org/expeditee/agents/DisplayTree.java
===================================================================
--- /trunk/src/org/expeditee/agents/DisplayTree.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/DisplayTree.java	(revision 1102)
@@ -19,5 +19,5 @@
 package org.expeditee.agents;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.MessageBay;
@@ -54,5 +54,5 @@
 
 		// push current frame on to back-stack
-		DisplayIO.addToBack(start);
+		DisplayController.addToBack(start);
 
 		return super.initialise(start, launcher);
@@ -63,5 +63,5 @@
 		// return the user to the Frame they started on
 		if (!_stop) {
-			DisplayIO.Back();
+			DisplayController.Back();
 		}
 		super.finalise(start);
@@ -79,6 +79,6 @@
 
 		// ignore loops
-		if (toProcess != DisplayIO.getCurrentFrame())
-			DisplayIO.setCurrentFrame(toProcess, false);
+		if (toProcess != DisplayController.getCurrentFrame())
+			DisplayController.setCurrentFrame(toProcess, false);
 		// parse the frame for any pause settings
 		delay(toProcess);
Index: /trunk/src/org/expeditee/agents/Format.java
===================================================================
--- /trunk/src/org/expeditee/agents/Format.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/Format.java	(revision 1102)
@@ -26,6 +26,6 @@
 import java.util.List;
 
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.items.Item;
@@ -148,5 +148,5 @@
 						+ /* item.getX() + */it.getBoundsWidth());
 
-			if (xCheck < FrameGraphics.getMaxSize().width) {
+			if (xCheck < DisplayController.getFramePaintArea().getWidth()) {
 				Item columnHead = columnHeads.get(i + 1);
 				if (columnHead.getX() < maxX && columnHead.getY() < maxY) {
@@ -182,5 +182,5 @@
 		start.setChanged(true);
 		start.addToUndoMove(changedItems);
-		FrameGraphics.requestRefresh(true);
+		DisplayController.requestRefresh(true);
 		return null;
 	}
Index: /trunk/src/org/expeditee/agents/GraphFramesetLinks.java
===================================================================
--- /trunk/src/org/expeditee/agents/GraphFramesetLinks.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/GraphFramesetLinks.java	(revision 1102)
@@ -19,11 +19,13 @@
 package org.expeditee.agents;
 
-import java.awt.Color;
 import java.util.List;
 
 import org.expeditee.actions.Misc;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Font;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.items.Item;
@@ -41,5 +43,4 @@
 import com.mxgraph.model.mxGraphModel;
 import com.mxgraph.view.mxGraph;
-import java.awt.Font;
 
 /**
@@ -74,8 +75,8 @@
 		String resultsFramesetName = "LinksGraphResults";
 
-		Color vertColor = new Color(51,145,148);
-		Color unlinkedVertColor = new Color(251,107,65);
-		Color outgoingVertColor = new Color(246,216,107);
-		Color lineColor = new Color(0,0,0, 20);
+		Colour vertColor = Colour.FromRGB255(51,145,148);
+		Colour unlinkedVertColor = Colour.FromRGB255(251,107,65);
+		Colour outgoingVertColor = Colour.FromRGB255(246,216,107);
+		Colour lineColor = Colour.FromRGBA255(0,0,0, 20);
 
 		try {
@@ -220,5 +221,6 @@
 		}
 		
-		Font keyFont = Font.decode(Font.SANS_SERIF + " 14");
+		Font keyFont = new Font("SansSerif");
+		keyFont.setSize(14);
 		
 		Text keyLink = resultsFrame.addText(0, 0, "\u2192 = Link", null);
@@ -228,5 +230,5 @@
 		
 		keyLink.setFont(keyFont);
-		keyLink.setColor(Color.DARK_GRAY);
+		keyLink.setColor(Colour.DARK_GREY);
 		
 		keyFrame.setFont(keyFont);;
@@ -239,13 +241,13 @@
 		keyFrameOutgoing.setColor(outgoingVertColor);
 		
-		keyFrameOutgoing.setAnchorBottom(10f);
-		keyFrameUnlinked.setAnchorBottom(30f);
-		keyFrame.setAnchorBottom(50f);
-		keyLink.setAnchorBottom(70f);
-		
-		keyFrameOutgoing.setAnchorLeft(10f);
-		keyFrameUnlinked.setAnchorLeft(10f);
-		keyFrame.setAnchorLeft(10f);
-		keyLink.setAnchorLeft(10f);
+		keyFrameOutgoing.setAnchorBottom(10);
+		keyFrameUnlinked.setAnchorBottom(30);
+		keyFrame.setAnchorBottom(50);
+		keyLink.setAnchorBottom(70);
+		
+		keyFrameOutgoing.setAnchorLeft(10);
+		keyFrameUnlinked.setAnchorLeft(10);
+		keyFrame.setAnchorLeft(10);
+		keyLink.setAnchorLeft(10);
 
 		// Moving to the area of the frame that contains the graph
@@ -256,6 +258,6 @@
 		Text link = new Text(toProcessFramesetName + " graph");
 		link.setLink(resultsFrame.getName());
-		link.setPosition(FrameMouseActions.getPosition());
-		FrameMouseActions.pickup(link);
+		link.setPosition(DisplayController.getMousePosition());
+		StandardGestureActions.pickup(link);
 		return null;
 	}
Index: /trunk/src/org/expeditee/agents/ScaleFrameset.java
===================================================================
--- /trunk/src/org/expeditee/agents/ScaleFrameset.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/ScaleFrameset.java	(revision 1102)
@@ -21,7 +21,7 @@
 import java.util.Collection;
 
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameKeyboardActions;
 import org.expeditee.gui.Vector;
 import org.expeditee.items.Item;
@@ -62,5 +62,5 @@
 
 		// TODO make this thread safe!
-		FrameKeyboardActions.Refresh();
+		StandardGestureActions.Refresh();
 
 		return null;
@@ -102,5 +102,5 @@
 				continue;
 			// if (!(item instanceof Line))
-			item.updatePolygon();
+			item.invalidateBounds();
 
 			if (item instanceof Line) {
Index: /trunk/src/org/expeditee/agents/SearchAgent.java
===================================================================
--- /trunk/src/org/expeditee/agents/SearchAgent.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/SearchAgent.java	(revision 1102)
@@ -21,7 +21,7 @@
 import java.util.Collection;
 
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameCreator;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
 import org.expeditee.io.Conversion;
@@ -126,10 +126,10 @@
 	}
 
-	public static boolean searchFrame(FrameCreator results, String frameName,
-			String pattern, String replacementString) {
-		int oldMode = FrameGraphics.getMode();
-		FrameGraphics.forceXRayMode(false);
+	public static boolean searchFrame(FrameCreator results, String frameName, String pattern, String replacementString)
+	{
+		boolean wasXrayMode = DisplayController.isXRayMode();
+		if (!wasXrayMode) DisplayController.ToggleXRayMode();
 		Frame frameToSearch = FrameIO.LoadFrame(frameName);
-		FrameGraphics.setMode(oldMode, false);
+		if (!wasXrayMode) DisplayController.ToggleXRayMode();
 		if (frameToSearch == null)
 			return false;
@@ -142,5 +142,5 @@
 			}
 		}
-		FrameGraphics.requestRefresh(true);
+		DisplayController.requestRefresh(true);
 		FrameIO.SaveFrame(frameToSearch, false);
 		return true;
@@ -177,5 +177,5 @@
 				_results.addText(surrogate.toString(), null,
 						frameName, null, false);
-				FrameGraphics.requestRefresh(true);
+				DisplayController.requestRefresh(true);
 			}
 		}
Index: /trunk/src/org/expeditee/agents/SearchGreenstone.java
===================================================================
--- /trunk/src/org/expeditee/agents/SearchGreenstone.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/SearchGreenstone.java	(revision 1102)
@@ -23,4 +23,5 @@
 import java.util.Vector;
 
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.greenstone.Greenstone3Connection;
 import org.expeditee.greenstone.Query;
@@ -29,9 +30,8 @@
 import org.expeditee.greenstone.ResultDocument;
 import org.expeditee.gui.AttributeValuePair;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameCreator;
 import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.MessageBay;
 import org.expeditee.items.Text;
@@ -175,8 +175,7 @@
 			doQuery(_pattern);
 		} else if (_currentResultSet != null) {
-			Text newText = DisplayIO.getCurrentFrame().createNewText(
-					getCursorText());
+			Text newText = DisplayController.getCurrentFrame().createNewText(getCursorText());
 			_clicked = newText;
-			FrameMouseActions.pickup(newText);
+			StandardGestureActions.pickup(newText);
 		}
 
@@ -389,5 +388,5 @@
 				false);
 
-		FrameGraphics.requestRefresh(true);
+		DisplayController.requestRefresh(true);
 	}
 
Index: /trunk/src/org/expeditee/agents/SearchTreeAndReplace.java
===================================================================
--- /trunk/src/org/expeditee/agents/SearchTreeAndReplace.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/SearchTreeAndReplace.java	(revision 1102)
@@ -22,6 +22,6 @@
 import java.util.HashSet;
 
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
 import org.expeditee.items.Text;
@@ -79,5 +79,5 @@
 			}
 		}
-		FrameGraphics.requestRefresh(true);
+		DisplayController.requestRefresh(true);
 		FrameIO.SaveFrame(frameToSearch, false);
 		return true;
Index: /trunk/src/org/expeditee/agents/Sort.java
===================================================================
--- /trunk/src/org/expeditee/agents/Sort.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/Sort.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.agents;
 
-import java.awt.Point;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -25,6 +24,7 @@
 import java.util.Comparator;
 
+import org.expeditee.core.Point;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.items.Text;
@@ -68,5 +68,5 @@
 		// items will need to be resorted after this
 		start.setResort(true);
-		FrameGraphics.Repaint();
+		DisplayController.requestRefresh(true);
 
 		return null;
Index: /trunk/src/org/expeditee/agents/SwitchyardTree.java
===================================================================
--- /trunk/src/org/expeditee/agents/SwitchyardTree.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/SwitchyardTree.java	(revision 1102)
@@ -19,7 +19,6 @@
 package org.expeditee.agents;
 
-import java.awt.Color;
-import java.awt.geom.Point2D;
-
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -44,12 +43,12 @@
 					Frame childFrame = FrameIO.LoadFrame(link);
 					if (childFrame != null) {
-						Point2D.Float lastItemEnd = textItem.getParagraphEndPosition();
+						Point lastItemEnd = textItem.getParagraphEndPosition();
 						for (Text childItem : childFrame.getBodyTextItems(false)) {
 							// look for red items (remember get color may be null
-							if (Color.RED.equals(childItem.getPaintColor())) {
+							if (Colour.RED.equals(childItem.getPaintColor())) {
 								// make a copy and add to parent frame
 								Text itemCopy = childItem.copy();
 								// add to the right of parent item
-								lastItemEnd.setLocation(lastItemEnd.x + 20, lastItemEnd.y);
+								lastItemEnd.set(lastItemEnd.x + 20, lastItemEnd.y);
 								itemCopy.setPosition(lastItemEnd.x, lastItemEnd.y);
 								lastItemEnd = itemCopy
Index: /trunk/src/org/expeditee/agents/mail/MailSession.java
===================================================================
--- /trunk/src/org/expeditee/agents/mail/MailSession.java	(revision 1101)
+++ /trunk/src/org/expeditee/agents/mail/MailSession.java	(revision 1102)
@@ -19,6 +19,4 @@
 package org.expeditee.agents.mail;
 
-import java.awt.Color;
-import java.awt.Point;
 import java.io.BufferedReader;
 import java.io.InputStream;
@@ -48,10 +46,12 @@
 import javax.mail.internet.MimeMessage;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.gio.DragAndDropManager;
 import org.expeditee.gui.AttributeValuePair;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameCreator;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.MessageBay;
-import org.expeditee.importer.FrameDNDTransferHandler;
 import org.expeditee.items.Text;
 
@@ -208,5 +208,5 @@
 						try {
 							MessageBay.displayMessage("New mail message!",
-									null, Color.green, true, "getMailByID "
+									null, Colour.GREEN, true, "getMailByID "
 											+ _folder.getMessageCount());
 							/*
@@ -247,5 +247,5 @@
 
 				MessageBay.displayMessage("Mail connection complete",
-						Color.GREEN);
+						Colour.GREEN);
 
 				displayUnreadMailCount();
@@ -262,5 +262,5 @@
 		int unreadCount = getUnreadCount();
 		Text text = new Text(-1, unreadCount + UNREAD_MESSAGE
-				+ (unreadCount == 1 ? "" : "s"), Color.BLUE, null);
+				+ (unreadCount == 1 ? "" : "s"), Colour.BLUE, null);
 		if (unreadCount > 0)
 			text.addAction("getUnreadMail " + unreadCount);
@@ -517,6 +517,5 @@
 			final Frame frame, final Point point) {
 
-		final Text source = FrameDNDTransferHandler.importString(
-				"Reading message " + messageNo + "...", point);
+		final Text source = DragAndDropManager.importString("Reading message " + messageNo + "...", point);
 
 		new Thread() {
@@ -598,5 +597,5 @@
 					frames.save();
 					source.setLink(frames.getName());
-					FrameGraphics.requestRefresh(true);
+					DisplayController.requestRefresh(true);
 				} catch (MessageRemovedException mre) {
 					source.setText("Message removed from inbox");
Index: /trunk/src/org/expeditee/gui/AttributeUtils.java
===================================================================
--- /trunk/src/org/expeditee/gui/AttributeUtils.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/AttributeUtils.java	(revision 1102)
@@ -19,7 +19,4 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Point;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -28,4 +25,7 @@
 import java.util.List;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Font;
+import org.expeditee.core.Point;
 import org.expeditee.io.Conversion;
 import org.expeditee.items.DotType;
@@ -33,5 +33,4 @@
 import org.expeditee.items.Justification;
 import org.expeditee.items.PermissionPair;
-import org.expeditee.items.Picture;
 import org.expeditee.items.Text;
 import org.expeditee.simple.IncorrectTypeException;
@@ -137,5 +136,6 @@
 			Class<?>[] pFloat = { float.class };
 			Class<?>[] pFloatO = { Float.class };
-			Class<?>[] pColor = { Color.class };
+			Class<?>[] pDouble = {double.class };
+			Class<?>[] pColor = { Colour.class };
 			Class<?>[] pBool = { boolean.class };
 			//Class[] pDouble = { double.class };
@@ -214,11 +214,11 @@
 			                                    Item.class.getMethod("setBorderColor", pColor));
 			_Attrib.put("AnchorLeft",           Item.class.getMethod("getAnchorLeft"),
-			                                    Item.class.getMethod("setAnchorLeft", pFloatO));
+			                                    Item.class.getMethod("setAnchorLeft", pIntO));
 			_Attrib.put("AnchorRight",          Item.class.getMethod("getAnchorRight"),
-			                                    Item.class.getMethod("setAnchorRight", pFloatO));
+			                                    Item.class.getMethod("setAnchorRight", pIntO));
 			_Attrib.put("AnchorTop",            Item.class.getMethod("getAnchorTop"),
-			                                    Item.class.getMethod("setAnchorTop", pFloatO));
+			                                    Item.class.getMethod("setAnchorTop", pIntO));
 			_Attrib.put("AnchorBottom",         Item.class.getMethod("getAnchorBottom"),
-			                                    Item.class.getMethod("setAnchorBottom", pFloatO));
+			                                    Item.class.getMethod("setAnchorBottom", pIntO));
 			_Attrib.put("Position",             Item.class.getMethod("getPosition"),
 			                                    Item.class.getMethod("setPosition", pPoint));
@@ -248,5 +248,5 @@
 			                                    Item.class.getMethod("setGradientColor", pColor));
 			_Attrib.put("GradientAngle",        Item.class.getMethod("getGradientAngle"),
-			                                    Item.class.getMethod("setGradientAngle", pInt));
+			                                    Item.class.getMethod("setGradientAngle", pDouble));
 			_Attrib.put("FillPattern",          Item.class.getMethod("getFillPattern"),
 			                                    Item.class.getMethod("setFillPattern", pString));
@@ -417,5 +417,5 @@
 
 		// create the text Item
-		Frame current = DisplayIO.getCurrentFrame();
+		Frame current = DisplayController.getCurrentFrame();
 		Item attribs = current.getStatsTextItem(attributes.toString());
 		return attribs;
@@ -486,7 +486,7 @@
 			if (((Double) o) < 0.0001)
 				return null;
-		} else if (o instanceof Color) {
+		} else if (o instanceof Colour) {
 			// converts the color to the Expeditee code
-			o = Conversion.getExpediteeColorCode((Color) o);
+			o = Conversion.getExpediteeColorCode((Colour) o);
 			if (o == null)
 				return null;
@@ -497,5 +497,5 @@
 			Font f = (Font) o;
 
-			String s = f.getName() + "-";
+			String s = f.getFamilyName() + "-";
 			if (f.isPlain())
 				s += "Plain";
Index: /trunk/src/org/expeditee/gui/Browser.java
===================================================================
--- /trunk/src/org/expeditee/gui/Browser.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/Browser.java	(revision 1102)
@@ -19,36 +19,26 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.MouseInfo;
-import java.awt.Point;
-import java.awt.RenderingHints;
-import java.awt.Toolkit;
-import java.awt.event.ComponentEvent;
-import java.awt.event.ComponentListener;
-import java.awt.event.WindowEvent;
-import java.awt.event.WindowListener;
-import java.awt.event.WindowStateListener;
 import java.io.File;
 import java.net.Authenticator;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedList;
-
-import javax.swing.JFrame;
-import javax.swing.RepaintManager;
-import javax.swing.SwingUtilities;
-
-import org.expeditee.AbsoluteLayout;
+
 import org.expeditee.actions.Actions;
 import org.expeditee.actions.Simple;
 import org.expeditee.agents.mail.MailSession;
-import org.expeditee.importer.FrameDNDTransferHandler;
+import org.expeditee.core.BlockingRunnable;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Point;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.EcosystemManager.Ecosystem;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.InputManager;
+import org.expeditee.gio.InputManager.WindowEventListener;
+import org.expeditee.gio.InputManager.WindowEventType;
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.io.ProxyAuth;
 import org.expeditee.items.Item;
+import org.expeditee.items.ItemUtils;
 import org.expeditee.items.Text;
 import org.expeditee.items.widgets.WidgetCacheManager;
@@ -68,16 +58,82 @@
  * processes any Events.
  * 
+ * TODO List:
+ * 
+ * Back to standard:
+ *  - JavaFX Text-hitting (requires JFX1.9)
+ *  - Overlays and Vectors review
+ *  - Pop-ups (unused in base Expeditee, only in Apollo)
+ *  - Apollo input (test)
+ *  - The rest of Apollo
+ *  - Make sure clipping/invalidation takes twin-frames into account
+ *  - Reinstate Simple input commands
+ *  - Test LinkedTrack.paintInFreeSpace()
+ *  - Test EmulatedTextItem.onMouseReleased(MouseEvent) (removed emulatedSource mouse button check)
+ *  - Constrained placement of items
+ *  
+ * Extra:
+ *  - Self-describing input
+ *  - Thread safety (most stuff on GIO event thread but Agents can start new threads)
+ *  - Touch input
+ *  - Better reflection??? (currently changes to the code break reflection as it relies on names)
+ *  - JavaFX lag (always rendering to images doesn't gel well with JavaFX)
+ *  - Swing widgets in JFX
+ *  - JavaFX Widgets (exception on drawing?)
+ *  - Reduce reliance on into-image rendering to improve JavaFX performance (utilise enforced-clip)
+ *  - Block Swing ecosystem setup until window is available, or...
+ *  - Reconfigure window-resized code so things are properly resized (PREFERRED).
+ *  - Swing alpha-compositing of colours (currently alpha is ignored e.g. drop-shadow in transition).
+ *  - Overly-thick extrusion lines (seems to depend on number of connected lines...)
+ *  - Make FreeItems control pickup etc.
+ *  - Remove MouseEventRouter
+ *  - Highlighting (should be controlled by the items themselves)
+ *  - Make Widgets into fully-fledged items (maybe???)
+ *  - Merge Widget and HeavyDutyWidget
+ *  - Redefine TextLayouts (relative/absolute layouts)
+ *  - Settings exceptions (Password widget in JFX) (currently fixed with hack)
+ *  - MessageBay (what did I mean by this specifically?)
+ *  - Order-dependency of start-up code
+ *  - MessageBay not refreshing at start-up
+ *  - Invalidation hierarchy (item => frame => display controller area => window)
+ *  - Add gesture data type checking
+ *  - Paintable interface
+ *  - EcosystemSpecific interface (utilise to enable/disable features based on ecosystem)
+ *  - Remove/modify Mutable class (in Apollo.util, change to InOutReference)
+ *  - Convert BlockingRunnable to interface
+ *  - Modify Metronome to utilise Timeouts
+ *  - Need AWT in FastAlphaEffect???
+ *  
+ * General:
+ *  - Tidy FrameGraphics
+ *  - Comment
+ *  - UserSettings.DEFAULT_PROFILE_NAME not actually a user setting
+ * 
+ * Done:
+ *  - Timers
+ *  - Timer input animations
+ *  - Finish DisplayController/FrameGraphics separation
+ *  - Anchor constraints (create class)
+ *  - Make MessageBay take lead from DisplayController
+ *  - Make message bay display again (to do with above)
+ *  - Tooltips (layout broken in Swing as window size not correct when tooltips laid out)
+ *  - Frame transitions
+ *  - Frame transitions in twin-frames mode drawing over each other
+ *  - JFX DnD manager
+ *  - Reinstate Simple
+ *  - Reinstate exclude source
+ *  - Reinstate commented code
+ *  - Twin-frames division 0 at startup
+ *  - Twin frames off-by-one frame size (draws a line of erroneous pixels)
+ *  - MessageBay delays showing messages on start-up
+ *  - JFX Antialiasing done on theScene??? Doesn't apply for our situation
+ *  - Incorporate Clip class into code
+ *  - Enforced clip
+ * 
+ * @author cts16
  * @author jdm18
- * 
  */
-public class Browser extends JFrame implements ComponentListener,
-		WindowListener, WindowStateListener, SaveStateChangedEventListener {
-
-	/**
-	 * Default version - just to stop eclipse from complaining about it.
-	 */
-	private static final long serialVersionUID = 1L;
-
-	// private static final JScrollPane scrollPane = new JScrollPane();
+public class Browser implements SaveStateChangedEventListener {
+	
+	public static final Ecosystem ECOSYSTEM_TYPE = Ecosystem.Swing;
 
 	public static Browser _theBrowser = null;
@@ -86,15 +142,7 @@
 
 	public static boolean _hasExited = false;
-	
-	protected MouseEventRouter _mouseEventRouter;
-
-	// A flag which is set once the application is exiting.
+
+	/** A flag which is set once the application is exiting. */
 	protected boolean _isExiting = false;
-
-	protected boolean _minimum_version6 = false;
-
-	public boolean isMinimumVersion6() {
-		return _minimum_version6;
-	}
 
 	protected static boolean _initComplete = false;
@@ -107,50 +155,44 @@
 	 * @param args
 	 */
-	public static void main(String[] args) {
-		
+	public static void main(String[] args)
+	{
+		// Parse the starting frame command-line argument
 		if(args.length > 0) {
 			_startFrame = args[0];
-			if(! Character.isDigit(_startFrame.charAt(_startFrame.length() - 1)))
-				_startFrame = _startFrame + "1";
-		}
-		else {
+			if(!Character.isDigit(_startFrame.charAt(_startFrame.length() - 1))) _startFrame = _startFrame + "1";
+		} else {
 		    _startFrame = "home1";
 		}
 
-		// Prepare all expeditee and swing data on the AWT event thread.
-		SwingUtilities.invokeLater(new Runnable() {
-			public void run() {
-				// MessageBay.supressMessages(true);
-
-				// MessageBay.supressMessages(false);
-
-				_theBrowser = new Browser();
-				
-				DisplayIO.refreshCursor();
-				_theBrowser.requestFocus();
-				FrameMouseActions.MouseX = MouseInfo.getPointerInfo()
-						.getLocation().x
-						- _theBrowser.getOrigin().x;
-				FrameMouseActions.MouseY = MouseInfo.getPointerInfo()
-						.getLocation().y
-						- _theBrowser.getOrigin().y;
-				_initComplete = true;
-				
-				Authenticator.setDefault(proxyAuth);
-			}
-		});
-
-	}
-
-	public Point getOrigin() {
-		return getContentPane().getLocationOnScreen();
-	}
-
-	/**
-	 * @return The mouse event router used for this browser. Never null after
-	 *         browser constructed.
-	 */
-	public MouseEventRouter getMouseEventRouter() {
-		return _mouseEventRouter;
+		// Window icon must be set before initialisation
+		GraphicsManager.setWindowIcon(DisplayController.ICON_IMAGE);
+		
+		// Setup the GIO ecosystem so it is ready when we need it
+		EcosystemManager.createEcosystem(ECOSYSTEM_TYPE);
+		
+		try {
+			EcosystemManager.getMiscManager().runOnGIOThread(new BlockingRunnable() {
+				@Override
+				public void execute() {
+					init();
+				}
+			});
+		} catch (Throwable e) {
+			e.printStackTrace(System.err);
+			System.exit(1);
+		}
+		
+		MessageBay.showDelayedMessages();
+	}
+	
+	public static void init()
+	{
+		_theBrowser = new Browser();
+
+		EcosystemManager.getGraphicsManager().requestFocus();
+		
+		Authenticator.setDefault(proxyAuth);
+		
+		_initComplete = true;
 	}
 
@@ -165,5 +207,5 @@
 	 * 
 	 */
-	public boolean isExisting() {
+	public boolean isExiting() {
 		return _isExiting;
 	}
@@ -173,147 +215,41 @@
 	}
 
-	public void setSizes(Dimension size) {
-		setSize(size);
-		setPreferredSize(size);
-		Dimension paneSize = getContentPane().getSize();
-		FrameGraphics.setMaxSize(paneSize);
-	}
-
-	protected Browser() {
+	protected Browser()
+	{
 		// center the frame on the screen
-		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
-		double xpos = screen.getWidth() / 2;
-		double ypos = screen.getHeight() / 2;
-		setLocation((int) (xpos - (UserSettings.InitialWidth.get() / 2)),
-				(int) (ypos - (UserSettings.InitialHeight.get() / 2)));
-
-		addWindowListener(this);
-		addWindowStateListener(this);
-
-		DisplayIO.addDisplayIOObserver(WidgetCacheManager.getInstance());
-		DisplayIO.addDisplayIOObserver(PopupManager.getInstance());
-
-		
-		// set up the image used for the icon
-	    try
-        {
-          URL iconURL = ClassLoader.getSystemResource("org/expeditee/assets/icons/expediteeicon128.png");
-          if (iconURL != null)
-          {
-            Image localImage = Toolkit.getDefaultToolkit().getImage(iconURL);
-            this.setIconImage(localImage);
-          }
-        }
-        catch (Exception e)
-        {
-          e.printStackTrace();
-        }
-	    
-	    setSizes(new Dimension(UserSettings.InitialWidth.get(), UserSettings.InitialHeight.get()));
-	    
-	    // set the layout to absolute layout for widgets
-	    // => this used to be done here, but now has been moved to later in the method
-	    //    as is works better when put in a JFXPanel
-	    //this.getContentPane().setLayout(new AbsoluteLayout());
-
-		_mouseEventRouter = new MouseEventRouter(getJMenuBar(),
-				getContentPane());
-
-		// enable the glasspane-for capturing all mouse events
-		this.setGlassPane(_mouseEventRouter);
-
-		this.getGlassPane().setVisible(true);
-		this.getContentPane().setBackground(Color.white);
-		this.getContentPane().setFocusTraversalKeysEnabled(false);
-
-		addComponentListener(this);
-		pack();
-		this.getContentPane().setLayout(new AbsoluteLayout()); // moved to here to work with JFXPanel
-
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		Dimension screen = g.getScreenSize();
+		double xpos = (screen.width - UserSettings.InitialWidth.get()) / 2.0;
+		double ypos = (screen.height - UserSettings.InitialHeight.get()) / 2.0;
+		g.setWindowLocation(new Point((int) xpos, (int) ypos));
+
+		DisplayController.Init();
+		
+		DisplayController.addDisplayObserver(WidgetCacheManager.getInstance());
+		if (ECOSYSTEM_TYPE == Ecosystem.Swing) {
+			DisplayController.addDisplayObserver(PopupManager.getInstance());
+		}
+
+		setInputManagerWindowRoutines();
+		
 		// Reset windows to user specified size
-		// Must be done after initialising the content pane above!
-		setSizes(new Dimension(UserSettings.InitialWidth.get(), UserSettings.InitialHeight.get()));
-	    
-		// UserSettings.ProfileName.set(FrameIO.ConvertToValidFramesetName(System.getProperty("user.name")));
-		String userName = UserSettings.ProfileName.get();
-		//UserSettings.UserName.set(UserSettings.ProfileName.get());
+		Dimension initialWindowSize = new Dimension(UserSettings.InitialWidth.get(), UserSettings.InitialHeight.get());
+		g.setWindowSize(initialWindowSize);
 		
 		// Load documentation and start pages
 		FrameUtils.extractResources(false);
+		
 		// Load fonts before loading any frames so the items on the frames will be able to access their fonts
 		Text.InitFonts();
-
-		Frame profile = loadProfile(userName);
-
-		// Need to display errors once things have been init otherwise
-		// exceptions occur if there are more than four messages neededing to be
-		// displayed.
-
-		Frame defaultProfile = loadProfile(UserSettings.DEFAULT_PROFILE_NAME);
-
-		Collection<String> warningMessages = new LinkedList<String>();
-		warningMessages.addAll(FrameUtils.ParseProfile(defaultProfile));
-		//Save the cursor if the defaultProfile had a custom cursor
-		Collection<Item> cursor = null;
-		if(FreeItems.hasCursor()){
-			cursor = new ArrayList<Item>();
-			cursor.addAll(FreeItems.getCursor());
-		}
-		warningMessages.addAll(FrameUtils.ParseProfile(profile));
-		if(cursor != null && !FreeItems.hasCursor()){
-			FreeItems.setCursor(cursor);
-		}
-
-		/*
-		 * See Java bug ID 4016934. They say that window closed events are
-		 * called once the JFrame is disposed.
-		 */
-		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
-		
-		// Expeditee handles its own repainting of AWT/Swing components
-		RepaintManager.setCurrentManager(ExpediteeRepaintManager.getInstance());
+		
+		Frame userProfile = loadProfiles();
 
 		// Listen for save status to display during and after runtime
 		EntitySaveManager.getInstance().addSaveStateChangedEventListener(this);
-
-		String full_version = System.getProperty("java.version");
-		String[] version_parts = full_version.split("\\.");
-		if (version_parts.length>=2) {
-			String version_str = version_parts[0] + "." + version_parts[1];
-			double version = Double.parseDouble(version_str);
-			
-			if (version >= 1.6) {
-				// Set the drag and drop handler
-				_minimum_version6 = true;
-				setTransferHandler(FrameDNDTransferHandler.getInstance());
-			} else {
-				System.err.println("Upgrade to a (minimum) of Java 1.6 to enable drag and drop support in Expeditee");
-			}
-		}
-		else {
-			System.err.println("Unable to parse Java version number " + full_version + " to determin if Drag and Drop supported");
-			
-		}
-		
-
+		
 		try {
-			warningMessages.addAll(Actions.Init());
+			MessageBay.warningMessages(Actions.Init());
 			
 			Settings.Init();
-
-			DisplayIO.Init(this);
-			// Set visible must be just after DisplayIO.Init for the message box
-			// to
-			// be the right size
-			setVisible(true);
-
-			setupGraphics();
-
-			// required to accept TAB key
-			setFocusTraversalKeysEnabled(false);
-
-			// Must be loaded after setupGraphics if images are on the frame
-			// Turn off XRay mode and load the first frame
-			FrameGraphics.setMode(FrameGraphics.MODE_NORMAL, false);
 			
 			// Go to the start frame if specified, otherwise go to the profile frame
@@ -321,51 +257,32 @@
 			if(_startFrame == null) {
 				_startFrame = UserSettings.StartFrame.get();
-				if(_startFrame != null && !Character.isDigit(_startFrame.charAt(_startFrame.length() - 1)))
+				if(_startFrame != null && !Character.isDigit(_startFrame.charAt(_startFrame.length() - 1))) {
 					_startFrame = _startFrame + "1";
-			}
+				}
+			}
+			
     		if((start = FrameIO.LoadFrame(_startFrame)) != null) {
     			// Make sure HomeFrame gets set
 		        UserSettings.HomeFrame.set(start.getName());
-		        //if (UserSettings.HomeFrame.get() == null) {
-			        //UserSettings.HomeFrame.set(profile.getName());
-
-			//}
-       			// Make sure the user can get back to the profile frame easily
-       			//DisplayIO.addToBack(profile);
+		        
        			// Go to the start frame
-       			DisplayIO.setCurrentFrame(start, true);
+       			DisplayController.setCurrentFrame(start, true);
     		} else {
     			// If an invalid start frame was specified, show a warning
-    			if(_startFrame != null) {
-    				warningMessages.add("Unknown frame: " + _startFrame);
-    			}
+    			if(_startFrame != null) MessageBay.warningMessage("Unknown frame: " + _startFrame);
+    			
     			// Go to the profile frame
-    			FrameUtils.loadFirstFrame(profile);
+    			FrameUtils.loadFirstFrame(userProfile);
     		}
-			DisplayIO.UpdateTitle();
-
-			/*
-			 * I think this can be moved back up to the top of the Go method
-			 * now... It used to crash the program trying to print error
-			 * messages up the top
-			 */
-			for (String message : warningMessages)
-				MessageBay.warningMessage(message);
-
-			this.getContentPane().addKeyListener(FrameKeyboardActions.getInstance());
-			this.addKeyListener(FrameKeyboardActions.getInstance());
-
-			_mouseEventRouter.addExpediteeMouseListener(FrameMouseActions.getInstance());
-			_mouseEventRouter.addExpediteeMouseMotionListener(FrameMouseActions.getInstance());
-			_mouseEventRouter.addExpediteeMouseWheelListener(FrameMouseActions.getInstance());
-
-			// Dont refresh for the profile frame otherwise error messages are shown twice
-			if (!DisplayIO.getCurrentFrame().equals(profile)) {
-				FrameKeyboardActions.Refresh();
+    		
+			DisplayController.updateTitle();
+
+			// Don't refresh for the profile frame otherwise error messages are shown twice
+			if (!DisplayController.getCurrentFrame().equals(userProfile)) {
+				StandardGestureActions.Refresh();
 			// If it's the profile frame just reparse it in order to display images/circles/widgets correctly
 			} else {
-				FrameUtils.Parse(profile);
-			}
-			// setVisible(true);
+				FrameUtils.Parse(userProfile);
+			}
 		} catch (Exception e) {
 			e.printStackTrace();
@@ -374,10 +291,221 @@
 	}
 
+	public void saveCompleted(SaveStateChangedEvent event)
+	{
+		MessageBay.displayMessage("Save finished!", Colour.BLUE);
+	}
+
+	public void saveStarted(SaveStateChangedEvent event)
+	{
+		String name = event.getEntity().getSaveName();
+		if (name == null) name = "data";
+		MessageBay.displayMessage("Saving " + name + "...", Colour.BLUE);
+	}
+
 	/**
-	 * @param userName
+	 * Closes the browser and ends the application. Performs saving operations -
+	 * halting until saves have completed. Feedback is given to the user while
+	 * the application is exiting. Must call on the swing thread.
+	 */
+	public void exit() {
+
+		// Set exiting flag
+		_isExiting = true;
+
+		MessageBay.displayMessage("System exiting...");
+
+		/**
+		 * TODO: Prompt the user etc.
+		 */
+
+		// TODO: Should we should a popup with a progress bar for user feedback?
+		// this would be nice and easy to do.
+		// Exit on a dedicated thread so that feedback can be obtained
+		new Exiter().start(); // this will exit the application
+	}
+
+	/**
+	 * The system must exit on a different thread other than the swing thread so
+	 * that the save threads can fire save-feedback to the swing thread and thus
+	 * provide user feedback on asynchronous save operations.
+	 * 
+	 * @author Brook Novak
+	 * 
+	 */
+	private class Exiter extends Thread {
+
+		@Override
+		public void run() {
+
+			// The final save point for saveable entities
+			EntitySaveManager.getInstance().saveAll();
+			try {
+				EntitySaveManager.getInstance().waitUntilAllSavingFinished();
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+			
+			// Stop any agents or simple programs
+			Simple.stop();
+			Actions.stopAgent();
+			// Wait for them to stop
+			try {
+				// Only stop if need to...
+				// Brook: What purpose does this serve?
+				MessageBay.displayMessage("Stopping Simple programs...");
+				while (Simple.isProgramRunning()) {
+					Thread.sleep(100);
+				}
+				
+				MessageBay.displayMessage("Stopping Agents...");
+				/* TODO: Only stop if need to... */
+				while (Actions.isAgentRunning()) {
+					Thread.sleep(100); // Brook: What purpose does this serve?
+				}
+			} catch (Exception e) {
+
+			}
+
+			MessageBay.displayMessage("Saving current frame...");
+			FrameIO.SaveFrame(DisplayController.getCurrentFrame());
+
+			MessageBay.displayMessage("Saving stats...");
+			StatsLogger.WriteStatsFile();
+
+			if (MailSession.getInstance() != null) {
+				if (MailSession.getInstance().finalise()) {
+					// TODO display this message before the finalising
+					// is done but only if the mail needs closing
+					MessageBay.displayMessage("Closed ExpMail...");
+				}
+			}
+
+			if (FrameShare.getInstance() != null) {
+				MessageBay.displayMessage("Stopping FrameServer...");
+				FrameShare.getInstance().finalise();
+			}
+
+			MessageBay.displayMessage("System exited");
+
+			// Finally remove the messages frameset
+			FrameIO.moveFrameset("messages", FrameIO.MESSAGES_PATH);
+
+			/*
+			 * Create a new messages folder so that it doesn't throw
+			 * Exceptions when two Expeditee's open at once and the
+			 * second tries to save its messages
+			 */
+			File file = new File(FrameIO.MESSAGES_PATH + "messages");
+			file.mkdirs();
+
+			Browser._hasExited = true;
+			
+			System.exit(0);
+		}
+	}
+
+	/**
+	 * Used to set up the the browser for use in testing.
+	 * 
 	 * @return
 	 */
-	protected Frame loadProfile(String userName) {
+	public static Browser initializeForTesting()
+	{
+		if (Browser._theBrowser == null) {
+			FrameShare.disableNetworking = true;
+			MailSession._autoConnect = false;
+
+			Browser.main(new String[]{});
+			try {
+				while (!isInitComplete()) {
+					Thread.sleep(10);
+				}
+			} catch (Exception e) {
+			}
+		}
+		return _theBrowser;
+	}
+	
+	private static void setInputManagerWindowRoutines()
+	{
+		InputManager manager = EcosystemManager.getInputManager();
+		
+	    // Refresh the layout when the window resizes
+		manager.addWindowEventListener(new WindowEventListener() {
+			@Override
+			public void onWindowEvent(WindowEventType type)
+			{
+				if (type != WindowEventType.WINDOW_RESIZED) return;
+				DisplayController.refreshWindowSize();
+				FrameIO.RefreshCacheImages();
+				for (Frame frame : DisplayController.getFrames()) {
+					if (frame != null) {
+						ItemUtils.Justify(frame);
+						frame.refreshSize();
+					}
+				}
+				DisplayController.requestRefresh(false);
+			}
+		});
+		
+		manager.addWindowEventListener(new WindowEventListener() {
+			@Override
+			public void onWindowEvent(WindowEventType type)
+			{
+				if (type != WindowEventType.MOUSE_EXITED_WINDOW) return;
+				StandardGestureActions.mouseExitedWindow();
+			}
+		});
+		
+		manager.addWindowEventListener(new WindowEventListener() {
+			@Override
+			public void onWindowEvent(WindowEventType type)
+			{
+				if (type != WindowEventType.MOUSE_ENTERED_WINDOW) return;
+				StandardGestureActions.mouseEnteredWindow();
+			}
+		});
+		
+		manager.addWindowEventListener(new WindowEventListener() {
+			@Override
+			public void onWindowEvent(WindowEventType type)
+			{
+				if (type != WindowEventType.WINDOW_CLOSED) return;
+				if (Browser._theBrowser != null) Browser._theBrowser.exit();
+			}
+		});
+	}
+
+	/**
+	 * @return The user's profile frame.
+	 */
+	private static Frame loadProfiles()
+	{
+		String defaultProfileName = UserSettings.DEFAULT_PROFILE_NAME;
+		String userName = UserSettings.ProfileName.get();
+
+		Frame defaultProfile = loadProfile(defaultProfileName);
+		Frame userProfile = loadProfile(userName);
+
+		MessageBay.warningMessages(FrameUtils.ParseProfile(defaultProfile));
+		
+		// Save the cursor if the defaultProfile had a custom cursor
+		Collection<Item> cursor = null;
+		if(FreeItems.hasCursor()) {
+			cursor = new ArrayList<Item>();
+			cursor.addAll(FreeItems.getCursor());
+		}
+		
+		MessageBay.warningMessages(FrameUtils.ParseProfile(userProfile));
+		
+		if (cursor != null && !FreeItems.hasCursor()) FreeItems.setCursor(cursor);
+		
+		return userProfile;
+	}
+
+	protected static Frame loadProfile(String userName)
+	{
 		Frame profile = FrameIO.LoadProfile(userName);
+		
 		if (profile == null) {
 			try {
@@ -392,247 +520,3 @@
 		return profile;
 	}
-
-	public Graphics2D g;
-
-	protected void setupGraphics() {
-		if (g != null)
-			g.dispose();
-		g = (Graphics2D) this.getContentPane().getGraphics();
-		assert (g != null);
-		g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
-				RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-		g.setFont(g.getFont().deriveFont(40f));
-		FrameGraphics.setDisplayGraphics(g);
-	}
-
-	// private int count = 0;
-	@Override
-	public void paint(Graphics g) {
-		// All this does is make sure the screen is repainted when the browser
-		// is moved so that some of the window is off the edge of the display
-		// then moved back into view
-		super.paint(g);
-		FrameGraphics.ForceRepaint();
-		// System.out.println("Paint " + count++);
-	}
-
-	/**
-	 * @inheritDoc
-	 */
-	public void componentResized(ComponentEvent e) {
-		setSizes(this.getSize());
-		setupGraphics();
-		FrameIO.RefreshCasheImages();
-		FrameGraphics.ForceRepaint();
-	}
-
-	/**
-	 * @inheritDoc
-	 */
-	public void componentMoved(ComponentEvent e) {
-		// FrameGraphics.setMaxSize(this.getSize());
-	}
-
-	/**
-	 * @inheritDoc
-	 */
-	public void componentShown(ComponentEvent e) {
-		DisplayIO.fullScreenTransitionPending=false;
-	}
-
-	/**
-	 * @inheritDoc
-	 */
-	public void componentHidden(ComponentEvent e) {
-	}
-
-	public void windowClosing(WindowEvent e) {
-	}
-
-	public void windowClosed(WindowEvent e) {
-		if (!DisplayIO.fullScreenTransitionPending) {
-			exit();
-		}
-	}
-
-	public void windowOpened(WindowEvent e) {
-	}
-
-	public void windowIconified(WindowEvent e) {
-	}
-
-	public void windowDeiconified(WindowEvent e) {
-	}
-
-	public void windowActivated(WindowEvent e) {
-	}
-
-	public void windowDeactivated(WindowEvent e) {
-	}
-
-	public void windowStateChanged(WindowEvent e) {
-	}
-
-	public int getDrawingAreaX() {
-		// return scrollPane.getLocationOnScreen().x;
-		return this.getLocationOnScreen().x;
-	}
-
-	public int getDrawingAreaY() {
-		// return scrollPane.getLocationOnScreen().y;
-		return this.getLocationOnScreen().y;
-	}
-
-	public void saveCompleted(SaveStateChangedEvent event) {
-		// if (isExisting()) {
-
-		// } else {
-		MessageBay.displayMessage("Save finished!", Color.BLUE);
-		// }
-	}
-
-	public void saveStarted(SaveStateChangedEvent event) {
-		// if (isExisting()) {
-
-		// } else {
-		String name = event.getEntity().getSaveName();
-		if (name == null)
-			name = "data";
-		MessageBay.displayMessage("Saving " + name + "...", Color.BLUE);
-		// }
-	}
-
-	/**
-	 * Closes the browser and ends the application. Performs saving operations -
-	 * halting until saves have completed. Feedback is given to the user while
-	 * the application is exiting. Must call on the swing thread.
-	 */
-	public void exit() {
-
-		// Set exiting flag
-		_isExiting = true;
-
-		MessageBay.displayMessage("System exiting...");
-
-		/**
-		 * TODO: Prompt the user etc.
-		 */
-
-		// TODO: Should we should a popup with a progress bar for user feedback?
-		// this would be nice and easy to do.
-		// Exit on a dedicated thread so that feedback can be obtained
-		new Exiter().start(); // this will exit the application
-	}
-
-	/**
-	 * The system must exit on a different thread other than the swing thread so
-	 * that the save threads can fire save-feedback to the swing thread and thus
-	 * provide user feedback on asynchronous save operations.
-	 * 
-	 * @author Brook Novak
-	 * 
-	 */
-	private class Exiter extends Thread {
-
-		@Override
-		public void run() {
-
-			// The final save point for saveable entities
-			EntitySaveManager.getInstance().saveAll();
-			try {
-				EntitySaveManager.getInstance().waitUntilAllSavingFinished();
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-
-			// The final phase must save on the swing thread since dealing with
-			// the expeditee data model
-			SwingUtilities.invokeLater(new Runnable() {
-				public void run() {
-
-					// Stop any agents or simple programs
-					Simple.stop();
-					Actions.stopAgent();
-					// Wait for them to stop
-					try {
-						MessageBay
-								.displayMessage("Stopping Simple programs..."); // TODO:
-						/**
-						 * Only stop if need to...
-						 */
-						while (Simple.isProgramRunning()) {
-							Thread.sleep(100);
-							/* Brook: What purpose does this serve? */
-						}
-						MessageBay.displayMessage("Stopping Agents...");
-						/* TODO: Only stop if need to... */
-						while (Actions.isAgentRunning()) {
-							Thread.sleep(100); // Brook: What purpose does this
-							// serve?
-						}
-					} catch (Exception e) {
-
-					}
-
-					MessageBay.displayMessage("Saving current frame...");
-					FrameIO.SaveFrame(DisplayIO.getCurrentFrame());
-
-					MessageBay.displayMessage("Saving stats...");
-					StatsLogger.WriteStatsFile();
-
-					if (MailSession.getInstance() != null) {
-						if (MailSession.getInstance().finalise()) {
-							// TODO display this message before the finalising
-							// is done but only if the mail needs closing
-							MessageBay.displayMessage("Closed ExpMail...");
-						}
-					}
-
-					if (FrameShare.getInstance() != null) {
-						MessageBay.displayMessage("Stopping FrameServer...");
-						FrameShare.getInstance().finalise();
-					}
-
-					MessageBay.displayMessage("System exited");
-
-					// Finally remove the messages frameset
-					FrameIO.moveFrameset("messages", FrameIO.MESSAGES_PATH);
-
-					/*
-					 * Create a new messages folder so that it doesn't throw
-					 * Exceptions when two Expeditee's open at once and the
-					 * second tries to save its messages
-					 */
-					File file = new File(FrameIO.MESSAGES_PATH + "messages");
-					file.mkdirs();
-
-					Browser._hasExited = true;
-					
-					System.exit(0);
-				}
-			});
-		}
-	}
-
-	/**
-	 * Used to set up the the browser for use in testing.
-	 * 
-	 * @return
-	 */
-	public static Browser initializeForTesting() {
-		if (Browser._theBrowser == null) {
-			FrameShare.disableNetworking = true;
-			MailSession._autoConnect = false;
-
-			Browser.main(new String[]{});
-			try {
-				while (!isInitComplete()) {
-					Thread.sleep(10);
-				}
-			} catch (Exception e) {
-			}
-		}
-		return _theBrowser;
-	}
-
 }
Index: /trunk/src/org/expeditee/gui/ColorUtils.java
===================================================================
--- /trunk/src/org/expeditee/gui/ColorUtils.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/ColorUtils.java	(revision 1102)
@@ -19,5 +19,5 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
+import org.expeditee.core.Colour;
 
 public class ColorUtils {
@@ -36,5 +36,5 @@
 	 * @return the next color on the color wheel
 	 */
-	public static Color getNextColor(Color color, Color[] wheel, Color skip) {
+	public static Colour getNextColor(Colour color, Colour[] wheel, Colour skip) {
 		if (color == null) {
 			color = wheel[0];
Index: /trunk/src/org/expeditee/gui/Frame.java
===================================================================
--- /trunk/src/org/expeditee/gui/Frame.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/Frame.java	(revision 1102)
@@ -19,9 +19,4 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.awt.image.ImageObserver;
-import java.awt.image.VolatileImage;
 import java.sql.Time;
 import java.util.ArrayList;
@@ -37,4 +32,10 @@
 
 import org.expeditee.actions.Simple;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.input.StandardInputEventListeners;
+import org.expeditee.gio.input.KBMInputEvent.Key;
 import org.expeditee.io.Conversion;
 import org.expeditee.items.Constraint;
@@ -50,5 +51,5 @@
 import org.expeditee.items.UserAppliedPermission;
 import org.expeditee.items.XRayable;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.settings.UserSettings;
@@ -66,12 +67,21 @@
  * 
  */
-public class Frame implements ImageObserver {
+public class Frame {
+	
+	/** The frame number to indicate this is a virtual frame. */
+	public static final int VIRTUAL_FRAME_NUMBER = -1;
+	
+	/** The background colour the frame name should take if the frame has user permission level 'none'. */
+	public static final Colour FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_NONE = Colour.FromRGB255(255, 220, 220);
+	/** The background colour the frame name should take if the frame has user permission level 'followLinks'. */
+	public static final Colour FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_FOLLOW_LINKS = Colour.FromRGB255(255, 230, 135);
+	/** The background colour the frame name should take if the frame has user permission level 'copy'. */
+	public static final Colour FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_COPY = Colour.FromRGB255(255, 255, 155);
+	/** The background colour the frame name should take if the frame has user permission level 'createFrames'. */
+	public static final Colour FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_CREATE_FRAMES = Colour.FromRGB255(220, 255, 220);
+	/** The background colour the frame name should take if the frame has user permission level 'full'. */
+	public static final Colour FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_FULL = null;
 
 	private boolean _protectionChanged = false;
-
-	public boolean isReadOnly() {
-		return !_frameName.hasPermission(UserAppliedPermission.full)
-				&& !_protectionChanged;
-	}
 
 	// The various attributes of this Frame
@@ -95,8 +105,8 @@
 
 	// Background color is clear
-	private Color _background = null;
+	private Colour _background = null;
 
 	// Foreground color is automatic by default
-	private Color _foreground = null;
+	private Colour _foreground = null;
 
 	private String path;
@@ -105,29 +115,10 @@
 
 	private boolean _sorted = true;
-
-	// The items contained in this Frame
-	// records whether a change has been made to this Frame (for saving
-	// purposes).
+	
+	/** Whether the frame has changed and therefore needs saving. */
 	private boolean _change = false;
 
+	/** Whether the frame has been saved. */
 	private boolean _saved = false;
-
-	private static final class History {
-		public enum Type {
-			deletion,
-			movement
-		}
-		public final List<Item> items;
-		public final Type type;
-		
-		public History(Collection<Item> items, Type type) {
-			this.items = new LinkedList<Item>(items);
-			this.type = type;
-		}
-		
-		public String toString() {
-			return this.type.toString() + ":\n" + this.items.toString();
-		}
-	}
 	
 	// list of deleted items that can be restored
@@ -141,5 +132,5 @@
 
 	// for drawing purposes
-	private List<InteractiveWidget> _iWidgets = new ArrayList<InteractiveWidget>();
+	private List<Widget> _iWidgets = new ArrayList<Widget>();
 
 	private int _lineCount = 0;
@@ -170,64 +161,74 @@
 	private Text _dotTemplate = TemplateSettings.DotTemplate.get().copy();
 
-	/**
-	 * Default constructor, nothing is set.
-	 */
-	public Frame() {
-	}
-
-	public void reset() {
+	Map<String, Text> _annotations = null;
+
+	private Collection<FrameObserver> _observers = new HashSet<FrameObserver>();
+
+	/** Default constructor, nothing is set. */
+	public Frame()
+	{
+	}
+
+	public boolean isReadOnly()
+	{
+		return !_frameName.hasPermission(UserAppliedPermission.full) && !_protectionChanged;
+	}
+
+	public void reset()
+	{
 		refreshItemPermissions(UserAppliedPermission.full);
-		//System.out.println("Reset");
 		resetDot();
 		SessionStats.NewFrameSession();
 	}
 
-	private void resetDot() {
+	private void resetDot()
+	{
 	    _dotTemplate.setColor(TemplateSettings.ColorWheel.getSafe(1));
 	    _dotTemplate.setFillColor(TemplateSettings.FillColorWheel.getSafe(0));
 	}
 
-	public void nextDot() {
-		_dotTemplate.setFillColor(ColorUtils.getNextColor(_dotTemplate
-				.getFillColor(), TemplateSettings.FillColorWheel.get(), null));
-		_dotTemplate.setColor(ColorUtils.getNextColor(_dotTemplate.getColor(),
-				TemplateSettings.ColorWheel.get(), null));
-
-		if (_dotTemplate.getColor() == null || _dotTemplate.getColor().equals(Color.white)) {
-			resetDot();
-		}
-	}
-
-	public Image getBuffer() {
+	public void nextDot()
+	{
+		_dotTemplate.setFillColor(ColorUtils.getNextColor(_dotTemplate.getFillColor(), TemplateSettings.FillColorWheel.get(), null));
+		_dotTemplate.setColor(ColorUtils.getNextColor(_dotTemplate.getColor(), TemplateSettings.ColorWheel.get(), null));
+		if (_dotTemplate.getColor() == null || _dotTemplate.getColor().equals(Colour.WHITE)) resetDot();
+	}
+
+	public Image getBuffer()
+	{
 		return _buffer;
 	}
 
-	public void setBuffer(Image newBuffer) {
+	public void setBuffer(Image newBuffer)
+	{
 		_buffer = newBuffer;
 	}
 
-	public boolean isBufferValid() {
-		if (_buffer == null
-				|| (_buffer instanceof VolatileImage && ((VolatileImage) _buffer)
-						.contentsLost()))
-			return false;
+	public boolean isBufferValid()
+	{
+		if (_buffer == null) return false;
 
 		return _validBuffer;
 	}
 
-	private void setBufferValid(boolean newValue) {
+	private void setBufferValid(boolean newValue)
+	{
 		_validBuffer = newValue;
 	}
 
-	public int getNextItemID() {
+	public int getNextItemID()
+	{
 		return ++_itemCount;
 	}
 
-	public void updateIDs(List<Item> items) {
-		for (Item i : items)
-			if (!(i instanceof Line))
+	public void updateIDs(List<Item> items)
+	{
+		for (Item i : items) {
+			if (!(i instanceof Line)) {
 				i.setID(getNextItemID());
-			else
+			} else {
 				i.setID(++_lineCount);
+			}
+		}
 	}
 
@@ -237,6 +238,7 @@
 	 *         Hence it excludes free-widgets. Returns a copy
 	 */
-	public List<InteractiveWidget> getInteractiveWidgets() {
-		LinkedList<InteractiveWidget> clone = new LinkedList<InteractiveWidget>();
+	public List<Widget> getInteractiveWidgets()
+	{
+		LinkedList<Widget> clone = new LinkedList<Widget>();
 		clone.addAll(this._iWidgets);
 		return clone;
@@ -248,8 +250,8 @@
 	 * @return True if this Frame has been altered, false otherwise.
 	 */
-	public boolean hasChanged() {
+	public boolean hasChanged()
+	{
 		// virtual frames are never saved
-		if (_number == -1)
-			return false;
+		if (_number == VIRTUAL_FRAME_NUMBER) return false;
 
 		return _change;
@@ -260,16 +262,9 @@
 	 * 
 	 * @param value
-	 *            False if this Frame should be saved to disk, False otherwise.
-	 */
-	public void setChanged(boolean value) {
-		// System.out.println(getName() + " " + value);
-		boolean oldValue = _change;
-
-		// if (value) {
-		// notifyObservers();
-		// }
-
-		if (oldValue == value)
-			return;
+	 *            True if this Frame should be saved to disk, False otherwise.
+	 */
+	public void setChanged(boolean value)
+	{
+		if (_change == value) return;
 
 		_change = value;
@@ -281,6 +276,4 @@
 	}
 
-	// private static int updateCount = 0;
-
 	/**
 	 * Notify items observing the data on this frame that the frame content has
@@ -290,8 +283,7 @@
 	 *            true if the frame should be recalculated first.
 	 */
-	public void notifyObservers(boolean bRecalculate) {
-		if (bRecalculate) {
-			recalculate();
-		}
+	public void notifyObservers(boolean bRecalculate)
+	{
+		if (bRecalculate) recalculate();
 		// Notify the frame listeners that the frame has changed
 		/*
@@ -301,16 +293,15 @@
 		 * changing this frames observer list.
 		 */
-		Collection<FrameObserver> observersCopy = new LinkedList<FrameObserver>(
-				_observers);
+		Collection<FrameObserver> observersCopy = new LinkedList<FrameObserver>(_observers);
 		// System.out.println(++updateCount + " update");
 
 		for (FrameObserver fl : observersCopy) {
-			if (/* !Item.isLocked(fl) && */fl.isVisible())
-				fl.update();
+			if (fl.isVisible()) fl.update();
 		}
 	}
 
 	// indicates the frame has changed
-	public void change() {
+	public void change()
+	{
 		setChanged(true);
 		_interactableItems.clear();
@@ -323,9 +314,14 @@
 	 * @return The list of Item objects that are on this Frame.
 	 */
-	public List<Item> getItems(boolean visible) {
+	public List<Item> getItems(boolean visible)
+	{
 		if (!_sorted) {
-			for(int i = 0; i < _body.size();)
-				if(_body.get(i) == null) _body.remove(i);
-				else i++;
+			for(int i = 0; i < _body.size();) {
+				if(_body.get(i) == null) {
+					_body.remove(i);
+				} else {
+					i++;
+				}
+			}
 			Collections.sort(_body);
 			_sorted = true;
@@ -335,6 +331,6 @@
 
 		for (Item i : _body) {
-			if (i == null)
-				continue;
+			if (i == null) continue;
+			
 			if (i.isVisible() || (!visible && !i.isDeleted())) {
 				items.add(i);
@@ -345,5 +341,7 @@
 	}
 
-	public List<Item> getItems() {
+	/** TODO: Comment. cts16 */
+	public List<Item> getItems()
+	{
 		return getItems(false);
 	}
@@ -354,7 +352,8 @@
 	 * @return True if this frame contains i.
 	 */
-	public boolean containsItem(Item i) {
-		if (i == null)
-			throw new NullPointerException("i");
+	public boolean containsItem(Item i)
+	{
+		if (i == null) throw new NullPointerException("i");
+		
 		return _body.contains(i);
 	}
@@ -372,15 +371,15 @@
 	 * @return the list of body text items.
 	 */
-	public List<Text> getBodyTextItems(boolean includeAnnotations) {
+	public List<Text> getBodyTextItems(boolean includeAnnotations)
+	{
 		List<Text> bodyTextItems = new ArrayList<Text>();
+		
 		for (Item i : getItems(true)) {
 			// only add up normal body text items
-			if ((i instanceof Text)
-					&& ((includeAnnotations && !((Text) i)
-							.isSpecialAnnotation()) || !i.isAnnotation())
-					&& !i.isLineEnd()) {
+			if ((i instanceof Text) && ((includeAnnotations && !((Text) i).isSpecialAnnotation()) || !i.isAnnotation()) && !i.isLineEnd()) {
 				bodyTextItems.add((Text) i);
 			}
 		}
+		
 		bodyTextItems.remove(getTitleItem());
 
@@ -388,15 +387,16 @@
 	}
 
-	public Collection<Item> getNonAnnotationItems(boolean removeTitle) {
+	public Collection<Item> getNonAnnotationItems(boolean removeTitle)
+	{
 		Collection<Item> items = new ArrayList<Item>();
 		for (Item i : getItems(true)) {
 			// only add up normal body text items
-			if (!i.isAnnotation()) {
-				items.add(i);
-			}
-		}
+			if (!i.isAnnotation()) items.add(i);
+		}
+		
 		if (removeTitle) {
 			items.remove(getTitleItem());
 		}
+		
 		return items;
 	}
@@ -408,5 +408,6 @@
 	 * @return the last non annotation text item.
 	 */
-	public Item getLastNonAnnotationTextItem() {
+	public Item getLastNonAnnotationTextItem()
+	{
 		List<Item> items = getItems();
 
@@ -431,9 +432,11 @@
 	 *         found.
 	 */
-	public Item getItemWithID(int id) {
-		for (Item i : _body)
-			if (i.getID() == id)
+	public Item getItemWithID(int id)
+	{
+		for (Item i : _body) {
+			if (i.getID() == id) {
 				return i;
-
+			}
+		}
 		return null;
 	}
@@ -445,7 +448,7 @@
 	 *            The title to assign to this Frame
 	 */
-	public void setTitle(String title) {
-		if (title == null || title.equals(""))
-			return;
+	public void setTitle(String title)
+	{
+		if (title == null || title.equals("")) return;
 
 		boolean oldchange = _change;
@@ -476,7 +479,6 @@
 			// title = ItemUtils.StripTagSymbol(title);
 			frameTitle.setText(title);
-			// If the @ symbol is followed by numbering or a bullet remove that
-			// too
-			String autoBulletText = FrameKeyboardActions.getAutoBullet(title);
+			// If the @ symbol is followed by numbering or a bullet remove that too
+			String autoBulletText = StandardGestureActions.getAutoBullet(title);
 			if (autoBulletText.length() > 0)
 				frameTitle.stripFirstWord();
@@ -485,6 +487,5 @@
 		// Brook: Cannot figure what is going on above... widget annot titles
 		// should be stripped always
-		if (ItemUtils.startsWithTag(frameTitle, ItemUtils
-				.GetTag(ItemUtils.TAG_IWIDGET))) {
+		if (ItemUtils.startsWithTag(frameTitle, ItemUtils.GetTag(ItemUtils.TAG_IWIDGET))) {
 			frameTitle.stripFirstWord();
 		}
@@ -496,10 +497,12 @@
 	}
 
-	public Text getTitleItem() {
+	public Text getTitleItem()
+	{
 		List<Item> items = getVisibleItems();
+		
 		for (Item i : items) {
-			if (i instanceof Text && i.getX() < UserSettings.TitlePosition.get()
-					&& i.getY() < UserSettings.TitlePosition.get())
+			if (i instanceof Text && i.getX() < UserSettings.TitlePosition.get() && i.getY() < UserSettings.TitlePosition.get()) {
 				return (Text) i;
+			}
 		}
 
@@ -507,24 +510,25 @@
 	}
 
-	public String getTitle() {
+	public String getTitle()
+	{
 		Text title = getTitleItem();
-		if (title == null)
-			return getName();
+		if (title == null) return getName();
 
 		return title.getFirstLine();
 	}
 
-	public Item getNameItem() {
+	public Item getNameItem()
+	{
 		return _frameName;
 	}
 
-	public Text getItemTemplate() {
-		return getTemplate(TemplateSettings.ItemTemplate.get(),
-				ItemUtils.TAG_ITEM_TEMPLATE);
-	}
-
-	public Text getAnnotationTemplate() {
-		Text t = getTemplate(TemplateSettings.AnnotationTemplate.get(),
-				ItemUtils.TAG_ANNOTATION_TEMPLATE);
+	public Text getItemTemplate()
+	{
+		return getTemplate(TemplateSettings.ItemTemplate.get(), ItemUtils.TAG_ITEM_TEMPLATE);
+	}
+
+	public Text getAnnotationTemplate()
+	{
+		Text t = getTemplate(TemplateSettings.AnnotationTemplate.get(), ItemUtils.TAG_ANNOTATION_TEMPLATE);
 
 		if (t == null) {
@@ -535,8 +539,8 @@
 	}
 
-	public Text getStatTemplate() {
+	public Text getStatTemplate()
+	{
 		SessionStats.CreatedText();
-		Text t = getTemplate(TemplateSettings.StatTemplate.get(),
-				ItemUtils.TAG_STAT_TEMPLATE);
+		Text t = getTemplate(TemplateSettings.StatTemplate.get(), ItemUtils.TAG_STAT_TEMPLATE);
 
 		if (t == null) {
@@ -547,21 +551,25 @@
 	}
 	
-	public Item getTooltipTextItem(String tooltipText) {
+	public Item getTooltipTextItem(String tooltipText)
+	{
 		return getTextItem(tooltipText, TemplateSettings.TooltipTemplate.get().copy());
 	}
 
-	public Item getStatsTextItem(String itemText) {
+	public Item getStatsTextItem(String itemText)
+	{
 		return getTextItem(itemText, getStatTemplate());
 	}
 
-	public Item getTextItem(String itemText) {
+	public Item getTextItem(String itemText)
+	{
 		return getTextItem(itemText, getItemTemplate());
 	}
 
-	private Item getTextItem(String itemText, Text template) {
+	private Item getTextItem(String itemText, Text template)
+	{
 		Text t = template;
 		// We dont want the stats to wrap at all
 		// t.setMaxWidth(Integer.MAX_VALUE);
-		t.setPosition(DisplayIO.getMouseX(), FrameMouseActions.getY());
+		t.setPosition(DisplayController.getMousePosition());
 		// The next line is needed to make sure the item is removed from the
 		// frame when picked up
@@ -571,7 +579,7 @@
 	}
 
-	public Text getCodeCommentTemplate() {
-		Text t = getTemplate(TemplateSettings.CommentTemplate.get(), 
-				ItemUtils.TAG_CODE_COMMENT_TEMPLATE);
+	public Text getCodeCommentTemplate()
+	{
+		Text t = getTemplate(TemplateSettings.CommentTemplate.get(), ItemUtils.TAG_CODE_COMMENT_TEMPLATE);
 
 		if (t == null) {
@@ -592,5 +600,6 @@
 	 *         Item.intersects(shape) return true.
 	 */
-	public Collection<Item> getItemsWithin(Polygon poly) {
+	public Collection<Item> getItemsWithin(PolygonBounds poly)
+	{
 		Collection<Item> results = new LinkedHashSet<Item>();
 		for (Item i : getVisibleItems()) {
@@ -606,7 +615,8 @@
 		}
 
-		for (Overlay o : _overlays.keySet())
+		for (Overlay o : _overlays.keySet()) {
 			results.addAll(o.Frame.getItemsWithin(poly));
-
+		}
+		
 		for (Item i : getVectorItems()) {
 			if (i.intersects(poly)) {
@@ -626,9 +636,11 @@
 	 *            The name to use for this Frame.
 	 */
-	public void setFrameset(String name) {
+	public void setFrameset(String name)
+	{
 		_frameset = name;
 	}
 
-	public void setName(String framename) {
+	public void setName(String framename)
+	{
 		int num = Conversion.getFrameNumber(framename);
 		String frameset = Conversion.getFramesetName(framename, false);
@@ -643,9 +655,9 @@
 	 *            The number to set as the frame number
 	 */
-	public void setFrameNumber(int number) {
+	public void setFrameNumber(int number)
+	{
 		assert (number >= 0);
 
-		if (_number == number)
-			return;
+		if (_number == number) return;
 
 		_number = number;
@@ -659,4 +671,5 @@
 			id = -1 * getNextItemID();
 		}
+		
 		_frameName = new Text(id);
 		_frameName.setParent(this);
@@ -671,5 +684,6 @@
 	 * @return The Frame number of this Frame or -1 if it is not set.
 	 */
-	public int getNumber() {
+	public int getNumber()
+	{
 		return _number;
 	}
@@ -681,5 +695,6 @@
 	 *            The version to use for this Frame.
 	 */
-	public void setVersion(int version) {
+	public void setVersion(int version)
+	{
 		_version = version;
 	}
@@ -691,12 +706,13 @@
 	 *            The protection to use for this Frame.
 	 */
-	public void setPermission(PermissionPair permission) {
-		if (_permissionPair != null && _permissionPair.getPermission(this._owner).equals(permission))
+	public void setPermission(PermissionPair permission)
+	{
+		if (_permissionPair != null && _permissionPair.getPermission(this._owner).equals(permission)) {
 			_protectionChanged = true;
+		}
 
 		_permissionPair = new PermissionPair(permission);
 
-		if (_body.size() > 0)
-			refreshItemPermissions(permission.getPermission(_owner));
+		if (_body.size() > 0) refreshItemPermissions(permission.getPermission(_owner));
 	}
 
@@ -707,5 +723,6 @@
 	 *            The owner to use for this Frame.
 	 */
-	public void setOwner(String owner) {
+	public void setOwner(String owner)
+	{
 		_owner = owner;
 	}
@@ -717,5 +734,6 @@
 	 *            The date to use for this Frame.
 	 */
-	public void setDateCreated(String date) {
+	public void setDateCreated(String date)
+	{
 		_creationDate = date;
 		_modifiedDate = date;
@@ -729,5 +747,6 @@
 	 * 
 	 */
-	public void resetDateCreated() {
+	public void resetDateCreated()
+	{
 		setDateCreated(Formatter.getDateTime());
 		resetTimes();
@@ -735,5 +754,6 @@
 	}
 
-	private void resetTimes() {
+	private void resetTimes()
+	{
 		setActiveTime(new Time(0));
 		setDarkTime(new Time(0));
@@ -746,5 +766,6 @@
 	 *            The user to set as the last modifying user.
 	 */
-	public void setLastModifyUser(String user) {
+	public void setLastModifyUser(String user)
+	{
 		_modifiedUser = user;
 	}
@@ -756,5 +777,6 @@
 	 *            The date to set as the last modified date.
 	 */
-	public void setLastModifyDate(String date) {
+	public void setLastModifyDate(String date)
+	{
 		_modifiedDate = date;
 	}
@@ -766,9 +788,11 @@
 	 *            The date to set as the last frozen date.
 	 */
-	public void setFrozenDate(String date) {
+	public void setFrozenDate(String date)
+	{
 		_frozenDate = date;
 	}
 
-	public void setResort(boolean value) {
+	public void setResort(boolean value)
+	{
 		_sorted = !value;
 	}
@@ -780,11 +804,12 @@
 	 *            The Item to add to this Frame.
 	 */
-	public void addItem(Item item) {
+	public void addItem(Item item)
+	{
 		addItem(item, true);
 	}
 
-	public void addItem(Item item, boolean recalculate) {
-		if (item == null || item.equals(_frameName) || _body.contains(item))
-			return;
+	public void addItem(Item item, boolean recalculate)
+	{
+		if (item == null || item.equals(_frameName) || _body.contains(item)) return;
 
 		// When an annotation item is anchored the annotation list must be
@@ -794,6 +819,5 @@
 		}
 
-		if (item instanceof Line)
-			_lineCount++;
+		if (item instanceof Line) _lineCount++;
 
 		_itemCount = Math.max(_itemCount, item.getID());
@@ -816,15 +840,15 @@
 		// add widget items to the list of widgets
 		if (item instanceof WidgetCorner) {
-			InteractiveWidget iw = ((WidgetCorner) item).getWidgetSource();
+			Widget iw = ((WidgetCorner) item).getWidgetSource();
 			if (!this._iWidgets.contains(iw)) { // A set would have been
-				if (FrameMouseActions.isControlDown())
+				if (StandardInputEventListeners.kbmStateListener.isKeyDown(Key.CTRL)) {
 					_iWidgets.add(iw);
-				else
+				} else {
 					_iWidgets.add(0, iw);
-			}
-		}
-
-		item.onParentStateChanged(new ItemParentStateChangedEvent(this,
-				ItemParentStateChangedEvent.EVENT_TYPE_ADDED));
+				}
+			}
+		}
+
+		item.onParentStateChanged(new ItemParentStateChangedEvent(this, ItemParentStateChangedEvent.EVENT_TYPE_ADDED));
 
 		// if (recalculate && item.recalculateWhenChanged())
@@ -834,12 +858,13 @@
 	}
 
-	public void refreshSize() {
-		// assert (size != null);
+	public void refreshSize()
+	{
 		boolean bReparse = false;
+		
 		for (Item i : getItems()) {
-			Float anchorLeft   = i.getAnchorLeft();
-			Float anchorRight  = i.getAnchorRight();
-			Float anchorTop    = i.getAnchorTop();
-			Float anchorBottom = i.getAnchorBottom();
+			Integer anchorLeft   = i.getAnchorLeft();
+			Integer anchorRight  = i.getAnchorRight();
+			Integer anchorTop    = i.getAnchorTop();
+			Integer anchorBottom = i.getAnchorBottom();
 	
 			
@@ -885,9 +910,9 @@
 	}
 
-	public void addAllItems(Collection<Item> toAdd) {
+	public void addAllItems(Collection<Item> toAdd)
+	{
 		for (Item i : toAdd) {
 			// If an annotation is being deleted clear the annotation list
-			if (i.isAnnotation())
-				i.getParentOrCurrentFrame().clearAnnotations();
+			if (i.isAnnotation()) i.getParentOrCurrentFrame().clearAnnotations();
 			// TODO Improve efficiency when addAll is called
 			addItem(i);
@@ -895,21 +920,22 @@
 	}
 
-	public void removeAllItems(Collection<Item> toRemove) {
+	public void removeAllItems(Collection<Item> toRemove)
+	{
 		for (Item i : toRemove) {
 			// If an annotation is being deleted clear the annotation list
-			if (i.isAnnotation())
-				i.getParentOrCurrentFrame().clearAnnotations();
+			if (i.isAnnotation()) i.getParentOrCurrentFrame().clearAnnotations();
 			removeItem(i);
 		}
 	}
 
-	public void removeItem(Item item) {
+	public void removeItem(Item item)
+	{
 		removeItem(item, true);
 	}
 
-	public void removeItem(Item item, boolean recalculate) {
+	public void removeItem(Item item, boolean recalculate)
+	{
 		// If an annotation is being deleted clear the annotation list
-		if (item.isAnnotation())
-			item.getParentOrCurrentFrame().clearAnnotations();
+		if (item.isAnnotation()) item.getParentOrCurrentFrame().clearAnnotations();
 
 		if (_body.remove(item)) {
@@ -917,9 +943,10 @@
 			// Remove widgets from the widget list
 			if (item != null) {
-				item.onParentStateChanged(new ItemParentStateChangedEvent(this,
-						ItemParentStateChangedEvent.EVENT_TYPE_REMOVED));
+				item.onParentStateChanged(new ItemParentStateChangedEvent(this, ItemParentStateChangedEvent.EVENT_TYPE_REMOVED));
+				
 				if (item instanceof WidgetCorner) {
 					_iWidgets.remove(((WidgetCorner) item).getWidgetSource());
 				}
+				
 				item.invalidateCommonTrait(ItemAppearence.Removed);
 			}
@@ -937,26 +964,27 @@
 	 * @param type  The type of event that occurred
 	 */
-	private void addToUndo(Collection<Item> items, History.Type type) {
-		if (items.size() < 1)
-			return;
-		
-		// System.out.println("Added: " + items);
+	private void addToUndo(Collection<Item> items, History.Type type)
+	{
+		if (items.size() < 1) return;
 
 		_undo.push(new History(items, type));
 	}
 	
-	public void addToUndoDelete(Collection<Item> items) {
+	public void addToUndoDelete(Collection<Item> items)
+	{
 		addToUndo(items, History.Type.deletion);
 	}
-	public void addToUndoMove(Collection<Item> items) {
+	
+	public void addToUndoMove(Collection<Item> items)
+	{
 		addToUndo(items, History.Type.movement);
 	}
 
-	public void undo() {
+	public void undo()
+	{
 		boolean bReparse = false;
 		boolean bRecalculate = false;
 
-		if (_undo.size() <= 0)
-			return;
+		if (_undo.size() <= 0) return;
 
 		History undo = _undo.pop();
@@ -992,6 +1020,9 @@
 			break;
 		}
+		
 		change();
-		FrameMouseActions.getInstance().refreshHighlights();
+		
+		StandardGestureActions.refreshHighlights();
+		
 		if (bReparse) {
 			FrameUtils.Parse(this, false, false);
@@ -999,19 +1030,19 @@
 			notifyObservers(bRecalculate);
 		}
+		
 		// always request a refresh otherwise filled shapes
 		// that were broken by a deletion and then reconnected by the undo
 		// don't get filled until the user otherwise causes them to redraw
-		FrameGraphics.requestRefresh(false);
-		FrameGraphics.Repaint();
+		DisplayController.requestRefresh(false);
 		// ItemUtils.EnclosedCheck(_body);
 		ItemUtils.Justify(this);
 	}
 	
-	public void redo() {
+	public void redo()
+	{
 		boolean bReparse = false;
 		boolean bRecalculate = false;
 
-		if (_redo.size() <= 0)
-			return;
+		if (_redo.size() <= 0) return;
 
 		History redo = _redo.pop();
@@ -1047,6 +1078,9 @@
 			break;
 		}
+		
 		change();
-		FrameMouseActions.getInstance().refreshHighlights();
+		
+		StandardGestureActions.refreshHighlights();
+		
 		if (bReparse) {
 			FrameUtils.Parse(this, false, false);
@@ -1054,9 +1088,9 @@
 			notifyObservers(bRecalculate);
 		}
+		
 		// always request a refresh otherwise filled shapes
 		// that were broken by a deletion and then reconnected by the undo
 		// don't get filled until the user otherwise causes them to redraw
-		FrameGraphics.requestRefresh(false);
-		FrameGraphics.Repaint();
+		DisplayController.requestRefresh(false);
 		// ItemUtils.EnclosedCheck(_body);
 		ItemUtils.Justify(this);
@@ -1068,9 +1102,11 @@
 	 * @return The name of this Frame's frameset.
 	 */
-	public String getFramesetName() {
+	public String getFramesetName()
+	{
 		return _frameset;
 	}
 
-	public String getName() {
+	public String getName()
+	{
 		return getFramesetName() + _number;
 	}
@@ -1081,58 +1117,69 @@
 	 * @return The version of this Frame.
 	 */
-	public int getVersion() {
+	public int getVersion()
+	{
 		return _version;
 	}
 
-	public PermissionPair getPermission() {
+	public PermissionPair getPermission()
+	{
 		return _permissionPair;
 	}
 	
-	public UserAppliedPermission getUserAppliedPermission() {
+	public UserAppliedPermission getUserAppliedPermission()
+	{
 		return getUserAppliedPermission(UserAppliedPermission.full);
 	}
 
-	public UserAppliedPermission getUserAppliedPermission(UserAppliedPermission defaultPermission) {
-		if (_permissionPair == null)
-			return defaultPermission;
+	public UserAppliedPermission getUserAppliedPermission(UserAppliedPermission defaultPermission)
+	{
+		if (_permissionPair == null) return defaultPermission;
 
 		return _permissionPair.getPermission(_owner);
 	}
 
-	
-	public String getOwner() {
+	public String getOwner()
+	{
 		return _owner;
 	}
 
-	public String getDateCreated() {
+	public String getDateCreated()
+	{
 		return _creationDate;
 	}
 
-	public String getLastModifyUser() {
+	public String getLastModifyUser()
+	{
 		return _modifiedUser;
 	}
 
-	public String getLastModifyDate() {
+	public String getLastModifyDate()
+	{
 		return _modifiedDate;
 	}
 
-	public String getFrozenDate() {
+	public String getFrozenDate()
+	{
 		return _frozenDate;
 	}
 
-	public void setBackgroundColor(Color back) {
+	public void setBackgroundColor(Colour back)
+	{
 		_background = back;
+		
 		change();
 
-		if (this == DisplayIO.getCurrentFrame()) {
-			FrameGraphics.refresh(false);
-		}
-	}
-
-	public Color getBackgroundColor() {
+		if (this == DisplayController.getCurrentFrame()) {
+			DisplayController.requestRefresh(false);
+		}
+	}
+
+	public Colour getBackgroundColor()
+	{
 		return _background;
 	}
 
-	public Color getPaintBackgroundColor() {
+	public Colour getPaintBackgroundColor()
+	{
 		// If null... return white
 		if (_background == null) {
@@ -1143,29 +1190,32 @@
 	}
 
-	public void setForegroundColor(Color front) {
+	public void setForegroundColor(Colour front)
+	{
 		_foreground = front;
+		
 		change();
-		// FrameGraphics.Repaint();
-	}
-
-	public Color getForegroundColor() {
+	}
+
+	public Colour getForegroundColor()
+	{
 		return _foreground;
 	}
 
-	public Color getPaintForegroundColor() {
-		final int GRAY = Color.gray.getBlue();
-		final int THRESHOLD = 10;
+	public Colour getPaintForegroundColor()
+	{
+		final int GRAY = Colour.GREY.getBlue();
+		final int THRESHOLD = Colour.FromComponent255(10);
 
 		if (_foreground == null) {
-			Color back = getPaintBackgroundColor();
+			Colour back = getPaintBackgroundColor();
 			if (Math.abs(back.getRed() - GRAY) < THRESHOLD
 					&& Math.abs(back.getBlue() - GRAY) < THRESHOLD
 					&& Math.abs(back.getGreen() - GRAY) < THRESHOLD)
-				return Color.WHITE;
-
-			Color fore = new Color(
-					Math.abs(Conversion.RGB_MAX - back.getRed()), Math
-							.abs(Conversion.RGB_MAX - back.getGreen()), Math
-							.abs(Conversion.RGB_MAX - back.getBlue()));
+			{
+				return Colour.WHITE;
+			}
+			
+			Colour fore = back.inverse();
+			
 			return fore;
 		}
@@ -1174,5 +1224,6 @@
 	}
 
-	public String toString() {
+	public String toString()
+	{
 		StringBuilder s = new StringBuilder();
 		s.append(String.format("Name: %s%d%n", _frameset, _number));
@@ -1187,7 +1238,9 @@
 	}
 
-	public Text getTextAbove(Text current) {
+	public Text getTextAbove(Text current)
+	{
 		Collection<Text> currentTextItems = FrameUtils.getCurrentTextItems();
 		List<Text> toCheck = new ArrayList<Text>();
+		
 		if (currentTextItems.contains(current)) {
 			toCheck.addAll(currentTextItems);
@@ -1195,35 +1248,20 @@
 			toCheck.addAll(getTextItems());
 		}
+		
 		// Make sure the items are sorted
 		Collections.sort(toCheck);
 
 		int ind = toCheck.indexOf(current);
-		if (ind == -1)
-			return null;
+		if (ind == -1) return null;
 
 		// loop through all items above this one, return the first match
 		for (int i = ind - 1; i >= 0; i--) {
 			Text check = toCheck.get(i);
-			if (FrameUtils.inSameColumn(check, current))
-				return check;
+			if (FrameUtils.inSameColumn(check, current)) return check;
 		}
 
 		return null;
 	}
-
-	/**
-	 * Updates any Images that require it from their ImageObserver (Principally
-	 * Animated GIFs)
-	 */
-	public boolean imageUpdate(Image img, int infoflags, int x, int y,
-			int width, int height) {
-		FrameGraphics.ForceRepaint();
-
-		if (DisplayIO.getCurrentFrame() == this)
-			return true;
-
-		return false;
-	}
-
+	
 	/**
 	 * Gets the text items that are in the same column and below a specified
@@ -1233,8 +1271,8 @@
 	 *            The Item to get the column for.
 	 */
-	public List<Text> getColumn(Item from) {
+	public List<Text> getColumn(Item from)
+	{
 		// Check that this item is on the current frame
-		if (!_body.contains(from))
-			return null;
+		if (!_body.contains(from)) return null;
 
 		if (from == null) {
@@ -1242,10 +1280,10 @@
 		}
 
-		if (from == null)
-			return null;
+		if (from == null) return null;
 
 		// Get the enclosedItems
 		Collection<Text> enclosed = FrameUtils.getCurrentTextItems();
 		List<Text> toCheck = null;
+		
 		if (enclosed.contains(from)) {
 			toCheck = new ArrayList<Text>();
@@ -1256,6 +1294,6 @@
 
 		List<Text> column = new ArrayList<Text>();
+		
 		if (toCheck.size() > 0) {
-
 			// Make sure the items are sorted
 			Collections.sort(toCheck);
@@ -1266,11 +1304,9 @@
 
 			// If its the title index will be 0
-			if (index < 0)
-				index = 0;
+			if (index < 0) index = 0;
 
 			for (int i = index; i < toCheck.size(); i++) {
 				Text item = toCheck.get(i);
-				if (FrameUtils.inSameColumn(from, item))
-					column.add(item);
+				if (FrameUtils.inSameColumn(from, item)) column.add(item);
 			}
 		}
@@ -1289,39 +1325,44 @@
 	 *             If overlay is null.
 	 */
-	protected boolean addVector(Vector toAdd) {
+	protected boolean addVector(Vector toAdd)
+	{
 		// make sure we dont add this frame as an overlay of itself
-		if (toAdd.Frame == this)
-			return false;
+		if (toAdd.Frame == this) return false;
+		
 		_vectors.add(toAdd);
+		
 		// Items must be notified that they have been added or removed from this
 		// frame via the vector...
 		int maxX = 0;
 		int maxY = 0;
+		
 		HighlightMode mode = toAdd.Source.getHighlightMode();
-		if (mode != HighlightMode.None)
-			mode = HighlightMode.Connected;
-		Color highlightColor = toAdd.Source.getHighlightColor();
+		if (mode != HighlightMode.None) mode = HighlightMode.Connected;
+		
+		Colour highlightColor = toAdd.Source.getHighlightColor();
+		
 		for (Item i : ItemUtils.CopyItems(toAdd.Frame.getVectorItems(), toAdd)) {
-			i.onParentStateChanged(new ItemParentStateChangedEvent(this,
-					ItemParentStateChangedEvent.EVENT_TYPE_ADDED_VIA_OVERLAY,
-					toAdd.permission));
+			i.onParentStateChanged(new ItemParentStateChangedEvent(this, ItemParentStateChangedEvent.EVENT_TYPE_ADDED_VIA_OVERLAY, toAdd.permission));
 			i.setEditTarget(toAdd.Source);
-			i.setHighlightMode(mode, highlightColor);
+			i.setHighlightModeAndColour(mode, highlightColor);
 			_vectorItems.add(i);
 			i.invalidateAll();
 			i.invalidateFill();
+			
 			// Get the right most x and bottom most y pos
 			int itemRight = i.getX() + i.getBoundsWidth();
-			if (itemRight > maxX)
-				maxX = itemRight;
+			if (itemRight > maxX) maxX = itemRight;
+			
 			int itemBottom = i.getY() + i.getBoundsHeight();
-			if (itemBottom > maxY)
-				maxY = itemBottom;
-		}
+			if (itemBottom > maxY) maxY = itemBottom;
+		}
+		
 		toAdd.setSize(maxX, maxY);
+		
 		return true;
 	}
 
-	public Collection<Vector> getVectors() {
+	public Collection<Vector> getVectors()
+	{
 		Collection<Vector> l = new LinkedList<Vector>();
 		l.addAll(_vectors);
@@ -1329,12 +1370,14 @@
 	}
 
-	public Collection<Overlay> getOverlays() {
+	public Collection<Overlay> getOverlays()
+	{
 		return new LinkedList<Overlay>(_overlays.keySet());
 	}
 
 	/**
-	 * @return All vectosr seen by this frame (including its vector's vectors).
-	 */
-	public List<Vector> getVectorsDeep() {
+	 * @return All vectors seen by this frame (including its vector's vectors).
+	 */
+	public List<Vector> getVectorsDeep()
+	{
 		List<Vector> l = new LinkedList<Vector>();
 		getVectorsDeep(l, this, new LinkedList<Frame>());
@@ -1342,15 +1385,13 @@
 	}
 
-	private boolean getVectorsDeep(List<Vector> vectors, Frame vector,
-			List<Frame> seenVectors) {
-
-		if (seenVectors.contains(vector))
-			return false;
+	private boolean getVectorsDeep(List<Vector> vectors, Frame vector, List<Frame> seenVectors)
+	{
+		if (seenVectors.contains(vector)) return false;
 
 		seenVectors.add(vector);
 
-		for (Vector o : vector.getVectors()) {
-			if (getVectorsDeep(vectors, o.Frame, seenVectors)) {
-				vectors.add(o);
+		for (Vector v : vector.getVectors()) {
+			if (getVectorsDeep(vectors, v.Frame, seenVectors)) {
+				vectors.add(v);
 			}
 		}
@@ -1359,20 +1400,46 @@
 	}
 
-	// private boolean getOverlaysDeep(List<Overlay> overlays, Frame overlay,
-	// List<Frame> seenOverlays) {
-	//
-	// if (seenOverlays.contains(overlay))
-	// return false;
-	//
-	// seenOverlays.add(overlay);
-	//
-	// for (Overlay o : overlay.getOverlays()) {
-	// if (getOverlaysDeep(overlays, o.Frame, seenOverlays)) {
-	// overlays.add(o);
-	// }
-	// }
-	//
-	// return true;
-	// }
+	public List<Overlay> getOverlaysDeep()
+	{
+		List<Overlay> ret = new LinkedList<Overlay>();
+		
+		getOverlaysDeep(ret, new LinkedList<Frame>());
+		
+		return ret;
+	}
+	
+	private boolean getOverlaysDeep(List<Overlay> overlays, List<Frame> seenOverlays)
+	{
+		if (seenOverlays.contains(this)) return false;
+		
+		seenOverlays.add(this);
+		
+		for (Overlay o : this.getOverlays()) {
+			if (o.Frame.getOverlaysDeep(overlays, seenOverlays)) {
+				overlays.add(o);
+			}
+		}
+		return true;
+	}
+	
+	/**
+	 * Recursive function similar to AddAllOverlayItems.
+	 * 
+	 * @param widgets
+	 *            The collection the widgets will be added to
+	 * @param overlay
+	 *            An "overlay" frame - this initially will be the parent frame
+	 * @param seenOverlays
+	 *            Used for state in the recursion stack. Pass as an empty
+	 *            (non-null) list.
+	 */
+	public List<Widget> getAllOverlayWidgets()
+	{
+		List<Widget> widgets = new LinkedList<Widget>();
+		
+		for (Overlay o : getOverlaysDeep()) widgets.addAll(o.Frame.getInteractiveWidgets());
+		
+		return widgets;
+	}
 
 	/**
@@ -1381,21 +1448,19 @@
 	 * @param item
 	 *            The item - must not be null.
-	 * @return The overlay that contains the itm. Null if no overlay owns the
+	 * @return The overlay that contains the item. Null if no overlay owns the
 	 *         item.
 	 */
-	public Overlay getOverlayOwner(Item item) {
-		if (item == null)
-			throw new NullPointerException("item");
+	public Overlay getOverlayOwner(Item item)
+	{
+		if (item == null) throw new NullPointerException("item");
 
 		for (Overlay l : getOverlays()) {
-			if (item.getParent() == l.Frame)
-				return l;
+			if (item.getParent() == l.Frame) return l;
 		}
 
 		// TODO return the correct vector... not just the first vector matching
-		// the vectorFrame
+		// the vector frame
 		for (Vector v : getVectors()) {
-			if (item.getParent() == v.Frame)
-				return v;
+			if (item.getParent() == v.Frame) return v;
 		}
 
@@ -1403,5 +1468,6 @@
 	}
 
-	public void clearVectors() {
+	public void clearVectors()
+	{
 		_vectors.clear();
 
@@ -1414,7 +1480,8 @@
 	}
 
-	protected boolean removeVector(Vector toRemove) {
-		if (!_vectors.remove(toRemove))
-			return false;
+	protected boolean removeVector(Vector toRemove)
+	{
+		if (!_vectors.remove(toRemove)) return false;
+		
 		for (Item i : toRemove.Frame.getVectorItems()) {
 			i.invalidateAll();
@@ -1426,12 +1493,13 @@
 
 		}
+		
 		return true;
 	}
 
-	public void clearOverlays() {
+	public void clearOverlays()
+	{
 		for (Overlay o : _overlays.keySet()) {
 			for (Item i : o.Frame.getItems()) {
-				i
-						.onParentStateChanged(new ItemParentStateChangedEvent(
+				i.onParentStateChanged(new ItemParentStateChangedEvent(
 								this,
 								ItemParentStateChangedEvent.EVENT_TYPE_REMOVED_VIA_OVERLAY,
@@ -1444,23 +1512,27 @@
 	}
 
-	protected boolean removeOverlay(Frame f) {
+	protected boolean removeOverlay(Frame f)
+	{
 		for (Overlay o : _overlays.keySet()) {
 			if (o.Frame == f) {
 				_overlays.remove(o);
+				
 				for (Item i : f.getItems()) {
 					_overlayItems.remove(i);
-					i
-							.onParentStateChanged(new ItemParentStateChangedEvent(
+					i.onParentStateChanged(new ItemParentStateChangedEvent(
 									this,
 									ItemParentStateChangedEvent.EVENT_TYPE_REMOVED_VIA_OVERLAY,
 									o.permission));
 				}
+				
 				return true;
 			}
 		}
+		
 		return false;
 	}
 
-	public void addAllVectors(List<Vector> vectors) {
+	public void addAllVectors(List<Vector> vectors)
+	{
 		for (Vector v : vectors) {
 			addVector(v);
@@ -1468,5 +1540,6 @@
 	}
 
-	public void addAllOverlays(Collection<Overlay> overlays) {
+	public void addAllOverlays(Collection<Overlay> overlays)
+	{
 		for (Overlay o : overlays) {
 			addOverlay(o);
@@ -1474,31 +1547,29 @@
 	}
 
-	protected boolean addOverlay(Overlay toAdd) {
+	protected boolean addOverlay(Overlay toAdd)
+	{
 		// make sure we dont add this frame as an overlay of itself
-		if (toAdd.Frame == this)
-			return false;
+		if (toAdd.Frame == this) return false;
+		
 		// Dont add the overlay if there is already one for this frame
-		if (_overlays.values().contains(toAdd.Frame))
-			return false;
+		if (_overlays.values().contains(toAdd.Frame)) return false;
+		
 		// Add the overlay to the map of overlays on this frame
 		_overlays.put(toAdd, toAdd.Frame);
+		
 		// Add all the overlays from the overlay frame to this frame
-		for (Overlay o : toAdd.Frame.getOverlays())
-			addOverlay(o);
+		// TODO: Can this cause a recursion loop? If A and B are overlays of each other? cts16
+		for (Overlay o : toAdd.Frame.getOverlays()) addOverlay(o);
 
 		// Add all the vectors from the overlay frame to this frame
-		for (Vector v : toAdd.Frame.getVectors())
-			addVector(v);
+		for (Vector v : toAdd.Frame.getVectors()) addVector(v);
 
 		// Now add the items for this overlay
-		UserAppliedPermission permission = UserAppliedPermission.min(toAdd.Frame.getUserAppliedPermission(),toAdd.permission);
+		UserAppliedPermission permission = UserAppliedPermission.min(toAdd.Frame.getUserAppliedPermission(), toAdd.permission);
 
 		// Items must be notified that they have been added or removed from this
 		// frame via the overlay...
 		for (Item i : toAdd.Frame.getVisibleItems()) {
-			i.onParentStateChanged(new ItemParentStateChangedEvent(this,
-					ItemParentStateChangedEvent.EVENT_TYPE_ADDED_VIA_OVERLAY,
-					permission));
-			// i.setPermission(permission);
+			i.onParentStateChanged(new ItemParentStateChangedEvent(this, ItemParentStateChangedEvent.EVENT_TYPE_ADDED_VIA_OVERLAY, permission));
 			_overlayItems.add(i);
 		}
@@ -1508,8 +1579,8 @@
 
 	@Override
-	public boolean equals(Object o) {
+	public boolean equals(Object o)
+	{
 		if (o instanceof String) {
-			return (String.CASE_INSENSITIVE_ORDER
-					.compare((String) o, getName()) == 0);
+			return (String.CASE_INSENSITIVE_ORDER.compare((String) o, getName()) == 0);
 		}
 
@@ -1526,7 +1597,7 @@
 	 * @param toMergeWith
 	 */
-	private void merge(Frame toMergeWith) {
-		if (toMergeWith == null)
-			return;
+	private void merge(Frame toMergeWith)
+	{
+		if (toMergeWith == null) return;
 
 		List<Item> copies = ItemUtils.CopyItems(toMergeWith.getItems());
@@ -1548,16 +1619,16 @@
 	 * @return the items that cant be merged
 	 */
-	public List<Item> merge(List<Item> toMerge) {
+	public List<Item> merge(List<Item> toMerge)
+	{
 		ArrayList<Item> remain = new ArrayList<Item>(0);
 
 		for (Item i : toMerge) {
-			if (!(i instanceof Text))
+			if (!(i instanceof Text)) {
 				remain.add(i);
-			else {
+			} else {
 				if (!AttributeUtils.setAttribute(this, (Text) i)) {
-					if (i.getLink() != null)
+					if (i.getLink() != null) {
 						merge(FrameIO.LoadFrame(i.getAbsoluteLink()));
-					else if (FrameIO
-							.isValidFrameName(((Text) i).getFirstLine())) {
+					} else if (FrameIO.isValidFrameName(((Text) i).getFirstLine())) {
 						// If we get hear we are merging frames
 						merge(FrameIO.LoadFrame(((Text) i).getFirstLine()));
@@ -1574,17 +1645,21 @@
 	 * items are added to the backup-stack.
 	 */
-	public void clear(boolean keepAnnotations) {
+	public void clear(boolean keepAnnotations)
+	{
 		List<Item> newBody = new ArrayList<Item>(0);
+		
 		Item title = getTitleItem();
+		
 		if (title != null) {
 			newBody.add(title);
 			_body.remove(title);
 		}
+		
 		if (keepAnnotations) {
 			for (Item i : _body) {
-				if (i.isAnnotation())
-					newBody.add(i);
-			}
-		}
+				if (i.isAnnotation()) newBody.add(i);
+			}
+		}
+		
 		_body.removeAll(newBody);
 		addToUndoDelete(_body);
@@ -1592,6 +1667,5 @@
 		change();
 
-		if (!keepAnnotations && _annotations != null)
-			_annotations.clear();
+		if (!keepAnnotations && _annotations != null) _annotations.clear();
 	}
 
@@ -1602,5 +1676,6 @@
 	 * @return
 	 */
-	public Text createNewText(String text) {
+	public Text createNewText(String text)
+	{
 		Text t = createBlankText(text);
 		t.setText(text);
@@ -1615,15 +1690,18 @@
 	 * @return The newly created Text Item
 	 */
-	public Text createBlankText(String templateType) {
+	public Text createBlankText(String templateType)
+	{
 		SessionStats.CreatedText();
 		Text t;
-		if (templateType.length() == 0)
+		
+		if (templateType.length() == 0) {
 			t = getItemTemplate().copy();
-		else
+		} else {
 			t = getItemTemplate(templateType.charAt(0));
-
+		}
+		
 		// reset attributes
 		t.setID(getNextItemID());
-		t.setPosition(DisplayIO.getMouseX(), FrameMouseActions.getY());
+		t.setPosition(DisplayController.getMousePosition());
 		t.setText("");
 		t.setParent(this);
@@ -1648,14 +1726,12 @@
 	}
 
-	public Item createDot() {
-		Item dot = new Dot(DisplayIO.getMouseX(), FrameMouseActions.getY(),
-				getNextItemID());
+	public Item createDot()
+	{
+		Item dot = new Dot(DisplayController.getMouseX(), DisplayController.getMouseY(), getNextItemID());
 
 		Item template = getTemplate(_dotTemplate, ItemUtils.TAG_DOT_TEMPLATE);
 		float thickness = template.getThickness();
-		if (thickness > 0)
-			dot.setThickness(template.getThickness());
-		if (template.getLinePattern() != null)
-			dot.setLinePattern(template.getLinePattern());
+		if (thickness > 0) dot.setThickness(template.getThickness());
+		if (template.getLinePattern() != null) dot.setLinePattern(template.getLinePattern());
 		dot.setColor(template.getColor());
 		dot.setFillColor(template.getFillColor());
@@ -1665,5 +1741,6 @@
 	}
 
-	private Text getTemplate(Text defaultTemplate, int templateTag) {
+	private Text getTemplate(Text defaultTemplate, int templateTag)
+	{
 		Text t = null;
 
@@ -1677,7 +1754,6 @@
 
 		if (t == null) {
-			if (defaultTemplate == null) {
-				return null;
-			}
+			if (defaultTemplate == null) return null;
+			
 			t = defaultTemplate;
 		}
@@ -1685,4 +1761,5 @@
 		// If the item is linked apply any attribute pairs on the child frame
 		String link = t.getAbsoluteLink();
+		
 		// need to get link first because copy doesnt copy the link
 		t = t.copy();
@@ -1701,21 +1778,28 @@
 	}
 
-	public Text getItemTemplate(char firstChar) {
+	/**
+	 * TODO: Comment. cts16
+	 * TODO: Remove magic constants. cts16 
+	 */
+	public Text getItemTemplate(char firstChar)
+	{
 		switch (firstChar) {
-		case '@':
-			return getAnnotationTemplate();
-		case '/':
-		case '#':
-			return getCodeCommentTemplate();
-		default:
-			return getItemTemplate();
-		}
-	}
-
-	public Text createNewText() {
+			case '@':
+				return getAnnotationTemplate();
+			case '/':
+			case '#':
+				return getCodeCommentTemplate();
+			default:
+				return getItemTemplate();
+		}
+	}
+
+	public Text createNewText()
+	{
 		return createNewText("");
 	}
 
-	public Text addText(int x, int y, String text, String action) {
+	public Text addText(int x, int y, String text, String action)
+	{
 		Text t = createNewText(text);
 		t.setPosition(x, y);
@@ -1724,12 +1808,14 @@
 	}
 
-	public Item addText(int x, int y, String text, String action, String link) {
-		Item t = addText(x, y, text, action);
+	public Text addText(int x, int y, String text, String action, String link)
+	{
+		Text t = addText(x, y, text, action);
 		t.setLink(link);
 		return t;
 	}
 
-	public Item addDot(int x, int y) {
-		Item d = new Dot(x, y, getNextItemID());
+	public Dot addDot(int x, int y)
+	{
+		Dot d = new Dot(x, y, getNextItemID());
 		addItem(d);
 		return d;
@@ -1754,5 +1840,6 @@
 	 *            Color to fill the rectangle with
 	 */
-	public List<Item> addRectangle(int x, int y, int width, int height, float borderThickness, Color borderColor, Color fillColor) {
+	public List<Item> addRectangle(int x, int y, int width, int height, float borderThickness, Colour borderColor, Colour fillColor)
+	{
 		List<Item> rectComponents = new ArrayList<Item>();
 		Item[] corners = new Item[4];
@@ -1796,23 +1883,23 @@
 		List<Item> rect = new ArrayList<Item>(rectComponents);
 		this.addAllItems(rectComponents);
-		FrameMouseActions.anchor(rectComponents);
+		StandardGestureActions.anchor(rectComponents);
 		return rect;
-		// rectComponents.clear();
-	}
-
-	public boolean isSaved() {
+	}
+
+	public boolean isSaved()
+	{
 		return _saved;
 	}
 
-	public void setSaved() {
-		// System.out.println(getName() + " saved");
+	public void setSaved()
+	{
 		_saved = true;
 		_change = false;
 	}
 
-	public static boolean rubberbandingLine() {
-		return FreeItems.getInstance().size() == 2
-				&& (FreeItems.getInstance().get(0) instanceof Line || FreeItems
-						.getInstance().get(1) instanceof Line);
+	public static boolean rubberbandingLine()
+	{
+		return 	FreeItems.getInstance().size() == 2 &&
+				(FreeItems.getInstance().get(0) instanceof Line || FreeItems.getInstance().get(1) instanceof Line);
 	}
 
@@ -1825,7 +1912,7 @@
 	 * @return true if the item is a normal text item
 	 */
-	public boolean isNormalTextItem(Item it) {
-		if (it instanceof Text && it != getTitleItem() && it != _frameName
-				&& !((Text) it).isSpecialAnnotation()) {
+	public boolean isNormalTextItem(Item it)
+	{
+		if (it instanceof Text && it != getTitleItem() && it != _frameName && !((Text) it).isSpecialAnnotation()) {
 			return true;
 		}
@@ -1839,16 +1926,15 @@
 	 * @param index
 	 */
-	public boolean moveMouseToTextItem(int index) {
+	public boolean moveMouseToTextItem(int index)
+	{
 		List<Item> items = getItems();
 		int itemsFound = 0;
 		for (int i = 0; i < items.size(); i++) {
 			Item it = items.get(i);
-			if (isNormalTextItem(it))
-				itemsFound++;
+			if (isNormalTextItem(it)) itemsFound++;
 			if (itemsFound > index) {
-				DisplayIO.setCursorPosition(((Text) it)
-						.getParagraphEndPosition().x, it.getY());
-				DisplayIO.resetCursorOffset();
-				FrameGraphics.Repaint();
+				DisplayController.setCursorPosition(((Text) it).getParagraphEndPosition().x, it.getY());
+				DisplayController.resetCursorOffset();
+				DisplayController.requestRefresh(true);
 				return true;
 			}
@@ -1857,22 +1943,13 @@
 		return false;
 	}
-
-	/*
-	 * public boolean moveMouseToNextTextItem(int index) { List<Item> items =
-	 * getItems(); int itemsFound = 0; for (int i = 0; i < items.size(); i++) {
-	 * Item it = items.get(i); if ( isNormalTextItem(it)) itemsFound++; if
-	 * (itemsFound > index) {
-	 * DisplayIO.setCursorPosition(((Text)it).getEndParagraphPosition().x,
-	 * it.getY()); DisplayIO.resetCursorOffset(); FrameGraphics.Repaint();
-	 * return true; } }
-	 * 
-	 * return false; }
-	 */
 
 	/**
 	 * Searches for an annotation item called start to be used as the default
 	 * cursor location when TDFC occurs.
-	 */
-	public boolean moveMouseToDefaultLocation() {
+	 * 
+	 * TODO: Remove magic constants. cts16
+	 */
+	public boolean moveMouseToDefaultLocation()
+	{
 		List<Item> items = getItems();
 
@@ -1880,6 +1957,5 @@
 			if (it instanceof Text) {
 				Text t = (Text) it;
-				if (t.getText().toLowerCase().startsWith("@start")
-						|| t.getText().toLowerCase().equals("@start:")) {
+				if (t.getText().toLowerCase().startsWith("@start") || t.getText().toLowerCase().equals("@start:")) {
 					// Used to allow users the option of putting an initial
 					// bullet after the @start
@@ -1888,12 +1964,13 @@
 					t.setText("");
 
-					if (t.getText().equals(""))
-						DisplayIO.getCurrentFrame().removeItem(t);
-					if (!FreeItems.itemsAttachedToCursor()) {
-						DisplayIO.setCursorPosition(((Text) it)
-								.getParagraphEndPosition());
-						DisplayIO.resetCursorOffset();
+					if (t.getText().equals("")) DisplayController.getCurrentFrame().removeItem(t);
+					
+					if (!FreeItems.hasItemsAttachedToCursor()) {
+						DisplayController.setCursorPosition(((Text) it).getParagraphEndPosition());
+						DisplayController.resetCursorOffset();
 					}
-					FrameGraphics.Repaint();
+					
+					DisplayController.requestRefresh(true);
+					
 					return true;
 				}
@@ -1911,5 +1988,6 @@
 	 *         name of the frame if the tag isnt on the frame.
 	 */
-	public String getExportFileName() {
+	public String getExportFileName()
+	{
 		String fileName = getExportFileTagValue();
 
@@ -1925,10 +2003,11 @@
 	}
 
-	public void toggleBackgroundColor() {
-		setBackgroundColor(ColorUtils.getNextColor(_background,
-				TemplateSettings.BackgroundColorWheel.get(), null));
-	}
-
-	public void setName(String frameset, int i) {
+	public void toggleBackgroundColor()
+	{
+		setBackgroundColor(ColorUtils.getNextColor(_background, TemplateSettings.BackgroundColorWheel.get(), null));
+	}
+
+	public void setName(String frameset, int i)
+	{
 		setFrameset(frameset);
 		setFrameNumber(i);
@@ -1940,7 +2019,7 @@
 	 * 
 	 */
-	public void refreshItemPermissions(UserAppliedPermission maxPermission) {
-		if(_frameName == null)
-			return;
+	public void refreshItemPermissions(UserAppliedPermission maxPermission)
+	{
+		if(_frameName == null) return;
 		
 		UserAppliedPermission permission = UserAppliedPermission.min(maxPermission, getUserAppliedPermission());
@@ -1948,17 +2027,17 @@
 		switch (permission) {
 		case none:
-			_frameName.setBackgroundColor(new Color(255, 220, 220));
+			_frameName.setBackgroundColor(FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_NONE);
 			break;
 		case followLinks:
-			_frameName.setBackgroundColor(new Color(255, 230, 135));
+			_frameName.setBackgroundColor(FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_FOLLOW_LINKS);
 			break;
 		case copy:
-			_frameName.setBackgroundColor(new Color(255, 255, 155));
+			_frameName.setBackgroundColor(FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_COPY);
 			break;
 		case createFrames:
-			_frameName.setBackgroundColor(new Color(220, 255, 220));
+			_frameName.setBackgroundColor(FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_CREATE_FRAMES);
 			break;
 		case full:
-			_frameName.setBackgroundColor(null);
+			_frameName.setBackgroundColor(FRAME_NAME_BACKGROUND_COLOUR_FOR_PERMISSION_FULL);
 			break;
 		default:
@@ -1975,20 +2054,18 @@
 	}
 
-	public boolean isTestFrame() {
+	public boolean isTestFrame()
+	{
 		Text title = getTitleItem();
-		if (title == null)
-			return false;
+		if (title == null) return false;
 		String action = title.getFirstAction();
-		if (action == null)
-			return false;
+		if (action == null) return false;
 		action = action.toLowerCase();
-		return action.startsWith(Simple.RUN_FRAME_ACTION)
-				|| action.startsWith(Simple.DEBUG_FRAME_ACTION);
-	}
-
-	public void setActiveTime(String activeTime) {
+		return action.startsWith(Simple.RUN_FRAME_ACTION) || action.startsWith(Simple.DEBUG_FRAME_ACTION);
+	}
+
+	public void setActiveTime(String activeTime)
+	{
 		try {
-			_activeTime = new Time(Time.valueOf(activeTime).getTime() + 12 * 60
-					* 60 * 1000);
+			_activeTime = new Time(Time.valueOf(activeTime).getTime() + 12 * 60 * 60 * 1000);
 		} catch (Exception e) {
 			_activeTime = new Time(0);
@@ -1996,16 +2073,18 @@
 	}
 
-	public void setActiveTime(Time activeTime) {
+	public void setActiveTime(Time activeTime)
+	{
 		_activeTime = activeTime;
 	}
 
-	public void setDarkTime(Time darkTime) {
+	public void setDarkTime(Time darkTime)
+	{
 		_darkTime = darkTime;
 	}
 
-	public void setDarkTime(String darkTime) {
+	public void setDarkTime(String darkTime)
+	{
 		try {
-			_darkTime = new Time(Time.valueOf(darkTime).getTime() + 12 * 60
-					* 60 * 1000);
+			_darkTime = new Time(Time.valueOf(darkTime).getTime() + 12 * 60 * 60 * 1000);
 		} catch (Exception e) {
 			_darkTime = new Time(0);
@@ -2018,8 +2097,9 @@
 	 * @return the backup frame for this frame
 	 */
-	public Frame getBackupFrame() {
+	public Frame getBackupFrame()
+	{
 		Text backupTag = _annotations.get("old");
-		if (backupTag == null)
-			return null;
+		if (backupTag == null) return null;
+		
 		// TODO want another way to deal with updating of annotations items
 		// without F12 refresh
@@ -2031,8 +2111,8 @@
 			return getBackupFrame();
 		}
+		
 		// Now return the name of the backed up frame
 		String link = backupTag.getAbsoluteLink();
-		if (link == null || link.equalsIgnoreCase(getName()))
-			return null;
+		if (link == null || link.equalsIgnoreCase(getName())) return null;
 
 		Frame backup = FrameIO.LoadFrame(link);
@@ -2040,9 +2120,11 @@
 	}
 
-	public Time getDarkTime() {
+	public Time getDarkTime()
+	{
 		return _darkTime;
 	}
 
-	public Time getActiveTime() {
+	public Time getActiveTime()
+	{
 		return _activeTime;
 	}
@@ -2054,13 +2136,16 @@
 	 * @return the number of frames in the backed up comet
 	 */
-	public int getCometLength() {
+	public int getCometLength()
+	{
 		Frame backup = getBackupFrame();
 		return 1 + (backup == null ? 0 : backup.getCometLength());
 	}
 
-	public void addAnnotation(Text item) {
+	public void addAnnotation(Text item)
+	{
 		if (_annotations == null) {
 			_annotations = new HashMap<String, Text>();
 		}
+		
 		// Check if this item has already been processed
 		String[] tokens = item.getProcessedText();
@@ -2074,4 +2159,5 @@
 		String text = item.getText().trim();
 		assert (text.charAt(0) == '@');
+		
 		// Ignore annotations with spaces after the tag symbol
 		if (text.length() < 2 || !Character.isLetter(text.charAt(1))) {
@@ -2079,4 +2165,5 @@
 			return;
 		}
+		
 		// The separator char must come before the first non letter otherwise we
 		// ignore the annotation item
@@ -2101,4 +2188,5 @@
 			}
 		}
+		
 		// If it was nothing but letters and digits save the tag
 		String lowerCaseText = text.substring(1).toLowerCase();
@@ -2107,7 +2195,8 @@
 	}
 
-	public boolean hasAnnotation(String annotation) {
-		if (_annotations == null)
-			refreshAnnotationList();
+	public boolean hasAnnotation(String annotation)
+	{
+		if (_annotations == null) refreshAnnotationList();
+		
 		return _annotations.containsKey(annotation.toLowerCase());
 	}
@@ -2121,35 +2210,36 @@
 	 *         is not on the frame or has no value.
 	 */
-	public String getAnnotationValue(String annotation) {
-		if (_annotations == null)
-			refreshAnnotationList();
+	public String getAnnotationValue(String annotation)
+	{
+		if (_annotations == null) refreshAnnotationList();
 
 		Text text = _annotations.get(annotation.toLowerCase());
-		if (text == null)
-			return null;
+		if (text == null) return null;
 
 		String[] tokens = text.getProcessedText();
-		if (tokens != null && tokens.length > 1)
-			return tokens[1];
+		
+		if (tokens != null && tokens.length > 1) return tokens[1];
+		
 		return null;
 	}
 
-	Map<String, Text> _annotations = null;
-
-	private Collection<FrameObserver> _observers = new HashSet<FrameObserver>();
-
-	public void clearAnnotations() {
+	public void clearAnnotations()
+	{
 		_annotations = null;
 	}
 
-	public List<Item> getVisibleItems() {
+	public List<Item> getVisibleItems()
+	{
 		return getItems(true);
 	}
 
-	private void refreshAnnotationList() {
-		if (_annotations == null)
+	private void refreshAnnotationList()
+	{
+		if (_annotations == null) {
 			_annotations = new HashMap<String, Text>();
-		else
+		} else {
 			_annotations.clear();
+		}
+		
 		for (Text text : getTextItems()) {
 			if (text.isAnnotation()) {
@@ -2159,8 +2249,10 @@
 	}
 
-	public Collection<Text> getAnnotationItems() {
+	public Collection<Text> getAnnotationItems()
+	{
 		if (_annotations == null) {
 			refreshAnnotationList();
 		}
+		
 		return _annotations.values();
 	}
@@ -2171,6 +2263,6 @@
 	 * @return the list of items to be saved to a text file
 	 */
-	public List<Item> getItemsToSave() {
-
+	public List<Item> getItemsToSave()
+	{
 		if (!_sorted) {
 			Collections.sort(_body);
@@ -2179,18 +2271,15 @@
 
 		// iWidgets are handled specially since 8 items are written as one
-		Collection<InteractiveWidget> seenWidgets = new LinkedHashSet<InteractiveWidget>();
+		Collection<Widget> seenWidgets = new LinkedHashSet<Widget>();
 
 		List<Item> toSave = new ArrayList<Item>();
 
 		for (Item i : _body) {
-			if (i == null || i.dontSave()) {
-				continue;
-			}
+			if (i == null || i.dontSave()) continue;
 
 			// Ensure only one of the WidgetCorners represent a single widget
 			if (i instanceof WidgetCorner) {
-				InteractiveWidget iw = ((WidgetCorner) i).getWidgetSource();
-				if (seenWidgets.contains(iw))
-					continue;
+				Widget iw = ((WidgetCorner) i).getWidgetSource();
+				if (seenWidgets.contains(iw)) continue;
 				seenWidgets.add(iw);
 				toSave.add(iw.getSource());
@@ -2198,6 +2287,6 @@
 				XRayable x = (XRayable) i;
 				toSave.addAll(x.getItemsToSave());
-			}// Circle centers are items with attached enclosures
-			else if (i.hasEnclosures()) {
+			// Circle centers are items with attached enclosures
+			} else if (i.hasEnclosures()) {
 				continue;
 			} else {
@@ -2213,5 +2302,6 @@
 	}
 
-	public Collection<Item> getOverlayItems() {
+	public Collection<Item> getOverlayItems()
+	{
 		return _overlayItems;
 	}
@@ -2223,9 +2313,11 @@
 	 * @return
 	 */
-	public boolean hasOverlay(Frame frame) {
+	public boolean hasOverlay(Frame frame)
+	{
 		return _overlays.containsValue(frame);
 	}
 
-	public Collection<Item> getAllItems() {
+	public Collection<Item> getAllItems()
+	{
 		Collection<Item> allItems = new LinkedHashSet<Item>(_body);
 		allItems.addAll(_overlayItems);
@@ -2234,5 +2326,6 @@
 	}
 
-	public Collection<Item> getVectorItems() {
+	public Collection<Item> getVectorItems()
+	{
 		Collection<Item> vectorItems = new LinkedHashSet<Item>(_vectorItems);
 		vectorItems.addAll(getNonAnnotationItems(false));
@@ -2245,6 +2338,8 @@
 	 * @return
 	 */
-	public Collection<Text> getTextItems() {
+	public Collection<Text> getTextItems()
+	{
 		Collection<Text> textItems = new ArrayList<Text>();
+		
 		for (Item i : getItems(true)) {
 			// only add up normal body text items
@@ -2253,16 +2348,17 @@
 			}
 		}
+		
 		return textItems;
 	}
 
-	public Text getAnnotation(String annotation) {
-		if (_annotations == null)
-			refreshAnnotationList();
+	public Text getAnnotation(String annotation)
+	{
+		if (_annotations == null) refreshAnnotationList();
 
 		return _annotations.get(annotation.toLowerCase());
 	}
 
-	public void recalculate() {
-
+	public void recalculate()
+	{
 		for (Item i : getItems()) {
 			if (i.hasFormula() && !i.isAnnotation()) {
@@ -2272,22 +2368,28 @@
 	}
 
-	public void removeObserver(FrameObserver observer) {
+	public void removeObserver(FrameObserver observer)
+	{
 		_observers.remove(observer);
 	}
 
-	public void addObserver(FrameObserver observer) {
+	public void addObserver(FrameObserver observer)
+	{
 		_observers.add(observer);
 	}
 
-	public void clearObservers() {
+	public void clearObservers()
+	{
 		for (FrameObserver fl : _observers) {
 			fl.removeSubject(this);
 		}
+		
 		// The frame listener will call the frames removeListener method
 		assert (_observers.size() == 0);
 	}
 
-	public Collection<Text> getNonAnnotationText(boolean removeTitle) {
+	public Collection<Text> getNonAnnotationText(boolean removeTitle)
+	{
 		Collection<Text> items = new LinkedHashSet<Text>();
+		
 		for (Item i : getItems(true)) {
 			// only add up normal body text items
@@ -2296,15 +2398,20 @@
 			}
 		}
+		
 		if (removeTitle) {
 			items.remove(getTitleItem());
 		}
+		
 		return items;
 	}
 
-	public void dispose() {
+	public void dispose()
+	{
 		clearObservers();
+		
 		for (Item i : _body) {
 			i.dispose();
 		}
+		
 		_frameName.dispose();
 		_body = null;
@@ -2312,40 +2419,47 @@
 	}
 
-	public void parse() {
+	public void parse()
+	{
 		for (Overlay o : getOverlays()) {
 			o.Frame.parse();
 		}
+		
 		// Must parse the frame AFTER the overlays
 		FrameUtils.Parse(this);
 	}
 
-	public void setPath(String path) {
+	public void setPath(String path)
+	{
 		this.path = path;
 	}
 
-	public String getPath() {
+	public String getPath()
+	{
 		return path;
 	}
 
-	public void setLocal(boolean isLocal) {
+	public void setLocal(boolean isLocal)
+	{
 		this._isLocal = isLocal;
 	}
 
-	public boolean isLocal() {
+	public boolean isLocal()
+	{
 		return _isLocal;
 	}
 
-	public String getExportFileTagValue() {
+	public String getExportFileTagValue()
+	{
 		return getAnnotationValue("file");
 	}
 
-	public void assertEquals(Frame frame2) {
+	public void assertEquals(Frame frame2)
+	{
 		// Check that all the items on the frame are the same
 		List<Item> items1 = getVisibleItems();
 		List<Item> items2 = frame2.getVisibleItems();
+		
 		if (items1.size() != items2.size()) {
-			throw new UnitTestFailedException(items1.size() + " items", items2
-					.size()
-					+ " items");
+			throw new UnitTestFailedException(items1.size() + " items", items2.size() + " items");
 		} else {
 			for (int i = 0; i < items1.size(); i++) {
@@ -2361,20 +2475,19 @@
 	}
 
-	public boolean hasObservers() {
+	public boolean hasObservers()
+	{
 		return _observers != null && _observers.size() > 0;
 	}
 
-	public Collection<? extends Item> getInteractableItems() {
+	public Collection<? extends Item> getInteractableItems()
+	{
 		/*
 		 * TODO: Cache the interactableItems list so we dont have to recreate it
 		 * every time this method is called
 		 */
-		if (_interactableItems.size() > 0)
-			return _interactableItems;
+		if (_interactableItems.size() > 0) return _interactableItems;
 
 		for (Item i : _body) {
-			if (i == null) {
-				continue;
-			}
+			if (i == null) continue;
 			if (i.isVisible()) {
 				_interactableItems.add(i);
@@ -2386,6 +2499,4 @@
 				_interactableItems.add(i);	
 			}
-			
-			
 		}
 
@@ -2398,3 +2509,26 @@
 		return _interactableItems;
 	}
+
+	private static final class History {
+		
+		public enum Type {
+			deletion,
+			movement
+		}
+		
+		public final List<Item> items;
+		
+		public final Type type;
+		
+		public History(Collection<Item> items, Type type)
+		{
+			this.items = new LinkedList<Item>(items);
+			this.type = type;
+		}
+		
+		public String toString()
+		{
+			return this.type.toString() + ":\n" + this.items.toString();
+		}
+	}
 }
Index: /trunk/src/org/expeditee/gui/FrameCreator.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameCreator.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/FrameCreator.java	(revision 1102)
@@ -19,12 +19,14 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.util.*;
+import java.util.LinkedList;
+import java.util.List;
 
 import org.expeditee.agents.ExistingFramesetException;
+import org.expeditee.core.Colour;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
 
 public class FrameCreator {
+	
 	public static final int INDENT_FROM_TITLE = 20;
 
@@ -60,5 +62,5 @@
 
 	public FrameCreator(String frameTitle) {
-		this(DisplayIO.getCurrentFrame().getFramesetName(), DisplayIO
+		this(DisplayController.getCurrentFrame().getFramesetName(), DisplayController
 				.getCurrentFrame().getPath(), frameTitle, false, false);
 	}
@@ -83,10 +85,10 @@
 	 * @return the newly created button.
 	 */
-	public static Item createButton(String text, Float x, Float y, Float right,
-			Float bottom) {
+	public static Item createButton(String text, Integer x, Integer y, Integer right,
+			Integer bottom) {
 		Text button = new Text(text);
 
-		button.setBackgroundColor(Color.LIGHT_GRAY);
-		button.setBorderColor(Color.DARK_GRAY);
+		button.setBackgroundColor(Colour.LIGHT_GREY);
+		button.setBorderColor(Colour.DARK_GREY);
 		button.setThickness(2.0F);
 		if (bottom != null)
@@ -99,19 +101,19 @@
 			button.setY(y);
 
-		button.updatePolygon();
+		button.invalidateBounds();
 
 		return button;
 	}
 
-	public FrameCreator(String name, String path, String frameTitle,
-			boolean recreate, boolean multiColumn) {
+	public FrameCreator(String name, String path, String frameTitle, boolean recreate, boolean multiColumn)
+	{
 		_multiColumn = multiColumn;
-		_Mnext = createButton("@Next", null, null, 10F, 15F);
+		_Mnext = createButton("@Next", null, null, 10, 15);
 
 		_Mprev = createButton("@Previous", null, null, _Mnext.getBoundsWidth()
-				+ _Mnext.getAnchorRight() + 20F, 15F);
+				+ _Mnext.getAnchorRight() + 20, 15);
 
 		_Mfirst = createButton("@First", null, null, _Mprev.getBoundsWidth()
-				+ _Mprev.getAnchorRight() + 20F, 15F);
+				+ _Mprev.getAnchorRight() + 20, 15);
 
 		Frame toUse = null;
@@ -180,5 +182,6 @@
 	}
 
-	private void resetGlobals(Frame toUse) {
+	private void resetGlobals(Frame toUse)
+	{
 		Text title = toUse.getTitleItem();
 		START_X = INDENT_FROM_TITLE + title.getX();
@@ -217,6 +220,5 @@
 				// new frame
 				if (!_multiColumn
-						|| toAdd.getBoundsWidth() + _lastX > FrameGraphics
-								.getMaxSize().width) {
+						|| toAdd.getBoundsWidth() + _lastX > DisplayController.getFramePaintArea().getWidth()) {
 					// Make sure text items that are created on the current
 					// frame are removed
@@ -229,5 +231,5 @@
 			toAdd.setOffset(0, 0);
 			toAdd.setID(_current.getNextItemID());
-			toAdd.setRightMargin(FrameGraphics.getMaxFrameSize().width, true);
+			toAdd.setRightMargin(DisplayController.getFramePaintArea().getWidth(), true);
 
 			_current.addItem(toAdd);
@@ -245,5 +247,5 @@
 	}
 
-	public Text addText(String toAdd, Color c, String link, String action,
+	public Text addText(String toAdd, Colour c, String link, String action,
 			boolean bSave) {
 		Text text = _current.createNewText(toAdd);
Index: /trunk/src/org/expeditee/gui/FrameGraphics.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameGraphics.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/FrameGraphics.java	(revision 1102)
@@ -19,18 +19,4 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.EventQueue;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.Area;
-import java.lang.reflect.Method;
-import java.awt.image.BufferedImage;
 import java.util.Collection;
 import java.util.Collections;
@@ -41,13 +27,20 @@
 import java.util.ListIterator;
 
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Image;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.input.StandardInputEventListeners;
+import org.expeditee.gio.input.KBMInputEvent.Key;
 import org.expeditee.items.Circle;
 import org.expeditee.items.Dot;
 import org.expeditee.items.Item;
-import org.expeditee.items.ItemUtils;
 import org.expeditee.items.Line;
 import org.expeditee.items.UserAppliedPermission;
 import org.expeditee.items.XRayable;
 import org.expeditee.items.Item.HighlightMode;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetEdge;
 import org.expeditee.settings.UserSettings;
@@ -55,305 +48,55 @@
 public class FrameGraphics {
 
-	// the graphics used to paint with
-	private static Graphics2D _DisplayGraphics;
-
-	// the maximum size that can be used to paint on
-	private static Dimension _MaxSize = null;
-
 	// Final passes to rendering the current frame
 	private static LinkedList<FrameRenderPass> _frameRenderPasses = new LinkedList<FrameRenderPass>();
-
-	// modes
-	protected static final int MODE_NORMAL = 0;
-
-	protected static final int MODE_AUDIENCE = 1;
-
-	protected static final int MODE_XRAY = 2;
 	
-	protected static final int MODE_AUDIENCE_FULLSCREEN = 4;
-	
-
-	// The following used to be true in the past:
-	//   Start in XRay mode so that errors aren't thrown when parsing the profile
-	//   frame if it has images on it
-	// More recently, so Exploratory Search starts up correctly with images
-	// rendered (rather than their @i form) the following assignment was changed
-	// to MODE_NORMAL.  No issue of parse errors has not been seen
-	private static int _Mode = MODE_NORMAL;
-
-	private FrameGraphics() {
-		// util constructor
-	}
-
-	/**
-	 * If Audience Mode is on this method will toggle it to be off, or
-	 * vice-versa. This results in the Frame being re-parsed and repainted.
-	 */
-	public static void ToggleAudienceMode() {
-		Frame current = DisplayIO.getCurrentFrame();
-		if (_Mode == MODE_XRAY) {
-			ToggleXRayMode();
-		}
-	
-
-		if (_Mode == MODE_AUDIENCE_FULLSCREEN) {
-			_Mode = MODE_NORMAL;
-			DisplayIO.leaveFullScreenMode();
-		}
-		else if (_Mode == MODE_AUDIENCE) {
-			if (DisplayIO.fullScreenCapable()) {
-				// Don't need to worry about UpdateConnectedToAnnotations, as this
-				// will have already been taken care of going to the 'first stage' of
-				// audience mode (MODE_AUDIENCE)
-				_Mode = MODE_AUDIENCE_FULLSCREEN;
-				DisplayIO.enterFullScreenMode();
-			}
-			else {
-				// return to normal mode
-				_Mode = MODE_NORMAL;
-			}
-		} 
-		else { // must currently be in regular mode => move to audience mode
-			_Mode = MODE_AUDIENCE;
-			ItemUtils.UpdateConnectedToAnnotations(current.getItems());
-			for (Overlay o : current.getOverlays()) {
-				ItemUtils.UpdateConnectedToAnnotations(o.Frame.getItems());
-			}
-			for (Vector v : current.getVectorsDeep()) {
-				ItemUtils.UpdateConnectedToAnnotations(v.Frame.getItems());
-			}
-		}
-		FrameUtils.Parse(current);
-		DisplayIO.UpdateTitle();
-		setMaxSize(new Dimension(_MaxSize.width, MessageBay
-				.getMessageBufferHeight()
-				+ _MaxSize.height));
-		refresh(false);
-	}
-
-	/**
-	 * If X-Ray Mode is on this method will toggle it to be off, or vice-versa.
-	 * This results in the Frame being re-parsed and repainted.
-	 */
-	public static void ToggleXRayMode() {
-		if (_Mode == MODE_AUDIENCE) {
-			ToggleAudienceMode();
-		}
-
-		if (_Mode == MODE_XRAY) {
-			setMode(MODE_NORMAL, true);
-		} else {
-			setMode(MODE_XRAY, true);
-		}
-		DisplayIO.getCurrentFrame().refreshSize();
-		DisplayIO.UpdateTitle();
-		FrameMouseActions.getInstance().refreshHighlights();
-		FrameMouseActions.updateCursor();
-		refresh(false);
-	}
-
-	public static void setMode(int mode, boolean parse) {
-		if (_Mode == mode)
-			return;
-		_Mode = mode;
-		if (parse) {
-			Frame current = DisplayIO.getCurrentFrame();
-			current.parse();
-		}
-	}
-
-	public static void forceXRayMode(boolean parse) {
-		setMode(MODE_XRAY,parse);
-	}
-	
-	/**
-	 * @return True if Audience Mode is currently on, False otherwise.
-	 */
-	public static boolean isAudienceMode() {
-		return (_Mode == MODE_AUDIENCE) || (_Mode == MODE_AUDIENCE_FULLSCREEN);
-	}
-
-	/**
-	 * @return True if X-Ray Mode is currently on, False otherwise.
-	 */
-	public static boolean isXRayMode() {
-		return _Mode == MODE_XRAY;
-	}
-
-	public static void setMaxSize(Dimension max) {
-		if (_MaxSize == null)
-			_MaxSize = max;
-
-		// Hide the message buffer if in audience mode
-		int newMaxHeight = max.height
-				- (isAudienceMode() ? 0 : MessageBay.MESSAGE_BUFFER_HEIGHT);
-		if (newMaxHeight > 0) {
-			_MaxSize.setSize(max.width, newMaxHeight);
-		}
-		Frame current = DisplayIO.getCurrentFrame();
-		if (current != null) {
-			current.setBuffer(null);
-			current.refreshSize();
-			if (DisplayIO.isTwinFramesOn()) {
-				Frame opposite = DisplayIO.getOppositeFrame();
-
-				/* When running the test suite opposite may be null! */
-				if (opposite != null) {
-					opposite.setBuffer(null);
-					opposite.refreshSize();
-				}
-			}
-		}
-
-		if (newMaxHeight > 0) {
-			MessageBay.updateSize();
-		}
-	}
-
-	public static Dimension getMaxSize() {
-		return _MaxSize;
-	}
-
-	public static Dimension getMaxFrameSize() {
-		if (DisplayIO.isTwinFramesOn()) {
-			return new Dimension((_MaxSize.width / 2), _MaxSize.height);
-		} else
-			return _MaxSize;
-	}
-
-	/**
-	 * Sets the Graphics2D object that should be used for all painting tasks.
-	 * Note: Actual painting is done by using g.create() to create temporary
-	 * instances that are then disposed of using g.dispose().
-	 * 
-	 * @param g
-	 *            The Graphics2D object to use for all painting
-	 */
-	public static void setDisplayGraphics(Graphics2D g) {
-		_DisplayGraphics = g;
-	}
-
-	/*
-	 * Displays the given Item on the screen
-	 */
-	static void PaintItem(Graphics2D g, Item i) {
-		if (i == null || g == null)
-			return;
-
-		// do not paint annotation items in audience mode
-		if (!isAudienceMode()
-				|| (isAudienceMode() && !i.isConnectedToAnnotation() && !i
-						.isAnnotation()) || i == FrameUtils.getLastEdited()) {
-
-			Graphics2D tg = (Graphics2D) g.create();
-			i.paint(tg);
-			tg.dispose();
-		}
-	}
-
-	/**
-	 * Adds all the scaled vector items for a frame into a list. It uses
-	 * recursion to get the items from nested vector frames.
-	 * 
-	 * @param items
-	 *            the list into which the vector items will be placed.
-	 * @param vector
-	 *            the frame containing vecor items.
-	 * @param seenVectors
-	 *            the vectors which should be ignored to prevent infinate loops.
-	 * @param origin
-	 *            start point for this frame or null if it is a top level frame.
-	 * @param scale
-	 *            the factor by which the item on the vector frame are to be
-	 *            scaled.
-	 */
-	// public static void AddAllVectorItems(List<Item> items, Vector vector,
-	// Collection<Frame> seenVectors) {
-	// // Check all the vector items and add the items on the vectors
-	// if (seenVectors.contains(vector))
-	// return;
-	// seenVectors.add(vector);
-	//
-	// float originX = origin == null ? 0 : origin.x;
-	// float originY = origin == null ? 0 : origin.y;
-	//
-	// for (Vector o : vector.getVectors())
-	// AddAllVectorItems(items, o.Frame, new HashSet<Frame>(seenVectors),
-	// new Point2D.Float(originX + o.Origin.x * scale, originY
-	// + o.Origin.y * scale), o.Scale * scale,
-	// o.Foreground, o.Background);
-	// // if its the original frame then were done
-	// if (origin == null) {
-	// ItemUtils.EnclosedCheck(items);
-	// return;
-	// }
-	// // Put copies of the items shifted to the origin of the VectorTag
-	// items.addAll(ItemUtils
-	// .CopyItems(vector.getNonAnnotationItems(), vector));
-	//		
-	// }
-	/**
-	 * Recursive function similar to AddAllOverlayItems.
-	 * 
-	 * @param widgets
-	 *            The collection the widgets will be added to
-	 * @param overlay
-	 *            An "overlay" frame - this intially will be the parent frame
-	 * @param seenOverlays
-	 *            Used for state in the recursion stack. Pass as an empty
-	 *            (non-null) list.
-	 */
-	public static void AddAllOverlayWidgets(List<InteractiveWidget> widgets,
-			Frame overlay, List<Frame> seenOverlays) {
-		if (seenOverlays.contains(overlay))
-			return;
-
-		seenOverlays.add(overlay);
-
-		for (Overlay o : overlay.getOverlays())
-			AddAllOverlayWidgets(widgets, o.Frame, seenOverlays);
-
-		widgets.addAll(overlay.getInteractiveWidgets());
-	}
-
-	private static Image Paint(Frame toPaint, Area clip) {
-		return Paint(toPaint, clip, true, true);
-	}
-
-	/**
-	 * 
-	 * @param toPaint
-	 * @param clip
-	 *            If null, then no clip applied.
-	 * @param isActualFrame
-	 * @return
-	 */
-	private static Image Paint(Frame toPaint, Area clip, boolean isActualFrame,
-			boolean createVolitile) {
-		if (toPaint == null)
-			return null;
+	private static Item _lastToolTippedItem = null;
+
+	/** Static-only class. */
+	private FrameGraphics()
+	{
+	}
+
+	/**
+	 * Gets an image of the given frame that has the given dimensions. If clip
+	 * is not null, only the areas inside clip are guaranteed to be drawn.
+	 */
+	public static Image getFrameImage(Frame toPaint, Clip clip, Dimension size)
+	{
+		return getFrameImage(toPaint, clip, size, true, true);
+	}
+
+	/**
+	 * Gets an image of the given frame that has the given dimensions. If clip
+	 * is not null, only the areas inside clip are guaranteed to be drawn.
+	 */
+	public static Image getFrameImage(Frame toPaint, Clip clip, Dimension size, boolean isActualFrame, boolean createVolatile)
+	{
+		if (toPaint == null) return null;
 
 		// the buffer is not valid, so it must be recreated
 		if (!toPaint.isBufferValid()) {
+			
 			Image buffer = toPaint.getBuffer();
-			if (buffer == null) {
-				GraphicsEnvironment ge = GraphicsEnvironment
-						.getLocalGraphicsEnvironment();
-				if (createVolitile) {
-					buffer = ge.getDefaultScreenDevice()
-							.getDefaultConfiguration()
-							.createCompatibleVolatileImage(_MaxSize.width,
-									_MaxSize.height);
+			// Get the size if it hasn't been given
+			if (size == null) {
+				// Can't get the size if there is no buffer
+				if (buffer == null) {
+					return null;
 				} else {
-					buffer = new BufferedImage(_MaxSize.width, _MaxSize.height,
-							BufferedImage.TYPE_INT_ARGB);
-				}
+					size = buffer.getSize();
+				}
+			}
+			
+			if (buffer == null || !buffer.getSize().equals(size)) {
+				buffer = Image.createImage(size.width, size.height, createVolatile);
 				toPaint.setBuffer(buffer);
-			}
-
-			Graphics2D bg = (Graphics2D) buffer.getGraphics();
-			paintFrame(toPaint, clip, isActualFrame, createVolitile, bg);
-
-			bg.dispose();
+				clip = null;
+			}
+			
+			EcosystemManager.getGraphicsManager().pushDrawingSurface(buffer);
+			EcosystemManager.getGraphicsManager().pushClip(clip);
+			paintFrame(toPaint, isActualFrame, createVolatile);
+			EcosystemManager.getGraphicsManager().popDrawingSurface();
 		}
 
@@ -361,24 +104,15 @@
 	}
 
-	/**
-	 * @param toPaint
-	 * @param clip
-	 * @param isActualFrame
-	 * @param createVolitile
-	 * @param bg
-	 */
-	public static void paintFrame(Frame toPaint, Area clip,
-			boolean isActualFrame, boolean createVolitile, Graphics2D bg) {
-
+	/** TODO: Comment. cts16 */
+	public static void paintFrame(Frame toPaint, boolean isActualFrame, boolean createVolitile)
+	{
+		Clip clip = EcosystemManager.getGraphicsManager().peekClip();
+		
 		// Prepare render passes
 		if (isActualFrame) {
-			currentClip = clip;
 			for (FrameRenderPass pass : _frameRenderPasses) {
-				currentClip = pass.paintStarted(currentClip);
-				clip = currentClip;
-			}
-		}
-
-		bg.setClip(clip);
+				clip = pass.paintStarted(clip);
+			}
+		}
 
 		// TODO: Revise images and clip - VERY IMPORTANT
@@ -386,10 +120,9 @@
 		// Nicer looking lines, but may be too jerky while
 		// rubber-banding on older machines
-		if (UserSettings.AntiAlias.get())
-			bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-					RenderingHints.VALUE_ANTIALIAS_ON);
-		// If we are doing @f etc... then have a clear background if its the
-		// default background color
-		Color backgroundColor = null;
+		if (UserSettings.AntiAlias.get()) EcosystemManager.getGraphicsManager().setAntialiasing(true);
+		
+		// If we are doing @f etc... then have a clear background if its the default background color
+		Colour backgroundColor = null;
+		
 		// Need to allow transparency for frameImages
 		if (createVolitile) {
@@ -397,19 +130,11 @@
 		} else {
 			backgroundColor = toPaint.getBackgroundColor();
-			if (backgroundColor == null)
-				backgroundColor = Item.TRANSPARENT;
-		}
-
-		// if(isActual)
-		bg.setColor(backgroundColor);
-		if (isActualFrame) {
-			// bg.setColor(Color.white); // TODO: TEMP FOR DEBUGGING
-
-			// System.out.println("paintPic");
-		}
-		bg.fillRect(0, 0, _MaxSize.width, _MaxSize.height);
+			if (backgroundColor == null) backgroundColor = Item.TRANSPARENT;
+		}
+
+		EcosystemManager.getGraphicsManager().clear(backgroundColor);
 
 		List<Item> visibleItems = new LinkedList<Item>();
-		List<InteractiveWidget> paintWidgets;
+		List<Widget> paintWidgets;
 
 		if (isActualFrame) {
@@ -417,6 +142,6 @@
 			// frames
 			visibleItems.addAll(toPaint.getAllItems());
-			paintWidgets = new LinkedList<InteractiveWidget>();
-			AddAllOverlayWidgets(paintWidgets, toPaint, new LinkedList<Frame>());
+			paintWidgets = toPaint.getAllOverlayWidgets();
+			paintWidgets.addAll(toPaint.getInteractiveWidgets());
 		} else {
 			visibleItems.addAll(toPaint.getVisibleItems());
@@ -425,16 +150,14 @@
 		}
 
-
-				HashSet<Item> paintedFillsAndLines = new HashSet<Item>();
+		HashSet<Item> paintedFillsAndLines = new HashSet<Item>();
 		// FIRST: Paint widgets swing gui (not expeditee gui) .
 		// Note that these are the anchored widgets
-		ListIterator<InteractiveWidget> widgetItor = paintWidgets
-				.listIterator(paintWidgets.size());
+		ListIterator<Widget> widgetItor = paintWidgets.listIterator(paintWidgets.size());
 		while (widgetItor.hasPrevious()) {
 			// Paint first-in-last-serve ordering - like swing
 			// If it is done the other way around then widgets are covered up by
 			// the box that is supposed to be underneath
-			InteractiveWidget iw = widgetItor.previous();
-			if (clip == null || clip.intersects(iw.getComponant().getBounds())) {
+			Widget iw = widgetItor.previous();
+			if (clip == null || clip.getBounds() == null || clip.getBounds().intersects(iw.getBounds())) {
 				paintedFillsAndLines.addAll(iw.getItems());
 				//iw.paint(bg);
@@ -457,5 +180,5 @@
 			paintItems = new LinkedList<Item>();
 			for (Item i : visibleItems) {
-				if (i.isInDrawingArea(clip)) {
+				if (clip == null || i.isInDrawingArea(clip.getBounds())) {
 					paintItems.add(i);
 				} else if (i.isEnclosed()) {
@@ -469,8 +192,8 @@
 			}
 		}
-		// Only paint files and lines once ... between anchored AND free
-		// items
-		PaintPictures(bg, paintItems, fillOnlyItems, paintedFillsAndLines);
-		PaintLines(bg, visibleItems);
+		
+		// Only paint files and lines once ... between anchored AND free items
+		PaintPictures(paintItems, fillOnlyItems, paintedFillsAndLines);
+		PaintLines(visibleItems);
 
 
@@ -480,8 +203,8 @@
 			// If it is done the other way around then widgets are covered up by
 			// the box that is supposed to be underneath
-			InteractiveWidget iw = widgetItor.previous();
-			if (clip == null || clip.intersects(iw.getComponant().getBounds())) {
-				iw.paint(bg);
-				PaintItem(bg, iw.getItems().get(4));
+			Widget iw = widgetItor.previous();
+			if (clip == null || clip.isNotClipped() || clip.getBounds().intersects(iw.getBounds())) {
+				iw.paint();
+				PaintItem(iw.getItems().get(4));
 			}
 		}
@@ -494,5 +217,5 @@
 		// Dont paint the free items for the other frame in twin frames mode
 		// if (toPaint == DisplayIO.getCurrentFrame()) {
-		if (clip == null) {
+		if (clip == null || clip.isNotClipped()) {
 			freeItemsToPaint = FreeItems.getInstance();
 		} else {
@@ -500,5 +223,5 @@
 			fillOnlyItems.clear();
 			for (Item i : FreeItems.getInstance()) {
-				if (i.isInDrawingArea(clip)) {
+				if (i.isInDrawingArea(clip.getBounds())) {
 					freeItemsToPaint.add(i);
 				} else if (i.isEnclosed()) {
@@ -509,18 +232,19 @@
 		// }
 
-		if (isActualFrame && toPaint == DisplayIO.getCurrentFrame())
-			PaintPictures(bg, freeItemsToPaint, fillOnlyItems,
-					paintedFillsAndLines);
+		if (isActualFrame && toPaint == DisplayController.getCurrentFrame()) {
+			PaintPictures(freeItemsToPaint, fillOnlyItems, paintedFillsAndLines);
+		}
+		
 		// TODO if we can get transparency with FreeItems.getInstance()...
 		// then text can be done before freeItems
-		PaintNonLinesNonPicture(bg, paintItems);
+		PaintNonLinesNonPicture(paintItems);
 
 		// toPaint.setBufferValid(true);
 
-		if (isActualFrame && !isAudienceMode()) {
-			PaintItem(bg, toPaint.getNameItem());
-		}
-
-		if (DisplayIO.isTwinFramesOn()) {
+		if (isActualFrame && !DisplayController.isAudienceMode()) {
+			PaintItem(toPaint.getNameItem());
+		}
+
+		if (DisplayController.isTwinFramesOn()) {
 			List<Item> lines = new LinkedList<Item>();
 			for (Item i : freeItemsToPaint) {
@@ -528,5 +252,5 @@
 					Line line = (Line) i;
 
-					if (toPaint == DisplayIO.getCurrentFrame()) {
+					if (toPaint == DisplayController.getCurrentFrame()) {
 						// If exactly one end of the line is floating...
 
@@ -560,188 +284,47 @@
 				}
 			}
-			if (isActualFrame)
-				PaintLines(bg, lines);
+			
+			if (isActualFrame) PaintLines(lines);
 		} else {
-			// Don't paint the
-			if (isActualFrame)
-				PaintLines(bg, freeItemsToPaint);
-		}
-
-		if (isActualFrame && toPaint == DisplayIO.getCurrentFrame())
-			PaintNonLinesNonPicture(bg, freeItemsToPaint);
+			if (isActualFrame) PaintLines(freeItemsToPaint);
+		}
+
+		if (isActualFrame && toPaint == DisplayController.getCurrentFrame()) {
+			PaintNonLinesNonPicture(freeItemsToPaint);
+		}
 
 		// Repaint popups / drags... As well as final passes
 		if (isActualFrame) {
 			for (FrameRenderPass pass : _frameRenderPasses) {
-				pass.paintPreLayeredPanePass(bg);
-			}
-			PopupManager.getInstance().paintLayeredPane(bg, clip);
+				pass.paintPreLayeredPanePass();
+			}
+			
+			//if (PopupManager.getInstance() != null) PopupManager.getInstance().paintLayeredPane(clip == null ? null : clip.getBounds());
+			
 			for (FrameRenderPass pass : _frameRenderPasses) {
-				pass.paintFinalPass(bg);
+				pass.paintFinalPass();
 			}
 		}
 		
 		// paint tooltip
-		if(!FreeItems.itemsAttachedToCursor()) {
+		if(!FreeItems.hasItemsAttachedToCursor()) {
 			Item current = FrameUtils.getCurrentItem();
-			if(current != null) {
-				current.paintTooltip(bg);
-			} //else {
-//				Item.clearTooltipOwner();
-//			}
-			if(previous != null) previous.clearTooltips();
-			previous = current;
-		}
-
-		if (FreeItems.hasCursor()
-				&& DisplayIO.getCursor() == Item.DEFAULT_CURSOR)
-			PaintNonLinesNonPicture(bg, FreeItems.getCursor());
-	}
-	
-	private static Item previous = null;
-
-	// creates a new line so that lines are shown correctly when spanning
-	// across frames in TwinFrames mode
-	// private static Line TransposeLine(Line line, Item d, Frame toPaint,
-	// int base, int adj) {
-	// Line nl = null;
-	//
-	// if (toPaint != DisplayIO.getCurrentFrame() && d.getParent() == null
-	// && line.getOppositeEnd(d).getParent() == toPaint) {
-	// nl = line.copy();
-	// if (d == line.getStartItem())
-	// d = nl.getStartItem();
-	// else
-	// d = nl.getEndItem();
-	//
-	// if (DisplayIO.FrameOnSide(toPaint) == 0)
-	// d.setX(base);
-	// else
-	// d.setX(base + adj);
-	//
-	// } else if (toPaint == DisplayIO.getCurrentFrame()
-	// && d.getParent() == null
-	// && line.getOppositeEnd(d).getParent() != toPaint) {
-	// nl = line.copy();
-	//
-	// if (d == line.getStartItem())
-	// d = nl.getEndItem();
-	// else
-	// d = nl.getStartItem();
-	//
-	// if (DisplayIO.FrameOnSide(toPaint) == 1)
-	// d.setX(d.getX() - DisplayIO.getMiddle());
-	// else
-	// d.setX(d.getX() + DisplayIO.getMiddle());
-	// }
-	// if (nl != null) {
-	// nl.invalidateAll();
-	// FrameGraphics.requestRefresh(true);
-	// }
-	// return nl;
-	// }
-
-	private static void Paint(Graphics g, Image left, Image right,
-			Color background) {
-
-	    // Triggers a FrameTransition is this has been signalled
-	    // through an '@frameTransition: xxxx' on the frame.  The type of
-	    // transition is specified in the 'xxxx' part
-
-
-		// if TwinFrames mode is on, then clipping etc has to be set
-		if (DisplayIO.isTwinFramesOn()) {
-			// draw the two lines down the middle of the window
-			if (left != null)
-				left.getGraphics().drawLine(DisplayIO.getMiddle() - 2, 0,
-						DisplayIO.getMiddle() - 2, _MaxSize.height);
-
-			if (right != null)
-				right.getGraphics().drawLine(0, 0, 0, _MaxSize.height);
-
-			// set the clipping area
-			((Graphics2D) g).setClip(0, 0, DisplayIO.getMiddle() - 1,
-					_MaxSize.height);
-			g.drawImage(left, 0, 0, Item.DEFAULT_BACKGROUND, null);
-			((Graphics2D) g).setClip(null);
-			g.drawImage(right, DisplayIO.getMiddle() + 1, 0,
-					Item.DEFAULT_BACKGROUND, null);
-
-			
-		}
-		// otherwise, just draw whichever side is active
-		else {
-		    if (DisplayIO.getCurrentSide() == 0) {
-		    	if (!paintTransition(g,left)) {
-		    		// Nothing fancy occurred, just need to render the next slide to screen
-		    		g.drawImage(left, 0, 0, Item.DEFAULT_BACKGROUND, null);
-		    	}
-		    }
-		    else {
-		    	if (!paintTransition(g,right)) {
-		    		// Nothing fancy occurred, just need to render the next slide to screen
-		    		g.drawImage(right, 0, 0, Item.DEFAULT_BACKGROUND, null);
-		    	}
-		    }
-		}
-
-	}
-
-        
-    private static boolean paintTransition(Graphics g, Image image)
-    {
-    	boolean performed_transition = false;
-    	
-    	//If we are doing a transition
-    	if(FrameTransitions.getSlide() == true){						
-
-    		String input = "org.expeditee.gui.FrameTransitions";
-    		String slide_mode_method = FrameTransitions.getslideModeMethod();
-
-    		try {
-    			Class<?> c = Class.forName(input);
-
-    			Class[] cArg = new Class[3];
-    			cArg[0] = Graphics.class;
-    			cArg[1] = Image.class;
-    			cArg[2] = Dimension.class;				       		        
-
-    			//Gets the method of transition and calls it
-    			Method lMethod = c.getDeclaredMethod(slide_mode_method, cArg);
-
-    			if(lMethod != null){
-    				// calling static method, so no class parameter needed
-    				Object o = lMethod.invoke(null, g, image, _MaxSize);
-    				performed_transition = true;
-    				
-    			}
-    			else{
-    				System.err.println("Unable to locate the transition '" + slide_mode_method + "'");
-    			}						
-
-    		} catch (Exception e) {						
-
-    			System.err.println("An Reflection Exception occurred trying to invoke '" + slide_mode_method + "'");
-    			e.printStackTrace();
-    		}	
-    	}		
-    	//Tells the frame to only transition once
-    	FrameTransitions.setSlideFalse();		
-    	
-    	return performed_transition;
-    }
-    
-
-	public static void Clear() {
-		Graphics g = _DisplayGraphics.create();
-		g.setColor(Color.WHITE);
-		g.fillRect(0, 0, _MaxSize.width, _MaxSize.height);
-		g.dispose();
-	}
-
-	private static void PaintNonLinesNonPicture(Graphics2D g, List<Item> toPaint) {
-		for (Item i : toPaint)
-			if (!(i instanceof Line) && !(i instanceof XRayable))
-				PaintItem(g, i);
+			if(current != null) current.paintTooltip();
+			if (_lastToolTippedItem != null) _lastToolTippedItem.clearTooltips();
+			_lastToolTippedItem = current;
+		}
+
+		if (FreeItems.hasCursor() && DisplayController.getCursor() == Item.DEFAULT_CURSOR) {
+			PaintNonLinesNonPicture(FreeItems.getCursor());
+		}
+	}
+
+	private static void PaintNonLinesNonPicture(List<Item> toPaint)
+	{
+		for (Item i : toPaint) {
+			if (!(i instanceof Line) && !(i instanceof XRayable)) {
+				PaintItem(i);
+			}
+		}
 	}
 
@@ -752,19 +335,20 @@
 	 * @param toPaint
 	 */
-	private static void PaintLines(Graphics2D g, List<Item> toPaint) {
+	private static void PaintLines(List<Item> toPaint)
+	{
 		// Use this set to keep track of the items that have been painted
 		Collection<Item> done = new HashSet<Item>();
-		for (Item i : toPaint)
+		for (Item i : toPaint) {
 			if (i instanceof Line) {
 				Line l = (Line) i;
 				if (done.contains(l)) {
-					l.paintArrows(g);
+					l.paintArrows();
 				} else {
 					// When painting a line all connected lines are painted too
 					done.addAll(l.getAllConnected());
-					if (l.getStartItem().getEnclosedArea() == 0)
-						PaintItem(g, i);
-				}
-			}
+					if (l.getStartItem().getEnclosedArea() == 0) PaintItem(i);
+				}
+			}
+		}
 	}
 
@@ -776,6 +360,6 @@
 	 * @param toPaint
 	 */
-	private static void PaintPictures(Graphics2D g, List<Item> toPaint,
-			HashSet<Item> fillOnlyItems, HashSet<Item> done) {
+	private static void PaintPictures(List<Item> toPaint, HashSet<Item> fillOnlyItems, HashSet<Item> done)
+	{
 
 		List<Item> toFill = new LinkedList<Item>();
@@ -783,8 +367,7 @@
 			// Ignore items that have already been done!
 			// Also ignore invisible items..
-			// TODO possibly ignore invisible items before coming to this
-			// method?
-			if (done.contains(i))
-				continue;
+			// TODO possibly ignore invisible items before coming to this method?
+			if (done.contains(i)) continue;
+			
 			if (i instanceof XRayable) {
 				toFill.add(i);
@@ -792,10 +375,8 @@
 			} else if (i.hasEnclosures()) {
 				for (Item enclosure : i.getEnclosures()) {
-					if (!toFill.contains(enclosure))
-						toFill.add(enclosure);
+					if (!toFill.contains(enclosure)) toFill.add(enclosure);
 				}
 				done.addAll(i.getConnected());
-			} else if (i.isLineEnd()
-					&& (!isAudienceMode() || !i.isConnectedToAnnotation())) {
+			} else if (i.isLineEnd() && (!DisplayController.isAudienceMode() || !i.isConnectedToAnnotation())) {
 				toFill.add(i);
 				done.addAll(i.getAllConnected());
@@ -805,7 +386,7 @@
 		if (fillOnlyItems != null) {
 			for (Item i : fillOnlyItems) {
-				if (done.contains(i))
+				if (done.contains(i)) {
 					continue;
-				else if (!isAudienceMode() || !i.isConnectedToAnnotation()) {
+				} else if (!DisplayController.isAudienceMode() || !i.isConnectedToAnnotation()) {
 					toFill.add(i);
 				}
@@ -821,27 +402,35 @@
 				int cmp = aArea.compareTo(bArea);
 				if (cmp == 0) {
-					// System.out.println(a.getEnclosureID() + " " +
-					// b.getID());\
 					// Shapes to the left go underneath
-					Polygon pA = a.getEnclosedShape();
-					Polygon pB = b.getEnclosedShape();
-					if (pA == null || pB == null)
-						return 0;
-					return new Integer(pA.getBounds().x).compareTo(pB
-							.getBounds().x);
+					PolygonBounds pA = a.getEnclosedShape();
+					PolygonBounds pB = b.getEnclosedShape();
+					if (pA == null || pB == null) return 0;
+					return new Integer(pA.getMinX()).compareTo(pB.getMinX());
 				}
 				return cmp * -1;
 			}
 		});
+		
 		for (Item i : toFill) {
 			if (i instanceof XRayable) {
-				PaintItem(g, i);
+				PaintItem(i);
 			} else {
 				// Paint the fill and lines
-				i.paintFill(g);
+				i.paintFill();
 				List<Line> lines = i.getLines();
-				if (lines.size() > 0)
-					PaintItem(g, lines.get(0));
-			}
+				if (lines.size() > 0) PaintItem(lines.get(0));
+			}
+		}
+	}
+
+	/** Displays the given Item on the screen. */
+	static void PaintItem(Item i)
+	{
+		if (i == null) return;
+
+		// do not paint annotation items in audience mode
+		if (!DisplayController.isAudienceMode() || (!i.isConnectedToAnnotation() && !i.isAnnotation()) || i == FrameUtils.getLastEdited())
+		{
+			i.paint();
 		}
 	}
@@ -862,34 +451,39 @@
 			// Check if within 20% of the end of the line
 			Line l = (Line) i;
-			Item toDisconnect = l.getEndPointToDisconnect(Math
-					.round(FrameMouseActions.MouseX), Math
-					.round(FrameMouseActions.MouseY));
+			Item toDisconnect = l.getEndPointToDisconnect(DisplayController.getMousePosition());
 
 			// Brook: Widget Edges do not have such a context
 			if (toDisconnect != null && !(i instanceof WidgetEdge)) {
 				Item.HighlightMode newMode = toDisconnect.getHighlightMode();
-				if (FreeItems.itemsAttachedToCursor())
+				if (FreeItems.hasItemsAttachedToCursor())
 					newMode = Item.HighlightMode.Normal;
 				// unhighlight all the other dots
 				for (Item conn : toDisconnect.getAllConnected()) {
 					conn.setHighlightMode(Item.HighlightMode.None);
+					conn.setHighlightColorToDefault();
 				}
 				l.setHighlightMode(newMode);
+				l.setHighlightColorToDefault();
 				// highlight the dot that will be in disconnect mode
 				toDisconnect.setHighlightMode(newMode);
+				toDisconnect.setHighlightColorToDefault();
 				i = toDisconnect;
 			} else {
-				if(FrameMouseActions.isShiftDown()) {
+				if (StandardInputEventListeners.kbmStateListener.isKeyDown(Key.SHIFT)) {
 					for(Item j : i.getAllConnected()) {
         				if(j instanceof Dot && !j.equals(i)) {
         					j.setHighlightMode(HighlightMode.None);
+        					j.setHighlightColorToDefault();
         				}
         			}
         			l.getStartItem().setHighlightMode(HighlightMode.Connected);
+        			l.getStartItem().setHighlightColorToDefault();
         			l.getEndItem().setHighlightMode(HighlightMode.Connected);
+        			l.getEndItem().setHighlightColorToDefault();
         		} else {
         			for(Item j : i.getAllConnected()) {
         				if(j instanceof Dot && !j.equals(i)) {
         					j.setHighlightMode(HighlightMode.Connected);
+        					j.setHighlightColorToDefault();
         				}
         			}
@@ -902,4 +496,5 @@
 		} else if (i instanceof Circle) {
 			i.setHighlightMode(Item.HighlightMode.Connected);
+			i.setHighlightColorToDefault();
 		} else if (!i.isVisible()) {
 			changeHighlightMode(i, Item.HighlightMode.Connected, null);
@@ -913,8 +508,9 @@
 			// highlight connected dots, but only if there aren't items being carried on the cursor
 			if(FreeItems.getInstance().size() == 0) {
-    			if(FrameMouseActions.isShiftDown()) {
+    			if (StandardInputEventListeners.kbmStateListener.isKeyDown(Key.SHIFT)) {
         			for(Item j : i.getAllConnected()) {
         				if(j instanceof Dot && !j.equals(i)) {
         					j.setHighlightMode(HighlightMode.Connected);
+        					j.setHighlightColorToDefault();
         				}
         			}
@@ -923,4 +519,5 @@
         				if(j instanceof Dot && !j.equals(i)) {
         					j.setHighlightMode(HighlightMode.None);
+        					j.setHighlightColorToDefault();
         				}
         			}
@@ -928,4 +525,5 @@
         				Item j = l.getOppositeEnd(i);
        					j.setHighlightMode(HighlightMode.Connected);
+       					j.setHighlightColorToDefault();
         			}
         		}
@@ -936,23 +534,22 @@
 			// For polygons need to make sure all other endpoints are
 			// unHighlighted
-			if (i.hasPermission(UserAppliedPermission.full))
-				changeHighlightMode(i, Item.HighlightMode.Normal,
-						Item.HighlightMode.None);
-			else
-				changeHighlightMode(i, Item.HighlightMode.Connected,
-						Item.HighlightMode.Connected);
-		}
-		Repaint();
+			if (i.hasPermission(UserAppliedPermission.full)) {
+				changeHighlightMode(i, Item.HighlightMode.Normal, Item.HighlightMode.None);
+			} else {
+				changeHighlightMode(i, Item.HighlightMode.Connected, Item.HighlightMode.Connected);
+			}
+		}
+		DisplayController.requestRefresh(true);
 		return i;
 	}
 
-	public static void changeHighlightMode(Item item, Item.HighlightMode newMode) {
+	public static void changeHighlightMode(Item item, Item.HighlightMode newMode)
+	{
 		changeHighlightMode(item, newMode, newMode);
 	}
 
-	public static void changeHighlightMode(Item item,
-			Item.HighlightMode newMode, Item.HighlightMode connectedNewMode) {
-		if (item == null)
-			return;
+	public static void changeHighlightMode(Item item, Item.HighlightMode newMode, Item.HighlightMode connectedNewMode)
+	{
+		if (item == null) return;
 
 		if (item.hasVector()) {
@@ -960,222 +557,33 @@
 				if (i.getEditTarget() == item) {
 					i.setHighlightMode(newMode);
+					i.setHighlightColorToDefault();
 				}
 			}
 			item.setHighlightMode(newMode);
+			item.setHighlightColorToDefault();
 		} else {
 			// Mike: TODO comment on why the line below is used!!
-			// I forgot already!!Opps
+			// I forgot already!! Oops
 			boolean freeItem = FreeItems.getInstance().contains(item);
 			for (Item i : item.getAllConnected()) {
 				if (/* freeItem || */!FreeItems.getInstance().contains(i)) {
 					i.setHighlightMode(connectedNewMode);
-				}
-			}
-			if (!freeItem && newMode != connectedNewMode)
+					i.setHighlightColorToDefault();
+				}
+			}
+			if (!freeItem && newMode != connectedNewMode) {
 				item.setHighlightMode(newMode);
-		}
-		Repaint();
-	}
-
-	/**
-	 * Repaints the buffer of the given Frame.
-	 * 
-	 * @param toUpdate
-	 *            The Frame whose buffer is to be repainted.
-	 */
-
-	public static void UpdateBuffer(Frame toUpdate, boolean paintOverlays,
-			boolean useVolitile) {
-		toUpdate.setBuffer(getBuffer(toUpdate, paintOverlays, useVolitile));
-	}
-
-	public static Image getBuffer(Frame toUpdate, boolean paintOverlays,
-			boolean useVolitile) {
-		if (toUpdate == null)
-			return null;
-
-		return Paint(toUpdate, null, paintOverlays, useVolitile);
-	}
-
-	public static int getMode() {
-		return _Mode;
-	}
-
-	public static Graphics createGraphics() {
-		// Error messages on start up will call this message before
-		// _DisplayGraphics has been initialised
-		if (_DisplayGraphics == null)
-			return null;
-		return _DisplayGraphics.create();
-	}
-
-	// Damaged areas pending to render. Accessessed by multiple threads
-	private static HashSet<Rectangle> damagedAreas = new HashSet<Rectangle>();
-
-	/** The clip used while paiting */
-	private static Area currentClip;
-
-	/**
-	 * The current clip that is used for painting at this instant.
-	 * 
-	 * Intention: for extra clipping within an items paint method - the clip is
-	 * lost in the graphics object for which can be regained via this method.
-	 * 
-	 * @return The current clip. Null if no clip (e.g. full screen render).
-	 */
-	public static Area getCurrentClip() {
-		return (currentClip != null) ? (Area) currentClip.clone() : null;
-	}
-
-	/**
-	 * Checks that the item is visible (on current frame && overlays) - if
-	 * visible then damaged area will be re-rendered on the next refresh.
-	 * 
-	 * @param damagedItem
-	 * @param toRepaint
-	 */
-	public static void invalidateItem(Item damagedItem, Rectangle toRepaint) {
-		// Only add area to repaint if item is visible...
-		if (ItemUtils.isVisible(damagedItem)) {
-			synchronized (damagedAreas) {
-				damagedAreas.add(toRepaint);
-			}
-		} else if (MessageBay.isMessageItem(damagedItem)) {
-			MessageBay.addDirtyArea(toRepaint);
-		}
-	}
-
-	/**
-	 * The given area will be re-rendered in the next refresh. This is the
-	 * quicker version and is more useful for re-rendering animated areas.
-	 * 
-	 * @param toRepaint
-	 */
-	public static void invalidateArea(Rectangle toRepaint) {
-		synchronized (damagedAreas) {
-			damagedAreas.add(toRepaint);
-		}
-	}
-
-	public static void clearInvalidAreas() {
-		synchronized (damagedAreas) {
-			damagedAreas.clear();
-		}
-	}
-
-	/**
-	 * Invalidates the buffered image of the current Frame and forces it to be
-	 * repainted on to the screen. Repaints all items. This is more expensive
-	 * than refresh.
-	 */
-	public static void ForceRepaint() { // TODO: TEMP: Use refresh
-		Frame current = DisplayIO.getCurrentFrame();
-
-		if (current == null)
-			return;
-		refresh(false);
-	}
-
-	public static void Repaint() { // TODO: TEMP: Use refresh
-		refresh(true);
-	}
-
-	/**
-	 * Called to refresh the display screen. Thread safe.
-	 */
-	public static void refresh(boolean useInvalidation) {
-
-		if (_DisplayGraphics == null || _MaxSize.width <= 0
-				|| _MaxSize.height <= 0)
-			return;
-
-		currentClip = null;
-		if (useInvalidation) { // build clip
-
-			synchronized (damagedAreas) {
-				if (!damagedAreas.isEmpty()) {
-
-					for (Rectangle r : damagedAreas) {
-						if (currentClip == null)
-							currentClip = new Area(r);
-						else
-							currentClip.add(new Area(r));
-					}
-					damagedAreas.clear();
-
-				} else if (MessageBay.isDirty()) {
-					// Paint dirty message bay
-					Graphics dg = _DisplayGraphics.create();
-					MessageBay.refresh(true, dg, Item.DEFAULT_BACKGROUND);
-					return;
-
-				} else
-					return; // nothing to render
-			}
-
-		} else {
-			synchronized (damagedAreas) {
-				damagedAreas.clear();
-			}
-			// System.out.println("FULLSCREEN REFRESH"); // TODO: REMOVE
-		}
-
-		Frame[] toPaint = DisplayIO.getFrames();
-		Image left = Paint(toPaint[0], currentClip);
-		Image right = Paint(toPaint[1], currentClip);
-
-		Graphics dg = _DisplayGraphics.create();
-
-		// Paint frame to window
-		Paint(dg, left, right, Item.DEFAULT_BACKGROUND);
-
-		// Paint any animations
-		PopupManager.getInstance().paintAnimations();
-
-		// Paint message bay
-		MessageBay.refresh(useInvalidation, dg, Item.DEFAULT_BACKGROUND);
-
-		dg.dispose();
-	}
-
-	/**
-	 * If wanting to refresh from another thread - other than the main thread
-	 * that handles the expeditee datamodel (modifying / accessing / rendering).
-	 * Use this method for thread safety.
-	 */
-	public static synchronized void requestRefresh(boolean useInvalidation) {
-
-		_requestMarsheller._useInvalidation = useInvalidation;
-
-		if (_requestMarsheller._isQueued) {
-			return;
-		}
-
-		_requestMarsheller._isQueued = true;
-		EventQueue.invokeLater(_requestMarsheller); // Render on AWT thread
-	}
-
-	private static RenderRequestMarsheller _requestMarsheller = new FrameGraphics().new RenderRequestMarsheller();
-
-	/**
-	 * Used for marshelling render requests from foreign threads to the event
-	 * dispatcher thread... (AWT)
-	 * 
-	 * @author Brook Novak
-	 */
-	private class RenderRequestMarsheller implements Runnable {
-
-		boolean _useInvalidation = true;
-
-		boolean _isQueued = false;
-
-		public void run() {
-			refresh(_useInvalidation);
-			_isQueued = false;
-			_useInvalidation = true;
-		}
-
-	}
-
+				item.setHighlightColorToDefault();
+			}
+		}
+		DisplayController.requestRefresh(true);
+	}
+
+	/*
+	 * 
+	 * FrameRenderPass stuff. (TODO: Not sure if this is used for anything? In Apollo. cts16)
+	 * 
+	 */
+	
 	/**
 	 * Adds a FinalFrameRenderPass to the frame-render pipeline...
@@ -1221,6 +629,6 @@
 	 * situations.
 	 * 
-	 * Although if there are multiples FinalFrameRenderPasses attatach to the
-	 * frame painter then it is not garaunteed to be rendered very last.
+	 * Although if there are multiples FinalFrameRenderPasses attach to the
+	 * frame painter then it is not guaranteed to be rendered very last.
 	 * 
 	 * @see FrameGraphics#addFinalFrameRenderPass(org.expeditee.gui.FrameGraphics.FrameRenderPass)
@@ -1236,11 +644,11 @@
 		 * 
 		 * @return The clip that the pass should use instead. i.e. if there are
-		 *         any effects that cannot invladate prior to paint call.
+		 *         any effects that cannot invalidate prior to paint call.
 		 */
-		Area paintStarted(Area currentClip);
-
-		void paintFinalPass(Graphics g);
-
-		void paintPreLayeredPanePass(Graphics g);
+		Clip paintStarted(Clip currentClip);
+
+		void paintFinalPass();
+
+		void paintPreLayeredPanePass();
 	}
 
Index: /trunk/src/org/expeditee/gui/FrameIO.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameIO.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/FrameIO.java	(revision 1102)
@@ -195,14 +195,12 @@
 	}
 
-	public static Frame LoadFrame(String frameName, String path,
-			boolean ignoreAnnotations) {
-		if (!isValidFrameName(frameName))
-			return null;
+	public static Frame LoadFrame(String frameName, String path, boolean ignoreAnnotations)
+	{
+		if (!isValidFrameName(frameName)) return null;
 
 		String frameNameLower = frameName.toLowerCase();
 		// first try reading from cache
 		if (isCacheOn() && _Cache.containsKey(frameNameLower)) {
-			Logger.Log(Logger.SYSTEM, Logger.LOAD, "Loading " + frameName
-					+ " from cache.");
+			Logger.Log(Logger.SYSTEM, Logger.LOAD, "Loading " + frameName + " from cache.");
 			Frame frame = _Cache.get(frameNameLower);
 			return frame;
@@ -389,5 +387,5 @@
 
 	public static boolean canAccessFrame(String frameName) {
-		Frame current = DisplayIO.getCurrentFrame();
+		Frame current = DisplayController.getCurrentFrame();
 		// Just in case the current frame is not yet saved...
 		if (frameName.equals(current.getName())) {
@@ -490,9 +488,9 @@
 
 		_UseCache = false;
-		Frame fresh = FrameIO.LoadFrame(DisplayIO.getCurrentFrame().getName());
+		Frame fresh = FrameIO.LoadFrame(DisplayController.getCurrentFrame().getName());
 		_UseCache = cache;
 		if (_Cache.containsKey(fresh.getName().toLowerCase()))
 			addToCache(fresh);
-		DisplayIO.setCurrentFrame(fresh, false);
+		DisplayController.setCurrentFrame(fresh, false);
 	}
 
@@ -599,19 +597,19 @@
 
 	public static Frame LoadZero() {
-		Frame current = DisplayIO.getCurrentFrame();
+		Frame current = DisplayController.getCurrentFrame();
 		return LoadZero(current.getFramesetName(), current.getPath());
 	}
 
 	public static Frame LoadLast() {
-		Frame current = DisplayIO.getCurrentFrame();
+		Frame current = DisplayController.getCurrentFrame();
 		return LoadLast(current.getFramesetName(), current.getPath());
 	}
 
 	public static Frame LoadNext() {
-		return LoadNext(DisplayIO.getCurrentFrame());
+		return LoadNext(DisplayController.getCurrentFrame());
 	}
 
 	public static Frame LoadPrevious() {
-		return LoadPrevious(DisplayIO.getCurrentFrame());
+		return LoadPrevious(DisplayController.getCurrentFrame());
 	}
 
@@ -747,5 +745,5 @@
 		}
 
-		// Remove the old frame from the cashe then add the new one
+		// Remove the old frame from the cache then add the new one
 		// TODO figure out some way that we can put both in the cache
 		_Cache.remove(template.getName().toLowerCase());
@@ -770,5 +768,5 @@
 		Item titleItem = template.getTitleItem();
 
-		if (!DisplayIO.isTwinFramesOn() && !Justification.center.equals(((Text)titleItem).getJustification())) {
+		if (!DisplayController.isTwinFramesOn() && !Justification.center.equals(((Text)titleItem).getJustification())) {
 			if ((titleItem.getX() + 1) < template.getNameItem().getX()) {
 				while (titleItem.getSize() > Text.MINIMUM_FONT_SIZE
@@ -811,8 +809,8 @@
 	}
 
-	public static void RefreshCasheImages() {
+	public static void RefreshCacheImages()
+	{
 		SuspendCache();
-		for (Frame f : _Cache.values())
-			f.setBuffer(null);
+		for (Frame frame : _Cache.values()) frame.setBuffer(null);
 		ResumeCache();
 	}
@@ -1152,7 +1150,8 @@
 	 * @return true if the frame is in the current user profile frameset
 	 */
-	public static boolean isProfileFrame(Frame toCheck) {
-		if (toCheck.getNumber() == 0)
-			return false;
+	public static boolean isProfileFrame(Frame toCheck)
+	{
+		if (toCheck.getNumber() == 0) return false;
+		
 		return toCheck.getPath().equals(PROFILE_PATH);
 		// return toCheck.getFramesetName()
@@ -1160,5 +1159,6 @@
 	}
 
-	public static Frame LoadProfile(String userName) {
+	public static Frame LoadProfile(String userName)
+	{
 		return LoadFrame(userName + "1");
 	}
@@ -1299,5 +1299,5 @@
 		String templateLink = linker.getAbsoluteLinkTemplate();
 		String framesetLink = linker.getAbsoluteLinkFrameset();
-		String frameset = (framesetLink != null ? framesetLink : DisplayIO
+		String frameset = (framesetLink != null ? framesetLink : DisplayController
 				.getCurrentFrame().getFramesetName());
 
@@ -1322,5 +1322,5 @@
 	 */
 	public static Frame CreateNewFrameset(String name) throws Exception {
-		String path = DisplayIO.getCurrentFrame().getPath();
+		String path = DisplayController.getCurrentFrame().getPath();
 
 		// if current frameset is profile directory change it to framesets
@@ -1394,11 +1394,9 @@
 	}
 
-	public static Frame CreateFrameset(String frameset, String path,
-			boolean recreate) throws Exception {
+	public static Frame CreateFrameset(String frameset, String path, boolean recreate) throws Exception
+	{
 		String conversion = frameset + " --> ";
 
-		if (!isValidFramesetName(frameset)) {
-			throw new Exception("Invalid frameset name");
-		}
+		if (!isValidFramesetName(frameset)) throw new Exception("Invalid frameset name");
 
 		if (!recreate && FrameIO.canAccessFrameset(frameset)) {
@@ -1474,6 +1472,5 @@
 		SaveFrame(base, true);
 
-		Logger.Log(Logger.SYSTEM, Logger.NEW_FRAMESET, "Created new frameset: "
-				+ frameset);
+		Logger.Log(Logger.SYSTEM, Logger.NEW_FRAMESET, "Created new frameset: " + frameset);
 
 		return base;
Index: /trunk/src/org/expeditee/gui/FrameKeyboardActions.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameKeyboardActions.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/FrameKeyboardActions.java	(revision 1102)
@@ -19,11 +19,8 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Rectangle;
 import java.awt.Toolkit;
 import java.awt.datatransfer.StringSelection;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
-import java.awt.geom.Point2D;
 import java.text.NumberFormat;
 import java.util.ArrayList;
@@ -37,4 +34,7 @@
 import org.expeditee.actions.Navigation;
 import org.expeditee.actions.Simple;
+import org.expeditee.core.AxisAlignedBoxBounds;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
 import org.expeditee.gui.indirect.keyboard.IndirectKeyboardActions;
 import org.expeditee.gui.indirect.keyboard.KeyboardAction;
@@ -51,7 +51,7 @@
 import org.expeditee.items.XRayable;
 import org.expeditee.items.MagneticConstraint.MagneticConstraints;
-import org.expeditee.items.widgets.InteractiveWidget;
+/*import org.expeditee.items.widgets.InteractiveWidget; TODO: Reinstate. cts16
 import org.expeditee.items.widgets.WidgetCorner;
-import org.expeditee.items.widgets.WidgetEdge;
+import org.expeditee.items.widgets.WidgetEdge;*/
 import org.expeditee.settings.experimental.ExperimentalFeatures;
 import org.expeditee.settings.templates.TemplateSettings;
@@ -60,10 +60,10 @@
 import org.expeditee.stats.SessionStats;
 
-public class FrameKeyboardActions implements KeyListener {
+public class FrameKeyboardActions {
 
 	private static FrameKeyboardActions _instance = new FrameKeyboardActions();
 
 	protected FrameKeyboardActions() {
-		IndirectKeyboardActions.getInstance().setDropDownAction(
+		/*IndirectKeyboardActions.getInstance().setDropDownAction(
 				new KeyboardAction() {
 					@Override
@@ -82,9 +82,8 @@
 						} else {
 							// Move to the top of the box
-							Rectangle rect = info.firstConnected
-									.getEnclosedShape().getBounds();
-							int newX = rect.x + Text.MARGIN_LEFT;
+							AxisAlignedBoxBounds rect = info.firstConnected.getBounds();
+							int newX = rect.getMinX() + Text.MARGIN_LEFT;
 							int newY = Text.MARGIN_LEFT
-									+ rect.y
+									+ rect.getMinY()
 									+ DisplayIO.getCurrentFrame()
 											.getItemTemplate()
@@ -171,5 +170,5 @@
 						return null;
 					}
-				});
+				});*/
 		IndirectKeyboardActions.getInstance().setCreateNewTextAction(
 				new KeyboardAction() {
@@ -179,8 +178,6 @@
 								"" + c);
 
-						Point2D.Float newMouse = t.insertChar(c,
-								DisplayIO.getMouseX(), FrameMouseActions.getY());
-						DisplayIO.setCursorPosition(newMouse.x, newMouse.y,
-								false);
+						Point newMouse = t.insertChar(c, DisplayIO.getMouseX(), FrameMouseActions.getY());
+						DisplayIO.setCursorPosition(newMouse.x, newMouse.y, false);
 
 						return t;
@@ -192,5 +189,5 @@
 					public Text exec(final KeyboardInfo info, final char c) {
 						float oldY = FrameMouseActions.MouseY;
-						Point2D.Float newMouse = null;
+						Point newMouse = null;
 						if (c == '\t') {
 							if (info.isShiftDown) {
@@ -212,5 +209,5 @@
 							// float diff = newMouse.y - oldY;
 							// System.out.print("c");
-							Rectangle rect = info.firstConnected.getPolygon().getBounds();
+							AxisAlignedBoxBounds rect = info.firstConnected.getBounds();
 
 							// Text lastEdited = FrameUtils.getLastEdited();
@@ -218,5 +215,5 @@
 
 							Item justBelow = FrameUtils.onItem(DisplayIO.getCurrentFrame(),
-									info.firstConnected.getX() + 10, rect.y + rect.height + 1, false);
+									info.firstConnected.getX() + 10, rect.getMinY() + rect.getHeight() + 1, false);
 
 							// FrameUtils.setLastEdited(lastEdited);
@@ -242,16 +239,7 @@
 	}
 
-	private static Text _toRemove = null;
-
-	private static Collection<Item> _enclosedItems = null;
-
-	public static void resetEnclosedItems() {
-		_enclosedItems = null;
-	}
-
 	public synchronized void keyTyped(KeyEvent e) {
 		if (Simple.isProgramRunning()) {
-			if (e.isControlDown()
-					&& (e.getKeyChar() == KeyEvent.VK_ESCAPE || e.getKeyChar() == KeyEvent.VK_C)) {
+			if (e.isControlDown() && (e.getKeyChar() == KeyEvent.VK_ESCAPE || e.getKeyChar() == KeyEvent.VK_C)) {
 				Simple.stop();
 				return;
@@ -262,6 +250,6 @@
 				Simple.KeyStroke(e.getKeyChar());
 			}
-			if (Simple.consumeKeyboardInput())
-				return;
+			
+			if (Simple.consumeKeyboardInput()) return;
 		}
 
@@ -284,224 +272,6 @@
 		// System.out.println(ch);
 
-		if (e.isAltDown()) {
-
-		} else {
-			processChar(ch, e.isShiftDown());
-		}
+		if (!e.isAltDown()) processChar(ch, e.isShiftDown());
 		// FrameGraphics.Repaint();
-	}
-
-	public static void processChar(char ch, boolean isShiftDown) {
-		Navigation.ResetLastAddToBack();
-		Item on = FrameUtils.getCurrentItem();
-
-		// permission check
-		if (on != null && !on.hasPermission(UserAppliedPermission.full)) {
-			MessageBay
-					.displayMessage("Insufficient permission to edit this item");
-			return;
-		}
-
-		if (isShiftDown && MagneticConstraints.getInstance().keyHit(-ch, on))
-			return;
-		else if (MagneticConstraints.getInstance().keyHit(ch, on))
-			return;
-
-		if (_toRemove != null && on != _toRemove) {
-			assert (_toRemove.getLength() == 0);
-			// This line is to protect mistaken removal of items if there is a
-			// bug...
-			if (_toRemove.getLength() == 0)
-				DisplayIO.getCurrentFrame().removeItem(_toRemove);
-		}
-		_toRemove = null;
-
-		// ignore delete and backspace if in free space
-		if ((on == null || !(on instanceof Text))
-				&& (ch == KeyEvent.VK_BACK_SPACE || ch == KeyEvent.VK_TAB || ch == KeyEvent.VK_DELETE))
-			return;
-
-		SessionStats.TypedChar(ch);
-
-		// check for dot's being replaced with text
-		if (on != null && on instanceof Dot && !(on instanceof WidgetCorner)) {
-			if (ch == KeyEvent.VK_BACK_SPACE || ch == KeyEvent.VK_DELETE) {
-				return;
-			}
-			replaceDot((Item) on, ch);
-			return;
-		}
-
-		// only text can interact with keyboard events
-		if (on != null && !(on instanceof Text))
-			on = null;
-
-		// DisplayIO.UpdateTitle();
-
-		Text text = (Text) on;
-		// if this text is empty but has not been removed (such as from
-		// ESC-pushdown)
-		if (text != null && text.isEmpty()
-				&& (ch == KeyEvent.VK_BACK_SPACE || ch == KeyEvent.VK_DELETE)) {
-			if (text.getLines().size() > 0)
-				replaceText(text);
-			else {
-				DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-			}
-			return;
-		}
-
-		// if the user is in free space, create a new text item
-		/*
-		 * MikeSays: Why do we have to check is highlighted... doing so causes
-		 * problems if you type characters to fast, they turn into multiple text
-		 * items. ie. JK together on the Linux laptop.
-		 */
-		if (on == null /* || !on.isHighlighted() */) {
-			// DisplayIO.UpdateTitle();
-			text = createText(ch);
-			text.justify(false);
-
-			FrameUtils.setLastEdited(text);
-			DisplayIO.setTextCursor(text, Text.NONE);
-			return;
-		} else {
-			FrameUtils.setLastEdited(text);
-		}
-
-		DisplayIO.setTextCursor(text, Text.NONE);
-		IndirectKeyboardActions.getInstance().getInsertCharacterAction()
-				.exec(new KeyboardInfo(null, ch, isShiftDown, isShiftDown,
-						_enclosedItems, text, _enclosedItems, _enclosedItems), ch);
-
-		// This repaint is needed for WINDOWS only?!?!? Mike is not sure why!
-		if (ch == KeyEvent.VK_DELETE)
-			FrameGraphics.requestRefresh(true);
-
-		// a change has occured to the Frame
-		text.getParent().setChanged(true);
-
-		// check that the Text item still exists (hasn't been deleted\backspaced
-		// away)
-		if (text.isEmpty()) {
-			_toRemove = text;
-
-			if (text.hasAction())
-				text.setActionMark(true);
-			else if (text.getLink() != null)
-				text.setLinkMark(true);
-			else if (text.getLines().size() > 0)
-				replaceText(text);
-			else {
-				// DisplayIO.getCurrentFrame().removeItem(text);
-				DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-			}
-		}
-	}
-
-	public static Text replaceDot(Item dot, char ch) {
-		Text text = createText(ch);
-		Item.DuplicateItem(dot, text);
-		FrameUtils.setLastEdited(text);
-
-		// Copy the lines list so it can be modified
-		List<Line> lines = new LinkedList<Line>(dot.getLines());
-		for (Line line : lines)
-			line.replaceLineEnd(dot, text);
-		Frame current = dot.getParentOrCurrentFrame();
-		current.removeItem(dot);
-		ItemUtils.EnclosedCheck(current.getItems());
-		return text;
-	}
-
-	/**
-	 * Replaces the given text item with a dot
-	 */
-	public static Item replaceText(Item text) {
-		Item dot = new Dot(text.getX(), text.getY(), text.getID());
-		Item.DuplicateItem(text, dot);
-
-		List<Line> lines = new LinkedList<Line>();
-		lines.addAll(text.getLines());
-		if (lines.size() > 0)
-			dot.setColor(lines.get(0).getColor());
-		for (Line line : lines) {
-			line.replaceLineEnd(text, dot);
-		}
-		text.delete();
-		Frame current = text.getParentOrCurrentFrame();
-		current.addItem(dot);
-		DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-		ItemUtils.EnclosedCheck(current.getItems());
-		return dot;
-	}
-
-	/**
-	 * Creates a new Text Item whose text contains the given character. This
-	 * method also moves the mouse cursor to be pointing at the newly created
-	 * Text Item ready to insert the next character.
-	 * 
-	 * @param start
-	 *            The character to use as the initial text of this Item.
-	 * @return The newly created Text Item
-	 */
-	private static Text createText(char start) {
-		return IndirectKeyboardActions.getInstance().getCreateNewTextAction()
-				.exec(new KeyboardInfo(null, start, false, false, _enclosedItems, _toRemove, _enclosedItems, _enclosedItems), start);
-	}
-
-	/**
-	 * Creates a new Text Item with no text. The newly created Item is a copy of
-	 * any ItemTemplate if one is present, and inherits all the attributes of
-	 * the Template
-	 * 
-	 * @return The newly created Text Item
-	 */
-	private static Text createText() {
-		return DisplayIO.getCurrentFrame().createNewText();
-	}
-
-	private void move(int direction, boolean isShiftDown, boolean isCtrlDown) {
-		Item on = FrameUtils.getCurrentItem();
-
-		if ((on == null) || (on instanceof Picture)){
-			navigateFrame(direction);
-			return;
-		}
-
-		if (on instanceof Text) {
-			Text text = (Text) on;
-			// When the user hits the left and right button with mouse
-			// positions over the the frame name navigation occurs
-			if (text.isFrameName()) {
-				navigateFrame(direction);
-				return;
-			} else {
-				FrameUtils.setLastEdited(text);
-				DisplayIO.setTextCursor(text, direction, false, isShiftDown,
-						isCtrlDown, true);
-			}
-		}
-	}
-
-	private void navigateFrame(int direction) {
-		switch (direction) {
-		case Text.RIGHT:
-		case Text.PAGE_UP:
-			Navigation.NextFrame(false);
-			break;
-		case Text.LEFT:
-		case Text.PAGE_DOWN:
-			Navigation.PreviousFrame(false);
-			break;
-		case Text.HOME:
-		case Text.LINE_HOME:
-			Navigation.ZeroFrame();
-			break;
-		case Text.END:
-		case Text.LINE_END:
-			Navigation.LastFrame();
-			break;
-		}
 	}
 
@@ -515,13 +285,18 @@
 		int keyCode = e.getKeyCode();
 
-		if (keyCode != KeyEvent.VK_F1 && keyCode != KeyEvent.VK_F2) {
+		// Empty the list of enclosed items if not a size-up or size-down press
+/*		if (keyCode != KeyEvent.VK_F1 && keyCode != KeyEvent.VK_F2) {
 			resetEnclosedItems();
 		}
 
+		// Notify the change in stats
+		// TODO: Will changing this to the Expeditee KBMInputEvent upset stats? cts16
 		SessionStats.AddFrameEvent("k" + KeyEvent.getKeyText(keyCode));
 
+		// Used for calculating frame stats (response time)
 		FrameUtils.ResponseTimer.restart();
 		// e.consume();
 
+		// Things that should consume input before main Expeditee
 		if (Actions.isAgentRunning()) {
 			if (keyCode == KeyEvent.VK_ESCAPE)
@@ -534,9 +309,13 @@
 		}
 
+		// Function keys are handled here
 		if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
-			functionKey(FunctionKey.values()[keyCode - KeyEvent.VK_F1 + 1],
-					e.isShiftDown(), e.isControlDown());
-			return;
-		} else if (e.isAltDown()) {
+			functionKey(FunctionKey.values()[keyCode - KeyEvent.VK_F1 + 1], e.isShiftDown(), e.isControlDown());
+			return;
+		}*/
+		
+		// Keyboard for mouse emulation
+		// TODO: Do we need individual mouse button clicks? Are the corresponding gestures enough? cts16
+		if (e.isAltDown()) {
 			int distance = e.isShiftDown() ? 1 : 20;
 			switch (keyCode) {
@@ -553,5 +332,5 @@
 				FrameMouseActions.rightButton();
 				break;
-			case KeyEvent.VK_LEFT:
+/*			case KeyEvent.VK_LEFT:
 				DisplayIO.translateCursor(-distance, 0);
 				break;
@@ -564,8 +343,10 @@
 			case KeyEvent.VK_DOWN:
 				DisplayIO.translateCursor(0, distance);
-				break;
-			}
-			return;
-		}
+				break;*/
+			}
+			return;
+		}
+		
+		// Notify the mouse handler of the control/shift key state
 		switch (keyCode) {
 		case KeyEvent.VK_CONTROL:
@@ -577,4 +358,5 @@
 		}
 
+		// Handles all CTRL+KEY combinations
 		if (e.isControlDown()) {
 			controlChar(e.getKeyCode(), e.isShiftDown());
@@ -582,16 +364,17 @@
 		}
 
-		switch (keyCode) {
+		// Handles all other keystrokes (with possible shift modifier)
+		// Note: At this point e.isControlDown() must be false
+/*		switch (keyCode) {
 		case KeyEvent.VK_ESCAPE:
-			// Do escape after control so Ctl+Escape does not perform DropDown
-			functionKey(FunctionKey.DropDown, e.isShiftDown(),
-					e.isControlDown());
+			// Do escape after control so Ctrl+Escape does not perform DropDown
+			functionKey(FunctionKey.DropDown, e.isShiftDown(), false);
 			SessionStats.Escape();
 			break;
 		case KeyEvent.VK_LEFT:
-			move(Text.LEFT, e.isShiftDown(), e.isControlDown());
+			move(Text.LEFT, e.isShiftDown(), false);
 			break;
 		case KeyEvent.VK_RIGHT:
-			move(Text.RIGHT, e.isShiftDown(), e.isControlDown());
+			move(Text.RIGHT, e.isShiftDown(), false);
 			break;
 		case KeyEvent.VK_PAGE_DOWN:
@@ -602,28 +385,14 @@
 			break;
 		case KeyEvent.VK_UP:
-			if (e.isControlDown()) {
-				NextTextItem(FrameUtils.getCurrentItem(), false);
-			} else {
-				move(Text.UP, e.isShiftDown(), e.isControlDown());
-			}
+			move(Text.UP, e.isShiftDown(), false);
 			break;
 		case KeyEvent.VK_DOWN:
-			if (e.isControlDown()) {
-				NextTextItem(FrameUtils.getCurrentItem(), true);
-			} else {
-				move(Text.DOWN, e.isShiftDown(), e.isControlDown());
-			}
+			move(Text.DOWN, e.isShiftDown(), false);
 			break;
 		case KeyEvent.VK_END:
-			if (e.isControlDown())
-				move(Text.END, e.isShiftDown(), e.isControlDown());
-			else
-				move(Text.LINE_END, e.isShiftDown(), e.isControlDown());
+			move(Text.LINE_END, e.isShiftDown(), false);
 			break;
 		case KeyEvent.VK_HOME:
-			if (e.isControlDown())
-				move(Text.HOME, e.isShiftDown(), e.isControlDown());
-			else
-				move(Text.LINE_HOME, e.isShiftDown(), e.isControlDown());
+			move(Text.LINE_HOME, e.isShiftDown(), false);
 			break;
 		// TODO remove this when upgrading Java
@@ -636,85 +405,5 @@
 			}
 			break;
-		}
-	}
-
-	/**
-	 * Moves the cursor to the next text item on the frame
-	 * 
-	 * @param currentItem
-	 * @param direction
-	 *            move up if direction is negative, down if direction is
-	 *            positive
-	 */
-	public static void NextTextItem(Item currentItem, boolean down) {
-		// Move the cursor to the next text item
-		Frame current = DisplayIO.getCurrentFrame();
-		Text title = current.getTitleItem();
-
-		Collection<Text> currentItems = FrameUtils.getCurrentTextItems();
-		List<Text> textItems = new ArrayList<Text>();
-		// Move to the next text item in the box if
-		if (currentItems.contains(currentItem)) {
-			textItems.addAll(currentItems);
-		} else {
-			if (title != null)
-				textItems.add(title);
-			textItems.addAll(current.getBodyTextItems(true));
-		}
-
-		Collections.sort(textItems);
-
-		if (textItems.size() == 0) {
-			// If there are no text items on the frame its a NoOp
-			if (title == null)
-				return;
-			if (title != null)
-				DisplayIO.MoveCursorToEndOfItem(title);
-			FrameGraphics.Repaint();
-			return;
-		}
-
-		// If the user is mouse wheeling in free space...
-		if (currentItem == null) {
-			// find the nearest item in the correct direction
-			int currY = FrameMouseActions.getY();
-			for (int i = 0; i < textItems.size(); i++) {
-				Item t = textItems.get(i);
-				if (currY < t.getY()) {
-					if (down) {
-						DisplayIO.MoveCursorToEndOfItem(t);
-					} else {
-						if (i == 0) {
-							DisplayIO.MoveCursorToEndOfItem(current
-									.getTitleItem());
-						} else {
-							DisplayIO.MoveCursorToEndOfItem(textItems
-									.get(i - 1));
-						}
-					}
-					FrameGraphics.Repaint();
-					return;
-				}
-			}
-			// If we are at the botton of the screen and the user scrolls down
-			// then scroll backup to the title
-			if (textItems.size() > 0) {
-				DisplayIO
-						.MoveCursorToEndOfItem(textItems.get(textItems.size() - 1));
-			}
-			return;
-		}
-
-		// Find the current item... then move to the next item
-		int i = textItems.indexOf(currentItem);
-
-		int nextIndex = i + (down ? 1 : -1);
-		if (nextIndex >= 0 && nextIndex < textItems.size()) {
-			DisplayIO.MoveCursorToEndOfItem(textItems.get(nextIndex));
-		} else {
-			DisplayIO.MoveCursorToEndOfItem(currentItem);
-		}
-		return;
-
+		}*/
 	}
 
@@ -739,20 +428,4 @@
 	}
 
-	private static void copyItemToClipboard(Item on) {
-		if (on == null || !(on instanceof Text))
-			return;
-
-		Text text = (Text) on;
-		String string = text.copySelectedText();
-
-		if (string == null || string.length() == 0)
-			string = text.getText();
-
-		// add the text of the item to the clipboard
-		StringSelection selection = new StringSelection(string);
-		Toolkit.getDefaultToolkit().getSystemClipboard()
-				.setContents(selection, null);
-	}
-
 	/**
 	 * Processes all control character keystrokes. Currently Ctrl+C and Ctrl+V
@@ -763,6 +436,5 @@
 	 */
 	private void controlChar(int key, boolean isShiftDown) {
-		Logger.Log(Logger.USER, Logger.CONTROL_CHAR, "User pressing: Ctrl+"
-				+ KeyEvent.getKeyText(key));
+		//Logger.Log(Logger.USER, Logger.CONTROL_CHAR, "User pressing: Ctrl+" + KeyEvent.getKeyText(key));
 		//
 		// if (FrameUtils.getCurrentItem() == null
@@ -776,5 +448,5 @@
 		int distance = isShiftDown ? 1 : 20;
 		switch (key) {
-		case KeyEvent.VK_HOME:
+/*		case KeyEvent.VK_HOME:
 			if (current != null && current instanceof Text) {
 				move(Text.HOME, isShiftDown, true);
@@ -802,7 +474,7 @@
 			break;
 		case KeyEvent.VK_ESCAPE:
-			// Do escape after control so Ctl+Escape does not perform DropDown
+			// Do escape after control so Ctrl+Escape does not perform DropDown
 			functionKey(FunctionKey.DropDown, isShiftDown, true);
-			SessionStats.Escape();
+			SessionStats.Escape();*/
 			break;
 		case KeyEvent.VK_1:
@@ -819,20 +491,18 @@
 			break;
 		case KeyEvent.VK_LEFT:
-			if (current instanceof Text) {
-				DisplayIO.setTextCursor((Text) current, Text.LEFT, false,
-						isShiftDown, true, true);
-			} else {
+/*			if (current instanceof Text) {
+				DisplayIO.setTextCursor((Text) current, Text.LEFT, false, isShiftDown, true, true);
+			} else */{
 				DisplayIO.translateCursor(-distance, 0);
 			}
 			break;
 		case KeyEvent.VK_RIGHT:
-			if (current instanceof Text) {
-				DisplayIO.setTextCursor((Text) current, Text.RIGHT, false,
-						isShiftDown, true, true);
-			} else {
+/*			if (current instanceof Text) {
+				DisplayIO.setTextCursor((Text) current, Text.RIGHT, false, isShiftDown, true, true);
+			} else */{
 				DisplayIO.translateCursor(distance, 0);
 			}
 			break;
-		case KeyEvent.VK_UP:
+/*		case KeyEvent.VK_UP:
 			// if (current instanceof Text) {
 			NextTextItem(FrameUtils.getCurrentItem(), false);
@@ -849,5 +519,5 @@
 			break;
 		case KeyEvent.VK_L:
-			// If its not linked then link it to its self
+			// If its not linked then link it to itself
 			if (current instanceof Text && current.getLink() == null) {
 				String text = ((Text) current).getText();
@@ -866,6 +536,6 @@
 			}
 			break;
-		case KeyEvent.VK_G:
-			// If its not linked then link it to its self
+		case KeyEvent.VK_G: // Same as CTRL+L but follows it afterwards
+			// If its not linked then link it to itself
 			if (current instanceof Text) {
 				String text = ((Text) current).getText();
@@ -922,5 +592,5 @@
 			return;
 		case KeyEvent.VK_C:
-			if (FreeItems.itemsAttachedToCursor()) {
+			if (FreeItems.hasItemsAttachedToCursor()) {
 				ItemSelection.copyClone();
 				return;
@@ -933,6 +603,5 @@
 			if (current instanceof Dot && current.getLines().size() == 1) {
 				item = replaceDot(current, '@');
-			} else if (current instanceof Line
-					&& current.getAllConnected().size() == 3) {
+			} else if (current instanceof Line && current.getAllConnected().size() == 3) {
 				Item end = ((Line) current).getEndItem();
 				if (end instanceof Dot) {
@@ -955,12 +624,9 @@
 			if (current == null)
 				return;
-			if (current != null
-					&& !current.hasPermission(UserAppliedPermission.full)) {
-				MessageBay
-						.displayMessage("Insufficient permission toggle the items mark");
-				return;
-			}
-			boolean newValue = !(current.getLinkMark() || current
-					.getActionMark());
+			if (current != null && !current.hasPermission(UserAppliedPermission.full)) {
+				MessageBay.displayMessage("Insufficient permission toggle the items mark");
+				return;
+			}
+			boolean newValue = !(current.getLinkMark() || current.getActionMark());
 			current.setLinkMark(newValue);
 			current.setActionMark(newValue);
@@ -980,5 +646,5 @@
 			// perform a delete operation
 			FrameMouseActions.delete(current);
-			break;
+			break;*/
 		case KeyEvent.VK_SPACE:
 			if (isShiftDown) {
@@ -988,5 +654,5 @@
 			}
 			break;
-		case KeyEvent.VK_F:
+/*		case KeyEvent.VK_F:
 			// perform a format operation
 			if (isShiftDown) {
@@ -1012,5 +678,5 @@
 			break;
 
-		case KeyEvent.VK_R:
+		case KeyEvent.VK_R: // TODO: What is this? Similar to above? cts16
 			Text textCurrent = getCurrentTextItem();
 			if (textCurrent == null) {
@@ -1026,10 +692,8 @@
 			break;
 		case KeyEvent.VK_S:
-			/*
-			 * Only split when shift is down... it is too easy to accidentally
-			 * hit Ctrl+S after completing a paragraph because this is the
-			 * shortcut for saving a document in most word processors and text
-			 * editors!
-			 */
+			// Only split when shift is down... it is too easy to accidentally
+			// hit Ctrl+S after completing a paragraph because this is the
+			// shortcut for saving a document in most word processors and text
+			// editors!
 			if (!isShiftDown) {
 				Save();
@@ -1057,11 +721,11 @@
 				currentFrame.addItem(newText);
 			}
-			break;
+			break;*/
 		case KeyEvent.VK_ENTER:
 			FrameMouseActions.leftButton();
 			break;
-		case KeyEvent.VK_BACK_SPACE:
+/*		case KeyEvent.VK_BACK_SPACE:
 			DisplayIO.Back();
-			break;
+			break;*/
 		}
 		FrameGraphics.Repaint();
@@ -1078,6 +742,5 @@
 
 		if (item != null && !item.hasPermission(UserAppliedPermission.full)) {
-			MessageBay
-					.displayMessage("Insufficient permission to copy that item");
+			MessageBay.displayMessage("Insufficient permission to copy that item");
 			return null;
 		}
@@ -1093,15 +756,15 @@
 	}
 
-	public static void functionKey(FunctionKey key, boolean isShiftDown,
-			boolean isControlDown) {
+/*	public static void functionKey(FunctionKey key, boolean isShiftDown, boolean isControlDown)
+	{
 		functionKey(key, 1, isShiftDown, isControlDown);
 	}
-
+*/
 	/**
 	 * Called when a Function key has been pressed, and performs the specific
 	 * action based on the key.
 	 */
-	public static void functionKey(FunctionKey key, int repeat,
-			boolean isShiftDown, boolean isControlDown) {
+/*	public static void functionKey(FunctionKey key, int repeat, boolean isShiftDown, boolean isControlDown)
+	{
 		// get whatever the user is pointing at
 		Item on = FrameUtils.getCurrentItem();
@@ -1195,18 +858,19 @@
 			}
 		}
+				
 		// Show a description of the function key pressed if the user is in free
 		// space and return for the F keys that dont do anything in free space.
 		if (on == null) {
 			
-			int mouse_x = FrameMouseActions.getX(), mouse_y = FrameMouseActions.getY();
+			// int mouse_x = FrameMouseActions.getX(), mouse_y = FrameMouseActions.getY();
 			
 			switch (key) {
 			// These function keys still work in free space
-			case DropDown:
-			case InsertDate:
+//			case DropDown:
+//			case InsertDate:
 			case XRayMode:
 			case AudienceMode:
 			case Refresh:
-			case Save:
+//			case Save:
 				break;
 				
@@ -1244,11 +908,10 @@
 				}
 			}
-			Drop(on, false);
+//			Drop(on, false);
 			return;
 		case SizeUp:
 			SetSize(on, repeat, true, false, isControlDown);
 			if (on instanceof Text) {
-				DisplayIO.setTextCursor((Text) on, Text.NONE, true, false,
-						false, true);
+				DisplayIO.setTextCursor((Text) on, Text.NONE, true, false, false, true);
 			}
 			break;
@@ -1256,6 +919,5 @@
 			SetSize(on, -repeat, true, false, isControlDown);
 			if (on instanceof Text) {
-				DisplayIO.setTextCursor((Text) on, Text.NONE, true, false,
-						false, true);
+				DisplayIO.setTextCursor((Text) on, Text.NONE, true, false, false, true);
 			}
 			break;
@@ -1300,1208 +962,3 @@
 			MessageBay.displayMessage(displayMessage);
 	}
-
-	private static void calculateItem(Item toCalculate) {
-		if (toCalculate == null)
-			return;
-
-		if (!toCalculate.update()) {
-			toCalculate.setFormula(null);
-			MessageBay.errorMessage("Can not calculate formula ["
-					+ toCalculate.getText() + ']');
-		}
-	}
-
-	public static void Save() {
-		Frame current = DisplayIO.getCurrentFrame();
-		current.change();
-		FrameIO.SaveFrame(current, true, true);
-	}
-
-	public static final String DEFAULT_NEW_ITEM_TEXT = "";
-
-	/**
-	 * Performs the dropping action: If the cursor is in free space then: the
-	 * cursor is repositioned below the last non-annotation text item. If the
-	 * cursor is on an item, and has items attached then: the cusor is
-	 * positioned below the pointed to item, and the items below are 'pushed
-	 * down' to make room.
-	 * 
-	 * @param toDropFrom
-	 *            The Item being pointed at by the mouse, may be null to
-	 *            indicate the cursor is in free space.
-	 */
-	public static boolean Drop(Item toDropFrom, boolean bPasting) {
-		try {
-			FrameUtils.setLastEdited(null);
-
-			String newItemText = DEFAULT_NEW_ITEM_TEXT;
-
-			// if a line is being rubber-banded, this is a no-op
-			if (Frame.rubberbandingLine())
-				return false; // No-op
-
-			// if the cursor is in free space then the drop will happen from the
-			// last non annotation text item on the frame
-			if (toDropFrom == null) {
-				toDropFrom = DisplayIO.getCurrentFrame()
-						.getLastNonAnnotationTextItem();
-			}
-
-			// if no item was found, return
-			if (toDropFrom == null) {
-				MessageBay.errorMessage("No item could be found to drop from");
-				return false;
-			}
-
-			if (!(toDropFrom instanceof Text)) {
-				MessageBay
-						.displayMessage("Only text items can be dropped from");
-				return false;
-			}
-
-			// Get the list of items that must be dropped
-			List<Text> column = DisplayIO.getCurrentFrame().getColumn(
-					toDropFrom);
-
-			if (column == null) {
-				MessageBay.errorMessage("No column found to align items to");
-				return false;
-			}
-
-			Item title = DisplayIO.getCurrentFrame().getTitleItem();
-
-			// We wont do auto bulleting when dropping from titles
-			if (!bPasting && toDropFrom != title) {
-				newItemText = getAutoBullet(((Text) toDropFrom).getFirstLine());
-			}
-
-			Text dummyItem = null;
-			if (!bPasting && FreeItems.textOnlyAttachedToCursor()) {
-				dummyItem = (Text) FreeItems.getItemAttachedToCursor();
-				String autoBullet = getAutoBullet(dummyItem.getText());
-
-				if (autoBullet.length() > 0)
-					newItemText = "";
-				dummyItem.setText(newItemText + dummyItem.getText());
-			}
-
-			dummyItem = createText();
-			if (FreeItems.textOnlyAttachedToCursor()) {
-				Text t = (Text) FreeItems.getItemAttachedToCursor();
-				dummyItem.setSize(t.getSize());
-				int lines = t.getTextList().size();
-				for (int i = 0; i < lines; i++) {
-					newItemText += '\n';
-				}
-			}
-
-			dummyItem.setText(newItemText);
-
-			// If the only item on the frame is the title and the frame name
-			// goto the zero frame and drop to the @start if there is one
-			// or a fixed amount if there is not
-			if (column.size() == 0) {
-				Frame current = DisplayIO.getCurrentFrame();
-				// Item itemTemplate = current.getItemTemplate();
-				int xPos = title.getX() + FrameCreator.INDENT_FROM_TITLE;
-				int yPos = FrameCreator.getYStart(title);
-				// Check for @start on the zero frame
-				Frame zero = FrameIO.LoadFrame(current.getFramesetName() + '0');
-				Text start = zero.getAnnotation("start");
-				if (start != null) {
-					xPos = start.getX();
-					yPos = start.getY();
-				}
-
-				dummyItem.setPosition(xPos, yPos);
-				// DisplayIO.setCursorPosition(xPos, yPos);
-
-				checkMovingCursor(dummyItem);
-			} else {
-				int yPos = column.get(0).getY() + 1;
-				int xPos = column.get(0).getX();
-				// Either position the new item below the title or just above
-				// the first item below the title
-				if (toDropFrom == title && column.get(0) != title) {
-					// If dropping from the title position just above top item
-					yPos = column.get(0).getY() - 1;
-
-					Frame current = DisplayIO.getCurrentFrame();
-					// Check for @start on the zero frame
-					Frame zero = FrameIO
-							.LoadFrame(current.getFramesetName() + '0');
-					Text start = zero.getAnnotation("start");
-					if (start != null) {
-						yPos = Math.min(yPos, start.getY());
-					}
-				}
-				dummyItem.setPosition(xPos, yPos);
-				column.add(dummyItem);
-				FrameUtils.Align(column, false, 0);
-				// Check if it will be outside the frame area
-				if (dummyItem.getY() < 0
-						|| dummyItem.getY() > FrameGraphics.getMaxFrameSize()
-								.getHeight()) {
-					// Check for the 'next' tag!
-					Frame current = DisplayIO.getCurrentFrame();
-					Item next = current.getAnnotation("next");
-					Item prev = current.getAnnotation("previous");
-					// Check for an unlinked next tag
-					if ((next != null && !next.hasLink())
-							|| (prev != null && prev.hasLink())) {
-						Frame firstFrame = current;
-						if (next != null)
-							next.delete();
-						FrameCreator frameCreator = new FrameCreator(null);
-						// Add the next button
-						next = frameCreator.addNextButton(current, null);
-
-						// Create the new frame linked to the next tag
-						boolean mouseMoved = FrameMouseActions.tdfc(next);
-						Frame moreFrame = DisplayIO.getCurrentFrame();
-
-						// Add previous button to the new frame
-						frameCreator.addPreviousButton(moreFrame,
-								firstFrame.getName());
-						Item first = current.getAnnotation("first");
-						if (first != null) {
-							frameCreator.addFirstButton(moreFrame,
-									first.getLink());
-						} else {
-							frameCreator.addFirstButton(moreFrame,
-									firstFrame.getName());
-						}
-						// Add the @next if we are pasting
-						// if (bPasting) {
-						// Item copy = next.copy();
-						// copy.setLink(null);
-						// moreFrame.addItem(copy);
-						// }
-
-						moreFrame.setTitle(firstFrame.getTitleItem().getText());
-						// need to move the mouse to the top of the frame if
-						// there wasnt an @start on it
-						if (!mouseMoved) {
-							Item moreTitle = moreFrame.getTitleItem();
-							moreTitle
-									.setOverlayPermission(UserAppliedPermission.full);
-							Drop(moreTitle, bPasting);
-						}
-						// Add the bullet text to the item
-						dummyItem.setPosition(DisplayIO.getMouseX(),
-								FrameMouseActions.getY());
-					} else {
-						MessageBay
-								.warningMessage("Can not create items outside the frame area");
-						// ensures correct repainting when items don't move
-						DisplayIO.setCursorPosition(DisplayIO.getMouseX(),
-								FrameMouseActions.getY());
-						return false;
-					}
-				}
-				if (!FreeItems.textOnlyAttachedToCursor()
-						&& !dummyItem.isEmpty()) {
-					DisplayIO.getCurrentFrame().addItem(dummyItem);
-				}
-
-				checkMovingCursor(dummyItem);
-			}
-			if (dummyItem.getText().length() == 0
-					|| FreeItems.itemsAttachedToCursor()) {
-				dummyItem.getParentOrCurrentFrame().removeItem(dummyItem);
-				dummyItem.setRightMargin(FrameGraphics.getMaxFrameSize().width,
-						false);
-			} else {
-				dummyItem.setWidth(toDropFrom.getWidth());
-			}
-
-			DisplayIO.resetCursorOffset();
-			FrameGraphics.Repaint();
-		} catch (RuntimeException e) {
-			// MessageBay.errorMessage(e.getMessage());
-			e.printStackTrace();
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * @param dummyItem
-	 */
-	private static void checkMovingCursor(Text dummyItem) {
-		// Move the item to the cursor position
-		if (FreeItems.itemsAttachedToCursor()) {
-			moveCursorAndFreeItems(dummyItem.getX(), dummyItem.getY());
-		} else {
-			DisplayIO.MoveCursorToEndOfItem(dummyItem);
-		}
-	}
-
-	/**
-	 * @param dummyItem
-	 */
-	public static void moveCursorAndFreeItems(int x, int y) {
-		int oldX = FrameMouseActions.getX();
-		int oldY = FrameMouseActions.getY();
-
-		if (oldX == x && oldY == y)
-			return;
-
-		DisplayIO.setCursorPosition(x, y);
-		Item firstItem = FreeItems.getItemAttachedToCursor();
-
-		if (firstItem == null) {
-			firstItem = null;
-			return;
-		}
-
-		int deltaX = firstItem.getX() - x;
-		int deltaY = firstItem.getY() - y;
-
-		for (Item i : FreeItems.getInstance()) {
-			i.setPosition(i.getX() - deltaX, i.getY() - deltaY);
-		}
-	}
-
-	/**
-	 * Gets the next letter sequence for a given string to be used in auto
-	 * lettering.
-	 * 
-	 * @param s
-	 *            a sequence of letters
-	 * @return the next sequence of letters
-	 */
-	static private String nextLetterSequence(String s) {
-		if (s.length() > 1)
-			return s;
-
-		if (s.equals("z"))
-			return "a";
-
-		return (char) ((int) s.charAt(0) + 1) + "";
-	}
-
-	public static String getBullet(String s) {
-		return getBullet(s, false);
-	}
-
-	public static String getAutoBullet(String s) {
-		return getBullet(s, true);
-	}
-
-	private static String getBullet(String s, boolean nextBullet) {
-		String newItemText = DEFAULT_NEW_ITEM_TEXT;
-
-		if (s == null)
-			return newItemText;
-		/*
-		 * Item i = ItemUtils.FindTag(DisplayIO.getCurrentFrame().getItems(),
-		 * "@NoAutoBullets"); if (i != null) return newItemText;
-		 */
-		// Separate the space at the start of the text item
-		String preceedingSpace = "";
-		for (int i = 0; i < s.length(); i++) {
-			if (!Character.isSpaceChar(s.charAt(i))) {
-				preceedingSpace = s.substring(0, i);
-				s = s.substring(i);
-				break;
-			}
-		}
-
-		// figure out the type of the text item
-		// This allows us to do auto bulleting
-		if (s != null && s.length() > 1) {
-			// First check for text beginning with * @ # etc
-			// These are simple auto bullets
-			if (!Character.isLetterOrDigit(s.charAt(0))
-					&& !Character.isSpaceChar(s.charAt(0))) {
-				if (Text.isBulletChar(s.charAt(0))) {
-					int nonSpaceIndex = 1;
-					// Find the end of the bullet and space after the bullet
-					while (nonSpaceIndex < s.length()
-							&& s.charAt(nonSpaceIndex) == ' ') {
-						nonSpaceIndex++;
-					}
-					// we must have a special char followed by >= 1 space
-					if (nonSpaceIndex > 1)
-						newItemText = s.substring(0, nonSpaceIndex);
-				}
-				// Auto numbering and lettering
-			} else {
-				if (Character.isDigit(s.charAt(0))) {
-					newItemText = getAutoNumber(s, nextBullet);
-					// Auto lettering
-				} else if (Character.isLetter(s.charAt(0))) {
-					newItemText = getAutoLetter(s, nextBullet);
-				}
-			}
-		}
-		return preceedingSpace + newItemText;
-	}
-
-	private static boolean isAutoNumberOrLetterChar(char c) {
-		return c == ':' || c == '-' || c == '.' || c == ')' || c == '>';
-	}
-
-	/**
-	 * Gets the string to be used to start the next auto numbered text item.
-	 * 
-	 * @param s
-	 *            the previous text item
-	 * @return the beginning of the next auto numbered text item
-	 */
-	private static String getAutoNumber(String s, boolean nextBullet) {
-		String newItemText = DEFAULT_NEW_ITEM_TEXT;
-
-		int nonDigitIndex = 1;
-		while (Character.isDigit(s.charAt(nonDigitIndex))) {
-			nonDigitIndex++;
-
-			if (nonDigitIndex + 1 >= s.length())
-				return DEFAULT_NEW_ITEM_TEXT;
-		}
-
-		if (isAutoNumberOrLetterChar(s.charAt(nonDigitIndex))) {
-
-			// we must have a number followed one non letter
-			// then one or more spaces
-			int nonSpaceIndex = nonDigitIndex + 1;
-			while (nonSpaceIndex < s.length() && s.charAt(nonSpaceIndex) == ' ') {
-				nonSpaceIndex++;
-			}
-
-			if (nonSpaceIndex > nonDigitIndex + 1) {
-				if (nextBullet)
-					newItemText = (Integer.parseInt(s.substring(0,
-							nonDigitIndex)) + 1)
-							+ s.substring(nonDigitIndex, nonSpaceIndex);
-				else
-					newItemText = s.substring(0, nonSpaceIndex);
-			}
-		}
-		return newItemText;
-	}
-
-	/**
-	 * Gets the string to be used to start the next auto lettered text item.
-	 * 
-	 * @param s
-	 *            the previous text items
-	 * @return the initial text for the new text item
-	 */
-	private static String getAutoLetter(String s, boolean nextBullet) {
-		String newItemText = DEFAULT_NEW_ITEM_TEXT;
-
-		int nonLetterIndex = 1;
-
-		if (isAutoNumberOrLetterChar(s.charAt(nonLetterIndex))) {
-
-			// Now search for the next non space character
-			int nonSpaceIndex = nonLetterIndex + 1;
-			while (nonSpaceIndex < s.length() && s.charAt(nonSpaceIndex) == ' ') {
-				nonSpaceIndex++;
-			}
-
-			// If there was a space then we have reached the end of our auto
-			// text
-			if (nonSpaceIndex > nonLetterIndex + 1) {
-				if (nextBullet)
-					newItemText = nextLetterSequence(s.substring(0,
-							nonLetterIndex))
-							+ s.substring(nonLetterIndex, nonSpaceIndex);
-				else
-					newItemText = s.substring(0, nonSpaceIndex);
-			}
-		}
-		return newItemText;
-	}
-
-	private static boolean refreshAnchors(Collection<Item> items) {
-		boolean bReparse = false;
-
-		for (Item i : items) {
-			Float anchorLeft = i.getAnchorLeft();
-			Float anchorRight = i.getAnchorRight();
-			Float anchorTop = i.getAnchorTop();
-			Float anchorBottom = i.getAnchorBottom();
-
-			if (anchorLeft != null) {
-				i.setAnchorLeft(anchorLeft);
-				if (i.hasVector()) {
-					bReparse = true;
-				}
-			}
-
-			if (anchorRight != null) {
-				i.setAnchorRight(anchorRight);
-				if (i.hasVector()) {
-					bReparse = true;
-				}
-			}
-
-			if (anchorTop != null) {
-				i.setAnchorTop(anchorTop);
-				if (i.hasVector()) {
-					bReparse = true;
-				}
-			}
-
-			if (anchorBottom != null) {
-				i.setAnchorBottom(anchorBottom);
-				if (i.hasVector()) {
-					bReparse = true;
-				}
-			}
-		}
-		return bReparse;
-	}
-
-	protected static void zoomFrame(Frame frame, double scaleFactor, int x, int y) {
-
-		if (frame == null) {
-			return;
-		}
-
-		Collection<Item> items = frame.getVisibleItems();
-
-		for (Item item : items) {
-			if (item instanceof Text
-					&& item.getSize() <= Text.MINIMUM_FONT_SIZE
-					&& scaleFactor < 1) {
-				return;
-			}
-		}
-
-		for (Vector v : frame.getVectors()) {
-			v.Source.scale((float) scaleFactor, x, y);
-		}
-
-		for (Item item : items) {
-			// This line is only needed for circles!!
-			// Need to really fix up the way this works!!
-			if (item.hasEnclosures())
-				continue;
-			if (!item.hasPermission(UserAppliedPermission.full))
-				continue;
-			item.invalidateAll();
-			if (!(item instanceof Line)) {
-				item.scale((float) scaleFactor, x, y);
-			}
-		}
-
-		for (Item item : items) {
-			if (!item.hasPermission(UserAppliedPermission.full))
-				continue;
-			// if (!(item instanceof Line))
-			item.updatePolygon();
-
-			if (item instanceof Line) {
-				((Line) item).refreshStroke(item.getThickness());
-			}
-
-			item.invalidateAll();
-		}
-	}
-
-	public static boolean zoomFrameIfEnabled(Frame frame, double scaleFactor, int mouse_x, int mouse_y)
-	{
-		boolean zoom_active = ExperimentalFeatures.FrameZoom.get();
-		
-		if (zoom_active) {
-			
-			int x, y;
-			if (ExperimentalFeatures.FrameZoomAroundCursor.get()) {
-				x = mouse_x;
-				y = mouse_y;
-			}
-			else {
-				x = 0;
-				y = 0;
-			}
-			
-			zoomFrame(DisplayIO.getCurrentFrame(), scaleFactor, x, y);
-			DisplayIO.getCurrentFrame().refreshSize();
-			FrameKeyboardActions.Refresh();
-		}
-		else {
-			String frameZoomingDisabledMessage = "Frame Zooming currently disabled. "
-					+ "Access Settings->Experimental->FrameZoom and set to 'true' to enable this";
-			MessageBay.displayMessageOnce(frameZoomingDisabledMessage);
-		}
-		
-		return zoom_active;
-	}
-	
-	public static boolean zoomFrameTopLeftIfEnabled(Frame frame, double scaleFactor)
-	{
-		return zoomFrameIfEnabled(frame, scaleFactor, 0, 0);
-	}
-	
-	/**
-	 * Adjusts the size of the given Item, by the given amount. Note: The amount
-	 * is relative and can be positive or negative.
-	 * 
-	 * @param toSet
-	 *            The Item whose size is to be adjusted
-	 * @param diff
-	 *            The amount to adjust the Item's size by
-	 * @param moveCursor
-	 *            true if the cursor position should be automatically adjusted
-	 *            with resizing
-	 */
-	public static void SetSize(Item item, int diff, boolean moveCursor,
-			boolean insideEnclosure, boolean isControlDown) {
-		Collection<Item> toSize = new HashSet<Item>();
-		Collection<InteractiveWidget> widgets = new HashSet<InteractiveWidget>();
-		// the mouse is only moved when the Item is on the frame, not free
-		// boolean moveMouse = false;
-		Item toSet = null;
-
-		// if the user is not pointing to any item
-		if (item == null) {
-			if (FreeItems.itemsAttachedToCursor())
-				toSize.addAll(FreeItems.getInstance());
-			else {
-				MessageBay
-						.displayMessage("There are no Items selected on the Frame or on the Cursor");
-				return;
-			}
-		} else {
-			if (item.isFrameName()) {
-				// scale the entire frame
-				if (diff != 0) {
-					double scaleFactor = diff > 0 ? 1.1 : 0.909090909;
-					zoomFrameTopLeftIfEnabled(DisplayIO.getCurrentFrame(), scaleFactor);
-				}
-				// MessageBay.displayMessage("Can not resize the frame name");
-				return;
-			}
-			// check permissions
-			if (!item.hasPermission(UserAppliedPermission.full)) {
-				Item editTarget = item.getEditTarget();
-				if (editTarget != item
-						&& editTarget.hasPermission(UserAppliedPermission.full)) {
-					item = editTarget;
-				} else {
-					MessageBay
-							.displayMessage("Insufficient permission to change the size of that item");
-					return;
-				}
-			}
-			toSet = item;
-			// For resizing enclosures pick up everything that is attached to
-			// items partly in the enclosure
-			// TODO make this only pick up stuff COMPLETELY enclosed... if we
-			// change copying to copy only the stuff completely enclosed
-			if (insideEnclosure) {
-				if (_enclosedItems == null) {
-					for (Item i : FrameUtils.getCurrentItems(toSet)) {
-						if (i.hasPermission(UserAppliedPermission.full)
-								&& !toSize.contains(i))
-							toSize.addAll(i.getAllConnected());
-					}
-					_enclosedItems = toSize;
-				} else {
-					toSize = _enclosedItems;
-				}
-
-			}// Enclosed circle centers are resized with the center as origin
-				// Just add the circle center to the list of items to size
-			else if (!toSet.hasEnclosures() && !(toSet instanceof Text)
-					&& toSet.isLineEnd()) {
-				toSize.addAll(toSet.getLines());
-			} else if (toSet instanceof Line) {
-
-				Line line = (Line) toSet;
-
-				if (!(toSet instanceof WidgetEdge)
-						|| ((WidgetEdge) toSet).getWidgetSource()
-								.isWidgetEdgeThicknessAdjustable()) {
-
-					float current = Math.abs(line.getThickness());
-					current = Math.max(current + diff, Item.MINIMUM_THICKNESS);
-					line.setThickness(current);
-					FrameGraphics.Repaint();
-					return;
-
-				}
-
-			} else {
-				toSize.add(toSet);
-			}
-		}
-
-		// add widgets to notify
-		for (Item i : toSize) {
-			if (i instanceof WidgetEdge) {
-				widgets.add(((WidgetEdge) i).getWidgetSource());
-			} else if (i instanceof WidgetCorner) {
-				widgets.add(((WidgetCorner) i).getWidgetSource());
-			}
-		}
-
-		Point2D origin = new Point2D.Float(FrameMouseActions.MouseX,
-				FrameMouseActions.MouseY);
-		// Inside enclosures increase the size of the enclosure
-		double ratio = (100.0 + diff * 2) / 100.0;
-		if (insideEnclosure) {
-			Collection<Item> done = new HashSet<Item>();
-			// adjust the size of all the items
-			for (Item i : toSize) {
-				if (done.contains(i))
-					continue;
-
-				if (i.isLineEnd()) {
-
-					if (!(i instanceof WidgetCorner)
-							|| !((WidgetCorner) i).getWidgetSource()
-									.isFixedSize()) { // don't size fixed
-						// widgets
-
-						Collection<Item> allConnected = i.getAllConnected();
-						done.addAll(allConnected);
-						for (Item it : allConnected) {
-							it.translate(origin, ratio);
-							it.setArrowheadLength((float) (it
-									.getArrowheadLength() * ratio));
-						}
-						i.setThickness((float) (i.getThickness() * ratio));
-					}
-				} else if (i instanceof XRayable) {
-					XRayable xRay = (XRayable) i;
-					Text source = xRay.getSource();
-					// Ensure that the source is done before the XRayable
-					if (!done.contains(source)) {
-						scaleText(insideEnclosure, origin, ratio, done, source);
-					}
-
-					i.translate(origin, ratio);
-					i.setThickness((float) (i.getThickness() * ratio));
-					done.add(i);
-				} else if (i.hasVector()) {
-					// TODO Improve the effiency of resizing vectors... ie...
-					// dont want to have to reparse all the time
-					assert (i instanceof Text);
-					Text text = (Text) i;
-					AttributeValuePair avp = new AttributeValuePair(
-							text.getText());
-					double scale = 1F;
-					try {
-						scale = avp.getDoubleValue();
-					} catch (Exception e) {
-					}
-					scale *= ratio;
-					NumberFormat nf = Vector.getNumberFormatter();
-					text.setAttributeValue(nf.format(scale));
-					text.translate(origin, ratio);
-					item.getParent().parse();
-				} else if (i instanceof Text) {
-					scaleText(insideEnclosure, origin, ratio, done, (Text) i);
-				}
-			}
-			// refresh anchored items
-			if (refreshAnchors(toSize)) {
-				FrameUtils.Parse(DisplayIO.getCurrentFrame(), false);
-			}
-			// notify widgets they were resized
-			for (InteractiveWidget iw : widgets) {
-				iw.onResized();
-			}
-			FrameGraphics.refresh(true);
-			return;
-		}
-
-		// adjust the size of all the items
-		for (Item i : toSize) {
-			// Lines and dots use thickness, not size
-			if (i.hasEnclosures()) {
-				Circle c = (Circle) i.getEnclosures().iterator().next();
-				c.setSize(c.getSize() * (float) ratio);
-			} else if (i instanceof Line || i instanceof Circle
-					&& !insideEnclosure) {
-				float current = Math.abs(i.getThickness());
-				current = Math.max(current + diff, Item.MINIMUM_THICKNESS);
-				i.setThickness(current);
-			} else if (i instanceof Dot) {
-				Item dot = (Item) i;
-				float current = Math.abs(dot.getThickness());
-				current = Math.max(current + diff, Item.MINIMUM_THICKNESS);
-				dot.setThickness(current);
-			} else if (i.hasVector()) {
-				assert (item instanceof Text);
-				Text text = (Text) item;
-				AttributeValuePair avp = new AttributeValuePair(text.getText());
-				double scale = 1F;
-				try {
-					scale = avp.getDoubleValue();
-				} catch (Exception e) {
-				}
-				scale *= ratio;
-				NumberFormat nf = Vector.getNumberFormatter();
-				text.setAttributeValue(nf.format(scale));
-				text.translate(origin, ratio);
-				item.getParent().parse();
-			} else {
-				float oldSize = Math.abs(i.getSize());
-				float newSize = Math
-						.max(oldSize + diff, Item.MINIMUM_THICKNESS);
-				float resizeRatio = newSize / oldSize;
-				// Set size for Picture also translates
-				i.setSize(newSize);
-				if (i instanceof Text && i.getSize() != oldSize) {
-					if (toSize.size() == 1 && !isControlDown) {
-						moveCursorAndFreeItems(i.getX(), i.getY());
-					} else {
-						i.translate(origin, resizeRatio);
-						if (i.isLineEnd()) {
-							i.setPosition(i.getPosition());
-						}
-					}
-				}
-			}
-		}
-
-		if (toSet != null)
-			toSet.getParent().setChanged(true);
-
-		// refresh anchored items
-		if (refreshAnchors(toSize)) {
-			FrameUtils.Parse(DisplayIO.getCurrentFrame(), false);
-		}
-
-		// notify widgets they were resized
-		for (InteractiveWidget iw : widgets) {
-			iw.onResized();
-		}
-		FrameGraphics.refresh(true);
-	}
-
-	/**
-	 * @param origin
-	 * @param ratio
-	 * @param done
-	 * @param source
-	 */
-	private static void scaleText(boolean insideEnclosure, Point2D origin,
-			double ratio, Collection<Item> done, Text source) {
-		if (insideEnclosure)
-			source.setWidth(Math.round((float) (source.getWidth() * ratio)));
-		source.translate(origin, ratio);
-		source.setSize((float) (source.getSize() * ratio));
-		done.add(source);
-	}
-
-	private static void SetFillColor(Item item, boolean setTransparent) {
-		if (item == null)
-			return;
-
-		if (!item.hasPermission(UserAppliedPermission.full)) {
-			MessageBay
-					.displayMessage("Insufficient permission to change fill color");
-			return;
-		}
-
-		Item toSet = item;
-		Color color = toSet.getFillColor();
-		if (setTransparent)
-			color = null;
-		else
-			color = ColorUtils.getNextColor(color,
-					TemplateSettings.FillColorWheel.get(),
-					toSet.getGradientColor());
-
-		// if (color == null) {
-		// MessageBay.displayMessage("FillColor is now transparent");
-		// }
-
-		toSet.setFillColor(color);
-		toSet.getParent().setChanged(true);
-
-		FrameGraphics.Repaint();
-	}
-
-	private static void SetGradientColor(Item item, boolean setTransparent) {
-		if (item == null)
-			return;
-
-		if (!item.hasPermission(UserAppliedPermission.full)) {
-			MessageBay
-					.displayMessage("Insufficient permission to change gradient color");
-			return;
-		}
-
-		Item toSet = item;
-		Color color = toSet.getGradientColor();
-		if (setTransparent)
-			color = null;
-		else
-			color = ColorUtils.getNextColor(color,
-					TemplateSettings.ColorWheel.get(), toSet.getFillColor());
-
-		// if (color == null) {
-		// MessageBay.displayMessage("FillColor is now transparent");
-		// }
-
-		toSet.setGradientColor(color);
-		toSet.getParent().setChanged(true);
-
-		FrameGraphics.Repaint();
-	}
-
-	/**
-	 * Sets the colour of the current Item based on its current colour. The
-	 * colours proceed in the order stored in COLOR_WHEEL.
-	 * 
-	 * @param toSet
-	 *            The Item whose colour is to be changed
-	 */
-	private static void SetColor(Item item, boolean setTransparent,
-			boolean setBackgroundColor) {
-		// first determine the next color
-		Color color = null;
-		Frame currentFrame = DisplayIO.getCurrentFrame();
-		if (item == null) {
-			if (FreeItems.itemsAttachedToCursor()) {
-				color = FreeItems.getInstance().get(0).getColor();
-			} else {
-				return;
-			}
-			// change the background color if the user is pointing on the
-			// frame name
-		} else if (item == currentFrame.getNameItem()) {
-			// check permissions
-			if (!item.hasPermission(UserAppliedPermission.full)) {
-				MessageBay
-						.displayMessage("Insufficient permission to the frame's background color");
-				return;
-			}
-			if (setTransparent)
-				currentFrame.setBackgroundColor(null);
-			else
-				currentFrame.toggleBackgroundColor();
-			// Display a message if the color has changed to transparent
-			// if (currentFrame.getBackgroundColor() == null)
-			// FrameGraphics
-			// .displayMessage("Background color is now transparent");
-			FrameGraphics.Repaint();
-			return;
-		} else {
-			// check permissions
-			if (!item.hasPermission(UserAppliedPermission.full)) {
-				Item editTarget = item.getEditTarget();
-				if (editTarget != item
-						&& editTarget.hasPermission(UserAppliedPermission.full)) {
-					item = editTarget;
-				} else {
-					MessageBay
-							.displayMessage("Insufficient permission to change color");
-					return;
-				}
-			}
-			// Toggling color of circle center changes the circle fill color
-			if (item.hasEnclosures()) {
-				if (setBackgroundColor) {
-					SetGradientColor(item.getEnclosures().iterator().next(),
-							setTransparent);
-				} else {
-					SetFillColor(item.getEnclosures().iterator().next(),
-							setTransparent);
-				}
-			} else if (setBackgroundColor) {
-				color = item.getPaintBackgroundColor();
-			} else {
-				color = item.getPaintColor();
-			}
-		}
-		if (setTransparent)
-			color = null;
-		else if (setBackgroundColor) {
-			color = ColorUtils
-					.getNextColor(color, TemplateSettings.FillColorWheel.get(),
-							item.getPaintColor());
-		} else {
-			color = ColorUtils.getNextColor(color,
-					TemplateSettings.ColorWheel.get(),
-					currentFrame.getPaintBackgroundColor());
-		}
-		// if (currentFrame.getPaintForegroundColor().equals(color))
-		// color = null;
-
-		// if color is being set to default display a message to indicate that
-		// if (color == null) {
-		// MessageBay.displayMessage("Color is set to default");
-		// }
-
-		if (setBackgroundColor) {
-			if (item == null && FreeItems.itemsAttachedToCursor()) {
-				for (Item i : FreeItems.getInstance())
-					i.setBackgroundColor(color);
-			} else {
-				item.setBackgroundColor(color);
-				item.getParent().setChanged(true);
-			}
-		} else {
-			if (item == null && FreeItems.itemsAttachedToCursor()) {
-				for (Item i : FreeItems.getInstance())
-					i.setColor(color);
-			} else {
-				item.setColor(color);
-				item.getParent().setChanged(true);
-			}
-		}
-		FrameGraphics.Repaint();
-	}
-
-	/**
-	 * Toggles the given Item's annotation status on\off.
-	 * 
-	 * @param toToggle
-	 *            The Item to toggle
-	 */
-	private static void ToggleAnnotation(Item toToggle) {
-		if (toToggle == null) {
-			MessageBay.displayMessage("There is no Item selected to toggle");
-			return;
-		}
-
-		// check permissions
-		if (!toToggle.hasPermission(UserAppliedPermission.full)) {
-			MessageBay
-					.displayMessage("Insufficient permission to toggle that item's annotation");
-			return;
-		}
-		toToggle.setAnnotation(!toToggle.isAnnotation());
-
-		toToggle.getParent().setChanged(true);
-		FrameGraphics.Repaint();
-	}
-
-	/**
-	 * Toggles the face style of a text item
-	 * 
-	 * @param toToggle
-	 *            The Item to toggle
-	 */
-	private static void ToggleFontStyle(Item toToggle) {
-		if (toToggle == null) {
-			MessageBay.displayMessage("There is no Item selected to toggle");
-			return;
-		}
-
-		// check permissions
-		if (!toToggle.hasPermission(UserAppliedPermission.full)) {
-			MessageBay
-					.displayMessage("Insufficient permission to toggle that item's annotation");
-			return;
-		}
-
-		if (toToggle instanceof Text) {
-			Text text = (Text) toToggle;
-			text.toggleFontStyle();
-
-			text.getParent().setChanged(true);
-			FrameGraphics.Repaint();
-		}
-	}
-
-	/**
-	 * Toggles the face style of a text item
-	 * 
-	 * @param toToggle
-	 *            The Item to toggle
-	 */
-	private static void ToggleFontFamily(Item toToggle) {
-		if (toToggle == null) {
-			MessageBay.displayMessage("There is no Item selected to toggle");
-			return;
-		}
-
-		// check permissions
-		if (!toToggle.hasPermission(UserAppliedPermission.full)) {
-			MessageBay
-					.displayMessage("Insufficient permission to toggle that item's annotation");
-			return;
-		}
-
-		if (toToggle instanceof Text) {
-			Text text = (Text) toToggle;
-			text.toggleFontFamily();
-
-			text.getParent().setChanged(true);
-			FrameGraphics.Repaint();
-		}
-	}
-
-	/**
-	 * If the given Item is null, then a new Text item is created with the
-	 * current date If the given Item is not null, then the current date is
-	 * prepended to the Item's text
-	 * 
-	 * @param toAdd
-	 *            The Item to prepend the date to, or null
-	 */
-	public static void AddDate(Item toAdd) {
-		String date1 = Formatter.getDateTime();
-		String date2 = Formatter.getDate();
-		final String leftSeparator = " :";
-		final String rightSeparator = ": ";
-		String dateToAdd = date1 + rightSeparator;
-		boolean prepend = false;
-		boolean append = false;
-
-		// if the user is pointing at an item, add the date where ever the
-		// cursor is pointing
-		if (toAdd != null && toAdd instanceof Text) {
-			// permission check
-			if (!toAdd.hasPermission(UserAppliedPermission.full)) {
-				MessageBay
-						.displayMessage("Insufficicent permission to add the date to that item");
-				return;
-			}
-
-			Text textItem = (Text) toAdd;
-
-			String text = textItem.getText();
-
-			// check if the default date has already been put on this item
-			if (text.startsWith(date1 + rightSeparator)) {
-				textItem.removeText(date1 + rightSeparator);
-				dateToAdd = date2 + rightSeparator;
-				prepend = true;
-			} else if (text.startsWith(date2 + rightSeparator)) {
-				textItem.removeText(date2 + rightSeparator);
-				dateToAdd = leftSeparator + date2;
-				append = true;
-			} else if (text.endsWith(leftSeparator + date2)) {
-				textItem.removeEndText(leftSeparator + date2);
-				append = true;
-				dateToAdd = leftSeparator + date1;
-			} else if (text.endsWith(leftSeparator + date1)) {
-				textItem.removeEndText(leftSeparator + date1);
-				if (textItem.getLength() > 0) {
-					dateToAdd = "";
-					prepend = true;
-				} else {
-					// use the default date format
-					prepend = true;
-				}
-			}
-
-			if (prepend) {
-				// add the date to the text item
-				textItem.prependText(dateToAdd);
-				if (dateToAdd.length() == textItem.getLength())
-					DisplayIO.setCursorPosition(textItem
-							.getParagraphEndPosition());
-			} else if (append) {
-				textItem.appendText(dateToAdd);
-				if (dateToAdd.length() == textItem.getLength())
-					DisplayIO.setCursorPosition(textItem.getPosition());
-			} else {
-				for (int i = 0; i < date1.length(); i++) {
-					processChar(date1.charAt(i), false);
-				}
-			}
-
-			textItem.getParent().setChanged(true);
-			FrameGraphics.Repaint();
-			// } else {
-			// MessageBay
-			// .displayMessage("Only text items can have the date prepended to
-			// them");
-			// }
-			// otherwise, create a new text item
-		} else {
-			Text newText = createText();
-			newText.setText(dateToAdd);
-			DisplayIO.getCurrentFrame().addItem(newText);
-			DisplayIO.getCurrentFrame().setChanged(true);
-			FrameGraphics.Repaint();
-
-			DisplayIO.setCursorPosition(newText.getParagraphEndPosition());
-		}
-
-	}
-
-	/**
-	 * Creates a new Frameset with the name given by the Item
-	 * 
-	 * @param name
-	 */
-	private static void CreateFrameset(Item item) {
-		if (item == null) {
-			MessageBay
-					.displayMessage("There is no selected item to use for the frameset name");
-			return;
-		}
-
-		if (!(item instanceof Text)) {
-			MessageBay
-					.displayMessage("Framesets can only be created from text items");
-			return;
-		}
-
-		// dont create frameset if the item is linked
-		if (item.getLink() != null) {
-			MessageBay
-					.displayMessage("A frameset can not be created from a linked item");
-			return;
-		}
-
-		// check permissions
-		if (!item.hasPermission(UserAppliedPermission.full)) {
-			MessageBay
-					.displayMessage("Insufficient permission to create a frameset from this item");
-			return;
-		}
-
-		Text text = (Text) item;
-		try {
-			// create the new frameset
-			Frame linkTo = FrameIO.CreateNewFrameset(text.getFirstLine());
-			DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-			text.setLink(linkTo.getName());
-			text.getParent().setChanged(true);
-			FrameUtils.DisplayFrame(linkTo, true, true);
-			linkTo.moveMouseToDefaultLocation();
-			// this needs to be done if the user doesnt move the mouse before
-			// doing Tdfc while the cursor is set to the text cursor
-			DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-		} catch (Exception e) {
-			MessageBay.errorMessage(e.getMessage());
-		}
-	}
-
-	/**
-	 * Forces a re-parse and repaint of the current Frame.
-	 */
-	public static void Refresh() {
-		Frame currentFrame = DisplayIO.getCurrentFrame();
-
-		if (FrameMouseActions.isShiftDown()) {
-			currentFrame.refreshSize();
-		}
-
-		// Refresh widgets that use its self as a data source
-		currentFrame.notifyObservers(true);
-
-		if (FrameIO.isProfileFrame(currentFrame)) {
-			// TODO ensure that users can not delete the first frame in a
-			// frameset...
-			// TODO handle the case when users manually delete the first frame
-			// in a frameset from the filesystem
-			Frame profile = FrameIO.LoadFrame(currentFrame.getFramesetName()
-					+ "1");
-			assert (profile != null);
-			FrameUtils.Parse(currentFrame);
-			FrameUtils.ParseProfile(profile);
-		} else {
-			FrameUtils.Parse(currentFrame);
-		}
-		// Need to update the cursor for when text items change to @b pictures
-		// etc and the text cursor is showing
-		FrameMouseActions.updateCursor();
-		FrameMouseActions.getInstance().refreshHighlights();
-		FrameGraphics.ForceRepaint();
-	}
-}
+}*/
Index: /trunk/src/org/expeditee/gui/FrameMouseActions.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameMouseActions.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/FrameMouseActions.java	(revision 1102)
@@ -19,20 +19,5 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyEvent;
 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.text.NumberFormat;
 import java.util.ArrayList;
@@ -45,11 +30,15 @@
 import java.util.List;
 import java.util.Set;
-import java.util.TimerTask;
-
-import javax.swing.Timer;
 
 import org.expeditee.actions.Actions;
 import org.expeditee.actions.Misc;
 import org.expeditee.actions.Navigation;
+import org.expeditee.core.AxisAlignedBoxBounds;
+import org.expeditee.core.Colour;
+import org.expeditee.core.OSManager;
+import org.expeditee.core.Point;
+import org.expeditee.core.swing.SwingConversions;
+import org.expeditee.gio.gesture.Gesture;
+import org.expeditee.gio.gesture.GestureListener;
 import org.expeditee.gui.indirect.mouse.IndirectMouseActions;
 import org.expeditee.gui.indirect.mouse.MouseAction;
@@ -71,14 +60,14 @@
 import org.expeditee.items.UserAppliedPermission;
 import org.expeditee.items.XRayable;
-import org.expeditee.items.widgets.ButtonWidget;
+/*import org.expeditee.items.widgets.ButtonWidget; TODO: Reinstate. cts16
 import org.expeditee.items.widgets.InteractiveWidget;
 import org.expeditee.items.widgets.WidgetCorner;
-import org.expeditee.items.widgets.WidgetEdge;
+import org.expeditee.items.widgets.WidgetEdge;*/
 import org.expeditee.settings.UserSettings;
 import org.expeditee.settings.experimental.ExperimentalFeatures;
 import org.expeditee.stats.SessionStats;
 
-public class FrameMouseActions implements MouseListener, MouseMotionListener,
-		MouseWheelListener {
+public class FrameMouseActions
+{
 
 	private static int _lastMouseClickModifiers = 0;
@@ -92,5 +81,5 @@
 			@Override
 			public List<Item> exec(MouseInfo info) {
-				//if user is not pointing at something,this is a back
+				//if user is not pointing at something, this is a back
 				if (info.isControlDown || info.isShiftDown)
 					forward();
@@ -105,6 +94,5 @@
 				// check for TDFC permission
 				if (!info.clicked.hasPermission(UserAppliedPermission.createFrames)) {
-					MessageBay
-							.displayMessage("Insufficient permission to TDFC (Top Down Frame Creation) from that item");
+					MessageBay.displayMessage("Insufficient permission to TDFC (Top Down Frame Creation) from that item");
 					return null;
 				}
@@ -178,12 +166,8 @@
 				copies.add(new Line(d[3], d[0], current.getNextItemID()));
 
-				new Constraint(d[0], d[1], current.getNextItemID(),
-						Constraint.HORIZONTAL);
-				new Constraint(d[2], d[3], current.getNextItemID(),
-						Constraint.HORIZONTAL);
-				new Constraint(d[1], d[2], current.getNextItemID(),
-						Constraint.VERTICAL);
-				new Constraint(d[3], d[0], current.getNextItemID(),
-						Constraint.VERTICAL);
+				new Constraint(d[0], d[1], current.getNextItemID(), Constraint.HORIZONTAL);
+				new Constraint(d[2], d[3], current.getNextItemID(), Constraint.HORIZONTAL);
+				new Constraint(d[1], d[2], current.getNextItemID(), Constraint.VERTICAL);
+				new Constraint(d[3], d[0], current.getNextItemID(), Constraint.VERTICAL);
 
 				anchor(new ArrayList<Item>(copies));
@@ -233,6 +217,5 @@
 				Collection<Item> enclosed = getFullyEnclosedItems(info.clickedIn);
 				if (enclosed.size() == 0) {
-					MessageBay
-							.displayMessage("Insufficient permission to copy items");
+					MessageBay.displayMessage("Insufficient permission to copy items");
 				} else {
 					copies = copy(enclosed);
@@ -308,18 +291,15 @@
 				List<Item> copies = new ArrayList<Item>();
 				if (info.clicked != null) {
-					Collection<Item> leftOver = merge(FreeItems
-							.getInstance(), info.clicked);
+					Collection<Item> leftOver = merge(FreeItems.getInstance(), info.clicked);
 					anchor(leftOver);
 				}
 				// This is executed when the user is putting down a line
 				// endpoint and unreeling. ie. Normal unreeling
-				copies = ItemUtils.UnreelLine(FreeItems.getInstance(),
-						_controlDown);
-
-				if (copies == null)
-					copies = copy(FreeItems.getInstance());
+				copies = ItemUtils.UnreelLine(FreeItems.getInstance(), _controlDown);
+
+				if (copies == null) copies = copy(FreeItems.getInstance());
+				
 				anchor(FreeItems.getInstance());
-				for (Item i : copies)
-					i.setOffset(0, 0);
+				for (Item i : copies) i.setOffset(0, 0);
 				// need to move to prevent cursor dislocation
 				move(copies);
@@ -354,6 +334,5 @@
 							if (next instanceof Line)
 								continue;
-							double distance = Point.distance(currentX,
-									currentY, next.getX(), next.getY());
+							double distance = Point.distance((int) currentX, (int) currentY, next.getX(), next.getY());
 							if (distance < shortestDistance) {
 								shortestDistance = distance;
@@ -469,6 +448,5 @@
 			public List<Item> exec(MouseInfo info) {
 				List<Item> copies = new ArrayList<Item>();
-				Item on = FrameUtils.onItem(DisplayIO.getCurrentFrame(), Math
-						.round(MouseX), Math.round(MouseY), true);
+				Item on = FrameUtils.onItem(DisplayIO.getCurrentFrame(), Math.round(MouseX), Math.round(MouseY), true);
 				// If we have permission to copy this item then pick it up
 				if (on != null && on.isLineEnd()
@@ -479,5 +457,5 @@
 				}
 
-				if (on instanceof WidgetEdge) {
+/*				if (on instanceof WidgetEdge) { TODO: Reinstate. cts16
 					// Don't allow the user to break widget edges.
 					// Note: had to return here because random dots would
@@ -485,5 +463,5 @@
 					// with create line.
 					return copies;
-				}
+				}*/
 
 				// if its on a line then split the line and put a point on it and
@@ -519,7 +497,7 @@
 				List<Item> copies = new ArrayList<Item>();
 				ArrayList<Item> toPickup = new ArrayList<Item>(info.clickedIn.size());
-				for (Item ip : info.clickedIn)
-					if (ip.hasPermission(UserAppliedPermission.full))
-						toPickup.add(ip);
+				for (Item ip : info.clickedIn) {
+					if (ip.hasPermission(UserAppliedPermission.full)) toPickup.add(ip);
+				}
 				pickup(toPickup);
 				// otherwise the user is creating a line
@@ -532,9 +510,8 @@
 				List<Item> items = new ArrayList<Item>();
 				// BROOK: WIDGET RECTANGLES DONT ALLOW DISCONNECTION
-				if (info.clicked instanceof Line && !(info.clicked instanceof WidgetEdge)) {
+				if (info.clicked instanceof Line/* && !(info.clicked instanceof WidgetEdge) TODO: Reinstate. cts16*/) {
 					// Check if within 20% of the end of the line
 					Line l = (Line) info.clicked;
-					Item toDisconnect = l.getEndPointToDisconnect(_lastMouseClick
-							.getX(), _lastMouseClick.getY());
+					Item toDisconnect = l.getEndPointToDisconnect(_lastMouseClick.getX(), _lastMouseClick.getY());
 
 					if (toDisconnect == null) {
@@ -696,6 +673,6 @@
 
 	public static FrameMouseActions getInstance() {
-		if (_instance == null)
-			_instance = new FrameMouseActions();
+		if (_instance == null) _instance = new FrameMouseActions();
+		
 		return _instance;
 	}
@@ -708,6 +685,4 @@
 	private static final int MINIMUM_RANGE_DEPRESS_TIME = 250;
 
-	private static final int RECTANGLE_TO_POINT_THRESHOLD = 20;
-
 	private static Date _lastMouseClickDate = new Date();
 
@@ -717,14 +692,4 @@
 
 	public static final int BIG_MOUSE_PAUSE = 750;
-
-	public static final int CONTEXT_FREESPACE = 0;
-
-	public static final int CONTEXT_AT_TEXT = 1;
-
-	public static final int CONTEXT_AT_LINE = 2;
-
-	public static final int CONTEXT_AT_DOT = 3;
-
-	public static final int CONTEXT_AT_ENCLOSURE = 4;
 
 	public static int _alpha = -1;
@@ -765,7 +730,4 @@
 	private static boolean _extrude = false;
 
-	// keeps track of the last highlighted Item
-	private static Item _lastHighlightedItem = null;
-
 	// keeps track of the item being 'ranged out' if there is one.
 	private static Text _lastRanged = null;
@@ -773,17 +735,4 @@
 	// keeps track of the picture being cropped if there is one
 	private static Picture _lastCropped = null;
-
-	// true if lastItem only has highlighting removed when a new item is
-	// highlighted
-	private static boolean _lastHoldsHighlight = false;
-
-	private static boolean _forceArrowCursor = true;
-
-	// the current context of the cursor
-	private static int _context = 0;
-
-	public static void setForceArrow(boolean val) {
-		_forceArrowCursor = val;
-	}
 
 	public static int getContext() {
@@ -807,6 +756,5 @@
 				public void actionPerformed(ActionEvent ae) {
 					// check if we are in free space
-					if (_lastClickedOn == null
-							&& FreeItems.getInstance().size() == 0) {
+					if (_lastClickedOn == null && FreeItems.getInstance().size() == 0) {
 						// System.out.println("SuperBack!");
 						_MouseTimer.setDelay(ZERO_MOUSE_PAUSE);
@@ -829,12 +777,10 @@
 			});
 
-	private static void setPulse(boolean pulseOn) {
-		if (_pulseOn == pulseOn) {
-			return;
-		}
+	private static void setPulse(boolean pulseOn)
+	{
+		if (_pulseOn == pulseOn) return;
+
 		int amount = PULSE_AMOUNT;
-		if (!pulseOn) {
-			amount *= -1;
-			}
+		if (!pulseOn) amount *= -1;
 		_pulseOn = pulseOn;
 
@@ -859,7 +805,4 @@
 				}
 			});
-
-	public void mouseClicked(MouseEvent e) {
-	}
 
 	/**
@@ -874,9 +817,8 @@
 
 	private void ProccessMousePressedEvent(MouseEvent e, int modifiersEx) {
-		// System.out.println("MousePressed " + e.getX() + "," + e.getY() + " "
-		// + e.getWhen());
+		// System.out.println("MousePressed " + e.getX() + "," + e.getY() + " " + e.getWhen());
 
 		// TODO WHY DID I NOT COMMENT THIS LINE!! MIKE SAYS
-		if (LastRobotX != null) {
+/*		if (LastRobotX != null) {
 			_RobotTimer.stop();
 			LastRobotX = null;
@@ -894,9 +836,8 @@
     		MouseX = panStartX;
     		MouseY = panStartY;
-		}
+		}*/
 
 		// System.out.println(modifiersEx);
-		if (_mouseDown == 0)
-			_lastMouseClickDate = new Date();
+		if (_mouseDown == 0) _lastMouseClickDate = new Date();
 
 		int buttonPressed = e.getButton();
@@ -916,24 +857,21 @@
 		 * backup stack.
 		 */
-		if (on == null || buttonPressed != MouseEvent.BUTTON1
-				|| !on.isFrameName()) {
+		if (on == null || buttonPressed != MouseEvent.BUTTON1 || !on.isFrameName()) {
 			Navigation.ResetLastAddToBack();
 		}
 
-		SessionStats.MouseClicked(e.getButton());
+		//SessionStats.MouseClicked(e.getButton());
 		if (buttonPressed == MouseEvent.BUTTON1) {
-			SessionStats.AddFrameEvent("Ld");
+			//SessionStats.AddFrameEvent("Ld");
 			_extrude = false;
 		} else if (buttonPressed == MouseEvent.BUTTON2) {
-			SessionStats.AddFrameEvent("Md");
+			//SessionStats.AddFrameEvent("Md");
 			_extrude = false;
 		} else if (buttonPressed == MouseEvent.BUTTON3) {
-			SessionStats.AddFrameEvent("Rd");
+			//SessionStats.AddFrameEvent("Rd");
 
 			// Check if the user picked up a paint brush
-			if (FreeItems.getInstance().size() == 1
-					&& FreeItems.getItemAttachedToCursor().isAutoStamp()) {
-				int delay = (int) (FreeItems.getItemAttachedToCursor()
-						.getAutoStamp() * 1000);
+			if (FreeItems.getInstance().size() == 1 && FreeItems.getItemAttachedToCursor().isAutoStamp()) {
+				int delay = (int) (FreeItems.getItemAttachedToCursor().getAutoStamp() * 1000);
 				if (delay < 10) {
 					_autoStamp = true;
@@ -958,13 +896,12 @@
 		 */
 		if (_lastClickedOn == null && FreeItems.getInstance().size() == 0) {
-			// System.out.println(e.getClickCount());
 			if (e.getClickCount() >= 2) {
 				_MouseTimer.start();
 			}
-		} else if (_lastClickedOn != null
-				&& FreeItems.getInstance().size() == 0
-				&& e.getButton() == MouseEvent.BUTTON3) {
+		} else if (	_lastClickedOn != null &&
+					FreeItems.getInstance().size() == 0 &&
+					e.getButton() == MouseEvent.BUTTON3)
+		{
 			_ExtrudeMouseTimer.start();
-
 		} else {
 			_MouseTimer.start();
@@ -994,14 +931,15 @@
 			_isDelete = false;
 			_isNoOp = true;
-		} else
+		} else {
 			_isDelete = false;
+		}
 
 		// This must happen before the previous code
 		// This is when the user is anchoring something
-		if (buttonPressed != MouseEvent.BUTTON1
-				&& (_context == CONTEXT_FREESPACE || _context == CONTEXT_AT_ENCLOSURE)
-				&& FreeItems.itemsAttachedToCursor()) {
-			FrameGraphics.changeHighlightMode(_lastHighlightedItem,
-					Item.HighlightMode.None);
+		if (	buttonPressed != MouseEvent.BUTTON1 &&
+				(_context == CONTEXT_FREESPACE || _context == CONTEXT_AT_ENCLOSURE) &&
+				FreeItems.hasItemsAttachedToCursor())
+		{
+			FrameGraphics.changeHighlightMode(_lastHighlightedItem, Item.HighlightMode.None);
 
 			_lastHighlightedItem = FreeItems.getItemAttachedToCursor();
@@ -1010,9 +948,8 @@
 			}
 			FrameGraphics.Repaint();
-			// this is when the user is picking something up
+		// this is when the user is picking something up
 		} else if (_lastHighlightedItem != null) {
 			if (!(_lastHighlightedItem instanceof Line)) {
-				_lastHighlightedItem
-						.setHighlightColor(Item.DEPRESSED_HIGHLIGHT);
+				_lastHighlightedItem.setHighlightColor(Item.DEPRESSED_HIGHLIGHT);
 			} else {
 				for (Item i : _lastHighlightedItem.getAllConnected()) {
@@ -1027,6 +964,5 @@
 			_lastRanged = (Text) on;
 			// set start-drag point
-			_lastRanged.setSelectionStart(DisplayIO.getMouseX(),
-					FrameMouseActions.getY());
+			_lastRanged.setSelectionStart(DisplayIO.getMouseX(), DisplayIO.getMouseY());
 		}
 
@@ -1040,10 +976,8 @@
 		}
 
-		if (on != null && on instanceof Picture
-				&& e.getButton() == MouseEvent.BUTTON3 && !_isDelete) {
+		if (on != null && on instanceof Picture && e.getButton() == MouseEvent.BUTTON3 && !_isDelete) {
 			_lastCropped = (Picture) on;
 			// set start crop point
-			_lastCropped.setStartCrop(DisplayIO.getMouseX(), FrameMouseActions
-					.getY());
+			_lastCropped.setStartCrop(DisplayIO.getMouseX(), DisplayIO.getMouseY());
 			_lastCropped.setShowCrop(true);
 		}
@@ -1055,5 +989,5 @@
 		// System.out.println("Released " + e.getX() + "," + e.getY() + " " +
 		// e.getWhen());
-		FrameUtils.ResponseTimer.restart();
+//		FrameUtils.ResponseTimer.restart();
 		_autoStampTimer.stop();
 		_autoStamp = false;
@@ -1063,10 +997,9 @@
 		// the user probably wants to click away the popup - therefore ignore
 		// the event
-		boolean shouldConsume = PopupManager.getInstance()
-				.shouldConsumeBackClick();
+/*		boolean shouldConsume = PopupManager.getInstance().shouldConsumeBackClick(); TODO: Reinstate. cts16
 		PopupManager.getInstance().hideAutohidePopups();
 		if (shouldConsume && e.getButton() == MouseEvent.BUTTON1) {
 			return; // consume back click event
-		}
+		}*/
 
 		// _lastMovedDistance = new Point(e.getX() - _lastMouseClick.getX(), e
@@ -1084,6 +1017,5 @@
 		// They are probably trying to pick something up in this case
 		if (lastRanged != null) {
-			long depressTime = (new Date()).getTime()
-					- _lastMouseClickDate.getTime();
+			long depressTime = (new Date()).getTime() - _lastMouseClickDate.getTime();
 			// double changeInDistance =
 			// e.getPoint().distance(_currentMouseClick.getPoint());
@@ -1092,6 +1024,5 @@
 			// System.out.println(depressTime);
 
-			if (depressTime < MINIMUM_RANGE_DEPRESS_TIME
-					|| lastRanged.getSelectionSize() <= 0) {// Text.MINIMUM_RANGED_CHARS)
+			if (depressTime < MINIMUM_RANGE_DEPRESS_TIME || lastRanged.getSelectionSize() <= 0) {// Text.MINIMUM_RANGED_CHARS)
 				// {
 				lastRanged.clearSelection();
@@ -1145,8 +1076,7 @@
 
 			if (_lastHighlightedItem != null)
-				FrameGraphics.changeHighlightMode(_lastHighlightedItem,
-						Item.HighlightMode.None);
-
-			if (FreeItems.itemsAttachedToCursor()) {
+				FrameGraphics.changeHighlightMode(_lastHighlightedItem, Item.HighlightMode.None);
+
+			if (FreeItems.hasItemsAttachedToCursor()) {
 				move(FreeItems.getInstance());
 			}
@@ -1174,6 +1104,7 @@
 					lastRanged.replaceSelectedText(((Text) i).getText());
 					FreeItems.getInstance().clear();
-				} else
+				} else {
 					lastRanged.cutSelectedText();
+				}
 				lastRanged.clearSelection();
 				FrameGraphics.Repaint();
@@ -1231,8 +1162,6 @@
 				// Check if the user is trying to range an item for which they
 				// do not have permission to do so... or it is the frame name
-				if (!lastRanged.hasPermission(UserAppliedPermission.full)
-						|| lastRanged.isFrameName()) {
-					MessageBay
-							.displayMessage("Insufficient permission to cut text");
+				if (!lastRanged.hasPermission(UserAppliedPermission.full) || lastRanged.isFrameName()) {
+					MessageBay.displayMessage("Insufficient permission to cut text");
 					lastRanged.clearSelection();
 					FrameGraphics.Repaint();
@@ -1241,6 +1170,5 @@
 				// if the entire text is selected and its not a line end then
 				// pickup the item
-				boolean entireText = lastRanged.getSelectionSize() == lastRanged
-						.getLength();
+				boolean entireText = lastRanged.getSelectionSize() == lastRanged.getLength();
 				if (entireText && !lastRanged.isLineEnd()) {
 					lastRanged.clearSelection();
@@ -1262,6 +1190,5 @@
 				// do not have permission to do so... or it is the frame name
 				if (!lastRanged.hasPermission(UserAppliedPermission.copy)) {
-					MessageBay
-							.displayMessage("Insufficient permission to copy text");
+					MessageBay.displayMessage("Insufficient permission to copy text");
 					lastRanged.clearSelection();
 					FrameGraphics.Repaint();
@@ -1272,5 +1199,5 @@
 
 			ranged.setParent(null);
-			ranged.setPosition(DisplayIO.getMouseX(), FrameMouseActions.getY());
+			ranged.setPosition(DisplayIO.getMouseX(), DisplayIO.getMouseY());
 			pickup(ranged);
 			lastRanged.clearSelection();
@@ -1303,6 +1230,5 @@
 				// MIKE put the code below up here
 				_lastCropped.clearCropping();
-				FrameGraphics.changeHighlightMode(_lastCropped,
-						HighlightMode.None);
+				FrameGraphics.changeHighlightMode(_lastCropped, HighlightMode.None);
 				_lastCropped = null;
 				FrameGraphics.Repaint();
@@ -1341,6 +1267,5 @@
 
 		// error, we should have returned by now
-		System.out.println("Error: mouseReleased should have returned by now. "
-				+ e);
+		System.out.println("Error: mouseReleased should have returned by now. " + e);
 	}
 
@@ -1348,6 +1273,6 @@
 	 * This method handles all left-click actions
 	 */
-	private void leftButton(Item clicked, Collection<Item> clickedIn,
-			boolean isShiftDown, boolean isControlDown) {
+	private void leftButton(Item clicked, Collection<Item> clickedIn, boolean isShiftDown, boolean isControlDown)
+	{
 		
 		//Gets the current frame
@@ -1355,9 +1280,9 @@
 		
 		//Checks if the current frame is an overlay
-		if(f.getOverlays() != null && FrameUtils.getCurrentItem() != null){
+		if (f.getOverlays() != null && FrameUtils.getCurrentItem() != null) {
 			Item i = FrameUtils.getCurrentItem();
 			
 			//Checks if the item clicked in the overlay is a Rubbish Bin. If it is, delete the item attached to the cursor and return.
-			if(i instanceof WidgetCorner){
+/*			if(i instanceof WidgetCorner){ TODO: Reinstate. cts16
 				
 				try{
@@ -1375,5 +1300,5 @@
 					e.printStackTrace();
 				}
-			}
+			}*/
 			
 			Item on = _lastClickedOn;
@@ -1387,5 +1312,5 @@
 			// Check if the user is nearby another item...
 			int mouseX = DisplayIO.getMouseX();
-			int mouseY = FrameMouseActions.getY();
+			int mouseY = DisplayIO.getMouseY();
 			// System.out.println(mouseX + "," + mouseY);
 			for (Item i : DisplayIO.getCurrentFrame().getItems()) {
@@ -1411,9 +1336,8 @@
 		
 		// If the user clicked into a widgets free space...
-		if (clicked == null && _lastClickedIn != null
-				&& _lastClickedIn.size() >= 4) {
+		if (clicked == null && _lastClickedIn != null && _lastClickedIn.size() >= 4) {
 
 			// Check to see if the user clicked into a widgets empty space
-			InteractiveWidget iw = null;
+/*			InteractiveWidget iw = null; TODO: Reinstate. cts16
 
 			for (Item i : _lastClickedIn) {
@@ -1441,5 +1365,5 @@
 				assert (widgetLink != null);
 				clicked = widgetLink;
-			} else {
+			} else*/ {
 				for (Item i : _lastClickedIn) {
 					/*
@@ -1464,5 +1388,5 @@
 			Picture clickedOnPicture = (Picture)clicked;
 			Frame current_frame = DisplayIO.getCurrentFrame();
-			Color bg_col = current_frame.getBackgroundColor();
+			Colour bg_col = current_frame.getBackgroundColor();
 			if (clickedOnPicture.MouseOverBackgroundPixel(mouseX,mouseY,bg_col)) {
 				// Make 'clicked' null, effectively causing a back() operation
@@ -1475,8 +1399,7 @@
 			boolean hasLinkOrAction = clicked.hasLink() || clicked.hasAction();
 
-			if ((hasLinkOrAction && !clicked
-					.hasPermission(UserAppliedPermission.followLinks))
-					|| (!hasLinkOrAction && !clicked
-							.hasPermission(UserAppliedPermission.createFrames))) {
+			if ((hasLinkOrAction && !clicked.hasPermission(UserAppliedPermission.followLinks))
+					|| (!hasLinkOrAction && !clicked.hasPermission(UserAppliedPermission.createFrames)))
+			{
 				Item editTarget = clicked.getEditTarget();
 				if (editTarget != clicked) {
@@ -1484,6 +1407,5 @@
 						clicked = editTarget;
 					} else {
-						MessageBay
-								.displayMessage("Insufficient permission to perform action on item");
+						MessageBay.displayMessage("Insufficient permission to perform action on item");
 						return;
 					}
@@ -1494,10 +1416,9 @@
 
 			// actions take priority
-			if (_lastMouseClick != null && !_lastMouseClick.isControlDown()
-					&& clickedOn.hasAction()) {
+			if (_lastMouseClick != null && !_lastMouseClick.isControlDown() && clickedOn.hasAction()) {
 				IndirectMouseActions.getInstance().getExecuteActionAction().exec(new MouseInfo(clicked, clickedIn, isShiftDown, isControlDown));
 			} else if (clickedOn.getLink() != null) {
 				IndirectMouseActions.getInstance().getFollowLinkAction().exec(new MouseInfo(clicked, clickedIn, isShiftDown, isControlDown));
-				// no link is found, perform TDFC
+			// no link is found, perform TDFC
 			} else {
 				/*
@@ -1519,51 +1440,4 @@
 	}
 
-	private static boolean doMerging(Item clicked) {
-		if (clicked == null)
-			return false;
-
-		// // Brook: widgets do not merge
-		// if (clicked instanceof WidgetCorner)
-		// return false;
-		//
-		// // Brook: widgets do not merge
-		// if (clicked instanceof WidgetEdge)
-		// return false;
-
-		// System.out.println(FreeItems.getInstance().size());
-		if (isRubberBandingCorner()) {
-			if (clicked.isLineEnd()
-					|| clicked.getAllConnected().contains(
-							FreeItems.getItemAttachedToCursor())) {
-				return true;
-			}
-		}
-
-		if (FreeItems.getInstance().size() > 2)
-			return false;
-
-		Item attachedToCursor = FreeItems.getItemAttachedToCursor();
-
-		if (clicked instanceof Text
-				&& !(attachedToCursor instanceof Text || attachedToCursor
-						.isLineEnd())) {
-			return false;
-		}
-
-		if (clicked instanceof Picture) {
-			int mouseX = DisplayIO.getMouseX();
-			int mouseY = FrameMouseActions.getY();
-			Picture clickedOnPicture = (Picture)clicked;
-			Frame current_frame = DisplayIO.getCurrentFrame();
-			Color bg_col = current_frame.getBackgroundColor();
-			if (clickedOnPicture.MouseOverBackgroundPixel(mouseX,mouseY,bg_col)) {
-				// Make 'clicked' null, effectively causing a back() operation
-				return false;
-			}
-		}
-		
-		return true;
-	}
-
 	public static void middleButton() {
 		Item currentItem = FrameUtils.getCurrentItem();
@@ -1582,6 +1456,5 @@
 	public static void leftButton() {
 		Item currentItem = FrameUtils.getCurrentItem();
-		getInstance().leftButton(currentItem,
-				FrameUtils.getCurrentItems(currentItem), false, false);
+		getInstance().leftButton(currentItem, FrameUtils.getCurrentItems(currentItem), false, false);
 		updateCursor();
 	}
@@ -1590,6 +1463,6 @@
 	 * This method handles all middle-click actions
 	 */
-	private void middleButton(Item clicked, Collection<Item> clickedIn,
-			boolean isShiftDown) {
+	private void middleButton(Item clicked, Collection<Item> clickedIn, boolean isShiftDown)
+	{
 		
 		// If the user clicked into a widgets free space...
@@ -1598,5 +1471,5 @@
 
 			// Check to see if the use clicked into a widgets empty space
-			InteractiveWidget iw = null;
+/*			InteractiveWidget iw = null; TODO: Reinstate. cts16
 
 			for (Item i : _lastClickedIn) {
@@ -1617,10 +1490,9 @@
 					return;
 				}
-			}
+			}*/
 		}
 		// if the cursor has Items attached
-		if (FreeItems.itemsAttachedToCursor()) {
-			// if the user is pointing at something, merge the items (if
-			// possible)
+		if (FreeItems.hasItemsAttachedToCursor()) {
+			// if the user is pointing at something, merge the items (if possible)
 			if (doMerging(clicked)) {
 				IndirectMouseActions.getInstance().getDeleteItemsAction().exec(new MouseInfo(clicked, clickedIn, false, false));
@@ -1635,5 +1507,5 @@
 				Picture clickedOnPicture = (Picture)clicked;
 				Frame current_frame = DisplayIO.getCurrentFrame();
-				Color bg_col = current_frame.getBackgroundColor();
+				Colour bg_col = current_frame.getBackgroundColor();
 				if (clickedOnPicture.MouseOverBackgroundPixel(mouseX,mouseY,bg_col)) {
 					clicked = null; // Effectively make it as if they haven't clicked on anything
@@ -1645,10 +1517,8 @@
 				if (!clicked.hasPermission(UserAppliedPermission.full)) {
 					Item editTarget = clicked.getEditTarget();
-					if (editTarget != clicked
-							&& editTarget.hasPermission(UserAppliedPermission.full)) {
+					if (editTarget != clicked && editTarget.hasPermission(UserAppliedPermission.full)) {
 						clicked = editTarget;
 					} else {
-						MessageBay
-						.displayMessage("Insufficient permission to pick up item");
+						MessageBay.displayMessage("Insufficient permission to pick up item");
 						return;
 					}
@@ -1663,48 +1533,4 @@
 		}
 		SessionStats.MovedItems(FreeItems.getInstance());
-	}
-
-	private static Item getFirstFreeLineEnd() {
-		for (Item i : FreeItems.getInstance())
-			if (i.isLineEnd())
-				return i;
-		return null;
-	}
-
-	private static boolean isRubberBandingCorner() {
-		return getShapeCorner(FreeItems.getInstance()) != null;
-	}
-
-	/**
-	 * Gets the rectangle corner from the list of items that are part of a
-	 * rectangle.
-	 * 
-	 * @param partialRectangle
-	 *            a corner and its two connecting lines.
-	 * @return the rectangle corner or null if the list of items is not part of
-	 *         a rectangle.
-	 */
-	private static Item getShapeCorner(List<Item> partialRectangle) {
-		if (partialRectangle.size() < 3)
-			return null;
-		Item lineEnd = null;
-		// only one lineEnd will be present for rectangles
-		// All other items must be lines
-		for (Item i : partialRectangle) {
-			if (i.isLineEnd()) {
-				if (lineEnd == null) {
-					lineEnd = i;
-				} else {
-					return null;
-				}
-			} else if (!(i instanceof Line)) {
-				return null;
-			}
-		}
-		// if this is at least the corner of two connected lines
-		if (lineEnd != null && lineEnd.getAllConnected().size() >= 5)
-			return lineEnd;
-
-		return null;
 	}
 
@@ -1719,5 +1545,5 @@
 
 			// Check to see if the use clicked into a widgets empty space
-			InteractiveWidget iw = null;
+/*			InteractiveWidget iw = null; TODO: Reinstate. cts16
 
 			for (Item i : _lastClickedIn) {
@@ -1738,5 +1564,5 @@
 					return;
 				}
-			}
+			}*/
 		}
 		
@@ -1744,13 +1570,11 @@
 
 		List<Item> copies = null;
-		if (FreeItems.itemsAttachedToCursor()) {
-			if (FreeItems.getInstance().size() == 1
-					&& FreeItems.getItemAttachedToCursor().isAutoStamp()) {
+		if (FreeItems.hasItemsAttachedToCursor()) {
+			if (FreeItems.getInstance().size() == 1 && FreeItems.getItemAttachedToCursor().isAutoStamp()) {
 				// Dont stamp if the user is painting... because we dont want to
 				// save any of the items created!
 				return;
-				// if the user is clicking on something, merge the items
-				// unless it is a point onto something other than a lineEnd or a
-				// dot
+			// if the user is clicking on something, merge the items unless
+			// it is a point onto something other than a lineEnd or a dot
 			} else if (clicked != null
 			// TODO Change the items merge methods so the logic is simplified
@@ -1758,17 +1582,13 @@
 							|| clicked instanceof Dot || clicked.isLineEnd())) {
 				// check permissions
-				if (!clicked.hasPermission(UserAppliedPermission.full)
-						&& clicked.getParent().getNameItem() != clicked) {
-					MessageBay
-							.displayMessage("Insufficient permission to merge items");
+				if (!clicked.hasPermission(UserAppliedPermission.full) && clicked.getParent().getNameItem() != clicked) {
+					MessageBay.displayMessage("Insufficient permission to merge items");
 					return;
 				}
-				if (clicked instanceof Text || clicked instanceof Dot
-						|| clicked instanceof XRayable) {
+				if (clicked instanceof Text || clicked instanceof Dot || clicked instanceof XRayable) {
 					if (isRubberBandingCorner()) {
 						copies = IndirectMouseActions.getInstance().getMergeGroupAction().exec(new MouseInfo(clicked, clickedIn, false, false));
 						// line onto something
-					} else if (FreeItems.getInstance().size() == 2
-					/* && clicked instanceof XRayable */) {
+					} else if (FreeItems.getInstance().size() == 2 /* && clicked instanceof XRayable */) {
 						copies = IndirectMouseActions.getInstance().getMergeTwoItemsAction().exec(new MouseInfo(clicked, clickedIn, false, false));
 					} else if (FreeItems.getInstance().size() == 1) {
@@ -1778,8 +1598,6 @@
 					}
 				} else {
-					copies = ItemUtils.UnreelLine(FreeItems.getInstance(),
-							_controlDown);
-					if (copies == null)
-						copies = copy(FreeItems.getInstance());
+					copies = ItemUtils.UnreelLine(FreeItems.getInstance(), _controlDown);
+					if (copies == null) copies = copy(FreeItems.getInstance());
 					for (Item i : copies) {
 						i.setOffset(0, 0);
@@ -1789,5 +1607,5 @@
 					pickup(copies);
 				}
-				// otherwise, anchor the items
+			// otherwise, anchor the items
 			} else {
 				// check if this is anchoring a rectangle
@@ -1812,5 +1630,5 @@
 				Picture clickedOnPicture = (Picture)clicked;
 				Frame current_frame = DisplayIO.getCurrentFrame();
-				Color bg_col = current_frame.getBackgroundColor();
+				Colour bg_col = current_frame.getBackgroundColor();
 				if (clickedOnPicture.MouseOverBackgroundPixel(mouseX,mouseY,bg_col)) {
 					clicked = null; // Effectively make it as if they haven't clicked on anything
@@ -1823,6 +1641,5 @@
 				if (clicked.isLineEnd()) {
 					if (!clicked.hasPermission(UserAppliedPermission.full)) {
-						MessageBay
-								.displayMessage("Insufficient permission to unreel");
+						MessageBay.displayMessage("Insufficient permission to unreel");
 						return;
 					}
@@ -1833,6 +1650,5 @@
 						clicked = editTarget;
 					} else {
-						MessageBay
-								.displayMessage("Insufficient permission to copy");
+						MessageBay.displayMessage("Insufficient permission to copy");
 						return;
 					}
@@ -1846,6 +1662,5 @@
 					// otherwise, create a rectangle
 				} else {
-					Item on = FrameUtils.onItem(DisplayIO.getCurrentFrame(),
-							MouseX, MouseY, true);
+					Item on = FrameUtils.onItem(DisplayIO.getCurrentFrame(), MouseX, MouseY, true);
 					// if its on a line then create a line from that line
 					if (on instanceof Line && on.hasPermission(UserAppliedPermission.full)) {
@@ -1860,23 +1675,4 @@
 		updateCursor();
 		FrameGraphics.Repaint();
-	}
-
-	/**
-	 * 
-	 */
-	private static void stampItemsOnCursor(boolean save) {
-		List<Item> copies = copy(FreeItems.getInstance());
-		// MIKE: what does the below 2 lines do?
-		for (Item i : copies) {
-			i.setOffset(0, 0);
-			i.setSave(save);
-		}
-		// The below code has a little problem withflicker when stamp
-		// and dragging
-		move(FreeItems.getInstance());
-		for (Item i : copies) {
-			i.setHighlightMode(HighlightMode.None);
-		}
-		anchor(copies);
 	}
 
@@ -1907,89 +1703,11 @@
 	}
 
-	/**
-	 * Marks the items as not belonging to any specific frame. When picking up
-	 * items the parent will be automatically cleared for items on the current
-	 * frame but not for overlay items. This method ensures that overlay items
-	 * will also be cleared. This is useful when picking up copies of items from
-	 * an overlay (with the right mouse button) to ensure that the copy will be
-	 * anchored on the current frame rather than the overlay. When items are
-	 * picked up with the middle button clearParent should NOT be called.
-	 * 
-	 * @param items
-	 *            to have their parent cleared
-	 */
-	private static void clearParent(List<Item> items) {
-		for (Item i : items) {
-			// The next line is only necessary for circles...
-			// Need to clean up/refactory some of this stuff
-			i.getParentOrCurrentFrame().removeItem(i);
-			i.setParent(null);
-		}
-	}
-
-	private static boolean inWindow = false;
-	/**
-	 * event called when mouse exits window
-	 * (can't use MouseListener callback since that callback doesn't
-	 *  correctly receive all mouse exit events) 
-	 */
-	public static void mouseExitedWindow(MouseEvent e) {
-		inWindow = false;
-		// System.out.println("Left window");
-		if(FreeItems.itemsAttachedToCursor()) {
-			boolean cut = true;
-			for(Item i : FreeItems.getInstance()) {
-				for(Item j : i.getAllConnected()) {
-					if(!FreeItems.getInstance().contains(j)) {
-						cut = false;
-						break;
-					}
-				}
-			}
-			if(cut) {
-				ItemSelection.cut();
-			}
-		}
-	}
-	
-	public void mouseEntered(MouseEvent e) {
-		// check if we are entering the window from outside of the window, or if we were just over a widget
-		if(!inWindow) {
-			inWindow = true;
-			// if there is expeditee data on the clipboard that has not yet been autoPasted, autoPaste it
-    		Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
-    		Transferable content = c.getContents(null);
-    		try {
-    			if(content.isDataFlavorSupported(ItemSelection.expDataFlavor)) {	// Expeditee data
-    				ExpDataHandler expData = (ExpDataHandler)content.getTransferData(ItemSelection.expDataFlavor);
-    				if(expData.autoPaste) {
-        				List<Item> items = new ExpClipReader(FrameMouseActions.getX(), FrameMouseActions.getY()).read(expData.items);
-       					// generate new IDs and pickup
-       					FrameMouseActions.pickup(ItemUtils.CopyItems(items));
-       					// update the clipboard contents so they won't be autoPasted again
-       					expData.autoPaste = false;
-       					String stringData = "";
-       					Image imageData = null;
-       					if(content.isDataFlavorSupported(DataFlavor.stringFlavor)) {
-       						stringData = (String) content.getTransferData(DataFlavor.stringFlavor);
-       					}
-       					if(content.isDataFlavorSupported(DataFlavor.imageFlavor)) {
-       						imageData = (Image) content.getTransferData(DataFlavor.imageFlavor);
-       					}
-          				c.setContents(new ItemSelection(stringData, imageData, expData), null);
-    				}
-    			}
-    		} catch(Exception ex) {
-    			ex.printStackTrace(); 
-    		}
-		}
-	}
-
-	public void mouseExited(MouseEvent e) {
-	}
+//	public void mouseExited(MouseEvent e) {
+//	}
 
 	private boolean _overFrame;
 	private int panStartX, panStartY;
 	private boolean _isPanOp;
+	
 	public void mouseDragged(MouseEvent e) {
 		_lastMouseDragged = e;
@@ -1998,7 +1716,7 @@
 		// Stop the longDepress mouse timer if the user drags above a threshold
 		if (_MouseTimer.isRunning()) {
-			if (Math.abs(e.getX() - _lastMouseClick.getX())
-					+ Math.abs(e.getY() - _lastMouseClick.getY()) > 10)
+			if (Math.abs(e.getX() - _lastMouseClick.getX()) + Math.abs(e.getY() - _lastMouseClick.getY()) > 10) {
 				_MouseTimer.stop();
+			}
 		}
 
@@ -2007,8 +1725,5 @@
 		}
 
-		/*
-		 * Have the free items follow the cursor if the user clicks in freespace
-		 * then moves.
-		 */
+		// Have the free items follow the cursor if the user clicks in freespace then moves.
 		if (FreeItems.getInstance().size() > 0 && _lastClickedOn == null) {
 			mouseMoved(e);
@@ -2017,7 +1732,8 @@
 		
 		// panning the frame when dragging the mouse while shift-leftclicking
-		if(ExperimentalFeatures.MousePan.get() && _overFrame && e.isShiftDown() &&
+/*		if(ExperimentalFeatures.MousePan.get() && _overFrame && e.isShiftDown() &&
 				(e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0 &&
-				(_isPanOp || (Math.max(Math.abs(panStartX - e.getX()), Math.abs(panStartY - e.getY())) > 5))) {
+				(_isPanOp || (Math.max(Math.abs(panStartX - e.getX()), Math.abs(panStartY - e.getY())) > 5)))
+		{
 			int dX = (int) (e.getX() - MouseX);
 			int dY = (int) (e.getY() - MouseY);
@@ -2026,5 +1742,5 @@
 			MouseY = e.getY();
 			_isPanOp = true;
-		}
+		}*/
 
 		// check if user is dragging across a text item
@@ -2036,7 +1752,5 @@
 
 			int distance = _lastRanged.getY() - FrameMouseActions.getY();
-			if (distance <= 0)
-				distance = FrameMouseActions.getY() - _lastRanged.getY()
-						- _lastRanged.getBoundsHeight();
+			if (distance <= 0) distance = FrameMouseActions.getY() - _lastRanged.getY() - _lastRanged.getBoundsHeight();
 
 			if (distance > UserSettings.NoOpThreshold.get()) {
@@ -2045,11 +1759,9 @@
 			} else {
 				// update the ranged section
-				_lastRanged.setSelectionEnd(DisplayIO.getMouseX(),
-						FrameMouseActions.getY());
+				_lastRanged.setSelectionEnd(DisplayIO.getMouseX(), DisplayIO.getMouseY());
 				_isNoOp = false;
 			}
 
-			DisplayIO.setTextCursor(_lastRanged, Text.NONE, false, e
-					.isShiftDown(), e.isControlDown(), false);
+			DisplayIO.setTextCursor(_lastRanged, Text.NONE, false, e.isShiftDown(), e.isControlDown(), false);
 			FrameGraphics.Repaint();
 			return;
@@ -2058,6 +1770,5 @@
 		// if the user is dragging across a picture
 		if (_lastCropped != null) {
-			// If shift is down then the distance moved is the same in the x and
-			// y
+			// If shift is down then the distance moved is the same in the x and y
 			MouseX = e.getX();
 			MouseY = e.getY();
@@ -2067,14 +1778,11 @@
 				int deltaY = Math.abs(e.getY() - _lastMouseClick.getY());
 				if (deltaX > deltaY) {
-					MouseY = _lastMouseClick.getY() + deltaX
-							* (e.getY() > _lastMouseClick.getY() ? 1 : -1);
+					MouseY = _lastMouseClick.getY() + deltaX * (e.getY() > _lastMouseClick.getY() ? 1 : -1);
 				} else {
-					MouseX = _lastMouseClick.getX() + deltaY
-							* (e.getX() > _lastMouseClick.getX() ? 1 : -1);
+					MouseX = _lastMouseClick.getX() + deltaY * (e.getX() > _lastMouseClick.getX() ? 1 : -1);
 				}
 			}
 			// update the ranged section
-			_lastCropped.setEndCrop(DisplayIO.getMouseX(), FrameMouseActions
-					.getY());
+			_lastCropped.setEndCrop(DisplayIO.getMouseX(), DisplayIO.getMouseY());
 
 			FrameGraphics.Repaint();
@@ -2082,12 +1790,11 @@
 		}
 
-		/*
-		 * This is the context of a user clicking in freespace an dragging onto
-		 * the edge of a line
-		 */
-		if ((_mouseDown == MouseEvent.BUTTON2 || _mouseDown == MouseEvent.BUTTON3)
-				&& _lastClickedOn == null && _lastClickedIn == null) {
-			Item on = FrameUtils.onItem(DisplayIO.getCurrentFrame(), e.getX(),
-					e.getY(), true);
+		// This is the context of a user clicking in freespace an dragging onto
+		// the edge of a line
+		if (	(_mouseDown == MouseEvent.BUTTON2 || _mouseDown == MouseEvent.BUTTON3) &&
+				_lastClickedOn == null &&
+				_lastClickedIn == null)
+		{
+			Item on = FrameUtils.onItem(DisplayIO.getCurrentFrame(), e.getX(), e.getY(), true);
 
 			if (FreeItems.getInstance().size() == 0) {
@@ -2101,6 +1808,5 @@
 					on.setHighlightMode(Item.HighlightMode.Normal);
 				} else if (_lastHighlightedItem != null) {
-					_lastHighlightedItem
-							.setHighlightMode(Item.HighlightMode.None);
+					_lastHighlightedItem.setHighlightMode(Item.HighlightMode.None);
 					_lastHighlightedItem = null;
 				}
@@ -2110,29 +1816,14 @@
 		// Use the below calculation for better speed. If it causes problems
 		// switch back to the Euclidean distance calculation
-		if (Math.abs(MouseX - e.getX()) > UserSettings.NoOpThreshold.get()
-				|| Math.abs(MouseY - e.getY()) > UserSettings.NoOpThreshold.get())
+		if (	Math.abs(MouseX - e.getX()) > UserSettings.NoOpThreshold.get() ||
+				Math.abs(MouseY - e.getY()) > UserSettings.NoOpThreshold.get())
+		{
 			_isNoOp = true;
-
+		}
+		
 		FrameGraphics.Repaint();
 	}
 
 	private static MouseEvent _lastMouseMoved = null;
-
-	private static Integer LastRobotX = null;
-
-	private static Integer LastRobotY = null;
-
-	// For some reason... sometimes the mouse move gets lost when moving the
-	// mouse really quickly after clicking...
-	// Use this timer to make sure it gets reset eventually if the Robot
-	// generated event never arrives.
-	private static Timer _RobotTimer = new Timer(200, new ActionListener() {
-		public void actionPerformed(ActionEvent ae) {
-			_RobotTimer.stop();
-			LastRobotX = null;
-			LastRobotY = null;
-			// System.out.println("RobotTimer");
-		}
-	});
 
 	private static Timer _autoStampTimer = new Timer(200, new ActionListener() {
@@ -2152,28 +1843,4 @@
 	}
 
-	public static boolean isControlDown() {
-		return _controlDown;
-	}
-
-	public static boolean isShiftDown() {
-		return _shiftDown;
-	}
-
-	public static void setLastRobotMove(float x, float y) {
-		// Make sure the system is in the right state while waiting for the
-		// Robots event to arrive.
-		MouseX = x;
-		MouseY = y;
-		// System.out.println("MouseMoved: " + MouseX + "," + MouseY + " " +
-		// System.currentTimeMillis());
-		LastRobotX = Math.round(x);
-		LastRobotY = Math.round(y);
-		_RobotTimer.start();
-	}
-
-	public static boolean isWaitingForRobot() {
-		return LastRobotX != null;
-	}
-
 	/**
 	 * Updates the stored mouse position and highlights any items as necessary.
@@ -2183,1362 +1850,14 @@
 	}
 
-	private void mouseMoved(MouseEvent e, boolean shiftStateChanged) {
-		// System.out.println("mouseMoved");
-		// System.out.println(_context);
-		if (_context == CONTEXT_FREESPACE)
-			FrameKeyboardActions.resetEnclosedItems();
-		// System.out.println(e.getX() + "," + e.getY() + " " + e.getWhen());
-		if (LastRobotX != null) {
-			// Wait until the last Robot mouse move event arrives before
-			// processing other events
-			if (/* FreeItems.getInstance().size() == 0 || */
-			(LastRobotX == e.getX() && LastRobotY == e.getY())) {
-				LastRobotX = null;
-				LastRobotY = null;
-				_RobotTimer.stop();
-			} else {
-				// System.out.println("Ignored: " +
-				// FreeItems.getInstance().size());
-				return;
-			}
-		}
-
-		MouseX = e.getX();
-		MouseY = e.getY();
-		
-		// System.out.println(MouseX + "," + MouseY);
-
-		// Moving the mouse a certain distance removes the last edited text if
-		// it is empty
-		Text lastEdited = FrameUtils.getLastEdited();
-		if (lastEdited != null && lastEdited.getText().length() == 0
-				&& lastEdited.getPosition().distance(e.getPoint()) > 20) {
-			FrameUtils.setLastEdited(null);
-		}
-
-		// If shift is down then the movement is constrained
-		if (_controlDown && FreeItems.getInstance().size() > 0) {
-			// Check if we are rubber banding a line
-			if (shiftStateChanged && rubberBanding()) {
-				// Get the line end that is being rubber banded
-				Item thisEnd = FreeItems.getInstance().get(0).isLineEnd() ? FreeItems
-						.getInstance().get(0)
-						: FreeItems.getInstance().get(1);
-				Line line = (Line) (FreeItems.getInstance().get(0).isLineEnd() ? FreeItems
-						.getInstance().get(1)
-						: FreeItems.getInstance().get(0));
-				Item otherEnd = line.getOppositeEnd(thisEnd);
-				int deltaX = Math.abs(e.getX() - otherEnd.getX());
-				int deltaY = Math.abs(e.getY() - otherEnd.getY());
-				// Check if its a vertical line
-				if (deltaX < deltaY / 2) {
-					// otherEnd.setX(thisEnd.getX());
-					// MouseX = otherEnd.getX();
-					if (shiftStateChanged) {
-						new Constraint(thisEnd, otherEnd, thisEnd
-								.getParentOrCurrentFrame().getNextItemID(),
-								Constraint.VERTICAL);
-					}
-				}
-				// Check if its horizontal
-				else if (deltaY <= deltaX / 2) {
-					// MouseY = otherEnd.getY();
-					// otherEnd.setY(thisEnd.getY());
-					if (shiftStateChanged) {
-						new Constraint(thisEnd, otherEnd, thisEnd
-								.getParentOrCurrentFrame().getNextItemID(),
-								Constraint.HORIZONTAL);
-					}
-				} else {
-					// Add DIAGONAL constraints
-					// if (deltaX > deltaY) {
-					// otherEnd.setY(thisEnd.getY() + deltaX
-					// * (e.getY() < otherEnd.getY() ? 1 : -1));
-					// } else {
-					// otherEnd.setX(thisEnd.getX() + deltaY
-					// * (e.getX() < otherEnd.getX() ? 1 : -1));
-					// }
-					if (shiftStateChanged) {
-						int constraint = Constraint.DIAGONAL_NEG;
-						// Check if the slope is positive
-						if ((thisEnd.getY() - otherEnd.getY())
-								/ (double) (thisEnd.getX() - otherEnd.getX()) > 0.0) {
-							constraint = Constraint.DIAGONAL_POS;
-						}
-
-						new Constraint(thisEnd, otherEnd, thisEnd
-								.getParentOrCurrentFrame().getNextItemID(),
-								constraint);
-					}
-				}
-			}// If its a lineend attached to two lines lengthen the shorter
-			// so it is the same length as the longer line
-			else if (FreeItems.getInstance().size() == 3) {
-				// check if we are rubber banding the corner of a shape
-				Item thisEnd = getShapeCorner(FreeItems.getInstance());
-				if (thisEnd != null) {
-					Line line1 = thisEnd.getLines().get(0);
-					Line line2 = thisEnd.getLines().get(1);
-					// Check if the two lines are constrained and hence it is a
-					// rectangle
-					Integer c1 = line1.getPossibleConstraint();
-					Integer c2 = line2.getPossibleConstraint();
-
-					if (c1 != null && c2 != null) {
-						// This is the case of a constrained rectangle
-						if ((c2 == Constraint.VERTICAL || c2 == Constraint.HORIZONTAL)
-								&& (c1 == Constraint.VERTICAL || c1 == Constraint.HORIZONTAL)
-								&& (c1 != c2)) {
-							Line vLine = line2;
-							Line hLine = line1;
-							if (c1 == Constraint.VERTICAL) {
-								vLine = line1;
-								hLine = line2;
-							}
-							Item hOtherEnd = hLine.getOppositeEnd(thisEnd);
-							Item vOtherEnd = vLine.getOppositeEnd(thisEnd);
-
-							double vLength = Math
-									.abs(vOtherEnd.getY() - MouseY);
-							double hLength = Math
-									.abs(hOtherEnd.getX() - MouseX);
-
-							if (vLength > hLength) {
-								MouseX = Math.round(hOtherEnd.getX() + vLength
-										* (MouseX > hOtherEnd.getX() ? 1 : -1));
-							} else /* if (hLength > vLength) */{
-								MouseY = Math.round(vOtherEnd.getY() + hLength
-										* (MouseY > vOtherEnd.getY() ? 1 : -1));
-							}
-						}
-						// } else if (c2 != null) {
-						//
-						// } // Other wise it is a not constrained shape so
-						// constrain
-						// the two lines lengths to be equal
-					} else {
-						Item lineEnd1 = line1.getOppositeEnd(thisEnd);
-						Item lineEnd2 = line2.getOppositeEnd(thisEnd);
-						double l1 = Line.getLength(lineEnd1.getPosition(), e
-								.getPoint());
-						double l2 = Line.getLength(lineEnd2.getPosition(), e
-								.getPoint());
-						double l3 = Line.getLength(lineEnd1.getPosition(),
-								lineEnd2.getPosition());
-						// l1 needs to be the shorter end
-						if (l1 > l2) {
-							Item temp = lineEnd1;
-							lineEnd1 = lineEnd2;
-							lineEnd2 = temp;
-							double tempL = l1;
-							l1 = l2;
-							l2 = tempL;
-						}
-						// Now use the cosine rule to calculate the angle
-						// between l1 and l3
-						double cosTheta = (l1 * l1 + l3 * l3 - l2 * l2)
-								/ (2 * l1 * l3);
-						// now calculate the new length for the lines using cos
-						// rule
-						double l_new = l3 / (2 * cosTheta);
-						double ratio = l_new / l1;
-						MouseX = Math.round((e.getX() - lineEnd1.getX())
-								* ratio)
-								+ lineEnd1.getX();
-						MouseY = Math.round((e.getY() - lineEnd1.getY())
-								* ratio)
-								+ lineEnd1.getY();
-
-					}
-				}
-			}
-		} else if (shiftStateChanged && !_controlDown && rubberBanding()) {
-			// Get the line end that is being rubber banded
-			Item thisEnd = FreeItems.getInstance().get(0).isLineEnd() ? FreeItems
-					.getInstance().get(0)
-					: FreeItems.getInstance().get(1);
-			thisEnd.removeAllConstraints();
-		}
-
-		if (_lastMouseMoved == null)
-			_lastMouseMoved = e;
-
-		_lastMouseMoved = e;
-
-		refreshHighlights();
-
-		if (FreeItems.hasCursor()) {
-			move(FreeItems.getCursor(), true);
-		}
-
-		if (FreeItems.itemsAttachedToCursor()) {
-			move(FreeItems.getInstance());
-			// System.out.println(FreeItems.getInstance().size());
-		}
-
-		if (_forceArrowCursor)
-			updateCursor();
-
-		_forceArrowCursor = true;
-	}
-
 	
-	public void refreshHighlights() {
-		// ByMike: Get the item the mouse is hovering over
-		Item click = FrameUtils.getCurrentItem();
-		Item on = null;
-		// System.out.println(click);
-		if (click != null) {
-			on = click;
-			// set the context
-			if (on instanceof Line)
-				_context = CONTEXT_AT_LINE;
-			else if (on instanceof Dot)
-				_context = CONTEXT_AT_DOT;
-			else if (on instanceof Text) {
-				_context = CONTEXT_AT_TEXT;
-			}
-			if (FreeItems.getInstance().size() > 0)
-				_alpha = 60;
-			else
-				_alpha = -1;
-		} else {
-			_context = CONTEXT_FREESPACE;
-			_alpha = -1;
-		}
-
-		// if the user is pointing at an item, highlight it
-		if (on != null && !FreeItems.getInstance().contains(on)) {
-			// if the user can spot-weld, show the virtual spot
-			if (FreeItems.getInstance().size() == 2 && on instanceof Line) {
-				Line line = (Line) on;
-				Item freeItem0 = FreeItems.getInstance().get(0);
-				Item freeItem1 = FreeItems.getInstance().get(1);
-				Item lineEnd = freeItem0.isLineEnd() ? freeItem0 : (freeItem1
-						.isLineEnd() ? freeItem1 : null);
-				if (lineEnd != null) {
-					if (_mouseDown == 0)
-						line.showVirtualSpot(lineEnd, DisplayIO.getMouseX(),
-								FrameMouseActions.getY());
-				} else
-					// The user is pointing at another point or text item
-					// etc
-					FrameGraphics.changeHighlightMode(on,
-							Item.HighlightMode.Normal);
-			} else {
-				// FrameGraphics.ChangeSelectionMode(on,
-				// Item.SelectedMode.Connected);
-				// TODO: The method below is for the most part redundant				
-				
-				on = FrameGraphics.Highlight(on.getEditTarget());
-			}
-			// if the last item highlighted is still highlighted, clear it
-			if (_lastHoldsHighlight) {
-				_lastHoldsHighlight = false;
-				for (Item i : DisplayIO.getCurrentFrame().getItems())
-					if (i.isHighlighted() && i != on)
-						FrameGraphics.changeHighlightMode(i,
-								Item.HighlightMode.None);
-			}
-
-			// if the user is not pointing at an item, check for enclosure
-			// highlighting
-		} else if (on == null) {
-			Collection<Item> enclosure = FrameUtils.getEnclosingLineEnds();
-			if (enclosure != null && enclosure.size() > 0) {
-				Item firstLineEnd = enclosure.iterator().next();
-				HighlightMode hm;
-				if(isShiftDown()) {
-					hm = HighlightMode.Connected;
-				} else {
-					hm = HighlightMode.Enclosed;
-				}
-				if (firstLineEnd.getLines().size() > 1 &&
-				// check that the enclosure is not part of a point being
-						// dragged in space
-						!ContainsOneOf(enclosure, FreeItems.getInstance())) {
-					on = firstLineEnd.getLines().get(0);
-					// System.out.println(on == null ? "Null" :
-					// on.toString());
-					FrameGraphics.changeHighlightMode(on, hm);
-				} else if (firstLineEnd instanceof XRayable) {
-					on = firstLineEnd;
-					FrameGraphics.changeHighlightMode(firstLineEnd, hm);
-				}
-				_context = CONTEXT_AT_ENCLOSURE;
-			} else if (_lastHighlightedItem != null) {
-				// System.out.println("LastHighlightedItem");
-				_lastHoldsHighlight = false;
-			}
-		}
-
-		// disable cursor changes when the cursor has items attached
-		if (FreeItems.itemsAttachedToCursor()
-				&& DisplayIO.getCursor() != Item.TEXT_CURSOR)
-			_forceArrowCursor = false;
-
-		// setLastHighlightedItem(on);
-
-		if (_lastHighlightedItem != null && _lastHighlightedItem != on
-				&& !_lastHoldsHighlight) {
-			// Turn off the highlighting only if
-			// the last highlighted item is not connected to the currentItem
-			// Otherwise we get flickering in transition from connected to
-			// normal mode while moving the cursor along a line.
-			if (on == null
-					|| (!on.getAllConnected().contains(_lastHighlightedItem))) {
-				FrameGraphics.changeHighlightMode(_lastHighlightedItem,
-						Item.HighlightMode.None);
-			}
-		}
-
-		_lastHighlightedItem = on;
-
-	}
-
-	private boolean ContainsOneOf(Collection<Item> enclosure,
-			Collection<Item> freeItems) {
-		if (freeItems == null)
-			return false;
-		for (Item i : freeItems) {
-			if (enclosure.contains(i))
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Checks if lines are being rubber banded.
-	 * 
-	 * @return true if the user is rubberBanding one or more lines
-	 */
-	private static boolean rubberBanding() {
-		if (FreeItems.getInstance().size() != 2) {
-			return false;
-		}
-
-		// if rubber-banding, there will be 1 lineend and the rest will be lines
-		boolean foundLineEnd = false;
-		for (Item i : FreeItems.getInstance()) {
-			if (i.isLineEnd()) {
-				if (foundLineEnd) {
-					return false;
-				}
-				foundLineEnd = true;
-			} else if (!(i instanceof Line) || !i.isVisible()) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Updates the current mouse cursor to whatever it should be. i.e. Hidden
-	 * when rubber-banding lines, otherwise default (arrow)
-	 */
-	public static void updateCursor() {
-		if (rubberBanding()) {
-			DisplayIO.setCursor(Item.HIDDEN_CURSOR);
-			return;
-		}
-		// This is to make sure the TEXT_CURSOR doesnt get inadvertantly turned
-		// off!
-		Item on = FrameUtils.getCurrentItem();
-		if (on != null && on instanceof Text) {
-			return;
-		}
-		DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-	}
-
-	public static void setHighlightHold(boolean hold) {
-		_lastHoldsHighlight = hold;
-	}
-
-	public static void resetOffset() {
-		if (FreeItems.itemsAttachedToCursor()) {
-			_offX = DisplayIO.getMouseX()
-					- FreeItems.getInstance().get(0).getX()
-					+ FreeItems.getInstance().get(0).getOffset().x;
-			_offY = getY() - FreeItems.getInstance().get(0).getY()
-					+ FreeItems.getInstance().get(0).getOffset().y;
-		}
-	}
-
-	/**
-	 * Moves the items to the current mouse position (plus the current offset)
-	 * 
-	 * @param toMove
-	 */
-	static void move(Collection<Item> toMove) {
-		move(toMove, false);
-	}
-
-	static void move(Collection<Item> toMove, boolean cursor) {
-
-		// Gets the origin of the first item to move
-		int xPos = (DisplayIO.getMouseX() - (cursor ? 0 : _offX));
-
-		Item firstDot = toMove.iterator().next();
-
-		int deltax = firstDot.getX() - xPos;
-		int deltay = firstDot.getY() - (getY() - (cursor ? 0 : _offY));
-
-		for (Item move : toMove) {
-			move.setPosition(move.getX() - deltax, move.getY() - deltay);
-
-			if (!cursor && move instanceof Text) {
-				((Text) move).setAlpha(_alpha);
-			}
-		}
-
-		FrameGraphics.requestRefresh(true);
-		// FrameGraphics.refresh(true);
-	}
-
-	private static void load(String toLoad, boolean addToHistory) {
-		if (FrameIO.isValidFrameName(toLoad)) {
-			DisplayIO.clearBackedUpFrames();
-			FrameUtils.DisplayFrame(toLoad, addToHistory, true);
-		} else {
-			MessageBay.errorMessage(toLoad + " is not a valid frame name.");
-		}
-	}
-
-	private static void back() {
-		DisplayIO.Back();
-
-		// repaint things if necessary
-		if (FreeItems.itemsAttachedToCursor())
-			move(FreeItems.getInstance());
-
-		if (FreeItems.hasCursor())
-			move(FreeItems.getCursor(), true);
-	}
-
-	private static void forward() {
-		DisplayIO.Forward();
-
-		// repaint things if necessary
-		if (FreeItems.itemsAttachedToCursor())
-			move(FreeItems.getInstance());
-
-		if (FreeItems.hasCursor())
-			move(FreeItems.getCursor(), true);
-	}
-
-	/**
-	 * Returns true if the mouse moved during TDFC. This will happen if there is
-	 * a start annotation item on the frame.
-	 * 
-	 * @param linker
-	 * @return
-	 */
-	public static boolean tdfc(Item linker) throws RuntimeException {
-		// if this is a non-usable item
-		if (linker.getID() < 0)
-			return false;
-
-		// Check if its an image that can be resized to fit a box
-		// around it
-		String text = linker.getText();
-		boolean isVector = text.equals("@v") || text.equals("@av");
-		boolean isFrameImage = text.equals("@f");
-		boolean isBitmap = false; // text.equals("@b");
-
-		if (isVector || isFrameImage || isBitmap) {
-			Collection<Item> enclosure = FrameUtils.getEnclosingLineEnds(linker
-					.getPosition());
-			if (enclosure != null) {
-				for (Item i : enclosure) {
-					if (i.isLineEnd() && i.isEnclosed()) {
-						if (!isVector)
-							DisplayIO.getCurrentFrame().removeAllItems(
-									enclosure);
-						Rectangle rect = i.getEnclosedRectangle();
-						long width = Math.round(rect.getWidth());
-						if (isVector) {
-							NumberFormat nf = Vector.getNumberFormatter();
-							linker.setText(linker.getText()
-									+ ": "
-									+ nf.format((width / FrameGraphics
-											.getMaxFrameSize().getWidth())));
-						} else {
-							linker.setText(linker.getText() + ": " + width);
-						}
-
-						linker.setPosition(new Point(rect.x, rect.y));
-						linker.setThickness(i.getThickness());
-						linker.setBorderColor(i.getColor());
-						break;
-					}
-				}
-				if (!isVector)
-					FrameMouseActions.deleteItems(enclosure, false);
-			}
-		}
-
-		boolean mouseMoved;
-
-		linker.getParent().setChanged(true);
-
-		Frame next = FrameIO.CreateNewFrame(linker, _onFrameAction);
-
-		linker.setLink("" + next.getNumber());
-
-		for (Item i : next.getTextItems()) {
-			// Set the link for @Parent annotation item if one
-			if (ItemUtils.startsWithTag(i, ItemUtils.TAG_PARENT)
-					&& i.getLink() == null) {
-				Frame parent = linker.getParentOrCurrentFrame();
-				i.setLink(parent.getName());
-			} else if (ItemUtils.startsWithTag(i, ItemUtils.TAG_BACKUP, false)) {
-				// Delink backup tag if it is on the frame
-				i.setLink(null);
-			}
-		}
-
-		FrameUtils.DisplayFrame(next, true, true);
-		FrameUtils.setTdfcItem(linker);
-
-		mouseMoved = next.moveMouseToDefaultLocation();
-		// this needs to be done if the user doesnt move the mouse before doing
-		// tdfc while the cursor is set to the text cursor
-		DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-		// This needs to be done in case there was a @start on the frame which
-		// triggers changed to be set to true when it should stay as false
-		next.setChanged(false);
-		return mouseMoved;
-	}
-
-	/**
-	 * Creates a new Text item and fills it with particular attributes extracted
-	 * from the given Item. Note: Users always have permission to extract
-	 * attributes, so it is not checked.
-	 * 
-	 * @param toExtract
-	 *            Item containing the Item to extract the attributes from.
-	 */
-	private static void extractAttributes(Item toExtract) {
-		if (toExtract == null || toExtract == null)
-			return;
-
-		if (FreeItems.itemsAttachedToCursor())
-			return;
-
-		Item attribs;
-		Item item = toExtract;
-		// Extract the frames attributes when the user clicks on the frame name
-		FrameGraphics.changeHighlightMode(item, HighlightMode.None);
-		if (item.isFrameName())
-			attribs = AttributeUtils.extractAttributes(item.getParent());
-		else {
-			attribs = AttributeUtils.extractAttributes(item);
-		}
-
-		if (attribs == null)
-			MessageBay
-					.displayMessage("All attributes of that item are default values.");
-		else {
-			// Give the attribute text item the color of the item for which
-			// attributes are being extracted.
-			// attribs.setColor(item.getColor());
-			pickup(attribs);
-		}
-	}
-
-	public static void delete(Item toDelete) {
-		boolean bRecalculate = false;
-
-		FrameUtils.setLastEdited(null);
-		_offX = _offY = 0;
-
-		Frame currentFrame = DisplayIO.getCurrentFrame();
-		// check if the user is pointing at the frame's framename
-		if (toDelete != null && toDelete == currentFrame.getNameItem()) {
-			currentFrame.clear(false);
-			FrameGraphics.Repaint();
-			return;
-		}
-
-		// if the user is deleting items attached to the cursor
-		if (FreeItems.itemsAttachedToCursor()) {
-			// if this is an item-swap
-			if (FreeItems.getInstance().size() == 1
-					&& FreeItems.getInstance().get(0) instanceof Text
-					&& toDelete != null && toDelete instanceof Text) {
-
-				// check permissions
-				if (!toDelete.hasPermission(UserAppliedPermission.full)) {
-					MessageBay
-							.displayMessage("Insufficient permission to swap Item text");
-					return;
-				}
-				Text anchored = (Text) toDelete;
-				Text free = (Text) FreeItems.getInstance().get(0);
-				SessionStats.DeletedItem(free);
-				// List<String> temp = anchored.getText();
-				anchored.setText(free.getText());
-				anchored.setFormula(free.getFormula());
-
-				// free.setTextList(temp);
-				FreeItems.getInstance().clear();
-
-				anchored.getParent().setChanged(true);
-
-				bRecalculate |= free.recalculateWhenChanged();
-				bRecalculate |= anchored.recalculateWhenChanged();
-
-				// update the offset since the text has changed
-				_offX = DisplayIO.getMouseX() - anchored.getX()
-						+ anchored.getOffset().x;
-				_offY = getY() - anchored.getY() + anchored.getOffset().y;
-			} else {
-				// if shift is pressed delete the entire shape attached to the dot
-				if(isShiftDown()) {
-    				List<Item> tmp = new ArrayList<Item>(FreeItems.getInstance());
-    				for(Item i : tmp) {
-    					// remove entire rectangles instead of just the corner
-    					if(i instanceof Dot) {
-    						FreeItems.getInstance().addAll(i.getAllConnected());
-    						for(Item j : i.getAllConnected()) {
-    							if(j instanceof Dot) {
-    								FreeItems.getInstance().addAll(j.getLines());
-    							}
-    						}
-    					}
-    				}
-				}
-				deleteItems(FreeItems.getInstance());
-			}
-			// reset the mouse cursor
-			updateCursor();
-			// the user is not pointing at an item
-		} else if (toDelete == null) {
-		
-			// if the user is pointing inside a closed shape, delete it
-			
-			Collection<Item> items = null;
-			// if shift is down, only delete the enclosing shape (ignore the items inside)
-			if(isShiftDown()) {
-				Collection<Item> tmp = FrameUtils.getEnclosingLineEnds();
-				if(tmp != null) {
-					items = new ArrayList<Item>();
-					items.addAll(tmp);
-    				for(Item i : tmp) {
-    					if(i instanceof Dot) {
-    						items.addAll(((Dot)i).getLines());
-    					}
-    				}
-				}
-			} else {
-				items = FrameUtils.getCurrentItems(null);
-			}
-			
-			if (items != null) {
-				Collection<Item> toRemove = new LinkedHashSet<Item>(items
-						.size());
-				for (Item ip : items) {
-					if (ip.hasPermission(UserAppliedPermission.full)) {
-						// Only include lines if one of their enpoints are also
-						// being removed
-						if (ip instanceof Line) {
-							Line l = (Line) ip;
-							Item end = l.getEndItem();
-							Item start = l.getStartItem();
-
-							// If one end of a line is being deleted, remove the
-							// other end if all its connecting lines are being
-							// deleted
-							if (items.contains(end)) {
-								if (!items.contains(start)
-										&& items.containsAll(start.getLines())) {
-									toRemove.add(start);
-								}
-							} else if (items.contains(start)) {
-								if (items.containsAll(end.getLines())) {
-									toRemove.add(end);
-								}
-							} else {
-								continue;
-							}
-						}
-						toRemove.add(ip);
-					}
-				}
-
-				deleteItems(toRemove);
-
-				// reset the mouse cursor
-				updateCursor();
-				FrameGraphics.Repaint();
-
-				// otherwise this is an undo command
-			} else {
-				if(isControlDown()) {
-					DisplayIO.getCurrentFrame().redo();
-				} else {
-					DisplayIO.getCurrentFrame().undo();
-				}
-			}
-			return;
-			// this is a delete command
-		} else {
-			
-			// Special case if toDelete item is an image: only want to delete if over non-background pixel color
-			if (toDelete instanceof Picture) {
-				int mouseX = DisplayIO.getMouseX();
-				int mouseY = FrameMouseActions.getY();
-				Picture clickedOnPicture = (Picture)toDelete;
-				Frame current_frame = DisplayIO.getCurrentFrame();
-				Color bg_col = current_frame.getBackgroundColor();
-				if (clickedOnPicture.MouseOverBackgroundPixel(mouseX,mouseY,bg_col)) {
-					// behave as if Redo/Undo request, then return
-					if(isControlDown()) {
-						DisplayIO.getCurrentFrame().redo();
-					} else {
-						DisplayIO.getCurrentFrame().undo();
-					}
-					return;
-				}
-				// If get to here, then user clicked on an image (non-trival pixel color),
-				// so go ahead and let it be deleted in the usual way
-			}
-				
-			
-			// check permissions
-			if (!toDelete.hasPermission(UserAppliedPermission.full)) {
-				Item editTarget = toDelete.getEditTarget();
-				if (editTarget != toDelete
-						&& editTarget.hasPermission(UserAppliedPermission.full)) {
-					toDelete = editTarget;
-				} else {
-					MessageBay
-							.displayMessage("Insufficient permission to delete item");
-					return;
-				}
-			}
-
-			Frame parent = toDelete.getParent();
-			if (parent != null) {
-				parent.setChanged(true);
-			}
-			Collection<Item> toUndo = null;
-			if (toDelete.isLineEnd()) {
-				// delete the entire connected shape if shift is down
-				if(isShiftDown()) {
-					List<Item> tmp = new ArrayList<Item>();
-					tmp.add(toDelete);
-					// remove entire shape instead of just the corner
-					tmp.addAll(toDelete.getAllConnected());
-					for(Item j : toDelete.getAllConnected()) {
-						if(j instanceof Dot) {
-							tmp.addAll(j.getLines());
-						}
-					}
-					deleteItems(tmp);
-					return;
-				} else {
-					toUndo = deleteLineEnd(toDelete);
-				}
-				// delete the entire connected shape if shift is down, unless we're hovering the end of the line
-			} else if (toDelete instanceof WidgetEdge) { // must notify
-				// widgets that they
-				// are being deleted
-				((WidgetEdge) toDelete).getWidgetSource().onDelete();
-				toUndo = toDelete.getConnected();
-			} else if (toDelete instanceof Line && isShiftDown() ||
-					toDelete.getHighlightMode() == Item.HighlightMode.Disconnect) {
-				Line line = (Line) toDelete;
-				Item start = line.getStartItem();
-				Item end = line.getEndItem();
-				Collection<Item> delete = new LinkedList<Item>();
-				delete.add(toDelete);
-				if (end.getLines().size() == 1) {
-					delete.add(end);
-				} else {
-					end.removeLine(line);
-				}
-				if (start.getLines().size() == 1) {
-					delete.add(start);
-				} else {
-					start.removeLine(line);
-				}
-				toUndo = delete;
-			} else {
-				bRecalculate |= toDelete.recalculateWhenChanged();
-				toUndo = toDelete.getConnected(); // copy(toDelete.getConnected());
-			}
-			SessionStats.DeletedItems(toUndo);
-			if (parent != null) {
-				parent.addToUndoDelete(toUndo);
-				parent.removeAllItems(toUndo); // toDelete.getConnected()
-			}
-			// reset the mouse cursor
-			updateCursor();
-			if (parent != null)
-				// ItemUtils.EnclosedCheck(parent.getItems());
-				ItemUtils.Justify(parent);
-			if (toDelete.hasOverlay()) {
-				FrameUtils.Parse(parent, false, false);
-				FrameGraphics.requestRefresh(false);
-			}
-
-			DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-
-		}
-
-		currentFrame.notifyObservers(bRecalculate);
-
-		FrameGraphics.Repaint();
-	}
-
-	public static void deleteItems(Collection<Item> itemList) {
-		deleteItems(itemList, true);
-	}
-
-	public static void deleteItems(Collection<Item> itemList, boolean addToUndo) {
-		boolean bReparse = false;
-		boolean bRecalculate = false;
-
-		SessionStats.DeletedItems(itemList);
-		List<Frame> modifiedFrames = new LinkedList<Frame>();
-		// Get a list of all the modified frames
-		for (Item i : itemList) {
-			Frame parent = i.getParent();
-			if (parent != null)
-				modifiedFrames.add(parent);
-			i.setHighlightMode(HighlightMode.None);
-			bReparse |= i.hasOverlay();
-			bRecalculate |= i.recalculateWhenChanged();
-		}
-		// If they are all free items then add the current frame
-		if (modifiedFrames.size() == 0) {
-			modifiedFrames.add(DisplayIO.getCurrentFrame());
-		}
-
-		Collection<Item> toUndo = new LinkedHashSet<Item>();
-		// disconnect any connected items
-		for (Item i : itemList) {
-
-			// Only delete the current item if have not already deleted.
-			// This is especially important for heavy duty widgets - so they
-			// do not have to expire several times per delete.
-			if (toUndo.contains(i))
-				continue;
-
-			// Make sure text items attached to cursor are reset back to the
-			// transparency they should have.
-			if (i instanceof Text) {
-				((Text) i).setAlpha(-1);
-			}
-
-			if (i.getLines().size() > 0) {
-
-				Collection<Item> toDelete = deleteLineEnd(i);
-				if (addToUndo) {
-					// add the copied items to the undo stack
-					for (Item itemToUndo : toDelete) {
-
-						if (!toUndo.contains(itemToUndo))
-							toUndo.add(itemToUndo);
-
-					}
-				}
-			} else if (!toUndo.contains(i)) {
-				if (addToUndo)
-					toUndo.add(i); // Why was is this a copy
-			}
-		}
-
-		for (Frame f : modifiedFrames) {
-			f.removeAllItems(itemList);
-			// ItemUtils.EnclosedCheck(f.getItems());
-			ItemUtils.Justify(f);
-		}
-		// TODO: How should undelete deal with undo when items are removed from
-		// the current frame as well as the overlay frame
-		Frame currentFrame = DisplayIO.getCurrentFrame();
-		currentFrame.addToUndoDelete(itemList);
-		itemList.clear();
-		if (bReparse) {
-			FrameUtils.Parse(currentFrame, false, false);
-			/*
-			 * TODO check if I need to recalculate even if reparse occurs, here
-			 * and in anchor, pickup etc
-			 */
-		} else {
-			currentFrame.notifyObservers(bRecalculate);
-		}
-
-	}
-
-	private static Collection<Item> deleteLineEnd(Item lineEnd) {
-
-		if (lineEnd instanceof WidgetCorner) { // Brook
-
-			WidgetCorner wc = (WidgetCorner) lineEnd;
-			Frame parent = wc.getWidgetSource().getParentFrame();
-
-			// Remove from the parent frame
-			if (parent != null) {
-				parent.removeAllItems(wc.getWidgetSource().getItems());
-			}
-
-			wc.getWidgetSource().onDelete(); // Changes the widgets
-			// corner/edges ID's...
-
-			return wc.getWidgetSource().getItems();
-
-		} else {
-
-			// // create a backup copy of the dot and its lines
-			// List<Item> copy = copy(lineEnd.getConnected());
-			//			
-			// // Remove lines from their anchored dots
-			// // note: the line is kept so that it can be properly restored
-			// for (Item ic : copy) {
-			// if (ic instanceof Line) {
-			// Line line = (Line) ic;
-			// // Remove the line from the item that is not the copy of the
-			// // line end being deletedF
-			// if (!copy.contains(line.getStartItem()))
-			// line.getStartItem().removeLine(line);
-			// if (!copy.contains(line.getEndItem()))
-			// line.getEndItem().removeLine(line);
-			// }
-			// }
-
-			Collection<Item> copy = lineEnd.getConnected();
-
-			// remove all lines being deleted
-			for (Item ic : lineEnd.getConnected()) {
-				if (ic instanceof Line
-						&& ((Line) ic).getOppositeEnd(lineEnd) != null) {
-					Line line = (Line) ic;
-
-					// Invalidate the line to make sure we dont get any ghost
-					// arrowheads.
-					ic.invalidateAll();
-
-					Item d = line.getOppositeEnd(lineEnd);
-					d.removeLine(line);
-
-					// if the dot was only part of one line, it can be
-					// removed
-					if (d.getLines().size() == 0) {
-						if (d.getParent() != null)
-							d.getParent().removeItem(d);
-						if (!copy.contains(d))
-							copy.add(d);
-					}
-
-					if (lineEnd.getParent() != null)
-						lineEnd.getParent().removeItem(ic);
-				}
-			}
-			return copy;
-		}
-	}
-
-	private static void removeAllLinesExcept(Item from, Item but) {
-		List<Line> lines = new LinkedList<Line>();
-		lines.addAll(from.getLines());
-		for (Line line : lines)
-			if (line.getOppositeEnd(from) != but)
-				from.removeLine(line);
-
-		List<Constraint> consts = new LinkedList<Constraint>();
-		consts.addAll(from.getConstraints());
-		for (Constraint c : consts)
-			if (c.getOppositeEnd(from) != but)
-				from.removeConstraint(c);
-	}
-
-	public static Collection<Item> merge(List<Item> merger, Item mergee) {
-		assert (mergee != null);
-		if (mergee.isFrameName()) {
-			return mergee.getParent().merge(merger);
-		}
-
-		// if(mergee instanceof XRayable)
-		// return merger;
-
-		// check for rectangle merging
-		if (merger.size() == 3 && mergee.getLines().size() == 2) {
-			Item corner = getShapeCorner(merger);
-			// if this is a corner of a shape
-			if (corner != null) {
-				Collection<Item> allConnected = corner.getAllConnected();
-				// Check if we are collapsing a rectangle
-				if (allConnected.size() == 8 && allConnected.contains(mergee)) {
-					DisplayIO.setCursorPosition(mergee.getPosition());
-					DisplayIO.getCurrentFrame().removeAllItems(allConnected);
-
-					// find the point opposite corner...
-					Item opposite = null;
-					List<Line> lines = corner.getLines();
-					for (Line l : lines) {
-						allConnected.remove(l.getOppositeEnd(corner));
-					}
-					allConnected.remove(corner);
-					for (Item i : allConnected) {
-						if (i.isLineEnd()) {
-							opposite = i;
-							break;
-						}
-					}
-					assert (opposite != null);
-
-					// check if the rectangle is small enough that it should be
-					// collapsed to a single point
-					int x1 = Math.abs(opposite.getX() - mergee.getX());
-					int x2 = Math.abs(opposite.getY() - mergee.getY());
-					int distance = (int) Math.sqrt(Math.pow(x1, 2)
-							+ Math.pow(x2, 2));
-
-					if (distance < RECTANGLE_TO_POINT_THRESHOLD) {
-						mergee.removeAllConstraints();
-						mergee.removeAllLines();
-						mergee.setThickness(4 * mergee.getThickness());
-						return mergee.getAllConnected();
-					} else {
-						removeAllLinesExcept(mergee, opposite);
-						removeAllLinesExcept(opposite, mergee);
-
-						return mergee.getAllConnected();
-					}
-				}
-			}
-		}
-
-		List<Item> remain = new ArrayList<Item>();
-		Item res = null;
-
-		for (Item i : merger) {			
-			if (!i.isVisible())
-				continue;
-			// check for link merging
-			if (i instanceof Text
-					&& FrameIO.isValidFrameName((((Text) i).getFirstLine()))
-					&& FrameIO.canAccessFrame((((Text) i).getFirstLine()))) {
-				// check that we can actually access the frame this link
-				// corresponds to
-				mergee.setLink(((Text) i).getFirstLine());
-			} else {
-				// check for attribute merging
-				if (i instanceof Text && !i.isLineEnd()) {
-					Text txt = (Text) i;
-
-					// if this is not an attribute merge
-					if (!AttributeUtils.setAttribute(mergee, txt)) {
-						// set mouse position for text merges
-						if (mergee instanceof Text) {
-							((Text) mergee).insertText(txt.getText(), DisplayIO
-									.getMouseX(), FrameMouseActions.getY());
-							//Delete the item which had its text merged
-							txt.delete();
-							return remain;
-						} else if (mergee instanceof WidgetCorner) {
-							if (merger.size() == 1 && txt.getLink() != null) {
-								// If the text item is linked then use that
-								((WidgetCorner) mergee).setLink(txt
-										.getAbsoluteLink(), txt);
-							} else {
-								remain.addAll(merger);
-							}
-							return remain;
-						} else if (mergee instanceof WidgetEdge) {
-							if (merger.size() == 1 && txt.getLink() != null) {
-								// If the text item is linked then use that
-								((WidgetEdge) mergee).setLink(txt
-										.getAbsoluteLink(), txt);
-							} else {
-								remain.addAll(merger);
-							}
-							return remain;
-						} else if (mergee instanceof Dot) {
-							DisplayIO.setCursorPosition(mergee.getPosition());
-							txt.setPosition(mergee.getPosition());
-							txt.setThickness(mergee.getThickness());
-							Frame parent = mergee.getParent();
-							parent.removeItem(mergee);
-							anchor(txt);
-							// change the end points of the lines to the text
-							// item
-							while (mergee.getLines().size() > 0) {
-								Line l = mergee.getLines().get(0);
-								l.replaceLineEnd(mergee, txt);
-							}
-							break;
-						}
-
-						// TODO tidy this up...
-						// Dot override doesnt use the x and y coords
-						// Text does... but could be removed
-						res = mergee.merge(i, DisplayIO.getMouseX(), getY());
-						if (res != null) {
-							remain.add(res);
-						}
-					}
-				} else {
-					if (mergee.isLineEnd()) {
-						DisplayIO.setCursorPosition(mergee.getPosition());
-					}
-					// Moving the cursor ensures shapes are anchored correctly
-					res = mergee.merge(i, DisplayIO.getMouseX(), getY());
-					if (res != null)
-						remain.addAll(res.getConnected());
-
-				}
-			}
-		}
-		updateCursor();
-
-		mergee.getParent().setChanged(true);
-
-		ItemUtils.EnclosedCheck(mergee.getParent().getItems());
-		// Mike: Why does parse frame have to be called?!?
-		FrameUtils.Parse(mergee.getParent());
-
-		return remain;
-	}
-
-	/**
-	 * Picks up an item on a frame.
-	 * 
-	 * @param toGrab
-	 *            item to be picked up
-	 * @param removeItem
-	 *            true if the item should be removed from the frame
-	 */
-	public static void pickup(Item toGrab) {
-		if (toGrab.isFrameName())
-			return;
-
-		if (!toGrab.hasPermission(UserAppliedPermission.full)) {
-			if (toGrab.getEditTarget() != toGrab) {
-				pickup(toGrab.getEditTarget());
-			} else {
-				MessageBay
-						.displayMessage("Insufficient permission pickup the item");
-			}
-			return;
-		}
-
-		if (toGrab instanceof Circle)
-			toGrab.setHighlightMode(HighlightMode.Connected);
-		// Dont set the highlight mode if a vector is being picked up
-		else if (toGrab.isVisible()) {
-			toGrab.setHighlightMode(HighlightMode.Normal);
-		}
-
-		// Brook: If the widget corner is being picked up. Instead refer to
-		// picking up the edge for fixed-sized widgets so it is not so confusing
-		if (toGrab instanceof WidgetCorner) {
-			WidgetCorner wc = (WidgetCorner) toGrab;
-			if (wc.getWidgetSource().isFixedSize()) {
-				for (Item i : toGrab.getConnected()) {
-					if (i instanceof WidgetEdge) {
-						toGrab = i;
-						break;
-					}
-				}
-			}
-		}
-		pickup(toGrab.getConnected());
-	}
-
-	public static void pickup(Collection<Item> toGrab) {
-		if (toGrab == null || toGrab.size() == 0)
-			return;
-
-		boolean bReparse = false;
-		boolean bRecalculate = false;
-
-		Frame currentFrame = DisplayIO.getCurrentFrame();
-		String currentFrameName = currentFrame.getName();
-		Iterator<Item> iter = toGrab.iterator();
-		while (iter.hasNext()) {
-			Item i = iter.next();
-			if (!i.hasPermission(UserAppliedPermission.full)) {
-				iter.remove();
-				continue;
-			}
-			if (i.equals(_lastHighlightedItem))
-				_lastHighlightedItem = null;
-
-			bRecalculate |= i.recalculateWhenChanged();
-			// i.setSelectedMode(SelectedMode.None);
-			// Check if it has a relative link if so make it absolute
-			i.setAbsoluteLink();
-			// parent may be null
-			if (i.getParent() != null) {
-				i.getParent().removeItem(i);
-				if (currentFrameName.equals(i.getParent().getName()))
-					i.setParent(null);
-			}
-			FreeItems.getInstance().add(i);
-			i.setFloating(true);
-			// If its a vector pick up a copy of the stuff on the vector frame
-			if (i.hasVector()) {
-				bReparse = true;
-
-				Frame overlayFrame = FrameIO.LoadFrame(i.getAbsoluteLink());
-				Collection<Item> copies = ItemUtils.CopyItems(overlayFrame
-						.getNonAnnotationItems(false), i.getVector());
-				for (Item copy : copies) {
-					FreeItems.getInstance().add(copy);
-					copy.setEditTarget(i);
-					copy.setFloating(true);
-					copy.setParent(null);
-					// copy.setHighlightMode(HighlightMode.Connected);
-				}
-			}
-		}
-		currentFrame.change();
-
-		_lastHighlightedItem = null;
-		updateCursor();
-
-		// if there are multiple items in the list, determine which to use for
-		// offset calculations
-		if (toGrab.size() > 1) {
-			for (Item i : toGrab) {
-				// MIKE: Movement goes haywire if these are removed because Line
-				// class returns 0 for getX
-				if (!(i instanceof Line) && !(i instanceof XRayable)) {
-					_offX = DisplayIO.getMouseX() - i.getX() + i.getOffset().x;
-					_offY = getY() - i.getY() + i.getOffset().y;
-
-					// make the offset item the first item in the list (so
-					// move method knows which item to use)
-					FreeItems.getInstance().set(
-							FreeItems.getInstance().indexOf(i),
-							FreeItems.getInstance().get(0));
-					FreeItems.getInstance().set(0, i);
-					break;
-				}
-			}
-
-			move(FreeItems.getInstance());
-			ItemUtils.EnclosedCheck(toGrab);
-			// otherwise, just use the first item
-		} else if (toGrab.size() == 1) {
-			Item soleItem = toGrab.iterator().next();
-			_offX = DisplayIO.getMouseX() - soleItem.getX()
-					+ soleItem.getOffset().x;
-			_offY = getY() - soleItem.getY() + soleItem.getOffset().y;
-			// Now call move so that if we are on a message in the message box
-			// It doesnt appear up the top of the scree!!
-			move(toGrab);
-		} else {
-			MessageBay
-					.displayMessage("Insufficient permission to pickup the items");
-		}
-		if (bReparse)
-			FrameUtils.Parse(currentFrame, false, false);
-		else
-			currentFrame.notifyObservers(bRecalculate);
-
-		FrameGraphics.Repaint();
-	}
-
-	private static Line createLine() {
-		Frame current = DisplayIO.getCurrentFrame();
-		// create the two endpoints
-		Item end = DisplayIO.getCurrentFrame().createDot();
-		Item start = DisplayIO.getCurrentFrame().createDot();
-
-		// create the Line
-		Line line = new Line(start, end, current.getNextItemID());
-		line.autoArrowheadLength();
-
-		// anchor the start
-		anchor(start);
-
-		// attach the line to the cursor
-		pickup(end);
-		_lastHighlightedItem = null;
-
-		// TODO figure out how to get the end to highlight
-		// end.setSelectedMode(SelectedMode.Normal);
-		// end.setSelectedMode(SelectedMode.None);
-
-		return line;
-	}
-
-	/**
-	 * Returns a list of copies of the list passed in
-	 * 
-	 * @param toCopy
-	 *            The list of items to copy
-	 * @return A List of copied Items
-	 */
-	private static List<Item> copy(Collection<Item> toCopy) {
-		return ItemUtils.CopyItems(toCopy);
-	}
-
-	public static void anchor(Item toAnchor, boolean checkEnclosure) {
-		// Only anchor items we have full permission over... i.e. don't anchor vector items
-		if (!toAnchor.hasPermission(UserAppliedPermission.full))
-			return;
-
-		toAnchor.anchor();
-
-		if (checkEnclosure) {
-			ItemUtils.EnclosedCheck(toAnchor.getParentOrCurrentFrame()
-					.getItems());
-			FrameGraphics.Repaint();
-		}
-	}
-
-	public static void anchor(Item toAnchor) {
-		anchor(toAnchor, true);
-	}
-
-	public static void anchor(Collection<Item> toAnchor) {
-		boolean bReparse = false;
-		boolean bRecalculate = false;
-		// Need to make sure we check enclosure for overlays etc
-		Set<Frame> checkEnclosure = new HashSet<Frame>();
-
-		// Create a clone of toAnchor since in the proccess of anchoring items
-		// they can change the state of the toAnchor collection and thus create
-		// concurrent modification exceptions.
-		// This is especially needed for widgets being removed when anchored:
-		// since they
-		// currently are composed of 8 items this is vital. In the new revision
-		// of
-		// widgets being implemented as a single item this this can be
-		// depreciated
-		// however it may be useful for other applications.
-		Collection<Item> toAnchorCopy = new ArrayList<Item>(toAnchor);
-
-		for (Item i : toAnchorCopy) {
-			if (toAnchor.contains(i)) { // since to anchor could change while
-				// anchoring
-				// if (!i.hasVector())
-				anchor(i, false);
-				checkEnclosure.add(i.getParentOrCurrentFrame());
-				bReparse |= i.hasOverlay();
-				bRecalculate |= i.recalculateWhenChanged();
-			}
-		}
-
-		toAnchor.clear();
-		// Check enclosure for all the frames of the items that were anchored
-		for (Frame f : checkEnclosure) {
-			// ItemUtils.EnclosedCheck(f.getItems());
-			ItemUtils.Justify(f);
-		}
-
-		Frame currentFrame = DisplayIO.getCurrentFrame();
-		if (bReparse)
-			FrameUtils.Parse(currentFrame, false, false);
-		else {
-			currentFrame.notifyObservers(bRecalculate);
-		}
-		FrameGraphics.Repaint();
-	}
+
+	
+
+
+	
+
+	
+
+	
 
 	/*
@@ -3554,9 +1873,7 @@
 
 		if (FreeItems.getInstance().size() == 2) {
-			if ((FreeItems.getInstance().get(0).isLineEnd() && FreeItems
-					.getInstance().get(1) instanceof Line)
-					|| (FreeItems.getInstance().get(1).isLineEnd() && FreeItems
-							.getInstance().get(0) instanceof Line)) {
-
+			if ((FreeItems.getInstance().get(0).isLineEnd() && FreeItems.getInstance().get(1) instanceof Line) ||
+					(FreeItems.getInstance().get(1).isLineEnd() && FreeItems.getInstance().get(0) instanceof Line))
+			{
 				Line line;
 				if (FreeItems.getInstance().get(0) instanceof Line)
@@ -3582,6 +1899,5 @@
 			}
 
-			FrameKeyboardActions.functionKey(rotationType, 1, arg0
-					.isShiftDown(), arg0.isControlDown());
+			FrameKeyboardActions.functionKey(rotationType, 1, arg0.isShiftDown(), arg0.isControlDown());
 
 		} else if (clicks >= MOUSE_WHEEL_THRESHOLD) {
@@ -3618,6 +1934,5 @@
 	 */
 	public static int getLastMouseButton() {
-		if (_lastMouseClick == null)
-			return MouseEvent.NOBUTTON;
+		if (_lastMouseClick == null) return MouseEvent.NOBUTTON;
 
 		return _lastMouseClick.getButton();
@@ -3625,19 +1940,15 @@
 
 	public static boolean isDelete(int modifiersEx) {
-
-		int onMask = MouseEvent.BUTTON3_DOWN_MASK
-				| MouseEvent.BUTTON2_DOWN_MASK;
+		int onMask = MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK;
 		return (modifiersEx & onMask) == onMask;
 	}
 
 	public static boolean isGetAttributes(int modifiersEx) {
-		int onMask = MouseEvent.BUTTON3_DOWN_MASK
-				| MouseEvent.BUTTON1_DOWN_MASK;
+		int onMask = MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK;
 		return (modifiersEx & onMask) == onMask;
 	}
 
 	public static boolean isTwoClickNoOp(int modifiersEx) {
-		int onMask = MouseEvent.BUTTON2_DOWN_MASK
-				| MouseEvent.BUTTON1_DOWN_MASK;
+		int onMask = MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK;
 		return (modifiersEx & onMask) == onMask;
 	}
@@ -3705,8 +2016,4 @@
 	}
 
-	public static Item getlastHighlightedItem() {
-		return _lastHighlightedItem;
-	}
-
 	public static Point getPosition() {
 		return new Point(getX(), getY());
@@ -3722,3 +2029,9 @@
 		getInstance().refreshHighlights();
 	}
+
+	@Override
+	public void onGesture(Gesture gesture) {
+		// TODO Auto-generated method stub
+		
+	}
 }
Index: /trunk/src/org/expeditee/gui/FrameUtils.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameUtils.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/FrameUtils.java	(revision 1102)
@@ -19,8 +19,4 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Rectangle;
 import java.io.File;
 import java.io.FileInputStream;
@@ -44,4 +40,10 @@
 import java.util.zip.ZipEntry;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.items.Circle;
 import org.expeditee.items.Dot;
@@ -60,5 +62,5 @@
 import org.expeditee.items.XRayable;
 import org.expeditee.items.widgets.ButtonWidget;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.InteractiveWidgetInitialisationFailedException;
 import org.expeditee.items.widgets.InteractiveWidgetNotAvailableException;
@@ -73,1764 +75,1761 @@
 public class FrameUtils {
 
-    private static final int COLUMN_WIDTH = 50;
-
-    /**
-     * Provides a way to monitor the time elapsed between button-down and the
-     * finished painting.
-     */
-    public static TimeKeeper ResponseTimer = new TimeKeeper();
-
-    private static float _ResponseTimeSum = 0;
-
-    private static float _LastResponse = 0;
-
-    private static Text LastEdited = null;
-
-    public static int MINIMUM_INTERITEM_SPACING = -6;
-
-    public static float getResponseTimeTotal() {
-	return _ResponseTimeSum;
-    }
-
-    public static float getLastResponseTime() {
-	return _LastResponse;
-    }
-
-    /**
-     * The list of known start pages framesets which will have prepopulated
-     * links in the home frame.
-     */
-    public static final String[] startPages = { "exploratorysearch",
-	    "webbrowser" };
-
-    /**
-     * Checks if the given top Item is above the given bottom Item, allowing for
-     * the X coordinates to be off by a certain width...
-     * 
-     * @param item1
-     *            The Item to check is above the other Item
-     * @param item2
-     *            The Item to check is below the top Item
-     * @return True if top is above bottom, False otherwise.
-     */
-    public static boolean inSameColumn(Item item1, Item item2) {
-	if (!(item1 instanceof Text) || !(item2 instanceof Text))
-	    return false;
-
-	if (item1.getID() < 0 || item2.getID() < 0)
-	    return false;
-
-	int minX = item2.getX();
-	int maxX = item2.getX() + item2.getBoundsWidth();
-
-	int startX = item1.getX();
-	int endX = item1.getX() + item1.getBoundsWidth();
-
-	// Check that the two items left values are close
-	if (Math.abs(item1.getX() - item2.getX()) > COLUMN_WIDTH)
-	    return false;
-
-	// Ensure the two items
-	if ((minX >= startX && minX <= endX)
-		|| (maxX >= startX && maxX <= endX)
-		|| (startX >= minX && startX <= maxX)
-		|| (endX >= minX && endX <= maxX))
-	    return true;
-
-	return false;
-    }
-
-    public static boolean sameBulletType(String bullet1, String bullet2) {
-	if (bullet1 == null || bullet2 == null)
-	    return false;
-
-	if (bullet1.equals("") || bullet2.equals(""))
-	    return false;
-
-	if (Character.isLetter(bullet1.charAt(0))
-		&& Character.isLetter(bullet2.charAt(0)))
-	    return true;
-
-	if (Character.isDigit(bullet1.charAt(0))
-		&& Character.isDigit(bullet2.charAt(0)))
-	    return true;
-
-	// TODO make this more sofisticated
-
-	return false;
-    }
-
-    private static boolean needsRenumbering(String s) {
-	if (s == null || s.equals(""))
-	    return false;
-	if (!Character.isLetterOrDigit(s.charAt(0)))
-	    return false;
-
-	s = s.trim();
-	// if its all letters then we dont want to auto adjust
-	if (s.length() > 2) {
-	    for (int i = 0; i < s.length() - 1; i++) {
-		if (!Character.isLetter(s.charAt(i)))
-		    return true;
-	    }
-	} else
-	    return true;
-
-	return false;
-    }
-
-    /**
-     * 
-     * @param toAlign
-     * @param moveAll
-     * @param adjust
-     * @return
-     */
-    public static int Align(List<Text> toAlign, boolean moveAll, int adjust,
-	    List<Item> changedItems) {
-	Collections.sort(toAlign);
-
-	/*
-	 * Single items dont need alignment But if there are two items we may
-	 * still want to format them... ie if they are too close together.
-	 */
-	if (toAlign.size() < 1)
-	    return 0;
-
-	// get the first item
-	Text from = toAlign.get(0);
-	if (from.getParent() == null)
-	    from = toAlign.get(1);
-	int x = from.getX();
-
-	Frame curr = from.getParent();
-	Text above = curr.getTextAbove(from);
-
-	String lastBullet = "";
-
-	if (above != null && curr.isNormalTextItem(above))
-	    lastBullet = FrameKeyboardActions.getAutoBullet(above.getText());
-	else {
-	    lastBullet = FrameKeyboardActions.getBullet(toAlign.get(0)
-		    .getText());
-	}
-	if (needsRenumbering(lastBullet)) {
-	    // renumber...
-	    for (int i = 0; i < toAlign.size(); i++) {
-
-		Text currentText = toAlign.get(i);
-		String currentBullet = FrameKeyboardActions
-			.getAutoBullet(currentText.getText());
-
-		if (sameBulletType(lastBullet, currentBullet)) {
-		    String oldText = currentText.getText();
-
-		    currentText.stripFirstWord();
-
-		    currentText.setText(lastBullet + currentText.getText());
-		    lastBullet = FrameKeyboardActions.getAutoBullet(currentText
-			    .getText());
-
-		    // if we changed the item, add to changedItems list
-		    if (changedItems != null
-			    && oldText != currentText.getText()
-			    && !changedItems.contains(currentText)) {
-			Item copy = currentText.copy();
-			copy.setID(currentText.getID());
-			copy.setText(oldText);
-			changedItems.add(copy);
-		    }
-		}
-	    }
-	}
-
-	// work out the spacing between the first item and the one above it
-
-	int space = 10 + adjust;
-
-	// if we are dropping from the title make the space a little bigger
-	// than normal
-
-	// If there are only two items get the gap from the start item on the
-	// zero frame if there is one
-	if (above == curr.getTitleItem()) {
-	    Frame zero = FrameIO.LoadFrame(curr.getFramesetName() + '0');
-	    String strGap = zero.getAnnotationValue("start");
-	    if (strGap != null) {
+	/**
+	 * The list of known start pages framesets which will have prepopulated
+	 * links in the home frame.
+	 */
+	public static final String[] startPages = { "exploratorysearch", "webbrowser" };
+
+	private static final int COLUMN_WIDTH = 50;
+
+	/**
+	 * Provides a way to monitor the time elapsed between button-down and the
+	 * finished painting.
+	 */
+	public static TimeKeeper ResponseTimer = new TimeKeeper();
+
+	private static float _ResponseTimeSum = 0;
+
+	private static float _LastResponse = 0;
+
+	private static Text LastEdited = null;
+
+	public static int MINIMUM_INTERITEM_SPACING = -6;
+
+	private static Item _tdfcItem = null;
+
+	public static float getResponseTimeTotal()
+	{
+		return _ResponseTimeSum;
+	}
+
+	public static float getLastResponseTime()
+	{
+		return _LastResponse;
+	}
+
+	/**
+	 * Checks if the given top Item is above the given bottom Item, allowing for
+	 * the X coordinates to be off by a certain width...
+	 * 
+	 * @param item1
+	 *            The Item to check is above the other Item
+	 * @param item2
+	 *            The Item to check is below the top Item
+	 * @return True if top is above bottom, False otherwise.
+	 */
+	public static boolean inSameColumn(Item item1, Item item2) {
+		if (!(item1 instanceof Text) || !(item2 instanceof Text))
+			return false;
+
+		if (item1.getID() < 0 || item2.getID() < 0)
+			return false;
+
+		int minX = item2.getX();
+		int maxX = item2.getX() + item2.getBoundsWidth();
+
+		int startX = item1.getX();
+		int endX = item1.getX() + item1.getBoundsWidth();
+
+		// Check that the two items left values are close
+		if (Math.abs(item1.getX() - item2.getX()) > COLUMN_WIDTH)
+			return false;
+
+		// Ensure the two items
+		if ((minX >= startX && minX <= endX)
+				|| (maxX >= startX && maxX <= endX)
+				|| (startX >= minX && startX <= maxX)
+				|| (endX >= minX && endX <= maxX))
+			return true;
+
+		return false;
+	}
+
+	public static boolean sameBulletType(String bullet1, String bullet2)
+	{
+		if (bullet1 == null || bullet2 == null)
+			return false;
+
+		if (bullet1.equals("") || bullet2.equals(""))
+			return false;
+
+		if (Character.isLetter(bullet1.charAt(0))
+				&& Character.isLetter(bullet2.charAt(0)))
+			return true;
+
+		if (Character.isDigit(bullet1.charAt(0))
+				&& Character.isDigit(bullet2.charAt(0)))
+			return true;
+
+		// TODO make this more sofisticated
+
+		return false;
+	}
+
+	private static boolean needsRenumbering(String s) {
+		if (s == null || s.equals(""))
+			return false;
+		if (!Character.isLetterOrDigit(s.charAt(0)))
+			return false;
+
+		s = s.trim();
+		// if its all letters then we dont want to auto adjust
+		if (s.length() > 2) {
+			for (int i = 0; i < s.length() - 1; i++) {
+				if (!Character.isLetter(s.charAt(i)))
+					return true;
+			}
+		} else
+			return true;
+
+		return false;
+	}
+
+	/**
+	 * 
+	 * @param toAlign
+	 * @param moveAll
+	 * @param adjust
+	 * @return
+	 */
+	public static int Align(List<Text> toAlign, boolean moveAll, int adjust,
+			List<Item> changedItems) {
+		Collections.sort(toAlign);
+
+		/*
+		 * Single items dont need alignment But if there are two items we may
+		 * still want to format them... ie if they are too close together.
+		 */
+		if (toAlign.size() < 1)
+			return 0;
+
+		// get the first item
+		Text from = toAlign.get(0);
+		if (from.getParent() == null)
+			from = toAlign.get(1);
+		int x = from.getX();
+
+		Frame curr = from.getParent();
+		Text above = curr.getTextAbove(from);
+
+		String lastBullet = "";
+
+		if (above != null && curr.isNormalTextItem(above))
+			lastBullet = StandardGestureActions.getAutoBullet(above.getText());
+		else {
+			lastBullet = StandardGestureActions.getBullet(toAlign.get(0)
+					.getText());
+		}
+		if (needsRenumbering(lastBullet)) {
+			// renumber...
+			for (int i = 0; i < toAlign.size(); i++) {
+
+				Text currentText = toAlign.get(i);
+				String currentBullet = StandardGestureActions.getAutoBullet(currentText.getText());
+
+				if (sameBulletType(lastBullet, currentBullet)) {
+					String oldText = currentText.getText();
+
+					currentText.stripFirstWord();
+
+					currentText.setText(lastBullet + currentText.getText());
+					lastBullet = StandardGestureActions.getAutoBullet(currentText.getText());
+
+					// if we changed the item, add to changedItems list
+					if (changedItems != null
+							&& oldText != currentText.getText()
+							&& !changedItems.contains(currentText)) {
+						Item copy = currentText.copy();
+						copy.setID(currentText.getID());
+						copy.setText(oldText);
+						changedItems.add(copy);
+					}
+				}
+			}
+		}
+
+		// work out the spacing between the first item and the one above it
+
+		int space = 10 + adjust;
+
+		// if we are dropping from the title make the space a little bigger
+		// than normal
+
+		// If there are only two items get the gap from the start item on the
+		// zero frame if there is one
+		if (above == curr.getTitleItem()) {
+			Frame zero = FrameIO.LoadFrame(curr.getFramesetName() + '0');
+			String strGap = zero.getAnnotationValue("start");
+			if (strGap != null) {
+				try {
+					int gap = Integer.parseInt(strGap);
+					space = gap;
+				} catch (NumberFormatException nfe) {
+
+				}
+			}
+		} else if (above != null) {
+			// Make the gap between all items the same as the gap between
+			// the first two
+			space = (int) (from.getBounds().getMinY() - above.getBounds().getMaxY());
+
+			if (space < MINIMUM_INTERITEM_SPACING)
+				space = MINIMUM_INTERITEM_SPACING;
+
+			if (UserSettings.FormatSpacingMax.get() != null) {
+				double maxSpace = UserSettings.FormatSpacingMax.get()
+						* above.getSize();
+				if (maxSpace < space) {
+					space = (int) Math.round(maxSpace);
+				}
+			}
+
+			if (UserSettings.FormatSpacingMin.get() != null) {
+				double minSpace = UserSettings.FormatSpacingMin.get()
+						* above.getSize();
+				if (minSpace > space) {
+					space = (int) Math.round(minSpace);
+				}
+			}
+
+			// Need to do things differently for FORMAT than for DROPPING
+			if (moveAll && above != curr.getNameItem()
+					&& above != curr.getTitleItem()) {
+				x = above.getX();
+				int y = (int) above.getBounds().getMaxY()
+						+ space
+						+ ((int) (from.getY() - from.getBounds().getMinY()));
+
+				if (changedItems != null
+						&& (from.getX() != x || from.getY() != y)
+						&& !changedItems.contains(from)) {
+					Item copy = from.copy();
+					copy.setID(from.getID());
+					changedItems.add(copy);
+				}
+				from.setPosition(x, y);
+			} else {
+				x = from.getX();
+			}
+
+			space += adjust;
+		}
+		for (int i = 1; i < toAlign.size(); i++) {
+			Item current = toAlign.get(i);
+			Item top = toAlign.get(i - 1);
+
+			// The bottom of the previous item
+			int bottom = (int) top.getBounds().getMaxY();
+
+			// the difference between the current item's Y coordinate and
+			// the top of the highlight box
+			int diff = (int) (current.getY() - current.getBounds().getMinY());
+
+			int newPos = bottom + space + diff;
+
+			if (changedItems != null
+					&& ((moveAll && current.getX() != x) || current.getY() != newPos)
+					&& !changedItems.contains(current)) {
+				Item copy = current.copy();
+				copy.setID(current.getID());
+				changedItems.add(copy);
+			}
+
+			if (moveAll) {
+				current.setPosition(x, newPos);
+			} else if (newPos > current.getY()) {
+				current.setY(newPos);
+			}
+
+		}
+
+		// if (insert != null)
+		// return insert.getY();
+
+		// Michael thinks we return the y value for the next new item??
+		int y = from.getY() + from.getBoundsHeight() + space;
+		return y;
+	}
+
+	public static int Align(List<Text> toAlign, boolean moveAll, int adjust) {
+		return Align(toAlign, moveAll, adjust, null);
+	}
+
+	public static boolean LeavingFrame(Frame current) {
+		checkTDFCItemWaiting(current);
+		// active overlay frames may also require saving if they have been
+		// changed
+		for (Overlay o : current.getOverlays())
+			if (!SaveCheck(o.Frame))
+				return false;
+
+		// if the check fails there is no point continuing
+		if (!SaveCheck(current))
+			return false;
+
+		for (Item i : current.getItems()) {
+			i.setHighlightMode(Item.HighlightMode.None);
+			i.setHighlightColorToDefault();
+		}
+		return true;
+	}
+
+	private static boolean SaveCheck(Frame toSave) {
+		// don't bother saving frames that haven't changed
+		if (!toSave.hasChanged())
+			return true;
+
+		// if the frame has been changed, then save it
+		if (DisplayController.isTwinFramesOn()) {
+			Frame opposite = DisplayController.getOppositeFrame();
+
+			String side = "left";
+			if (DisplayController.getCurrentSide() == DisplayController.TwinFramesSide.RIGHT)
+				side = "right";
+
+			// if the two frames both have changes, prompt the user for the
+			// next move
+			if (opposite.hasChanged() && opposite.equals(toSave)) {
+				if (EcosystemManager.getGraphicsManager().showDialog("Changes", "Leaving this frame will discard changes made in the " + side + " Frame. Continue?")) {
+					FrameIO.SaveFrame(toSave);
+					DisplayController.Reload(DisplayController.getSideFrameIsOn(opposite));
+					return true;
+				} else
+					return false;
+			} else if (opposite.hasOverlay(toSave)) {
+				if (toSave.hasChanged())
+					if (EcosystemManager.getGraphicsManager().showDialog("Changes", "Leaving this frame will discard changes made in the " + side + " Frame. Continue?")) {
+						FrameIO.SaveFrame(toSave);
+						DisplayController.Reload(DisplayController.getSideFrameIsOn(opposite));
+						return true;
+					} else
+						return false;
+			}
+
+			// save the current frame and restore the other side
+			FrameIO.SaveFrame(toSave);
+			return true;
+		}
+
+		// single-frame mode can just save and return
+		FrameIO.SaveFrame(toSave);
+		return true;
+	}
+
+	// TODO: consider reloating this method to Frame class?    
+	protected static Item getAnnotation(Frame frame, String annotationStr)
+	{
+		Item matched_item = null;
+
+		// check for an updated template...
+		for (Item i : frame.getAnnotationItems()) {				
+
+			if (ItemUtils.startsWithTag(i, annotationStr)) {
+
+				matched_item = i;
+				break;
+			}
+		}
+
+		return matched_item;
+	}
+
+	protected static void doFrameTransition(Item frameTransition, Frame from, Frame to)
+	{
+		String s = frameTransition.getText();		
+		String[] s_array = s.split(":");
+		if(s_array.length > 1){
+			String slide_mode_method = s_array[1].trim();
+			
+			FrameTransition transition = new FrameTransition(from.getBuffer(), slide_mode_method);
+			
+			DisplayController.setTransition(from, transition);
+			
+			System.out.println("Triggered on annotation: " + s);
+		} else {
+			System.err.println("Warning: failed to detect frameTransition type");
+			// TODO: print list as a result of reflection listing	   
+		}
+	}				
+
+	/**
+	 * Displays the given Frame on the display. If the current frame has changed
+	 * since the last save then it will be saved before the switch is made. The
+	 * caller can also dictate whether the current frame is added to the
+	 * back-stack or not.
+	 * 
+	 * @param toDisplay
+	 *            The Frame to display on the screen
+	 * @param addToBack
+	 *            True if the current Frame should be added to the back-stack,
+	 *            False otherwise
+	 */
+	public static void DisplayFrame(Frame toDisplay, boolean addToBack, boolean incrementStats)
+	{
+		if (toDisplay == null)
+			return;
+
+		Frame current = DisplayController.getCurrentFrame();
+
+		// Dont need to do anything if the frame to display is already being
+		// displayed
+		if (current.equals(toDisplay))
+			return;
+
+		// move any anchored connected items
+		if (FreeItems.hasItemsAttachedToCursor()) {
+			List<Item> toAdd = new ArrayList<Item>();
+			List<Item> toCheck = new ArrayList<Item>(FreeItems.getInstance());
+
+			while (toCheck.size() > 0) {
+				Item i = toCheck.get(0);
+				Collection<Item> connected = i.getAllConnected();
+
+				// // Only move completely enclosed items
+				// if (!toCheck.containsAll(connected)) {
+				// connected.retainAll(FreeItems.getInstance());
+				// FreeItems.getInstance().removeAll(connected);
+				// toCheck.removeAll(connected);
+				// FrameMouseActions.anchor(connected);
+				// } else {
+				// toCheck.removeAll(connected);
+				// }
+
+				// Anchor overlay items where they belong
+				if (i.getParent() != null && i.getParent() != current) {
+					FreeItems.getInstance().removeAll(connected);
+					toCheck.removeAll(connected);
+					StandardGestureActions.anchor(connected);
+				} else {
+					// Add stuff that is partially enclosed
+					// remove all the connected items from our list to check
+					toCheck.removeAll(connected);
+					// Dont add the items that are free
+					connected.removeAll(FreeItems.getInstance());
+					toAdd.addAll(connected);
+				}
+			}
+
+			current.removeAllItems(toAdd);
+
+			boolean oldChange = toDisplay.hasChanged();
+			toDisplay.updateIDs(toAdd);
+			toDisplay.addAllItems(toAdd);
+			toDisplay.setChanged(oldChange);
+		}
+
+		if (addToBack && current != toDisplay) {
+			FrameIO.checkTDFC(current);
+		}
+
+		// if the saving happened properly, we can continue
+		if (!LeavingFrame(current)) {
+			MessageBay.displayMessage("Navigation cancelled");
+			return;
+		}
+
+		if (addToBack && current != toDisplay) {
+			DisplayController.addToBack(current);
+		}
+
+		Parse(toDisplay);
+
+		if (DisplayController.isAudienceMode()) {
+			// Only need to worry about frame transitions when in Audience Mode
+
+			// Test to see if frame transition specified through annotation, and perform it if one if found
+			Item frameTransition = getAnnotation(toDisplay, "@frameTransition");
+			if (frameTransition != null) {
+				doFrameTransition(frameTransition,current,toDisplay);
+			}
+		}
+
+		DisplayController.setCurrentFrame(toDisplay, incrementStats);
+		StandardGestureActions.updateCursor();
+		// FrameMouseActions.getInstance().refreshHighlights();
+		// update response timer
+		_LastResponse = ResponseTimer.getElapsedSeconds();
+		_ResponseTimeSum += _LastResponse;
+		DisplayController.updateTitle();
+	}
+
+	/**
+	 * Loads and displays the Frame with the given framename, and adds the
+	 * current frame to the back-stack if required.
+	 * 
+	 * @param framename
+	 *            The name of the Frame to load and display
+	 * @param addToBack
+	 *            True if the current Frame should be added to the back-stack,
+	 *            false otherwise
+	 */
+	public static void DisplayFrame(String frameName, boolean addToBack,
+			boolean incrementStats) {
+		Frame newFrame = getFrame(frameName);
+
+		if (newFrame != null)
+			// display the frame
+			DisplayFrame(newFrame, addToBack, incrementStats);
+	}
+
+	/**
+	 * Loads and displays the Frame with the given framename and adds the
+	 * current frame to the back-stack. This is the same as calling
+	 * DisplayFrame(framename, true)
+	 * 
+	 * @param framename
+	 *            The name of the Frame to load and display
+	 */
+	public static void DisplayFrame(String framename) {
+		DisplayFrame(framename, true, true);
+	}
+
+	public static Frame getFrame(String frameName) {
+		// if the new frame does not exist then tell the user
+		Frame f = FrameIO.LoadFrame(frameName);
+
+		if (f == null) {
+			MessageBay.errorMessage("Frame '" + frameName + "' could not be found.");
+		}
+
+		return f;
+	}
+
+	/**
+	 * Creates a new Picture Item from the given Text source Item and adds it to
+	 * the given Frame.
+	 * 
+	 * @return True if the image was created successfully, false otherwise
+	 */
+	private static boolean createPicture(Frame frame, Text txt) {
+		// attempt to create the picture
+		Picture pic = ItemUtils.CreatePicture(txt);
+
+		// if the picture could not be created successfully
+		if (pic == null) {
+			String imagePath = txt.getText();
+			assert (imagePath != null);
+			imagePath = new AttributeValuePair(imagePath).getValue().trim();
+			if (imagePath.length() == 0) {
+				return false;
+				// MessageBay.errorMessage("Expected image path after @i:");
+			} else {
+				MessageBay.errorMessage("Image " + imagePath
+						+ " could not be loaded");
+			}
+			return false;
+		}
+		frame.addItem(pic);
+
+		return true;
+	}
+
+	/**
+	 * Creates an interactive widget and adds it to a frame. If txt has no
+	 * parent the parent will be set to frame.
+	 * 
+	 * @param frame
+	 *            Frame to add widget to. Must not be null.
+	 * 
+	 * @param txt
+	 *            Text to create the widget from. Must not be null.
+	 * 
+	 * @return True if created/added. False if could not create.
+	 * 
+	 * @author Brook Novak
+	 */
+	private static boolean createWidget(Frame frame, Text txt) {
+
+		if (frame == null)
+			throw new NullPointerException("frame");
+		if (txt == null)
+			throw new NullPointerException("txt");
+
+		// Safety
+		if (txt.getParent() == null)
+			txt.setParent(frame);
+
+		Widget iw = null;
+
 		try {
-		    int gap = Integer.parseInt(strGap);
-		    space = gap;
-		} catch (NumberFormatException nfe) {
-
-		}
-	    }
-	} else if (above != null) {
-	    // Make the gap between all items the same as the gap between
-	    // the first two
-	    space = (int) (from.getPolygon().getBounds().getMinY() - above
-		    .getPolygon().getBounds().getMaxY());
-
-	    if (space < MINIMUM_INTERITEM_SPACING)
-		space = MINIMUM_INTERITEM_SPACING;
-
-	    if (UserSettings.FormatSpacingMax.get() != null) {
-		double maxSpace = UserSettings.FormatSpacingMax.get()
-			* above.getSize();
-		if (maxSpace < space) {
-		    space = (int) Math.round(maxSpace);
-		}
-	    }
-
-	    if (UserSettings.FormatSpacingMin.get() != null) {
-		double minSpace = UserSettings.FormatSpacingMin.get()
-			* above.getSize();
-		if (minSpace > space) {
-		    space = (int) Math.round(minSpace);
-		}
-	    }
-
-	    // Need to do things differently for FORMAT than for DROPPING
-	    if (moveAll && above != curr.getNameItem()
-		    && above != curr.getTitleItem()) {
-		x = above.getX();
-		int y = (int) above.getPolygon().getBounds().getMaxY()
-			+ space
-			+ ((int) (from.getY() - from.getPolygon().getBounds()
-				.getMinY()));
-
-		if (changedItems != null
-			&& (from.getX() != x || from.getY() != y)
-			&& !changedItems.contains(from)) {
-		    Item copy = from.copy();
-		    copy.setID(from.getID());
-		    changedItems.add(copy);
-		}
-		from.setPosition(x, y);
-	    } else {
-		x = from.getX();
-	    }
-
-	    space += adjust;
-	}
-	for (int i = 1; i < toAlign.size(); i++) {
-	    Item current = toAlign.get(i);
-	    Item top = toAlign.get(i - 1);
-
-	    // The bottom of the previous item
-	    int bottom = (int) top.getPolygon().getBounds().getMaxY();
-
-	    // the difference between the current item's Y coordinate and
-	    // the top of the highlight box
-	    int diff = (int) (current.getY() - current.getPolygon().getBounds()
-		    .getMinY());
-
-	    int newPos = bottom + space + diff;
-
-	    if (changedItems != null
-		    && ((moveAll && current.getX() != x) || current.getY() != newPos)
-		    && !changedItems.contains(current)) {
-		Item copy = current.copy();
-		copy.setID(current.getID());
-		changedItems.add(copy);
-	    }
-
-	    if (moveAll) {
-		current.setPosition(x, newPos);
-	    } else if (newPos > current.getY()) {
-		current.setY(newPos);
-	    }
-
-	}
-
-	// if (insert != null)
-	// return insert.getY();
-
-	// Michael thinks we return the y value for the next new item??
-	int y = from.getY() + from.getBoundsHeight() + space;
-	return y;
-    }
-
-    public static int Align(List<Text> toAlign, boolean moveAll, int adjust) {
-	return Align(toAlign, moveAll, adjust, null);
-    }
-
-    public static boolean LeavingFrame(Frame current) {
-	checkTDFCItemWaiting(current);
-	// active overlay frames may also require saving if they have been
-	// changed
-	for (Overlay o : current.getOverlays())
-	    if (!SaveCheck(o.Frame))
-		return false;
-
-	// if the check fails there is no point continuing
-	if (!SaveCheck(current))
-	    return false;
-
-	for (Item i : current.getItems())
-	    i.setHighlightMode(Item.HighlightMode.None);
-	return true;
-    }
-
-    private static boolean SaveCheck(Frame toSave) {
-	// don't bother saving frames that haven't changed
-	if (!toSave.hasChanged())
-	    return true;
-
-	// if the frame has been changed, then save it
-	if (DisplayIO.isTwinFramesOn()) {
-	    Frame opposite = DisplayIO.getOppositeFrame();
-
-	    String side = "left";
-	    if (DisplayIO.getCurrentSide() == 0)
-		side = "right";
-
-	    // if the two frames both have changes, prompt the user for the
-	    // next move
-	    if (opposite.hasChanged() && opposite.equals(toSave)) {
-		if (DisplayIO.DisplayConfirmDialog(
-			"Leaving this frame will discard changes made in the "
-				+ side + " Frame. Continue?", "Changes",
-			DisplayIO.TYPE_WARNING, DisplayIO.OPTIONS_OK_CANCEL,
-			DisplayIO.RESULT_OK)) {
-		    FrameIO.SaveFrame(toSave);
-		    DisplayIO.Reload(DisplayIO.FrameOnSide(opposite));
-		    return true;
-		} else
-		    return false;
-	    } else if (opposite.hasOverlay(toSave)) {
-		if (toSave.hasChanged())
-		    if (DisplayIO.DisplayConfirmDialog(
-			    "Leaving this frame will discard changes made in the "
-				    + side + " Frame. Continue?", "Changes",
-			    DisplayIO.TYPE_WARNING,
-			    DisplayIO.OPTIONS_OK_CANCEL, DisplayIO.RESULT_OK)) {
-			FrameIO.SaveFrame(toSave);
-			DisplayIO.Reload(DisplayIO.FrameOnSide(opposite));
-			return true;
-		    } else
+
+			iw = Widget.createWidget(txt);
+
+		} catch (InteractiveWidgetNotAvailableException e) {
+			e.printStackTrace();
+			MessageBay.errorMessage("Cannot create iWidget: " + e.getMessage());
+		} catch (InteractiveWidgetInitialisationFailedException e) {
+			e.printStackTrace();
+			MessageBay.errorMessage("Cannot create iWidget: " + e.getMessage());
+		} catch (IllegalArgumentException e) {
+			e.printStackTrace();
+			MessageBay.errorMessage("Cannot create iWidget: " + e.getMessage());
+		}
+
+		if (iw == null)
 			return false;
-	    }
-
-	    // save the current frame and restore the other side
-	    FrameIO.SaveFrame(toSave);
-	    return true;
-	}
-
-	// single-frame mode can just save and return
-	FrameIO.SaveFrame(toSave);
-	return true;
-    }
-
-    // TODO: consider reloating this method to Frame class?    
-    protected static Item getAnnotation(Frame frame, String annotationStr)
-    {
-	Item matched_item = null;
+
+		frame.removeItem(txt);
+
+		frame.addAllItems(iw.getItems());
+
+		return true;
+	}
+
+	public static List<String> ParseProfile(Frame profile)
+	{
+		List<String> errors = new LinkedList<String>();
+		
+		if (profile == null) return errors;
+
+		/*
+		 * Make sure the correct cursor shows when turning off the custom cursor
+		 * and reparsing the profile frame
+		 */
+		FreeItems.getCursor().clear();
+		DisplayController.setCursor(Item.HIDDEN_CURSOR);
+		DisplayController.setCursor(Item.DEFAULT_CURSOR);
+
+		// check for settings tags
+		for (Text item : profile.getBodyTextItems(true)) {
+			try {
+
+				AttributeValuePair avp = new AttributeValuePair(item.getText());
+				String attributeFullCase = avp.getAttributeOrValue();
+
+				if (attributeFullCase == null) continue;
+				
+				String attribute = attributeFullCase.trim().toLowerCase().replaceAll("^@", "");
+
+				if (attribute.equals("settings")) Settings.parseSettings(item);
+
+			} catch (Exception e) {
+				if (e.getMessage() != null) {
+					errors.add(e.getMessage());
+				} else {
+					e.printStackTrace();
+					errors.add("Error parsing [" + item.getText() + "] on " + profile.getName());
+				}
+			}
+		}
+
+		return errors;
+	}
+
+	/**
+	 * Sets the first frame to be displayed.
+	 * 
+	 * @param profile
+	 */
+	public static void loadFirstFrame(Frame profile)
+	{
+		if (UserSettings.HomeFrame.get() == null) UserSettings.HomeFrame.set(profile.getName());
+
+		Frame firstFrame = FrameIO.LoadFrame(UserSettings.HomeFrame.get());
+		if (firstFrame == null) {
+			MessageBay.warningMessage("Home frame not found: " + UserSettings.HomeFrame);
+			UserSettings.HomeFrame.set(profile.getName());
+			DisplayController.setCurrentFrame(profile, true);
+		} else {
+			DisplayController.setCurrentFrame(firstFrame, true);
+		}
+
+	}
+
+	public static Colour[] getColorWheel(Frame frame)
+	{
+		if (frame != null) {
+			List<Text> textItems = frame.getBodyTextItems(false);
+			Colour[] colorList = new Colour[textItems.size() + 1];
+			for (int i = 0; i < textItems.size(); i++) {
+				colorList[i] = textItems.get(i).getColor();
+			}
+			// Make the last item transparency or default for forecolor
+			colorList[colorList.length - 1] = null;
+
+			return colorList;
+		}
+		return new Colour[] { Colour.BLACK, Colour.WHITE, null };
+	}
+
+	public static String getLink(Item item, String alt)
+	{
+		if (item == null || !(item instanceof Text)) return alt;
+
+		AttributeValuePair avp = new AttributeValuePair(item.getText());
+		assert (avp != null);
+
+		if (avp.hasPair() && avp.getValue().trim().length() != 0) {
+			item.setLink(avp.getValue());
+			return avp.getValue();
+		} else if (item.getLink() != null) {
+			return item.getAbsoluteLink();
+		}
+
+		return alt;
+	}
+
+	public static String getDir(String name)
+	{
+		if (name != null) {
+			File tester = new File(name);
+			if (tester.exists() && tester.isDirectory()) {
+				if (name.endsWith(File.separator)) {
+					return name;
+				} else {
+					return name + File.separator;
+				}
+			} else {
+				throw new RuntimeException("Directory not found: " + name);
+			}
+		}
+		throw new RuntimeException("Missing value for profile attribute" + name);
+	}
+
+	public static ArrayList<String> getDirs(Item item)
+	{
+		ArrayList<String> dirsToAdd = new ArrayList<String>();
+		String dirListFrameName = item.getAbsoluteLink();
+		if (dirListFrameName != null) {
+			Frame dirListFrame = FrameIO.LoadFrame(dirListFrameName);
+			if (dirListFrame != null) {
+				for (Text t : dirListFrame.getBodyTextItems(false)) {
+					String dirName = t.getText().trim();
+					File tester = new File(dirName);
+					if (tester.exists() && tester.isDirectory()) {
+						if (dirName.endsWith(File.separator))
+							dirsToAdd.add(dirName);
+						else
+							dirsToAdd.add(dirName + File.separator);
+					}
+				}
+			}
+		}
+
+		return dirsToAdd;
+	}
+
+	public static void Parse(Frame toParse)
+	{
+		Parse(toParse, false);
+	}
+
+	/**
+	 * Checks for any special Annotation items and updates the display as
+	 * necessary. Special Items: Images, overlays, sort.
+	 * 
+	 */
+	public static void Parse(Frame toParse, boolean firstParse)
+	{
+		Parse(toParse, firstParse, false);
+	}
+
+	/**
+	 * 
+	 * @param toParse
+	 * @param firstParse
+	 * @param ignoreAnnotations
+	 *            used to prevent infinate loops such as when performing TDFC
+	 *            with an ao tag linked to a frame with an frameImage of a frame
+	 *            which also has an ao tag on it.
+	 */
+	public static void Parse(Frame toParse, boolean firstParse, boolean ignoreAnnotations)
+	{
+		// TODO check why we are getting toParse == null... when profile frame
+		// is being created and change the lines below
+		if (toParse == null) return;
+
+		if (firstParse) ItemUtils.EnclosedCheck(toParse.getItems());
+		
+		List<Item> items = toParse.getItems();
+
+		// if XRayMode is on, replace pictures with their underlying text
+		if (DisplayController.isXRayMode()) {
+
+			// BROOK: Must handle these a little different
+			List<Widget> widgets = toParse.getInteractiveWidgets();
+
+			for (Item i : items) {
+				if (i instanceof XRayable) {
+					toParse.removeItem(i);
+					// Show the items
+					for (Item item : ((XRayable) i).getConnected()) {
+						item.setVisible(true);
+						item.removeEnclosure(i);
+					}
+				} else if (i instanceof WidgetCorner) {
+					toParse.removeItem(i);
+				} else if (i instanceof WidgetEdge) {
+					toParse.removeItem(i);
+				} else if (i.hasFormula()) {
+					i.setText(i.getFormula());
+				} else if (i.hasOverlay()) {
+					i.setVisible(true);
+					// int x = i.getBoundsHeight();
+				}
+			}
+
+			for (Widget iw : widgets) {
+				toParse.addItem(iw.getSource());
+			}
+		}
+
+		// Text title = null;
+		// Text template = UserSettingsTemplate.copy();
+
+		List<Overlay> overlays = new ArrayList<Overlay>();
+		List<Vector> vectors = new ArrayList<Vector>();
+
+		// disable reading of cached overlays if in twinframes mode
+		if (DisplayController.isTwinFramesOn()) FrameIO.SuspendCache();
+
+		DotType pointtype = DotType.square;
+		boolean filledPoints = true;
+
+		UserAppliedPermission permission = toParse.getUserAppliedPermission();
+		toParse.clearAnnotations();
+
+		// check for any new overlay items
+		for (Item i : toParse.getItems()) {
+			try {
+				// reset overlay permission
+				i.setOverlayPermission(null);
+				// i.setPermission(permission);
+				if (i instanceof WidgetCorner) {
+					// TODO improve efficiency so it only updates once... using
+					// observer design pattern
+					i.update();
+				} else if (i instanceof Text) {
+					if (i.isAnnotation()) {
+						if (ItemUtils.startsWithTag(i, ItemUtils.TAG_POINTTYPE)) {
+							Text txt = (Text) i;
+							String line = txt.getFirstLine();
+							line = ItemUtils.StripTag(line,
+									ItemUtils.GetTag(ItemUtils.TAG_POINTTYPE));
+
+							if (line != null) {
+								line = line.toLowerCase();
+								if (line.indexOf(" ") > 0) {
+									String fill = line.substring(line
+											.indexOf(" ") + 1);
+									if (fill.startsWith("nofill"))
+										filledPoints = false;
+									else
+										filledPoints = true;
+								}
+
+								if (line.startsWith("circle"))
+									pointtype = DotType.circle;
+								else
+									pointtype = DotType.square;
+							}
+						}// check for new VECTOR items
+						else if (!DisplayController.isXRayMode()
+								&& ItemUtils.startsWithTag(i,
+										ItemUtils.TAG_VECTOR)
+								&& i.getLink() != null) {
+							if (!i.getAbsoluteLink().equals(toParse.getName()))
+								addVector(vectors, UserAppliedPermission.none,
+										permission, i);
+						} else if (!DisplayController.isXRayMode()
+								&& ItemUtils.startsWithTag(i,
+										ItemUtils.TAG_ACTIVE_VECTOR)
+								&& i.getLink() != null) {
+							if (!i.getAbsoluteLink().equals(toParse.getName()))
+								addVector(vectors,
+										UserAppliedPermission.followLinks,
+										permission, i);
+						}
+						// check for new OVERLAY items
+						else if (!ignoreAnnotations && ItemUtils.startsWithTag(i, ItemUtils.TAG_OVERLAY) && i.getLink() != null) {
+							if (i.getAbsoluteLink().equalsIgnoreCase(toParse.getName())) {
+								// This frame contains an active overlay which
+								// points to itself
+								MessageBay.errorMessage(toParse.getName() + " contains an @o which links to itself");
+								continue;
+							}
+
+							Frame overlayFrame = FrameIO.LoadFrame(i.getAbsoluteLink());
+							// Parse(overlay);
+							if (overlayFrame != null && Overlay.getOverlay(overlays, overlayFrame) == null) {
+								overlays.add(new Overlay(overlayFrame, UserAppliedPermission.none));
+							}
+						}
+						// check for ACTIVE_OVERLAY items
+						else if (!ignoreAnnotations
+								&& ItemUtils.startsWithTag(i,
+										ItemUtils.TAG_ACTIVE_OVERLAY)
+								&& i.getLink() != null) {
+							String link = i.getAbsoluteLink();
+							if (link.equalsIgnoreCase(toParse.getName())) {
+								// This frame contains an active overlay which
+								// points to itself
+								MessageBay
+								.errorMessage(toParse.getName()
+										+ " contains an @ao which links to itself");
+								continue;
+							}
+							Frame overlayFrame = null;
+
+							Frame current = DisplayController.getCurrentFrame();
+							if (current != null) {
+								for (Overlay o : current.getOverlays()) {
+									if (o.Frame.getName()
+											.equalsIgnoreCase(link))
+										overlayFrame = o.Frame;
+								}
+							}
+							if (overlayFrame == null)
+								overlayFrame = FrameIO.LoadFrame(link);
+
+							// get level if specified
+							String level = new AttributeValuePair(i.getText())
+									.getValue();
+							// default permission (if none is specified)
+							PermissionPair permissionLevel = new PermissionPair(
+									level, UserAppliedPermission.followLinks);
+
+							if (overlayFrame != null) {
+								Overlay existingOverlay = Overlay.getOverlay(
+										overlays, overlayFrame);
+								// If it wasn't in the list create it and add
+								// it.
+								if (existingOverlay == null) {
+									Overlay newOverlay = new Overlay(
+											overlayFrame,
+											permissionLevel
+											.getPermission(overlayFrame
+													.getOwner()));
+									i.setOverlay(newOverlay);
+									overlays.add(newOverlay);
+								} else {
+									existingOverlay.Frame
+									.setPermission(permissionLevel);
+								}
+							}
+						}
+						// check for Images and widgets
+						else {
+							if (!DisplayController.isXRayMode()) {
+								if (ItemUtils.startsWithTag(i,
+										ItemUtils.TAG_IMAGE, true)) {
+									if (!i.hasEnclosures()) {
+										createPicture(toParse, (Text) i);
+									}
+									// check for frame images
+								} else if (ItemUtils.startsWithTag(i,
+										ItemUtils.TAG_FRAME_IMAGE)
+										&& i.getLink() != null
+										&& !i.getAbsoluteLink()
+										.equalsIgnoreCase(
+												toParse.getName())) {
+									XRayable image = null;
+									if (i.hasEnclosures()) {
+										// i.setHidden(true);
+										// image =
+										// i.getEnclosures().iterator().next();
+										// image.refresh();
+									} else {
+										image = new FrameImage((Text) i, null);
+									}
+									// TODO Add the image when creating new
+									// FrameImage
+									toParse.addItem(image);
+								} else if (ItemUtils.startsWithTag(i,
+										ItemUtils.TAG_BITMAP_IMAGE)
+										&& i.getLink() != null
+										&& !i.getAbsoluteLink()
+										.equalsIgnoreCase(
+												toParse.getName())) {
+									XRayable image = null;
+									if (i.hasEnclosures()) {
+										// image =
+										// i.getEnclosures().iterator().next();
+										// image.refresh();
+										// i.setHidden(true);
+									} else {
+										// If a new bitmap is created for a
+										// frame which already has a bitmap dont
+										// recreate the bitmap
+										image = new FrameBitmap((Text) i, null);
+									}
+									toParse.addItem(image);
+								} else if (ItemUtils.startsWithTag(i, "@c")) {
+									// Can only have a @c
+									if (!i.hasEnclosures()
+											&& i.getLines().size() == 1) {
+										toParse.addItem(new Circle((Text) i));
+									}
+									// Check for JSItem
+								} else if(ItemUtils.startsWithTag(i, "@js")) {
+									toParse.addItem(new JSItem((Text) i));
+									// Check for interactive widgets
+								} else if (ItemUtils.startsWithTag(i, ItemUtils.TAG_IWIDGET)) {
+									createWidget(toParse, (Text) i);
+								}
+							}
+							// TODO decide exactly what to do here!!
+							toParse.addAnnotation((Text) i);
+						}
+					} else if (!DisplayController.isXRayMode() && i.hasFormula()) {
+						i.calculate(i.getFormula());
+					}
+				}
+			} catch (Exception e) {
+				Logger.Log(e);
+				e.printStackTrace();
+				MessageBay.warningMessage("Exception occured when loading "
+						+ i.getClass().getSimpleName() + "(ID: " + i.getID()
+						+ ") " + e.getMessage() != null ? e.getMessage() : "");
+			}
+		}
+
+		/*
+		 * for (Item i : items) { if (i instanceof Dot) { ((Dot)
+		 * i).setPointType(pointtype); ((Dot) i).useFilledPoints(filledPoints);
+		 * } }
+		 */
+
+		FrameIO.ResumeCache();
+
+		toParse.clearOverlays();
+		toParse.clearVectors();
+		toParse.addAllOverlays(overlays);
+		toParse.addAllVectors(vectors);
+
+	}
+
+	/**
+	 * TODO: Comment. cts16
+	 * 
+	 * @param vectors
+	 * @param permission
+	 * @param i
+	 */
+	private static void addVector(List<Vector> vectors, UserAppliedPermission defaultPermission, UserAppliedPermission framePermission, Item i)
+	{
+		// TODO It is possible to get into an infinite loop if a
+		// frame contains an @ao which leads to a frame with an
+		// @v which points back to the frame with the @ao
+		Frame vector = FrameIO.LoadFrame(i.getAbsoluteLink());
+
+		// Get the permission from off the vector frame
+		UserAppliedPermission vectorPermission = UserAppliedPermission.getPermission(vector.getAnnotationValue("permission"), defaultPermission);
+		
+		// If the frame permission is lower, use that
+		vectorPermission = UserAppliedPermission.min(vectorPermission, framePermission);
+		
+		// Highest permissable permission for vectors is copy
+		vectorPermission = UserAppliedPermission.min(vectorPermission, UserAppliedPermission.copy);
+		if (vector != null) {
+			String scaleString = new AttributeValuePair(i.getText()).getValue();
+			Float scale = 1F;
+			try {
+				scale = Float.parseFloat(scaleString);
+			} catch (Exception e) {
+			}
+			Vector newVector = new Vector(vector, vectorPermission, scale, i);
+			i.setOverlay(newVector);
+			i.setVisible(false);
+			vectors.add(newVector);
+		}
+	}
+
+	public static Item onItem(float floatX, float floatY, boolean changeLastEdited)
+	{
+		return onItem(DisplayController.getCurrentFrame(), floatX, floatY, changeLastEdited);
+	}
+
+	/**
+	 * Searches through the list of items on this frame to find one at the given
+	 * x,y coordinates.
+	 * 
+	 * @param x
+	 *            The x coordinate
+	 * @param y
+	 *            The y coordinate
+	 * @return The Item at the given coordinates, or NULL if none is found.
+	 */
+	public static Item onItem(Frame toCheck, float floatX, float floatY, boolean bResetLastEdited)
+	{
+		// System.out.println("MouseX: " + floatX + " MouseY: " + floatY);
+		int x = Math.round(floatX);
+		int y = Math.round(floatY);
+		if (toCheck == null)
+			return null;
+
+		List<Item> possibles = new ArrayList<Item>(0);
+
+		// if the mouse is in the message area
+		if (y >= DisplayController.getMessageBayPaintArea().getMinY()) {
+			// check the individual message items
+			for (Item message : MessageBay.getMessages()) {
+				if (message != null) {
+					if (message.contains(new Point(x, y))) {
+						message.setOverlayPermission(UserAppliedPermission.copy);
+						possibles.add(message);
+					} else {
+						// Not sure why but if the line below is removed then
+						// several items can be highlighted at once
+						message.setHighlightMode(Item.HighlightMode.None);
+						message.setHighlightColorToDefault();
+					}
+				}
+			}
+
+			// check the link to the message frame
+			if (MessageBay.getMessageLink() != null) {
+				if (MessageBay.getMessageLink().contains(new Point(x, y))) {
+					MessageBay.getMessageLink().setOverlayPermission(UserAppliedPermission.copy);
+					possibles.add(MessageBay.getMessageLink());
+				}
+			}
+
+			// this is taken into account in contains
+			// y -= FrameGraphics.getMaxFrameSize().height;
+			// otherwise, the mouse is on the frame
+		} else {
+			if (LastEdited != null) {
+				if (LastEdited.contains(x, y)
+						&& !FreeItems.getInstance().contains(LastEdited)
+						&& LastEdited.getParent() == DisplayController.getCurrentFrame()
+						&& LastEdited.getParent().getItems().contains(LastEdited))
+				{
+					LastEdited.setOverlayPermission(UserAppliedPermission.full);
+					return LastEdited;
+				} else if (bResetLastEdited) {
+					setLastEdited(null);
+				}
+			}
+			ArrayList<Item> checkList = new ArrayList<Item>();
+			checkList.addAll(toCheck.getInteractableItems());
+			checkList.add(toCheck.getNameItem());
+
+			for (Item i : checkList) {
+
+				// do not check annotation items in audience mode
+				//TODO: Upon hover of Rubbish Bin, Undo and Restore Widgets, flickering occurs depending on the mouse distance from a corner. Resolve this.
+				if (i.isVisible() && !(DisplayController.isAudienceMode() && i.isAnnotation())) {
+					if (i instanceof WidgetCorner) {
+						WidgetCorner wc = (WidgetCorner) i;
+						if (wc.getWidgetSource() instanceof ButtonWidget) {
+							ButtonWidget bw = (ButtonWidget) wc.getWidgetSource();
+
+							if (bw.getdropInteractableStatus() == true) {
+								Widget iw = wc.getWidgetSource();
+
+								if(iw.getBounds().contains(x, y)){
+
+									if( !FreeItems.getInstance().contains(i))
+									{
+										possibles.add(i);					    		
+									}
+								}	
+							}
+						}
+					}
+
+					if (i.contains(new Point(x, y))){
+						if(!FreeItems.getInstance().contains(i)) {
+							possibles.add(i);		    		
+						}
+					}
+
+				}
+			}
+		}
+
+		// if there are no possible items, return null
+		if (possibles.size() == 0)
+			return null;
+
+		// if there is only one possibility, return it
+		if (possibles.size() == 1)
+			return possibles.get(0);
+
+		// return closest x,y pair to mouse
+		Item closest = possibles.get(0);
+		int distance = (int) Math.round(Math.sqrt(Math.pow(
+				Math.abs(closest.getX() - x), 2)
+				+ Math.pow(Math.abs(closest.getY() - y), 2)));
+
+		for (Item i : possibles) {
+			int d = (int) Math.round(Math.sqrt(Math.pow(Math.abs(i.getX() - x),
+					2) + Math.pow(Math.abs(i.getY() - y), 2)));
+
+			// System.out.println(d);
+			if (d <= distance) {
+				distance = d;
+
+				// dots take precedence over lines
+				if ((!(closest instanceof Dot && i instanceof Line))
+						&& (!(closest instanceof Text && i instanceof Line)))
+					closest = i;
+
+			}
+
+		}	
+
+		return closest;
+	}
 	
-    	// check for an updated template...
-	for (Item i : frame.getAnnotationItems()) {				
-	    
-	    if (ItemUtils.startsWithTag(i, annotationStr)) {
-
-		matched_item = i;
-		break;
-	    }
-	}
-
-	return matched_item;
-    }
-
-    protected static void doFrameTransition(Item frameTransition, Frame from, Frame to)
-    {
-	String s = frameTransition.getText();		
-	String[] s_array = s.split(":");
-	if(s_array.length > 1){
-	    String slide_mode_method = s_array[1].trim();
-	    
-	    FrameTransitions.setSlideModeMethod(slide_mode_method);
-	    System.out.println("Triggered on annotation: " + s);
-	    FrameTransitions.setSlideTrue();
-	    FrameTransitions.setSlideModeBaseImage(FrameGraphics.getBuffer(from, false, false));
-	}
-	else {
-	    System.err.println("Warning: failed to detect frameTransition type");
-	    // TODO: print list as a result of reflection listing	   
-	}
-    }				
-
-    /**
-     * Displays the given Frame on the display. If the current frame has changed
-     * since the last save then it will be saved before the switch is made. The
-     * caller can also dictate whether the current frame is added to the
-     * back-stack or not.
-     * 
-     * @param toDisplay
-     *            The Frame to display on the screen
-     * @param addToBack
-     *            True if the current Frame should be added to the back-stack,
-     *            False otherwise
-     */
-    public static void DisplayFrame(Frame toDisplay, boolean addToBack,
-	    boolean incrementStats) {
-	if (toDisplay == null)
-	    return;
-
-	Frame current = DisplayIO.getCurrentFrame();
-
-	// Dont need to do anything if the frame to display is already being
-	// displayed
-	if (current.equals(toDisplay))
-	    return;
-
-	// move any anchored connected items
-	if (FreeItems.itemsAttachedToCursor()) {
-	    List<Item> toAdd = new ArrayList<Item>();
-	    List<Item> toCheck = new ArrayList<Item>(FreeItems.getInstance());
-
-	    while (toCheck.size() > 0) {
-		Item i = toCheck.get(0);
-		Collection<Item> connected = i.getAllConnected();
-
-		// // Only move completely enclosed items
-		// if (!toCheck.containsAll(connected)) {
-		// connected.retainAll(FreeItems.getInstance());
-		// FreeItems.getInstance().removeAll(connected);
-		// toCheck.removeAll(connected);
-		// FrameMouseActions.anchor(connected);
-		// } else {
-		// toCheck.removeAll(connected);
-		// }
-
-		// Anchor overlay items where they belong
-		if (i.getParent() != null && i.getParent() != current) {
-		    FreeItems.getInstance().removeAll(connected);
-		    toCheck.removeAll(connected);
-		    FrameMouseActions.anchor(connected);
+	/**
+	 * Checks if the mouse is currently over an item.
+	 * 
+	 * @return
+	 * 		True if the mouse is over any item, false otherwise.
+	 */
+	public static boolean hasCurrentItem()
+	{
+		return getCurrentItem() != null;
+	}
+
+	public synchronized static Item getCurrentItem()
+	{
+		return onItem(DisplayController.getCurrentFrame(), DisplayController.getMouseX(), DisplayController.getMouseY(), true);
+	}
+
+	public static PolygonBounds getEnlosingPolygon()
+	{
+		Collection<Item> enclosure = getEnclosingLineEnds();
+		
+		if (enclosure == null || enclosure.size() == 0) return null;
+
+		return enclosure.iterator().next().getEnclosedShape();
+	}
+
+	/**
+	 * 
+	 * @param currentItem
+	 * @return
+	 */
+	public static Collection<Item> getCurrentItems()
+	{
+		return getCurrentItems(getCurrentItem());
+	}
+
+	public static Collection<Item> getCurrentItems(Item currentItem)
+	{
+		Collection<Item> enclosure = getEnclosingLineEnds();
+		
+		if (enclosure == null || enclosure.size() == 0) return null;
+
+		Item firstItem = enclosure.iterator().next();
+
+		Collection<Item> enclosed = getItemsEnclosedBy(DisplayController.getCurrentFrame(), firstItem.getEnclosedShape());
+
+		// Brook: enclosed widgets are to be fully enclosed, never partially
+		/*
+		 * MIKE says: but doesn't this mean that widgets are treated differently
+		 * from ALL other object which only need to be partially enclosed to be
+		 * picked up
+		 */
+		List<Widget> enclosedWidgets = new LinkedList<Widget>();
+		for (Item i : enclosed) {
+			// Don't want to lose the highlighting from the current item
+			if (i == currentItem || enclosure.contains(i)) {
+				continue;
+			}
+			// Don't want to lose the highlighting of connected Dots
+			// TODO: this code does nothing (perhaps the continue is meant for the outer
+			// for loop?). cts16
+			if (i instanceof Dot && i.getHighlightMode() == HighlightMode.Connected) {
+				for (Line l : i.getLines()) {
+					if (l.getOppositeEnd(i).getHighlightMode() == HighlightMode.Normal) {
+						continue;
+					}
+				}
+			}
+			
+			if (i instanceof WidgetCorner) {
+				if (!enclosedWidgets.contains(((WidgetCorner) i).getWidgetSource())) {
+					enclosedWidgets.add(((WidgetCorner) i).getWidgetSource());
+				}
+			}
+			
+			i.setHighlightMode(Item.HighlightMode.None);
+			i.setHighlightColorToDefault();
+		}
+
+		for (Widget iw : enclosedWidgets) {
+			for (Item i : iw.getItems()) {
+				if (!enclosed.contains(i)) {
+					enclosed.add(i);
+				}
+			}
+		}
+
+		return enclosed;
+	}
+
+	/**
+	 * Gets the collection of Dot items that form the enclosure nearest to the current mouse position.
+	 */
+	public static Collection<Item> getEnclosingLineEnds()
+	{
+		return getEnclosingLineEnds(new Point(DisplayController.getMouseX(), DisplayController.getMouseY()));
+	}
+
+	/**
+	 * Gets the collection of Dot items that form the enclosure nearest to the given position.
+	 */
+	public static Collection<Item> getEnclosingLineEnds(Point position)
+	{
+		// update enclosed shapes
+		Frame current = DisplayController.getCurrentFrame();
+		if (current == null) return null;
+		List<Item> items = current.getItems();
+
+		// Remove all items that are connected to freeItems
+		List<Item> freeItems = new ArrayList<Item>(FreeItems.getInstance());
+		while (freeItems.size() > 0) {
+			Item item = freeItems.get(0);
+			Collection<Item> connected = item.getAllConnected();
+			items.removeAll(connected);
+			freeItems.removeAll(connected);
+		}
+
+		List<Item> used = new ArrayList<Item>(0);
+
+		while (items.size() > 0) {
+			Item i = items.get(0);
+			items.remove(i);
+			if (i.isEnclosed()) {
+				PolygonBounds p = i.getEnclosedShape();
+				if (p.contains(position)) {
+					used.add(i);
+					items.removeAll(i.getEnclosingDots());
+				}
+			}
+		}
+
+		if (used.size() == 0) return null;
+
+		// if there is only one possibility, return it
+		if (used.size() == 1) {
+			return used.get(0).getEnclosingDots();
+		// otherwise, determine which polygon is closest to the cursor
 		} else {
-		    // Add stuff that is partially enclosed
-		    // remove all the connected items from our list to check
-		    toCheck.removeAll(connected);
-		    // Dont add the items that are free
-		    connected.removeAll(FreeItems.getInstance());
-		    toAdd.addAll(connected);
-		}
-	    }
-
-	    current.removeAllItems(toAdd);
-
-	    boolean oldChange = toDisplay.hasChanged();
-	    toDisplay.updateIDs(toAdd);
-	    toDisplay.addAllItems(toAdd);
-	    toDisplay.setChanged(oldChange);
-	}
-
-	if (addToBack && current != toDisplay) {
-	    FrameIO.checkTDFC(current);
-	}
-
-	// if the saving happened properly, we can continue
-	if (!LeavingFrame(current)) {
-	    MessageBay.displayMessage("Navigation cancelled");
-	    return;
-	}
-
-	if (addToBack && current != toDisplay) {
-	    DisplayIO.addToBack(current);
-	}
-
-	Parse(toDisplay);
-
-	if (FrameGraphics.isAudienceMode()) {
-		// Only need to worry about frame transitions when in Audience Mode
+			Collections.sort(used, new Comparator<Item>() {
+				public int compare(Item d1, Item d2) {
+					PolygonBounds p1 = d1.getEnclosedShape();
+					PolygonBounds p2 = d2.getEnclosedShape();
+
+					int closest = Integer.MAX_VALUE;
+					int close2 = Integer.MAX_VALUE;
+
+					int mouseX = DisplayController.getMouseX();
+					int mouseY = DisplayController.getMouseY();
+
+					for (int i = 0; i < p1.getPointCount(); i++) {
+						int diff = Math.abs(p1.getPoint(i).x - mouseX) + Math.abs(p1.getPoint(i).y - mouseY);
+						int diff2 = Integer.MAX_VALUE;
+
+						if (i < p2.getPointCount())
+							diff2 = Math.abs(p2.getPoint(i).x - mouseX)  + Math.abs(p2.getPoint(i).y - mouseY);
+
+						if (diff < Math.abs(closest)) {
+							close2 = closest;
+							closest = diff;
+						} else if (diff < Math.abs(close2))
+							close2 = diff;
+
+						if (diff2 < Math.abs(closest)) {
+							close2 = closest;
+							closest = -diff2;
+						} else if (diff2 < Math.abs(close2))
+							close2 = diff2;
+					}
+
+					if (closest > 0 && close2 > 0)
+						return -10;
+
+					if (closest < 0 && close2 < 0)
+						return 10;
+
+					if (closest > 0)
+						return -10;
+
+					return 10;
+				}
+
+			});
+
+			return used.get(0).getEnclosingDots();
+		}
+	}
+
+	// TODO Remove this method!!
+	// Can just getItemsWithin be used?
+	public static Collection<Item> getItemsEnclosedBy(Frame frame, PolygonBounds poly)
+	{
+		Collection<Item> contained = frame.getItemsWithin(poly);
+
+		Collection<Item> results = new LinkedHashSet<Item>(contained.size());
+
+		// check for correct permissions
+		for (Item item : contained) {
+			// if the item is on the frame
+			if (item.getParent() == frame || item.getParent() == null) {
+				// item.Permission = Permission.full;
+				results.add(item);
+				// otherwise, it must be on an overlay frame
+			} else {
+				for (Overlay overlay : frame.getOverlays()) {
+					if (overlay.Frame == item.getParent()) {
+						item.setOverlayPermission(overlay.permission);
+						results.add(item);
+						break;
+					}
+				}
+			}
+		}
+
+		return results;
+	}
+
+	/**
+	 * Fills the given Frame with default profile tags
+	 */
+	public static void CreateDefaultProfile(String username, Frame profile)
+	{
+		Text title = profile.getTitleItem();
+		if (username.equals(UserSettings.DEFAULT_PROFILE_NAME)) {
+			title.setText("Default Profile Frame");
+		} else {
+			// if this profile is not the default profile, copy it from the default profile instead of generating a new profile
+			// (this allows the possibility of modifying the default profile and having any new profiles get those modifications)
+			Frame nextDefault = FrameIO.LoadProfile(UserSettings.DEFAULT_PROFILE_NAME);
+			if (nextDefault == null) {
+				try {
+					nextDefault = FrameIO.CreateNewProfile(UserSettings.DEFAULT_PROFILE_NAME);
+				} catch (Exception e) {
+					// TODO tell the user that there was a problem creating the
+					// profile frame and close nicely
+					e.printStackTrace();
+				}
+			}
+			// load profile frame and set title correctly
+			profile.reset();
+			profile.removeAllItems(profile.getAllItems());
+			// set relative link on all items so their links will correctly point to the page on the current profile rather than on the default profile
+			for(Item i : nextDefault.getAllItems()) {
+				i.setRelativeLink();
+			}
+			profile.addAllItems(ItemUtils.CopyItems(nextDefault.getAllItems()));
+			profile.setTitle(username + "'s Profile Frame");
+			FrameIO.SaveFrame(profile);
+
+			Frame nextProfile = profile;
+			MessageBay.suppressMessages(true);
+			while((nextDefault = FrameIO.LoadNext(nextDefault)) != null) {
+				// in case there are gaps in the frame numbering of the default profile (e.g. if a user has edited it),
+				// we need to replicate those gaps in the copied profile so the links will work correctly
+				while(nextProfile.getNumber() < nextDefault.getNumber()) {
+					nextProfile = FrameIO.CreateFrame(profile.getFramesetName(), null, null);
+				}
+				// if the new profile has a frame number higher than the current frame number in the default profile,
+				// the new profile must already exist, so just exit
+				// (TODO: should we wipe the frames instead?)
+				if(nextProfile.getNumber() > nextDefault.getNumber()) {
+					break;
+				}
+				nextProfile.reset();
+				nextProfile.removeAllItems(nextProfile.getAllItems());
+				// set relative link on all items so their links will correctly point to the page on the current profile rather than on the default profile
+				for(Item i : nextDefault.getAllItems()) {
+					i.setRelativeLink();
+				}
+				nextProfile.addAllItems(ItemUtils.CopyItems(nextDefault.getAllItems()));
+				FrameIO.SaveFrame(nextProfile);
+			}
+			MessageBay.suppressMessages(false);
+
+			return;
+		}
+
+		// int spacing = 50;
+		final int intialYPos = 75;
+		int xPos = 75;
+		int yPos = intialYPos;
+
+		// yPos += spacing;
+		// profile.addText(xPos, yPos, "@HomeFrame", null, profile.getName());
+		// yPos += spacing;
+		// String defaultFrameName = profile.getFramesetName() + "0";
+		// profile.addText(xPos, yPos, "@DefaultFrame", null, defaultFrameName);
+		// yPos += spacing;
+		//
+		// profile.addText(xPos, yPos, "@InitialWidth: "
+		// + UserSettings.InitialWidth, null);
+		// yPos += spacing;
+		//
+		// profile.addText(xPos, yPos, "@InitialHeight: "
+		// + UserSettings.InitialHeight, null);
+		// yPos += spacing;
+		//
+		// Text t = profile.addText(xPos, yPos, "@ItemTemplate", null);
+		// t.setColor(null);
+		//
+		// yPos += spacing;
+		// t = profile.addText(xPos, yPos, "@AnnotationTemplate", null);
+		// t.setColor(Color.gray);
+		//
+		// yPos += spacing;
+		// t = profile.addText(xPos, yPos, "@CommentTemplate", null);
+		// t.setColor(Color.green.darker());
+		//
+		// yPos += spacing;
+		// t = profile.addText(xPos, yPos, "@StatsTemplate", null);
+		// t.setColor(Color.BLACK);
+		// t.setBackgroundColor(new Color(0.9F, 0.9F, 0.9F));
+		// t.setFamily(Text.MONOSPACED_FONT);
+		// t.setSize(14);
+
+		Text t;
+
+		xPos = 300;
+		// yPos = intialYPos + spacing;
+		yPos = 100;
+
+		// Add documentation links
+		File helpDirectory = new File(FrameIO.HELP_PATH);
+		if (helpDirectory != null) {
+			File[] helpFramesets = helpDirectory.listFiles();
+			if (helpFramesets != null) {
+
+				// Add the title for the help index
+				Text help = profile.addText(xPos, yPos, "@Expeditee Help", null);
+				help.setSize(25);
+				help.setFontStyle("Bold");
+				help.setFamily("SansSerif");
+				help.setColor(TemplateSettings.ColorWheel.get()[3]);
+
+				xPos += 25;
+				System.out.println("Installing frameset: ");
+
+				boolean first_item = true;
+
+				for (File helpFrameset : helpFramesets) {
+					String framesetName = helpFrameset.getName();
+					if (!FrameIO.isValidFramesetName(framesetName)) {
+						continue;
+					}
+
+					if (first_item) {
+						System.out.print("  " + framesetName);
+						first_item = false;
+					}
+					else {
+						System.out.print(", " + framesetName);
+					}
+					System.out.flush();
+
+					Frame indexFrame = FrameIO.LoadFrame(framesetName + '1');
+					// Look through the folder for help index pages
+					if (indexFrame != null
+							&& ItemUtils.FindTag(indexFrame.getItems(),
+									"@HelpIndex") != null) {
+						// yPos += spacing;
+						yPos += 30;
+						t = profile.addText(xPos, yPos,
+								'@' + indexFrame.getFramesetName(), null);
+						t.setLink(indexFrame.getName());
+						t.setColor(Colour.GREY);
+					}
+				}
+				System.out.println();
+			}
+		}
+
+		xPos = 50;
+		yPos = 100;
+
+		// Populate Start Pages and Settings
+		File framesetDirectory = new File(FrameIO.FRAME_PATH);
+
+		if (framesetDirectory.exists()) {
+			File[] startpagesFramesets = framesetDirectory.listFiles();
+
+			if (startpagesFramesets != null) {
+				// Add Start Page title
+				Text templates = profile.addText(xPos, yPos, "@Start Pages",
+						null);
+				templates.setSize(25);
+				templates.setFontStyle("Bold");
+				templates.setFamily("SansSerif");
+				templates.setColor(TemplateSettings.ColorWheel.get()[3]);
+
+				xPos += 25;
+
+				// Start Pages should be the first frame in its own frameset +
+				// frameset name should be present in FrameUtils.startPages[].
+				for (File startpagesFrameset : startpagesFramesets) {
+					String framesetName = startpagesFrameset.getName();
+
+					// Only add link if frameset is a startpage
+					for (int i = 0; i < startPages.length; i++) {
+						if (framesetName.equals(startPages[i])) {
+							Frame indexFrame = FrameIO
+									.LoadFrame(framesetName + '1');
+
+							// Add start page link
+							if (indexFrame != null) {
+								yPos += 30;
+								t = profile.addText(xPos, yPos,
+										'@' + indexFrame.getFramesetName(),
+										null);
+								t.setLink(indexFrame.getName());
+								t.setColor(Colour.GREY);
+							}
+						}
+					}
+				}
+			}
+		}
+
+		FrameIO.SaveFrame(profile);
+
+		// Populate settings frameset
+		Settings.Init();
+		t = profile.addText(550, 100, "@Settings", null);
+		t.setSize((float) 25.0);
+		t.setFamily("SansSerif");
+		t.setFontStyle("Bold");
+		t.setColor(Colour.GREY);
+		Settings.generateSettingsTree(t);
+
+		FrameIO.SaveFrame(profile);
+	}
+
+	private static void checkTDFCItemWaiting(Frame currentFrame)
+	{
+		Item tdfcItem = FrameUtils.getTdfcItem();
+		// if there is a TDFC Item waiting
+		if (tdfcItem != null) {
+			boolean change = currentFrame.hasChanged();
+			boolean saved = currentFrame.isSaved();
+			// Save the parent of the item if it has not been saved
+			if (!change && !saved) {
+				tdfcItem.setLink(null);
+				tdfcItem.getParent().setChanged(true);
+				FrameIO.SaveFrame(tdfcItem.getParent());
+				DisplayController.requestRefresh(true);
+			} else {
+				SessionStats.CreatedFrame();
+			}
+
+			setTdfcItem(null);
+		}
+	}
+
+	public static void setTdfcItem(Item _tdfcItem)
+	{
+		FrameUtils._tdfcItem = _tdfcItem;
+	}
+
+	public static Item getTdfcItem()
+	{
+		return FrameUtils._tdfcItem;
+	}
+
+	public static void setLastEdited(Text lastEdited)
+	{
+		// If the lastEdited is being changed then check if its @i
+		Frame toReparse = null;
+		Frame toRecalculate = null;
+		Frame toUpdateObservers = null;
+
+		if (LastEdited == null) {
+			// System.out.print("N");
+		} else if (LastEdited != null) {
+			// System.out.print("T");
+			Frame parent = LastEdited.getParentOrCurrentFrame();
+
+			if (lastEdited != LastEdited) {
+				if (LastEdited.startsWith("@i")) {
+					// Check if its an image that can be resized to fit a box
+					// around it
+					String text = LastEdited.getText();
+					if (text.startsWith("@i:")
+							&& !Character
+							.isDigit(text.charAt(text.length() - 1))) {
+						Collection<Item> enclosure = FrameUtils
+								.getEnclosingLineEnds(LastEdited.getPosition());
+						if (enclosure != null) {
+							for (Item i : enclosure) {
+								if (i.isLineEnd() && i.isEnclosed()) {
+									DisplayController.getCurrentFrame().removeAllItems(
+											enclosure);
+									AxisAlignedBoxBounds rect = i.getEnclosedBox();
+									LastEdited
+									.setText(LastEdited.getText()
+											+ " "
+											+ Math.round(rect
+													.getWidth()));
+									LastEdited.setPosition(rect.getTopLeft());
+									LastEdited.setThickness(i.getThickness());
+									LastEdited.setBorderColor(i.getColor());
+									break;
+								}
+							}
+							StandardGestureActions.deleteItems(enclosure, false);
+						}
+					}
+					toReparse = parent;
+				} else if (LastEdited.recalculateWhenChanged()) {
+					toRecalculate = parent;
+				}
+
+				if (parent.hasObservers()) {
+					toUpdateObservers = parent;
+				}
+				// Update the formula if in XRay mode
+				if (DisplayController.isXRayMode() && LastEdited.hasFormula()) {
+					LastEdited.setFormula(LastEdited.getText());
+				}
+			}
+			if (lastEdited != LastEdited && LastEdited.getText().length() == 0) {
+				parent.removeItem(LastEdited);
+			}
+		}
+		LastEdited = lastEdited;
+
+		if (!DisplayController.isXRayMode()) {
+			if (toReparse != null) {
+				Parse(toReparse, false, false);
+			} else {
+				if (toRecalculate != null) {
+					toRecalculate.recalculate();
+				}
+
+				if (toUpdateObservers != null) {
+					toUpdateObservers.notifyObservers(false);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Extracts files/folders from the assets/resources folder directly into
+	 * ${PARENT_FOLDER} (~/.expeditee)
+	 * 
+	 * @param force if true, resources will be extracted even if they have already been extracted before
+	 */
+	public static void extractResources(boolean force)
+	{
+		File check = new File(FrameIO.PARENT_FOLDER + ".res");
 		
-		// Test to see if frame transition specified through annotation, and perform it if one if found
-		Item frameTransition = getAnnotation(toDisplay, "@frameTransition");
-		if (frameTransition != null) {
-			doFrameTransition(frameTransition,current,toDisplay);
-		}
-	}
-	
-	DisplayIO.setCurrentFrame(toDisplay, incrementStats);
-	FrameMouseActions.updateCursor();
-	// FrameMouseActions.getInstance().refreshHighlights();
-	// update response timer
-	_LastResponse = ResponseTimer.getElapsedSeconds();
-	_ResponseTimeSum += _LastResponse;
-	DisplayIO.UpdateTitle();
-    }
-
-    /**
-     * Loads and displays the Frame with the given framename, and adds the
-     * current frame to the back-stack if required.
-     * 
-     * @param framename
-     *            The name of the Frame to load and display
-     * @param addToBack
-     *            True if the current Frame should be added to the back-stack,
-     *            false otherwise
-     */
-    public static void DisplayFrame(String frameName, boolean addToBack,
-	    boolean incrementStats) {
-	Frame newFrame = getFrame(frameName);
-
-	if (newFrame != null)
-	    // display the frame
-	    DisplayFrame(newFrame, addToBack, incrementStats);
-    }
-
-    /**
-     * Loads and displays the Frame with the given framename and adds the
-     * current frame to the back-stack. This is the same as calling
-     * DisplayFrame(framename, true)
-     * 
-     * @param framename
-     *            The name of the Frame to load and display
-     */
-    public static void DisplayFrame(String framename) {
-	DisplayFrame(framename, true, true);
-    }
-
-    public static Frame getFrame(String frameName) {
-	// if the new frame does not exist then tell the user
-	Frame f = FrameIO.LoadFrame(frameName);
-
-	if (f == null) {
-	    MessageBay.errorMessage("Frame '" + frameName
-		    + "' could not be found.");
-	}
-
-	return f;
-    }
-
-    /**
-     * Creates a new Picture Item from the given Text source Item and adds it to
-     * the given Frame.
-     * 
-     * @return True if the image was created successfully, false otherwise
-     */
-    private static boolean createPicture(Frame frame, Text txt) {
-	// attempt to create the picture
-	Picture pic = ItemUtils.CreatePicture(txt, frame);
-
-	// if the picture could not be created successfully
-	if (pic == null) {
-	    String imagePath = txt.getText();
-	    assert (imagePath != null);
-	    imagePath = new AttributeValuePair(imagePath).getValue().trim();
-	    if (imagePath.length() == 0) {
-		return false;
-		// MessageBay.errorMessage("Expected image path after @i:");
-	    } else {
-		MessageBay.errorMessage("Image " + imagePath
-			+ " could not be loaded");
-	    }
-	    return false;
-	}
-	frame.addItem(pic);
-
-	return true;
-    }
-
-    /**
-     * Creates an interactive widget and adds it to a frame. If txt has no
-     * parent the parent will be set to frame.
-     * 
-     * @param frame
-     *            Frame to add widget to. Must not be null.
-     * 
-     * @param txt
-     *            Text to create the widget from. Must not be null.
-     * 
-     * @return True if created/added. False if coul not create.
-     * 
-     * @author Brook Novak
-     */
-    private static boolean createWidget(Frame frame, Text txt) {
-
-	if (frame == null)
-	    throw new NullPointerException("frame");
-	if (txt == null)
-	    throw new NullPointerException("txt");
-
-	// Safety
-	if (txt.getParent() == null)
-	    txt.setParent(frame);
-
-	InteractiveWidget iw = null;
-
-	try {
-
-	    iw = InteractiveWidget.createWidget(txt);
-
-	} catch (InteractiveWidgetNotAvailableException e) {
-	    e.printStackTrace();
-	    MessageBay.errorMessage("Cannot create iWidget: " + e.getMessage());
-	} catch (InteractiveWidgetInitialisationFailedException e) {
-	    e.printStackTrace();
-	    MessageBay.errorMessage("Cannot create iWidget: " + e.getMessage());
-	} catch (IllegalArgumentException e) {
-	    e.printStackTrace();
-	    MessageBay.errorMessage("Cannot create iWidget: " + e.getMessage());
-	}
-
-	if (iw == null)
-	    return false;
-
-	frame.removeItem(txt);
-
-	frame.addAllItems(iw.getItems());
-
-	return true;
-    }
-
-    public static Collection<String> ParseProfile(Frame profile) {
-	Collection<String> errors = new LinkedList<String>();
-	if (profile == null)
-	    return errors;
-
-	/*
-	 * Make sure the correct cursor shows when turning off the custom cursor
-	 * and reparsing the profile frame
-	 */
-	FreeItems.getCursor().clear();
-	DisplayIO.setCursor(Item.HIDDEN_CURSOR);
-	DisplayIO.setCursor(Item.DEFAULT_CURSOR);
-
-	// check for settings tags
-	for (Text item : profile.getBodyTextItems(true)) {
-	    try {
-
-		AttributeValuePair avp = new AttributeValuePair(item.getText());
-		String attributeFullCase = avp.getAttributeOrValue();
-
-		if (attributeFullCase == null) {
-		    continue;
-		}
-		String attribute = attributeFullCase.trim().toLowerCase()
-			.replaceAll("^@", "");
-
-		if (attribute.equals("settings")) {
-		    Settings.parseSettings(item);
-		}
-
-	    } catch (Exception e) {
-		if (e.getMessage() != null) {
-		    errors.add(e.getMessage());
-		} else {
-		    e.printStackTrace();
-		    errors.add("Error parsing [" + item.getText() + "] on "
-			    + profile.getName());
-		}
-	    }
-	}
-
-	return errors;
-    }
-
-    /**
-     * Sets the first frame to be displayed.
-     * 
-     * @param profile
-     */
-    public static void loadFirstFrame(Frame profile) {
-	if (UserSettings.HomeFrame.get() == null)
-	    UserSettings.HomeFrame.set(profile.getName());
-
-	Frame firstFrame = FrameIO.LoadFrame(UserSettings.HomeFrame.get());
-	if (firstFrame == null) {
-	    MessageBay.warningMessage("Home frame not found: "
-		    + UserSettings.HomeFrame);
-	    UserSettings.HomeFrame.set(profile.getName());
-	    DisplayIO.setCurrentFrame(profile, true);
-	} else {
-	    DisplayIO.setCurrentFrame(firstFrame, true);
-	}
-
-    }
-
-    public static Color[] getColorWheel(Frame frame) {
-	if (frame != null) {
-	    List<Text> textItems = frame.getBodyTextItems(false);
-	    Color[] colorList = new Color[textItems.size() + 1];
-	    for (int i = 0; i < textItems.size(); i++) {
-		colorList[i] = textItems.get(i).getColor();
-	    }
-	    // Make the last item transparency or default for forecolor
-	    colorList[colorList.length - 1] = null;
-
-	    return colorList;
-	}
-	return new Color[] { Color.black, Color.white, null };
-    }
-
-    public static String getLink(Item item, String alt) {
-	if (item == null || !(item instanceof Text))
-	    return alt;
-
-	AttributeValuePair avp = new AttributeValuePair(item.getText());
-	assert (avp != null);
-
-	if (avp.hasPair() && avp.getValue().trim().length() != 0) {
-	    item.setLink(avp.getValue());
-	    return avp.getValue();
-	} else if (item.getLink() != null) {
-	    return item.getAbsoluteLink();
-	}
-
-	return alt;
-    }
-
-    public static String getDir(String name) {
-	if (name != null) {
-	    File tester = new File(name);
-	    if (tester.exists() && tester.isDirectory()) {
-		if (name.endsWith(File.separator))
-		    return name;
-		else
-		    return name + File.separator;
-	    } else {
-		throw new RuntimeException("Directory not found: " + name);
-	    }
-	}
-	throw new RuntimeException("Missing value for profile attribute" + name);
-    }
-
-    public static ArrayList<String> getDirs(Item item) {
-	ArrayList<String> dirsToAdd = new ArrayList<String>();
-	String dirListFrameName = item.getAbsoluteLink();
-	if (dirListFrameName != null) {
-	    Frame dirListFrame = FrameIO.LoadFrame(dirListFrameName);
-	    if (dirListFrame != null) {
-		for (Text t : dirListFrame.getBodyTextItems(false)) {
-		    String dirName = t.getText().trim();
-		    File tester = new File(dirName);
-		    if (tester.exists() && tester.isDirectory()) {
-			if (dirName.endsWith(File.separator))
-			    dirsToAdd.add(dirName);
-			else
-			    dirsToAdd.add(dirName + File.separator);
-		    }
-		}
-	    }
-	}
-
-	return dirsToAdd;
-    }
-
-    public static void Parse(Frame toParse) {
-	Parse(toParse, false);
-    }
-
-    /**
-     * Checks for any special Annotation items and updates the display as
-     * necessary. Special Items: Images, overlays, sort.
-     * 
-     */
-    public static void Parse(Frame toParse, boolean firstParse) {
-	Parse(toParse, firstParse, false);
-    }
-
-    /**
-     * 
-     * @param toParse
-     * @param firstParse
-     * @param ignoreAnnotations
-     *            used to prevent infinate loops such as when performing TDFC
-     *            with an ao tag linked to a frame with an frameImage of a frame
-     *            which also has an ao tag on it.
-     */
-    public static void Parse(Frame toParse, boolean firstParse,
-	    boolean ignoreAnnotations) {
-	// TODO check why we are getting toParse == null... when profile frame
-	// is being created and change the lines below
-	if (toParse == null)
-	    return;
-	// System.out.println(firstParse);
-	if (firstParse)
-	    ItemUtils.EnclosedCheck(toParse.getItems());
-	List<Item> items = toParse.getItems();
-
-	// if XRayMode is on, replace pictures with their underlying text
-	if (FrameGraphics.isXRayMode()) {
-
-	    // BROOK: Must handle these a little different
-	    List<InteractiveWidget> widgets = toParse.getInteractiveWidgets();
-
-	    for (Item i : items) {
-		if (i instanceof XRayable) {
-		    toParse.removeItem(i);
-		    // Show the items
-		    for (Item item : ((XRayable) i).getConnected()) {
-			item.setVisible(true);
-			item.removeEnclosure(i);
-		    }
-		} else if (i instanceof WidgetCorner) {
-		    toParse.removeItem(i);
-		} else if (i instanceof WidgetEdge) {
-		    toParse.removeItem(i);
-		} else if (i.hasFormula()) {
-		    i.setText(i.getFormula());
-		} else if (i.hasOverlay()) {
-		    i.setVisible(true);
-		    // int x = i.getBoundsHeight();
-		}
-	    }
-
-	    for (InteractiveWidget iw : widgets) {
-		toParse.addItem(iw.getSource());
-	    }
-	}
-
-	// Text title = null;
-	// Text template = UserSettingsTemplate.copy();
-
-	List<Overlay> overlays = new ArrayList<Overlay>();
-	List<Vector> vectors = new ArrayList<Vector>();
-
-	// disable reading of cached overlays if in twinframes mode
-	if (DisplayIO.isTwinFramesOn())
-	    FrameIO.SuspendCache();
-
-	DotType pointtype = DotType.square;
-	boolean filledPoints = true;
-
-	UserAppliedPermission permission = toParse.getUserAppliedPermission();
-	toParse.clearAnnotations();
-
-	// check for any new overlay items
-	for (Item i : toParse.getItems()) {
-	    try {
-		// reset overlay permission
-		i.setOverlayPermission(null);
-		// i.setPermission(permission);
-		if (i instanceof WidgetCorner) {
-		    // TODO improve efficiency so it only updates once... using
-		    // observer design pattern
-		    i.update();
-		} else if (i instanceof Text) {
-		    if (i.isAnnotation()) {
-			if (ItemUtils.startsWithTag(i, ItemUtils.TAG_POINTTYPE)) {
-			    Text txt = (Text) i;
-			    String line = txt.getFirstLine();
-			    line = ItemUtils.StripTag(line,
-				    ItemUtils.GetTag(ItemUtils.TAG_POINTTYPE));
-
-			    if (line != null) {
-				line = line.toLowerCase();
-				if (line.indexOf(" ") > 0) {
-				    String fill = line.substring(line
-					    .indexOf(" ") + 1);
-				    if (fill.startsWith("nofill"))
-					filledPoints = false;
-				    else
-					filledPoints = true;
-				}
-
-				if (line.startsWith("circle"))
-				    pointtype = DotType.circle;
-				else
-				    pointtype = DotType.square;
-			    }
-			}// check for new VECTOR items
-			else if (!FrameGraphics.isXRayMode()
-				&& ItemUtils.startsWithTag(i,
-					ItemUtils.TAG_VECTOR)
-				&& i.getLink() != null) {
-			    if (!i.getAbsoluteLink().equals(toParse.getName()))
-				addVector(vectors, UserAppliedPermission.none,
-					permission, i);
-			} else if (!FrameGraphics.isXRayMode()
-				&& ItemUtils.startsWithTag(i,
-					ItemUtils.TAG_ACTIVE_VECTOR)
-				&& i.getLink() != null) {
-			    if (!i.getAbsoluteLink().equals(toParse.getName()))
-				addVector(vectors,
-					UserAppliedPermission.followLinks,
-					permission, i);
-			}
-			// check for new OVERLAY items
-			else if (!ignoreAnnotations
-				&& ItemUtils.startsWithTag(i,
-					ItemUtils.TAG_OVERLAY)
-				&& i.getLink() != null) {
-			    if (i.getAbsoluteLink().equalsIgnoreCase(
-				    toParse.getName())) {
-				// This frame contains an active overlay which
-				// points to itself
-				MessageBay
-					.errorMessage(toParse.getName()
-						+ " contains an @o which links to itself");
-				continue;
-			    }
-
-			    Frame overlayFrame = FrameIO.LoadFrame(i
-				    .getAbsoluteLink());
-			    // Parse(overlay);
-			    if (overlayFrame != null
-				    && Overlay.getOverlay(overlays,
-					    overlayFrame) == null)
-				overlays.add(new Overlay(overlayFrame,
-					UserAppliedPermission.none));
-			}
-			// check for ACTIVE_OVERLAY items
-			else if (!ignoreAnnotations
-				&& ItemUtils.startsWithTag(i,
-					ItemUtils.TAG_ACTIVE_OVERLAY)
-				&& i.getLink() != null) {
-			    String link = i.getAbsoluteLink();
-			    if (link.equalsIgnoreCase(toParse.getName())) {
-				// This frame contains an active overlay which
-				// points to itself
-				MessageBay
-					.errorMessage(toParse.getName()
-						+ " contains an @ao which links to itself");
-				continue;
-			    }
-			    Frame overlayFrame = null;
-
-			    Frame current = DisplayIO.getCurrentFrame();
-			    if (current != null) {
-				for (Overlay o : current.getOverlays()) {
-				    if (o.Frame.getName()
-					    .equalsIgnoreCase(link))
-					overlayFrame = o.Frame;
-				}
-			    }
-			    if (overlayFrame == null)
-				overlayFrame = FrameIO.LoadFrame(link);
-
-			    // get level if specified
-			    String level = new AttributeValuePair(i.getText())
-				    .getValue();
-			    // default permission (if none is specified)
-			    PermissionPair permissionLevel = new PermissionPair(
-				    level, UserAppliedPermission.followLinks);
-
-			    if (overlayFrame != null) {
-				Overlay existingOverlay = Overlay.getOverlay(
-					overlays, overlayFrame);
-				// If it wasn't in the list create it and add
-				// it.
-				if (existingOverlay == null) {
-				    Overlay newOverlay = new Overlay(
-					    overlayFrame,
-					    permissionLevel
-						    .getPermission(overlayFrame
-							    .getOwner()));
-				    i.setOverlay(newOverlay);
-				    overlays.add(newOverlay);
-				} else {
-				    existingOverlay.Frame
-					    .setPermission(permissionLevel);
-				}
-			    }
-			}
-			// check for Images and widgets
-			else {
-			    if (!FrameGraphics.isXRayMode()) {
-				if (ItemUtils.startsWithTag(i,
-					ItemUtils.TAG_IMAGE, true)) {
-				    if (!i.hasEnclosures()) {
-					createPicture(toParse, (Text) i);
-				    }
-				    // check for frame images
-				} else if (ItemUtils.startsWithTag(i,
-					ItemUtils.TAG_FRAME_IMAGE)
-					&& i.getLink() != null
-					&& !i.getAbsoluteLink()
-						.equalsIgnoreCase(
-							toParse.getName())) {
-				    XRayable image = null;
-				    if (i.hasEnclosures()) {
-					// i.setHidden(true);
-					// image =
-					// i.getEnclosures().iterator().next();
-					// image.refresh();
-				    } else {
-					image = new FrameImage((Text) i,
-						toParse, null);
-				    }
-				    // TODO Add the image when creating new
-				    // FrameImage
-				    toParse.addItem(image);
-				} else if (ItemUtils.startsWithTag(i,
-					ItemUtils.TAG_BITMAP_IMAGE)
-					&& i.getLink() != null
-					&& !i.getAbsoluteLink()
-						.equalsIgnoreCase(
-							toParse.getName())) {
-				    XRayable image = null;
-				    if (i.hasEnclosures()) {
-					// image =
-					// i.getEnclosures().iterator().next();
-					// image.refresh();
-					// i.setHidden(true);
-				    } else {
-					// If a new bitmap is created for a
-					// frame which already has a bitmap dont
-					// recreate the bitmap
-					image = new FrameBitmap((Text) i,
-						toParse, null);
-				    }
-				    toParse.addItem(image);
-				} else if (ItemUtils.startsWithTag(i, "@c")) {
-				    // Can only have a @c
-				    if (!i.hasEnclosures()
-					    && i.getLines().size() == 1) {
-					toParse.addItem(new Circle((Text) i));
-				    }
-				    // Check for JSItem
-				} else if(ItemUtils.startsWithTag(i, "@js")) {
-					toParse.addItem(new JSItem((Text) i));
-				    // Check for interactive widgets
-				} else if (ItemUtils.startsWithTag(i,
-					ItemUtils.TAG_IWIDGET)) {
-				    createWidget(toParse, (Text) i);
-				}
-			    }
-			    // TODO decide exactly what to do here!!
-			    toParse.addAnnotation((Text) i);
-			}
-		    } else if (!FrameGraphics.isXRayMode() && i.hasFormula()) {
-			i.calculate(i.getFormula());
-		    }
-		}
-	    } catch (Exception e) {
-		Logger.Log(e);
-		e.printStackTrace();
-		MessageBay.warningMessage("Exception occured when loading "
-			+ i.getClass().getSimpleName() + "(ID: " + i.getID()
-			+ ") " + e.getMessage() != null ? e.getMessage() : "");
-	    }
-	}
-
-	/*
-	 * for (Item i : items) { if (i instanceof Dot) { ((Dot)
-	 * i).setPointType(pointtype); ((Dot) i).useFilledPoints(filledPoints);
-	 * } }
-	 */
-
-	FrameIO.ResumeCache();
-
-	toParse.clearOverlays();
-	toParse.clearVectors();
-	toParse.addAllOverlays(overlays);
-	toParse.addAllVectors(vectors);
-
-    }
-
-    /**
-     * @param vectors
-     * @param permission
-     * @param i
-     */
-    private static void addVector(List<Vector> vectors,
-	    UserAppliedPermission defaultPermission,
-	    UserAppliedPermission framePermission, Item i) {
-	// TODO It is possible to get into an infinate loop if a
-	// frame contains an @ao which leads to a frame with an
-	// @v which points back to the frame with the @ao
-	Frame vector = FrameIO.LoadFrame(i.getAbsoluteLink());
-
-	// Get the permission from off the vector frame
-	UserAppliedPermission vectorPermission = UserAppliedPermission
-		.getPermission(vector.getAnnotationValue("permission"),
-			defaultPermission);
-	// If the frame permission is lower, use that
-	vectorPermission = UserAppliedPermission.min(vectorPermission,
-		framePermission);
-	// Highest permissable permission for vectors is copy
-	vectorPermission = UserAppliedPermission.min(vectorPermission,
-		UserAppliedPermission.copy);
-	if (vector != null) {
-	    String scaleString = new AttributeValuePair(i.getText()).getValue();
-	    Float scale = 1F;
-	    try {
-		scale = Float.parseFloat(scaleString);
-	    } catch (Exception e) {
-	    }
-	    Vector newVector = new Vector(vector, vectorPermission, scale, i);
-	    i.setOverlay(newVector);
-	    i.setVisible(false);
-	    vectors.add(newVector);
-	}
-    }
-
-    public static Item onItem(float floatX, float floatY,
-	    boolean changeLastEdited) {
-	return onItem(DisplayIO.getCurrentFrame(), floatX, floatY,
-		changeLastEdited);
-    }
-
-    /**
-     * Searches through the list of items on this frame to find one at the given
-     * x,y coordinates.
-     * 
-     * @param x
-     *            The x coordinate
-     * @param y
-     *            The y coordinate
-     * @return The Item at the given coordinates, or NULL if none is found.
-     */
-    public static Item onItem(Frame toCheck, float floatX, float floatY,
-	    boolean bResetLastEdited) {
-	// System.out.println("MouseX: " + floatX + " MouseY: " + floatY);
-	int x = Math.round(floatX);
-	int y = Math.round(floatY);
-	if (toCheck == null)
-	    return null;
-
-	List<Item> possibles = new ArrayList<Item>(0);
-
-	// if the mouse is in the message area
-	if (y > FrameGraphics.getMaxFrameSize().getHeight()) {
-	    // check the individual message items
-	    for (Item message : MessageBay.getMessages()) {
-		if (message != null) {
-		    if (message.contains(x, y)) {
-			message.setOverlayPermission(UserAppliedPermission.copy);
-			possibles.add(message);
-		    } else {
-			// Not sure why but if the line below is removed then
-			// several items can be highlighted at once
-			message.setHighlightMode(Item.HighlightMode.None);
-		    }
-		}
-	    }
-
-	    // check the link to the message frame
-	    if (MessageBay.getMessageLink() != null) {
-		if (MessageBay.getMessageLink().contains(x, y)) {
-		    MessageBay.getMessageLink().setOverlayPermission(
-			    UserAppliedPermission.copy);
-		    possibles.add(MessageBay.getMessageLink());
-		}
-	    }
-
-	    // this is taken into account in contains
-	    // y -= FrameGraphics.getMaxFrameSize().height;
-	    // otherwise, the mouse is on the frame
-	} else {
-	    if (LastEdited != null) {
-		if (LastEdited.contains(x, y)
-			&& !FreeItems.getInstance().contains(LastEdited)
-			&& LastEdited.getParent() == DisplayIO
-				.getCurrentFrame()
-			&& LastEdited.getParent().getItems()
-				.contains(LastEdited)) {
-		    LastEdited.setOverlayPermission(UserAppliedPermission.full);
-		    return LastEdited;
-		} else if (bResetLastEdited) {
-		    setLastEdited(null);
-		}
-	    }
-	    ArrayList<Item> checkList = new ArrayList<Item>();
-	    checkList.addAll(toCheck.getInteractableItems());
-	    checkList.add(toCheck.getNameItem());
-	    
-	    for (Item i : checkList) {
-	    	    	
-		// do not check annotation items in audience mode
-	    //TODO: Upon hover of Rubbish Bin, Undo and Restore Widgets, flickering occurs depending on the mouse distance from a corner. Resolve this.
-		if (i.isVisible()
-			&& !(FrameGraphics.isAudienceMode() && i.isAnnotation())) {
-			if(i instanceof WidgetCorner){
-				WidgetCorner wc = (WidgetCorner)i;
-				if(wc.getWidgetSource() instanceof ButtonWidget){
-					ButtonWidget bw = (ButtonWidget) wc.getWidgetSource();
-					
-					if(bw.getdropInteractableStatus() == true){
-						InteractiveWidget iw = wc.getWidgetSource();
-						
-						if(iw.getBounds().contains(x, y)){
-							
-							if( !FreeItems.getInstance().contains(i))
-					    	{
-								possibles.add(i);					    		
-					    	}
-						}	
-					}
-					
-				}
-				
-	    	}
-
-		    if (i.contains(x, y)){
-		    	if( !FreeItems.getInstance().contains(i))
-		    	{
-		    		possibles.add(i);		    		
-		    	}
-		    }
-			   
-		}
-	    }
-	}
-
-	// if there are no possible items, return null
-	if (possibles.size() == 0)
-	    return null;
-
-	// if there is only one possibility, return it
-	if (possibles.size() == 1)
-	    return possibles.get(0);
-	
-	// return closest x,y pair to mouse
-	Item closest = possibles.get(0);
-	int distance = (int) Math.round(Math.sqrt(Math.pow(
-		Math.abs(closest.getX() - x), 2)
-		+ Math.pow(Math.abs(closest.getY() - y), 2)));
-
-	for (Item i : possibles) {
-	    int d = (int) Math.round(Math.sqrt(Math.pow(Math.abs(i.getX() - x),
-		    2) + Math.pow(Math.abs(i.getY() - y), 2)));
-
-	    // System.out.println(d);
-	    if (d <= distance) {
-		distance = d;
-
-		// dots take precedence over lines
-		if ((!(closest instanceof Dot && i instanceof Line))
-			&& (!(closest instanceof Text && i instanceof Line)))
-		    closest = i;
-
-	    }
-
-	}	
-
-	return closest;
-    }
-
-    public synchronized static Item getCurrentItem() {
-	return onItem(DisplayIO.getCurrentFrame(), DisplayIO.getMouseX(),
-		FrameMouseActions.getY(), true);
-    }
-
-    public static Polygon getEnlosingPolygon() {
-	Collection<Item> enclosure = getEnclosingLineEnds();
-	if (enclosure == null || enclosure.size() == 0)
-	    return null;
-
-	return enclosure.iterator().next().getEnclosedShape();
-    }
-
-    /**
-     * 
-     * @param currentItem
-     * @return
-     */
-    public static Collection<Item> getCurrentItems() {
-	return getCurrentItems(getCurrentItem());
-    }
-
-    public static Collection<Item> getCurrentItems(Item currentItem) {
-
-	Collection<Item> enclosure = getEnclosingLineEnds();
-	if (enclosure == null || enclosure.size() == 0)
-	    return null;
-
-	Item firstItem = enclosure.iterator().next();
-
-	Collection<Item> enclosed = getItemsEnclosedBy(
-		DisplayIO.getCurrentFrame(), firstItem.getEnclosedShape());
-
-	// Brook: enclosed widgets are to be fully enclosed, never partially
-	/*
-	 * MIKE says: but doesnt this mean that widgets are treated differently
-	 * from ALL other object which only need to be partially enclosed to be
-	 * picked up
-	 */
-	List<InteractiveWidget> enclosedWidgets = new LinkedList<InteractiveWidget>();
-	for (Item i : enclosed) {
-	    // Don't want to lose the highlighting from the current item
-	    if (i == currentItem || enclosure.contains(i)) {
-		continue;
-	    }
-	    // Don't want to lose the highlighting of connected Dots
-	    if (i instanceof Dot
-		    && i.getHighlightMode() == HighlightMode.Connected) {
-		for (Line l : i.getLines()) {
-		    if (l.getOppositeEnd(i).getHighlightMode() == HighlightMode.Normal) {
-			continue;
-		    }
-		}
-	    }
-	    if (i instanceof WidgetCorner) {
-		if (!enclosedWidgets.contains(((WidgetCorner) i)
-			.getWidgetSource()))
-		    enclosedWidgets.add(((WidgetCorner) i).getWidgetSource());
-	    }
-	    i.setHighlightMode(Item.HighlightMode.None);
-	}
-
-	for (InteractiveWidget iw : enclosedWidgets) {
-	    for (Item i : iw.getItems()) {
-		if (!enclosed.contains(i)) {
-		    enclosed.add(i);
-		}
-	    }
-	}
-
-	return enclosed;
-    }
-
-    public static Collection<Item> getEnclosingLineEnds() {
-	return getEnclosingLineEnds(new Point(DisplayIO.getMouseX(),
-		FrameMouseActions.getY()));
-    }
-
-    public static Collection<Item> getEnclosingLineEnds(Point position) {
-	// update enclosed shapes
-	Frame current = DisplayIO.getCurrentFrame();
-	List<Item> items = current.getItems();
-
-	// Remove all items that are connected to freeItems
-	List<Item> freeItems = new ArrayList<Item>(FreeItems.getInstance());
-	while (freeItems.size() > 0) {
-	    Item item = freeItems.get(0);
-	    Collection<Item> connected = item.getAllConnected();
-	    items.removeAll(connected);
-	    freeItems.removeAll(connected);
-	}
-
-	List<Item> used = new ArrayList<Item>(0);
-
-	while (items.size() > 0) {
-	    Item i = items.get(0);
-	    items.remove(i);
-	    if (i.isEnclosed()) {
-		Polygon p = i.getEnclosedShape();
-		if (p.contains(position.x, position.y)) {
-		    used.add(i);
-		    items.removeAll(i.getEnclosingDots());
-		}
-	    }
-	}
-
-	if (used.size() == 0)
-	    return null;
-
-	// if there is only one possibility, return it
-	if (used.size() == 1) {
-	    return used.get(0).getEnclosingDots();
-	    // otherwise, determine which polygon is closest to the cursor
-	} else {
-	    Collections.sort(used, new Comparator<Item>() {
-		public int compare(Item d1, Item d2) {
-		    Polygon p1 = d1.getEnclosedShape();
-		    Polygon p2 = d2.getEnclosedShape();
-
-		    int closest = Integer.MAX_VALUE;
-		    int close2 = Integer.MAX_VALUE;
-
-		    int mouseX = DisplayIO.getMouseX();
-		    int mouseY = FrameMouseActions.getY();
-
-		    for (int i = 0; i < p1.npoints; i++) {
-			int diff = Math.abs(p1.xpoints[i] - mouseX)
-				+ Math.abs(p1.ypoints[i] - mouseY);
-			int diff2 = Integer.MAX_VALUE;
-
-			if (i < p2.npoints)
-			    diff2 = Math.abs(p2.xpoints[i] - mouseX)
-				    + Math.abs(p2.ypoints[i] - mouseY);
-
-			if (diff < Math.abs(closest)) {
-			    close2 = closest;
-			    closest = diff;
-			} else if (diff < Math.abs(close2))
-			    close2 = diff;
-
-			if (diff2 < Math.abs(closest)) {
-			    close2 = closest;
-			    closest = -diff2;
-			} else if (diff2 < Math.abs(close2))
-			    close2 = diff2;
-		    }
-
-		    if (closest > 0 && close2 > 0)
-			return -10;
-
-		    if (closest < 0 && close2 < 0)
-			return 10;
-
-		    if (closest > 0)
-			return -10;
-
-		    return 10;
-		}
-
-	    });
-
-	    return used.get(0).getEnclosingDots();
-	}
-    }
-
-    // TODO Remove this method!!
-    // Can just getItemsWithin be used?
-    public static Collection<Item> getItemsEnclosedBy(Frame frame, Polygon poly) {
-	Collection<Item> contained = frame.getItemsWithin(poly);
-
-	Collection<Item> results = new LinkedHashSet<Item>(contained.size());
-
-	// check for correct permissions
-	for (Item item : contained) {
-	    // if the item is on the frame
-	    if (item.getParent() == frame || item.getParent() == null) {
-		// item.Permission = Permission.full;
-		results.add(item);
-		// otherwise, it must be on an overlay frame
-	    } else {
-		for (Overlay overlay : frame.getOverlays()) {
-		    if (overlay.Frame == item.getParent()) {
-			item.setOverlayPermission(overlay.permission);
-			results.add(item);
-			break;
-		    }
-		}
-	    }
-	}
-
-	return results;
-    }
-
-    /**
-     * Fills the given Frame with default profile tags
-     */
-    public static void CreateDefaultProfile(String username, Frame profile) {
-	Text title = profile.getTitleItem();
-	if (username.equals(UserSettings.DEFAULT_PROFILE_NAME)) {
-	    title.setText("Default Profile Frame");
-	} else {
-	    // if this profile is not the default profile, copy it from the default profile instead of generating a new profile
-		// (this allows the possibility of modifying the default profile and having any new profiles get those modifications)
-		Frame nextDefault = FrameIO.LoadProfile(UserSettings.DEFAULT_PROFILE_NAME);
-		if (nextDefault == null) {
-			try {
-				nextDefault = FrameIO.CreateNewProfile(UserSettings.DEFAULT_PROFILE_NAME);
-			} catch (Exception e) {
-				// TODO tell the user that there was a problem creating the
-				// profile frame and close nicely
-				e.printStackTrace();
-			}
-		}
-		// load profile frame and set title correctly
-		profile.reset();
-		profile.removeAllItems(profile.getAllItems());
-		// set relative link on all items so their links will correctly point to the page on the current profile rather than on the default profile
-		for(Item i : nextDefault.getAllItems()) {
-			i.setRelativeLink();
-		}
-		profile.addAllItems(ItemUtils.CopyItems(nextDefault.getAllItems()));
-		profile.setTitle(username + "'s Profile Frame");
-		FrameIO.SaveFrame(profile);
+		if(!force && check.exists()) return;
 		
-		Frame nextProfile = profile;
-		MessageBay.suppressMessages(true);
-		while((nextDefault = FrameIO.LoadNext(nextDefault)) != null) {
-			// in case there are gaps in the frame numbering of the default profile (e.g. if a user has edited it),
-			// we need to replicate those gaps in the copied profile so the links will work correctly
-			while(nextProfile.getNumber() < nextDefault.getNumber()) {
-				nextProfile = FrameIO.CreateFrame(profile.getFramesetName(), null, null);
-			}
-			// if the new profile has a frame number higher than the current frame number in the default profile,
-			// the new profile must already exist, so just exit
-			// (TODO: should we wipe the frames instead?)
-			if(nextProfile.getNumber() > nextDefault.getNumber()) {
-				break;
-			}
-			nextProfile.reset();
-    		nextProfile.removeAllItems(nextProfile.getAllItems());
-    		// set relative link on all items so their links will correctly point to the page on the current profile rather than on the default profile
-    		for(Item i : nextDefault.getAllItems()) {
-    			i.setRelativeLink();
-    		}
-    		nextProfile.addAllItems(ItemUtils.CopyItems(nextDefault.getAllItems()));
-    		FrameIO.SaveFrame(nextProfile);
-		}
-		MessageBay.suppressMessages(false);
+		System.out.println("Extracting/Installing resources:");
 		
-		return;
-	}
-
-	// int spacing = 50;
-	final int intialYPos = 75;
-	int xPos = 75;
-	int yPos = intialYPos;
-
-	// yPos += spacing;
-	// profile.addText(xPos, yPos, "@HomeFrame", null, profile.getName());
-	// yPos += spacing;
-	// String defaultFrameName = profile.getFramesetName() + "0";
-	// profile.addText(xPos, yPos, "@DefaultFrame", null, defaultFrameName);
-	// yPos += spacing;
-	//
-	// profile.addText(xPos, yPos, "@InitialWidth: "
-	// + UserSettings.InitialWidth, null);
-	// yPos += spacing;
-	//
-	// profile.addText(xPos, yPos, "@InitialHeight: "
-	// + UserSettings.InitialHeight, null);
-	// yPos += spacing;
-	//
-	// Text t = profile.addText(xPos, yPos, "@ItemTemplate", null);
-	// t.setColor(null);
-	//
-	// yPos += spacing;
-	// t = profile.addText(xPos, yPos, "@AnnotationTemplate", null);
-	// t.setColor(Color.gray);
-	//
-	// yPos += spacing;
-	// t = profile.addText(xPos, yPos, "@CommentTemplate", null);
-	// t.setColor(Color.green.darker());
-	//
-	// yPos += spacing;
-	// t = profile.addText(xPos, yPos, "@StatsTemplate", null);
-	// t.setColor(Color.BLACK);
-	// t.setBackgroundColor(new Color(0.9F, 0.9F, 0.9F));
-	// t.setFamily(Text.MONOSPACED_FONT);
-	// t.setSize(14);
-
-	Text t;
-
-	xPos = 300;
-	// yPos = intialYPos + spacing;
-	yPos = 100;
-
-	// Add documentation links
-	File helpDirectory = new File(FrameIO.HELP_PATH);
-	if (helpDirectory != null) {
-	    File[] helpFramesets = helpDirectory.listFiles();
-	    if (helpFramesets != null) {
-
-		// Add the title for the help index
-		Text help = profile.addText(xPos, yPos, "@Expeditee Help", null);
-		help.setSize(25);
-		help.setFontStyle("Bold");
-		help.setFamily("SansSerif");
-		help.setColor(TemplateSettings.ColorWheel.get()[3]);
-
-		xPos += 25;
-		System.out.println("Installing frameset: ");
-
-		boolean first_item = true;
-
-		for (File helpFrameset : helpFramesets) {
-		    String framesetName = helpFrameset.getName();
-		    if (!FrameIO.isValidFramesetName(framesetName)) {
-			continue;
-		    }
-
-		    if (first_item) {
-			System.out.print("  " + framesetName);
-			first_item = false;
-		    }
-		    else {
-			System.out.print(", " + framesetName);
-		    }
-		    System.out.flush();
-
-		    Frame indexFrame = FrameIO.LoadFrame(framesetName + '1');
-		    // Look through the folder for help index pages
-		    if (indexFrame != null
-			    && ItemUtils.FindTag(indexFrame.getItems(),
-				    "@HelpIndex") != null) {
-			// yPos += spacing;
-			yPos += 30;
-			t = profile.addText(xPos, yPos,
-				'@' + indexFrame.getFramesetName(), null);
-			t.setLink(indexFrame.getName());
-			t.setColor(Color.gray);
-		    }
-		}
-		System.out.println();
-	    }
-	}
-
-	xPos = 50;
-	yPos = 100;
-
-	// Populate Start Pages and Settings
-	File framesetDirectory = new File(FrameIO.FRAME_PATH);
-
-	if (framesetDirectory.exists()) {
-	    File[] startpagesFramesets = framesetDirectory.listFiles();
-
-	    if (startpagesFramesets != null) {
-		// Add Start Page title
-		Text templates = profile.addText(xPos, yPos, "@Start Pages",
-			null);
-		templates.setSize(25);
-		templates.setFontStyle("Bold");
-		templates.setFamily("SansSerif");
-		templates.setColor(TemplateSettings.ColorWheel.get()[3]);
-
-		xPos += 25;
-
-		// Start Pages should be the first frame in its own frameset +
-		// frameset name should be present in FrameUtils.startPages[].
-		for (File startpagesFrameset : startpagesFramesets) {
-		    String framesetName = startpagesFrameset.getName();
-
-		    // Only add link if frameset is a startpage
-		    for (int i = 0; i < startPages.length; i++) {
-			if (framesetName.equals(startPages[i])) {
-			    Frame indexFrame = FrameIO
-				    .LoadFrame(framesetName + '1');
-
-			    // Add start page link
-			    if (indexFrame != null) {
-				yPos += 30;
-				t = profile.addText(xPos, yPos,
-					'@' + indexFrame.getFramesetName(),
-					null);
-				t.setLink(indexFrame.getName());
-				t.setColor(Color.gray);
-			    }
-			}
-		    }
-		}
-	    }
-	}
-
-	FrameIO.SaveFrame(profile);
-
-	// Populate settings frameset
-	Settings.Init();
-	t = profile.addText(550, 100, "@Settings", null);
-	t.setSize((float) 25.0);
-	t.setFamily("SansSerif");
-	t.setFontStyle("Bold");
-	t.setColor(Color.gray);
-	Settings.generateSettingsTree(t);
-
-	FrameIO.SaveFrame(profile);
-    }
-
-    private static void checkTDFCItemWaiting(Frame currentFrame) {
-	Item tdfcItem = FrameUtils.getTdfcItem();
-	// if there is a TDFC Item waiting
-	if (tdfcItem != null) {
-	    boolean change = currentFrame.hasChanged();
-	    boolean saved = currentFrame.isSaved();
-	    // Save the parent of the item if it has not been saved
-	    if (!change && !saved) {
-		tdfcItem.setLink(null);
-		tdfcItem.getParent().setChanged(true);
-		FrameIO.SaveFrame(tdfcItem.getParent());
-		FrameGraphics.Repaint();
-	    } else {
-		SessionStats.CreatedFrame();
-	    }
-
-	    setTdfcItem(null);
-	}
-    }
-
-    public static void setTdfcItem(Item _tdfcItem) {
-	FrameUtils._tdfcItem = _tdfcItem;
-    }
-
-    public static Item getTdfcItem() {
-	return FrameUtils._tdfcItem;
-    }
-
-    private static Item _tdfcItem = null;
-
-    public static void setLastEdited(Text lastEdited) {
-
-	// If the lastEdited is being changed then check if its @i
-	Frame toReparse = null;
-	Frame toRecalculate = null;
-	Frame toUpdateObservers = null;
-
-	if (LastEdited == null) {
-	    // System.out.print("N");
-	} else if (LastEdited != null) {
-	    // System.out.print("T");
-	    Frame parent = LastEdited.getParentOrCurrentFrame();
-
-	    if (lastEdited != LastEdited) {
-		if (LastEdited.startsWith("@i")) {
-		    // Check if its an image that can be resized to fit a box
-		    // around it
-		    String text = LastEdited.getText();
-		    if (text.startsWith("@i:")
-			    && !Character
-				    .isDigit(text.charAt(text.length() - 1))) {
-			Collection<Item> enclosure = FrameUtils
-				.getEnclosingLineEnds(LastEdited.getPosition());
-			if (enclosure != null) {
-			    for (Item i : enclosure) {
-				if (i.isLineEnd() && i.isEnclosed()) {
-				    DisplayIO.getCurrentFrame().removeAllItems(
-					    enclosure);
-				    Rectangle rect = i.getEnclosedRectangle();
-				    LastEdited
-					    .setText(LastEdited.getText()
-						    + " "
-						    + Math.round(rect
-							    .getWidth()));
-				    LastEdited.setPosition(new Point(rect.x,
-					    rect.y));
-				    LastEdited.setThickness(i.getThickness());
-				    LastEdited.setBorderColor(i.getColor());
-				    break;
-				}
-			    }
-			    FrameMouseActions.deleteItems(enclosure, false);
-			}
-		    }
-		    toReparse = parent;
-		} else if (LastEdited.recalculateWhenChanged()) {
-		    toRecalculate = parent;
-		}
-
-		if (parent.hasObservers()) {
-		    toUpdateObservers = parent;
-		}
-		// Update the formula if in XRay mode
-		if (FrameGraphics.isXRayMode() && LastEdited.hasFormula()) {
-		    LastEdited.setFormula(LastEdited.getText());
-		}
-	    }
-	    if (lastEdited != LastEdited && LastEdited.getText().length() == 0) {
-		parent.removeItem(LastEdited);
-	    }
-	}
-	LastEdited = lastEdited;
-
-	if (!FrameGraphics.isXRayMode()) {
-	    if (toReparse != null) {
-		Parse(toReparse, false, false);
-	    } else {
-		if (toRecalculate != null) {
-		    toRecalculate.recalculate();
-		}
-
-		if (toUpdateObservers != null) {
-		    toUpdateObservers.notifyObservers(false);
-		}
-	    }
-	}
-    }
-
-    /**
-     * Extracts files/folders from the assets/resources folder directly into
-     * ${PARENT_FOLDER} (~/.expeditee)
-     * 
-     * @param force if true, resources will be extracted even if they have already been extracted before
-     */
-    public static void extractResources(boolean force) {
-    	File check = new File(FrameIO.PARENT_FOLDER + ".res");
-    	if(!force && check.exists()) {
-    		return;
-    	}
-		System.out.println("Extracting/Installing resources:");
 		try	{
 			check.getParentFile().mkdirs();
-	        check.createNewFile();
-	        
+			check.createNewFile();
+
 			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 			URL docURL = classLoader.getResource("org/expeditee/assets/resources");
-			
+
 			// copy files from the jar file to the profile folder
 			if (docURL.getProtocol().equals("jar")) {
@@ -1840,7 +1839,7 @@
 				String res = "org/expeditee/assets/resources/";
 				int resLength = res.length();
-				
+
 				ZipEntry ze;
-				
+
 				while(jarEntries.hasMoreElements()) {
 					ze = jarEntries.nextElement();
@@ -1850,7 +1849,7 @@
 					File out = new File(FrameIO.PARENT_FOLDER + ze.getName().substring(resLength));
 					// System.out.println("Didn't crash here " + out.getPath());
-//					if(out.exists()) {
-//						continue;
-//					}
+					//					if(out.exists()) {
+					//						continue;
+					//					}
 					if(ze.isDirectory()) {
 						// System.out.println(out.getPath() + " IS DIRECTORY");
@@ -1881,6 +1880,6 @@
 					}
 				}
-				
-			// Copy files from the source folder to the profile folder
+
+				// Copy files from the source folder to the profile folder
 			} else if (docURL.getProtocol().equals("bundleresource")) {
 				final URLConnection urlConnection = docURL.openConnection();
@@ -1899,42 +1898,44 @@
 	}
 
-    private static void extractResourcesFromFolder(File folder) throws IOException {
-	LinkedList<File> items = new LinkedList<File>();
-	items.addAll(Arrays.asList(folder.listFiles()));
-	LinkedList<File> files = new LinkedList<File>();
-	String res = "org" + File.separator + "expeditee" + File.separator + "assets" + File.separator + "resources";
-	int resLength = res.length();
-	
-	while (items.size() > 0) {
-		File file = items.remove(0);
-		if(file.isFile()) {
-			if(!file.getName().contains(".svn")) {
-				files.add(file);
-			}
-		} else {
-			if (!file.getName().contains(".svn")) {
-				items.addAll(Arrays.asList(file.listFiles()));
-			}
-		}
-	}
-	for (File file : files) {
-		System.out.println(file.getPath());
-		File out = new File(FrameIO.PARENT_FOLDER + file.getPath().substring(file.getPath().indexOf(res) + resLength));
-//		if(out.exists()) {
-//			continue;
-//		}
-		copyFile(file, out, true);
-	}
-    }
-    
-    /**
-     * @param src
-     * @param dst
-     * @throws IOException
-     */
-    public static void copyFile(File src, File dst, boolean overWrite) throws IOException {
-    	if(!overWrite && dst.exists())
-    		return;
-    	dst.getParentFile().mkdirs();
+	private static void extractResourcesFromFolder(File folder) throws IOException
+	{
+		LinkedList<File> items = new LinkedList<File>();
+		items.addAll(Arrays.asList(folder.listFiles()));
+		LinkedList<File> files = new LinkedList<File>();
+		String res = "org" + File.separator + "expeditee" + File.separator + "assets" + File.separator + "resources";
+		int resLength = res.length();
+
+		while (items.size() > 0) {
+			File file = items.remove(0);
+			if(file.isFile()) {
+				if(!file.getName().contains(".svn")) {
+					files.add(file);
+				}
+			} else {
+				if (!file.getName().contains(".svn")) {
+					items.addAll(Arrays.asList(file.listFiles()));
+				}
+			}
+		}
+		for (File file : files) {
+			System.out.println(file.getPath());
+			File out = new File(FrameIO.PARENT_FOLDER + file.getPath().substring(file.getPath().indexOf(res) + resLength));
+			//		if(out.exists()) {
+			//			continue;
+			//		}
+			copyFile(file, out, true);
+		}
+	}
+
+	/**
+	 * @param src
+	 * @param dst
+	 * @throws IOException
+	 */
+	public static void copyFile(File src, File dst, boolean overWrite) throws IOException
+	{
+		if(!overWrite && dst.exists()) return;
+		
+		dst.getParentFile().mkdirs();
 		FileOutputStream fOut = null;
 		FileInputStream fIn = null;
@@ -1959,21 +1960,23 @@
 			}
 		}
-    }
-
-    public static Text getLastEdited() {
-	return LastEdited;
-    }
-
-    public static Collection<Text> getCurrentTextItems() {
-	Collection<Text> currentTextItems = new LinkedHashSet<Text>();
-	Collection<Item> currentItems = getCurrentItems(null);
-	if (currentItems != null) {
-	    for (Item i : getCurrentItems(null)) {
-		if (i instanceof Text && !i.isLineEnd()) {
-		    currentTextItems.add((Text) i);
-		}
-	    }
-	}
-	return currentTextItems;
-    }
+	}
+
+	public static Text getLastEdited()
+	{
+		return LastEdited;
+	}
+
+	public static Collection<Text> getCurrentTextItems()
+	{
+		Collection<Text> currentTextItems = new LinkedHashSet<Text>();
+		Collection<Item> currentItems = getCurrentItems(null);
+		if (currentItems != null) {
+			for (Item i : getCurrentItems(null)) {
+				if (i instanceof Text && !i.isLineEnd()) {
+					currentTextItems.add((Text) i);
+				}
+			}
+		}
+		return currentTextItems;
+	}
 }
Index: /trunk/src/org/expeditee/gui/FreeItems.java
===================================================================
--- /trunk/src/org/expeditee/gui/FreeItems.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/FreeItems.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.gui;
 
-import java.awt.Polygon;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -29,4 +28,5 @@
 import java.util.Map;
 
+import org.expeditee.core.bounds.PolygonBounds;
 import org.expeditee.items.Dot;
 import org.expeditee.items.Item;
@@ -42,17 +42,22 @@
 	private static FreeItems _cursor = new FreeItems();
 
-	private FreeItems() {
-	}
-
-	public static FreeItems getCursor() {
+	public static FreeItems getCursor()
+	{
 		return _cursor;
 	}
 	
-	public static FreeItems getInstance() {
+	public static FreeItems getInstance()
+	{
 		return _instance;
 	}
 
-	@Override
-	public void clear() {
+	/** Singleton class (although there are two of them). */
+	private FreeItems()
+	{
+	}
+	
+	@Override
+	public void clear()
+	{
 		for (Item i : this) {
 			i.invalidateAll();
@@ -63,5 +68,6 @@
 
 	@Override
-	public Item remove(int index) {
+	public Item remove(int index)
+	{
 		Item i = get(index);
 		remove(i);
@@ -70,9 +76,11 @@
 
 	@Override
-	public boolean remove(Object o) {
+	public boolean remove(Object o)
+	{
 		if (o instanceof Item) {
 			((Item) o).invalidateAll();
 			((Item) o).invalidateFill();
 		}
+		
 		return super.remove(o);
 	}
@@ -84,5 +92,6 @@
 	 * @return true if at least one item is attached to the cursor.
 	 */
-	public static boolean itemsAttachedToCursor() {
+	public static boolean hasItemsAttachedToCursor()
+	{
 		return getInstance().size() > 0;
 	}
@@ -94,24 +103,26 @@
 	 *         attached are text items.
 	 */
-	public static boolean textOnlyAttachedToCursor() {
-		if (!itemsAttachedToCursor())
-			return false;
-		for (Item i : getInstance()) {
-			if (!(i instanceof Text)) {
-				return false;
-			}
-		}
+	public static boolean textOnlyAttachedToCursor()
+	{
+		if (!hasItemsAttachedToCursor()) return false;
+		
+		for (Item i : getInstance()) {
+			if (!(i instanceof Text)) return false;
+		}
+		
 		return true;
 	}
 
-	public static Item getItemAttachedToCursor() {
-		if (itemsAttachedToCursor())
-			return getInstance().get(0);
+	public static Item getItemAttachedToCursor()
+	{
+		if (hasItemsAttachedToCursor()) return getInstance().get(0);
+		
 		return null;
 	}
 
-	public static Text getTextAttachedToCursor() {
-		if (textOnlyAttachedToCursor())
-			return (Text) getInstance().get(0);
+	public static Text getTextAttachedToCursor()
+	{
+		if (textOnlyAttachedToCursor()) return (Text) getInstance().get(0);
+		
 		return null;
 	}
@@ -121,10 +132,10 @@
 	 * @return the list of free text items
 	 */
-	public static Collection<Text> getTextItems() {
+	public static Collection<Text> getTextItems()
+	{
 		Collection<Text> textItems = new LinkedList<Text>();
-		for (Item i : getInstance()) {
-			if (i instanceof Text) {
-				textItems.add((Text) i);
-			}
+		
+		for (Item i : getInstance()) {
+			if (i instanceof Text) textItems.add((Text) i);
 		}
 
@@ -132,12 +143,13 @@
 	}
 
-	public static Map<String, Collection<String>> getGroupedText() {
+	public static Map<String, Collection<String>> getGroupedText()
+	{
 		Map<String, Collection<String>> groupedText = new HashMap<String, Collection<String>>();
+		
 		// Go throught the lineEnds
 		Collection<Item> addedItems = new HashSet<Item>();
 		for (Item i : getInstance()) {
-			if (!(i instanceof Text) || !i.isLineEnd()) {
-				continue;
-			}
+			if (!(i instanceof Text) || !i.isLineEnd()) continue;
+			
 			// Check for text inside the box
 			Collection<String> textList = new LinkedList<String>();
@@ -146,8 +158,10 @@
 				addedItems.add(enclosed);
 			}
+			
 			if (textList.size() > 0) {
 				groupedText.put(i.getText(), textList);
 			}
 		}
+		
 		// Now add the items that were not contained in any of the boxes
 		Collection<String> outsideList = new LinkedList<String>();
@@ -157,4 +171,5 @@
 			}
 		}
+		
 		groupedText.put("", outsideList);
 
@@ -169,6 +184,8 @@
 	 * @return
 	 */
-	private Collection<Text> getTextWithin(Item lineEnd) {
-		Polygon poly = lineEnd.getEnclosedShape();
+	private Collection<Text> getTextWithin(Item lineEnd)
+	{
+		PolygonBounds poly = lineEnd.getEnclosedShape();
+		
 		Collection<Text> results = new LinkedHashSet<Text>();
 		for (Item i : this) {
@@ -177,18 +194,23 @@
 			}
 		}
+		
 		return results;
 	}
 
-	public static boolean hasCursor() {
+	public static boolean hasCursor()
+	{
 		return getCursor().size() > 0;
 	}
 
-	public static void setCursor(Collection<Item> cursor) {
+	public static void setCursor(Collection<Item> cursor)
+	{
 		_cursor.clear();
 		_cursor.addAll(cursor);
 	}
 	
-	public static boolean hasMultipleVisibleItems() {
+	public static boolean hasMultipleVisibleItems()
+	{
 		List<Item> toCount = new LinkedList<Item>(getInstance());
+		
 		int c = 0;
 		while(!toCount.isEmpty()) {
@@ -199,10 +221,44 @@
 			}
 		}
+		
 		return false;
 	}
 	
-	public static boolean isDrawingPolyLine() {
+	public static boolean isDrawingPolyLine()
+	{
 		List<Item> tmp = getInstance();
+		
 		return tmp.size() == 2 && tmp.get(0) instanceof Dot && tmp.get(1) instanceof Line;
 	}
+
+	/**
+	 * Checks if lines are being rubber banded.
+	 * 
+	 * @return true if the user is rubberBanding one or more lines
+	 */
+	public static boolean rubberBanding()
+	{
+		if (getInstance().size() != 2) return false;
+
+		// if rubber-banding, there will be 1 line end and the rest will be lines
+		boolean foundLineEnd = false;
+		for (Item i : getInstance()) {
+			if (i.isLineEnd()) {
+				if (foundLineEnd) return false;
+				foundLineEnd = true;
+			} else if (!(i instanceof Line) || !i.isVisible()) {
+				return false;
+			}
+		}
+		
+		return true;
+	}
+	
+	@Override
+	public FreeItems clone()
+	{
+		FreeItems ret = new FreeItems();
+		ret.addAll(this);
+		return ret;
+	}
 }
Index: /trunk/src/org/expeditee/gui/FunctionKey.java
===================================================================
--- /trunk/src/org/expeditee/gui/FunctionKey.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/FunctionKey.java	(revision 1102)
@@ -19,7 +19,18 @@
 package org.expeditee.gui;
 
-//these numbers correspond to the Function Key numbers (0 = Escape key)
+/** Enumerates the Function Key numbers (0 = Escape key) */
 public enum FunctionKey {
-	DropDown, SizeUp, SizeDown, ChangeColor, ToggleAnnotation, InsertDate, NewFrameset, ChangeFontStyle, ChangeFontFamily,
-	AudienceMode, XRayMode, Save, Refresh;
+	DropDown,
+	SizeUp,
+	SizeDown,
+	ChangeColor,
+	ToggleAnnotation,
+	InsertDate,
+	NewFrameset,
+	ChangeFontStyle,
+	ChangeFontFamily,
+	AudienceMode,
+	XRayMode,
+	Save,
+	Refresh
 }
Index: /trunk/src/org/expeditee/gui/Help.java
===================================================================
--- /trunk/src/org/expeditee/gui/Help.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/Help.java	(revision 1102)
@@ -26,9 +26,8 @@
 import org.expeditee.items.Picture;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.items.widgets.WidgetEdge;
 import org.expeditee.settings.experimental.ExperimentalFeatures;
-
 
 public class Help {
@@ -120,4 +119,6 @@
 			if((mod & shift) == 0)return "Extend line";
 			break;
+		default:
+			break;
 		}
 		if((other & cursor) != 0) return "Stamp copy";
@@ -152,4 +153,6 @@
 			}
 			break;
+		default:
+			break;
 		}
 		return "Delete";
@@ -165,4 +168,6 @@
 			if((other & cursor) == 0) return "Select text region";
 			break;
+		default:
+			break;
 		}
 		return null;
@@ -174,4 +179,6 @@
 		case text:
 			if((other & cursor) == 0) return "Cut text region";
+		default:
+			break;
 		}
 		return null;
@@ -187,4 +194,6 @@
 		case text:
 			if((other & cursor) == 0) return "Copy text region";
+		default:
+			break;
 		}
 		return null;
@@ -192,9 +201,10 @@
 	
 	
-	public static void updateStatus() {
+	public static void updateStatus(boolean controlDown, boolean shiftDown)
+	{
 		Item current = FrameUtils.getCurrentItem();
 		Collection<Item> currents;
 		Context context;
-		InteractiveWidget iw = null;
+		Widget iw = null;
 		if(current != null) {
 			if(current instanceof Line) {
@@ -232,9 +242,9 @@
 			}
 		}
-		int mod = (FrameMouseActions.isControlDown() ? control : 0) | (FrameMouseActions.isShiftDown() ? shift : 0);
+		int mod = (controlDown ? control : 0) | (shiftDown ? shift : 0);
 		int other = (ExperimentalFeatures.MousePan.get() ? panning : 0) |
 				(current != null && current.hasAction() ? action : 0)|
 				(current != null && current.hasLink() ? link : 0) |
-				(FreeItems.itemsAttachedToCursor() ? cursor : 0);
+				(FreeItems.hasItemsAttachedToCursor() ? cursor : 0);
 		String status = "";
 		
@@ -264,5 +274,4 @@
 		}
 		
-		
 		MessageBay.setStatus(status);
 	}
Index: /trunk/src/org/expeditee/gui/MessageBay.java
===================================================================
--- /trunk/src/org/expeditee/gui/MessageBay.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/MessageBay.java	(revision 1102)
@@ -19,273 +19,202 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.GraphicsEnvironment;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.geom.Area;
-import java.awt.image.VolatileImage;
 import java.util.LinkedList;
 import java.util.List;
 
+import org.expeditee.Util;
 import org.expeditee.actions.Misc;
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Font;
+import org.expeditee.core.Image;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
 
 /**
- * The bay at the bottom of the expeditee browser which displays messages. TODO
- * make it thread safe!
- * 
+ * The bay at the bottom of the expeditee browser which displays messages.
+ * TODO: Make it thread safe!
  */
 public final class MessageBay {
 
-
-	public static final int MESSAGE_BUFFER_HEIGHT = 105;
-
+	/** The distance from the top of the message bay to the Message frame link. */
 	private static final int MESSAGE_LINK_Y_OFFSET = 100;
 
+	/** TODO: Comment. cts16 */
 	private static final int MESSAGE_LINK_X = 50;
 
-	public static final Color ERROR_COLOR = Color.red;
-
+	/** TODO: Comment. cts16 */
+	public static final Colour ERROR_COLOR = Colour.RED;
+
+	/** TODO: Comment. cts16 */
 	public static final String MESSAGES_FRAMESET_NAME = "Messages";
 
-	// messages shown in the message window
+	/** The list of messages shown in the message bay. */
 	private static List<Item> _messages = new LinkedList<Item>();
+	
+	/** Messages which were delayed because they couldn't be shown at time of creation. */
+	private static List<DelayedMessage> _delayedMessages = new LinkedList<DelayedMessage>();
+
+	/** TODO: Comment. cts16 */
 	private static Text _status = null;
 
-	// buffer of the message window
-	private static VolatileImage _messageBuffer = null;
-
-	// creator for creating the message frames
+	/** Buffer image of the message window. */
+	private static Image _messageBuffer = null;
+
+	/** Creator for creating the message frames. */
 	private static FrameCreator _creator = null;
 
-	// font used for the messages
-	private static Font _messageFont = Font.decode("Serif-Plain-16");
-
-	// the number of messages currently shown (used for scrolling up)
+	/** Font used for the messages. */
+	private static Font _messageFont = new Font("Serif-Plain-16");
+
+	/** The number of messages currently shown (used for scrolling up). */
 	private static int _messageCount = 0;
 
-	// if true, error messages are not shown to the user
+	/** If true, error messages are not shown to the user. */
 	private static boolean _suppressMessages = false;
 
-	// The link to the message frameset
-	private static Item _messageLink = new Text(-2, "@"
-			+ MESSAGES_FRAMESET_NAME, Color.black, Color.white);
-
-	private static List<Rectangle> _dirtyAreas = new LinkedList<Rectangle>();
-
+	/** The link to the message frameset. */
+	private static Item _messageLink = new Text(-2, "@" + MESSAGES_FRAMESET_NAME, Colour.BLACK, Colour.WHITE);
+
+	/** TODO: Comment. cts16 */
 	private static String _lastMessage = null;
 
-	private MessageBay() {
-	}
-
-	/**
-	 * Syncs messsage bay size according to FrameGraphics max size.
-	 * 
-	 */
-	static void updateSize() {
-
-		_messageBuffer = null;
-
+	/** TODO: Comment. cts16 */
+	private static boolean isLinkInitialized = false;
+
+	/** Static-only class. */
+	private MessageBay()
+	{
+	}
+	
+	/** Whether the message bay is ready to display messages. */
+	public static boolean isReady()
+	{
+		return Browser.isInitComplete();
+	}
+
+	/** Syncs message bay size according to FrameGraphics max size. */
+	static void updateSize()
+	{
 		for(Item i : _messages) {
 			if(i != null) {
-				i.setOffset(0, -FrameGraphics.getMaxFrameSize().height);
-				// i.setMaxWidth(FrameGraphics.getMaxFrameSize().width);
+				i.setOffset(0, -DisplayController.getMessageBayPaintArea().getMinY());
 			}
 		}
 
-		_messageLink.setOffset(0, -FrameGraphics.getMaxFrameSize().height);
-		// _messageLink.setMaxWidth(FrameGraphics.getMaxFrameSize().width);
-		// _messageLink.setPosition(FrameGraphics.getMaxFrameSize().width
-		// - MESSAGE_LINK_Y_OFFSET, MESSAGE_LINK_X);
+		_messageLink.setOffset(0, -DisplayController.getMessageBayPaintArea().getMinY());
+
 		updateLink();
-		initBuffer();
-	}
-
-	/**
-	 * @param i
-	 * @return True if i is an item in the message bay
-	 */
-	public static boolean isMessageItem(Item i) {
-		
-		return _messages.contains(i) || i == _messageLink;
-	}
-
-	public synchronized static void addDirtyArea(Rectangle r) {
-		_dirtyAreas.add(r);
-	}
-
-	static synchronized int getMessageBufferHeight() {
-		if (_messageBuffer != null)
-			return _messageBuffer.getHeight();
-		return 0;
-	}
-
-	public synchronized static Item getMessageLink() {
+	}
+
+	/** Whether the given item is an item in the message bay. */
+	public static boolean isMessageItem(Item i)
+	{
+		return _messages.contains(i) || i == _messageLink || i == _status;
+	}
+
+	/** TODO: Comment. cts16 */
+	public synchronized static Item getMessageLink()
+	{
 		return _messageLink;
 	}
 
-	public synchronized static List<Item> getMessages() {
+	/** TODO: Comment. cts16 */
+	public synchronized static List<Item> getMessages()
+	{
 		return _messages;
 	}
 
-	public synchronized static boolean isDirty() {
-		return !_dirtyAreas.isEmpty();
-	}
-
-	public synchronized static void invalidateFullBay() {
-		if (_messageBuffer != null) {
-			_dirtyAreas.clear();
-			addDirtyArea(new Rectangle(0,
-					FrameGraphics.getMaxFrameSize().height, _messageBuffer
-							.getWidth(), _messageBuffer.getHeight()));
-		}
-	}
-
-	private synchronized static boolean initBuffer() {
-		if (_messageBuffer == null) {
-			if (FrameGraphics.isAudienceMode()
-					|| FrameGraphics.getMaxSize().width <= 0)
-				return false;
-
-			GraphicsEnvironment ge = GraphicsEnvironment
-					.getLocalGraphicsEnvironment();
-			_messageBuffer = ge.getDefaultScreenDevice()
-					.getDefaultConfiguration().createCompatibleVolatileImage(
-							FrameGraphics.getMaxSize().width,
-							MESSAGE_BUFFER_HEIGHT);
-		}
-		return true;
-	}
-
-	private static boolean isLinkInitialized = false;
-
-	private static void updateLink() {
-
-		if (!isLinkInitialized && FrameGraphics.getMaxSize().width > 0) {
+	/** Causes the entire message bay area to be invalidated. */
+	public synchronized static void invalidateFullBay()
+	{
+		DisplayController.invalidateArea(DisplayController.getMessageBayPaintArea());
+	}
+
+	/** TODO: Comment. cts16 */
+	private static void updateLink()
+	{
+		if (!isLinkInitialized && DisplayController.getFramePaintArea().getWidth() > 0) {
 			// set up 'Messages' link on the right hand side
-			_messageLink.setPosition(FrameGraphics.getMaxSize().width
-					- MESSAGE_LINK_Y_OFFSET, MESSAGE_LINK_X);
-			_messageLink.setOffset(0, -FrameGraphics.getMaxFrameSize().height);
+			_messageLink.setPosition(DisplayController.getMessageBayPaintArea().getWidth() - MESSAGE_LINK_Y_OFFSET, MESSAGE_LINK_X);
+			_messageLink.setOffset(0, -DisplayController.getMessageBayPaintArea().getMinY());
 			isLinkInitialized = true;
-
 		} else {
-			_messageLink.setPosition(FrameGraphics.getMaxSize().width
-					- MESSAGE_LINK_Y_OFFSET, MESSAGE_LINK_X);
-		}
-	}
-
-	/**
-	 * Repaints the message bay. Updates the message bay buffer and draws to
-	 * given graphics.
-	 * 
-	 * @param useInvalidation
-	 *            Set to true of repinting dirty areas only. Otherwise false for
-	 *            full-repaint.
-	 * 
-	 * @param g
-	 * 
-	 * @param background
-	 *            The color of the message background
-	 */
-	public static synchronized void refresh(boolean useInvalidation,
-			Graphics g, Color background) {
-
-		if(g == null)
-			return;
-		
-		if (FrameGraphics.getMaxSize().width <= 0)
-			return;
-
-		Area clip = null;
-
-		if (useInvalidation) { // build clip
-
-			if (!_dirtyAreas.isEmpty()) {
-
-				for (Rectangle r : _dirtyAreas) {
-					r.y = (r.y < 0) ? 0 : r.y;
-					r.x = (r.x < 0) ? 0 : r.x;
-					if (clip == null)
-						clip = new Area(r);
-					else
-						clip.add(new Area(r));
+			_messageLink.setPosition(DisplayController.getMessageBayPaintArea().getWidth() - MESSAGE_LINK_Y_OFFSET, MESSAGE_LINK_X);
+		}
+	}
+
+	/** TODO: Comment. cts16 */
+	public static Image getImage(Clip clip, Dimension size)
+	{
+		// Can't get an image with an invalid size
+		if (size == null || size.width <= 0 || size.height <= 0) return null;
+
+		// Update the buffer
+		updateBuffer(Item.DEFAULT_BACKGROUND, clip, size);
+		
+		// Return the image buffer
+		return _messageBuffer;
+	}
+
+	/** Updates the image buffer to reflect the current state of the message bay. */
+	private static void updateBuffer(Colour background, Clip clip, Dimension size)
+	{
+		// If the buffer doesn't exist or is the wrong size, recreate it
+		if (_messageBuffer == null || !_messageBuffer.getSize().equals(size)) {
+			_messageBuffer = Image.createImage(size, true);
+			clip = null; // Need to recreate the entire image;
+			updateSize();
+		}
+
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		g.pushDrawingSurface(_messageBuffer);
+
+		if (clip != null) g.pushClip(clip);
+		g.setAntialiasing(true);
+		
+		g.clear(background);
+		
+		g.setFont(_messageFont);
+		
+		for (Item message : _messages) {
+			if (message != null) {
+				if (clip == null || clip.isNotClipped() || message.isInDrawingArea(clip.getBounds())) {
+					FrameGraphics.PaintItem(message);
 				}
-			} else
-				return; // nothing to render
-		}
-
-		_dirtyAreas.clear();
-
-		// Update the buffer
-		updateBuffer(background, clip);
-
-		// Now repaint to screen
-		if (!FrameGraphics.isAudienceMode()) {
-
-			// Translate clip to messagebox coords
-			// clip.transform(t) // TODO
-			// g.setClip(clip);
-
-			g.drawImage(_messageBuffer, 0, FrameGraphics.getMaxFrameSize().height, null);
-		}
-
-	}
-
-	private static void updateBuffer(Color background, Area clip) {
-		if (!initBuffer())
-			return;
-
-		Graphics2D g = _messageBuffer.createGraphics();
-
-		g.setClip(clip);
-
-		g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
-				RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
-		g.setColor(background);
-		g.fillRect(0, 0, FrameGraphics.getMaxSize().width,
-				MESSAGE_BUFFER_HEIGHT);
-		g.setFont(_messageFont);
-		g.setColor(Color.BLACK);
-		g.drawLine(0, 0, FrameGraphics.getMaxSize().width, 0);
-
-		for (Item t : _messages) {
-			if (t == null)
-				continue;
-			if (clip == null || t.isInDrawingArea(clip))
-				FrameGraphics.PaintItem(g, t);
-		}
-		if(_status != null)
-			FrameGraphics.PaintItem(g, _status);
-
-		if (// _messageLink.getLink() != null
-		// &&
-		(clip == null || _messageLink.isInDrawingArea(clip))) {
-			FrameGraphics.PaintItem(g, _messageLink);
-		}
-		g.dispose();
-
-	}
-
-	private static Text displayMessage(String message, String link,
-			List<String> actions, Color color) {
+			}
+		}
+		
+		if (_status != null) FrameGraphics.PaintItem(_status);
+
+		if (clip == null || clip.isNotClipped() || _messageLink.isInDrawingArea(clip.getBounds())) {
+			FrameGraphics.PaintItem(_messageLink);
+		}
+		
+		g.popDrawingSurface();
+	}
+
+	/** TODO: Comment. cts16 */
+	private static Text displayMessage(String message, String link, List<String> actions, Colour color)
+	{
 		return displayMessage(message, link, actions, color, true);
 	}
 
-	public synchronized static Text displayMessage(String message, String link, Color color,
-			boolean displayAlways, String action) {
+	/** TODO: Comment. cts16 */
+	public synchronized static Text displayMessage(String message, String link, Colour color, boolean displayAlways, String action)
+	{
 		List<String> actions = new LinkedList<String>();
-		if (action != null)
-			actions.add(action);
+		if (action != null) actions.add(action);
 		return displayMessage(message, link, actions, color, displayAlways);
 	}
-	
-	private static Text newMessage(String message, String link, List<String> actions, Color color) {
+
+	/** TODO: Comment. cts16 */
+	private static Text newMessage(String message, String link, List<String> actions, Colour color)
+	{
 		Text t = new Text(getMessagePrefix(true) + message);
 		t.setPosition(20, 15 + _messages.size() * 25);
-		t.setOffset(0, -FrameGraphics.getMaxFrameSize().height);
+		t.setOffset(0, -DisplayController.getFramePaintArea().getHeight());
 		t.setColor(color);
 		t.setLink(link);
@@ -296,15 +225,21 @@
 		return t;
 	}
-	
-	private synchronized static Text displayMessage(String message, String link,
-			List<String> actions, Color color, boolean displayAlways, boolean redraw) {
+
+	/** TODO: Comment. cts16 */
+	private synchronized static Text displayMessage(String message, String link, List<String> actions, Colour color, boolean displayAlways, boolean redraw)
+	{
+		assert (message != null);
+		
+		if (!isReady()) {
+			delayMessage(message, link, actions, color, displayAlways, redraw);
+			return null;
+		}
+		
 		System.out.println(message);
-		assert (message != null);
 
 		// Invalidate whole area
 		invalidateFullBay();
 
-		if (_suppressMessages)
-			return null;
+		if (_suppressMessages) return null;
 
 		if (!displayAlways && message.equals(_lastMessage)) {
@@ -312,9 +247,9 @@
 			return null;
 		}
+		
 		_lastMessage = message;
 
 		if (_creator == null) {
-			_creator = new FrameCreator(MESSAGES_FRAMESET_NAME,
-					FrameIO.MESSAGES_PATH, MESSAGES_FRAMESET_NAME, true, false);
+			_creator = new FrameCreator(MESSAGES_FRAMESET_NAME, FrameIO.MESSAGES_PATH, MESSAGES_FRAMESET_NAME, true, false);
 		}
 
@@ -336,9 +271,7 @@
 		_messageLink.setLink(_creator.getCurrent());
 
+		// TODO: Can we just make this DisplayController.requestRefresh()? cts16
 		if(redraw) {
-    		Graphics g = FrameGraphics.createGraphics();
-    		if (g != null) {
-    		    refresh(false, g, Item.DEFAULT_BACKGROUND);
-    		}
+			DisplayController.requestRefresh(true);
 		}
 
@@ -346,30 +279,36 @@
 	}
 
-	public synchronized static Text displayMessage(String message, String link,
-			List<String> actions, Color color, boolean displayAlways) {
+	/** TODO: Comment. cts16 */
+	public synchronized static Text displayMessage(String message, String link, List<String> actions, Colour color, boolean displayAlways)
+	{
 		return displayMessage(message, link, actions, color, displayAlways, true);
 	}
 
-	public synchronized static void overwriteMessage(String message) {
+	/** TODO: Comment. cts16 */
+	public synchronized static void overwriteMessage(String message)
+	{
 		overwriteMessage(message, null);
 	}
 
-	public synchronized static void overwriteMessage(String message, Color color) {
+	/** TODO: Comment. cts16 */
+	public synchronized static void overwriteMessage(String message, Colour color)
+	{
 		_messages.remove(_messages.size() - 1);
 		Text t = newMessage(message, null, null, color);
 		_messages.add(t);
-		Graphics g = FrameGraphics.createGraphics();
-		if (g != null) {
-		    refresh(false, g, Item.DEFAULT_BACKGROUND);
-		}
-	}
-	
-	private static String getMessagePrefix(int counter) {
+		DisplayController.requestRefresh(true);
+	}
+
+	/** TODO: Comment. cts16 */
+	private static String getMessagePrefix(int counter)
+	{
 		return "@" + counter + ": ";
 	}
 
-	private static String getMessagePrefix(boolean incrementCounter) {
-		if (incrementCounter)
-			_messageCount++;
+	/** TODO: Comment. cts16 */
+	private static String getMessagePrefix(boolean incrementCounter)
+	{
+		if (incrementCounter) _messageCount++;
+		
 		return getMessagePrefix(_messageCount);
 	}
@@ -382,18 +321,18 @@
 	 *            the message to be displayed
 	 */
-	public synchronized static Text linkedErrorMessage(String message) {
-		if (_suppressMessages)
-			return null;
+	public synchronized static Text linkedErrorMessage(String message)
+	{
+		if (_suppressMessages) return null;
 		Misc.beep();
 		String[] tokens = message.split(Text.FRAME_NAME_SEPARATOR);
 		String link = null;
-		if (tokens.length > 1)
-			link = tokens[tokens.length - 1];
+		if (tokens.length > 1) link = tokens[tokens.length - 1];
 		return displayMessage(message, link, null, ERROR_COLOR);
 	}
 
-	public synchronized static Text errorMessage(String message) {
-		if (_suppressMessages)
-			return null;
+	/** TODO: Comment. cts16 */
+	public synchronized static Text errorMessage(String message)
+	{
+		if (_suppressMessages) return null;
 		Misc.beep();
 		return displayMessage(message, null, null, ERROR_COLOR, false);
@@ -407,82 +346,115 @@
 	 *            The message to display to the user in the message area
 	 */
-	public synchronized static Text displayMessage(String message) {
+	public synchronized static Text displayMessage(String message)
+	{
 		return displayMessageAlways(message);
 	}
 
-	public synchronized static Text displayMessageOnce(String message) {
-		return displayMessage(message, null, null, Color.BLACK, false);
-	}
-
-	public synchronized static Text displayMessage(String message, Color textColor) {
+	/** TODO: Comment. cts16 */
+	public synchronized static Text displayMessageOnce(String message)
+	{
+		return displayMessage(message, null, null, Colour.BLACK, false);
+	}
+
+	/** TODO: Comment. cts16 */
+	public synchronized static Text displayMessage(String message, Colour textColor)
+	{
 		return displayMessage(message, null, null, textColor);
-		// Misc.Beep();
-	}
-
-	public synchronized static Text displayMessage(Text message) {
+	}
+
+	/** TODO: Comment. cts16 */
+	public synchronized static Text displayMessage(Text message)
+	{
 		Text t = null;
 		String link = message.getLink();
 		List<String> action = message.getAction();
-		Color color = message.getColor();
+		Colour color = message.getColor();
 		for (String s : message.getTextList()) {
 			t = displayMessage(s, link, action, color);
 		}
 		return t;
+	}
+
+	/** TODO: Comment. cts16 */
+	public synchronized static Text displayMessageAlways(String message)
+	{
+		return displayMessage(message, null, null, Colour.BLACK);
 		// Misc.Beep();
 	}
 
-	public synchronized static Text displayMessageAlways(String message) {
-		return displayMessage(message, null, null, Color.BLACK);
-		// Misc.Beep();
-	}
-
-	public synchronized static Text warningMessage(String message) {
-		return displayMessage(message, null, null, Color.MAGENTA);
-		// Misc.Beep();
-	}
-
-	public synchronized static void suppressMessages(boolean val) {
+	/** TODO: Comment. cts16 */
+	public synchronized static Text warningMessage(String message)
+	{
+		return displayMessage(message, null, null, Colour.MAGENTA);
+	}
+
+	/** TODO: Comment. cts16 */
+	public synchronized static List<Text> warningMessages(List<String> messages)
+	{
+		if (messages == null) return null;
+		List<Text> ret = new LinkedList<Text>();
+		for (String message : messages) ret.add(warningMessage(message));
+		return ret;
+	}
+
+	/** TODO: Comment. cts16 */
+	public synchronized static void suppressMessages(boolean val)
+	{
 		_suppressMessages = val;
 	}
-	
-	public synchronized static void setStatus(String status) {
+
+	/** TODO: Comment. cts16 */
+	public synchronized static void setStatus(String status)
+	{
 		if (_status == null) {
 			_status = new Text(status);
 			_status.setPosition(0, 85);
-			_status.setOffset(0, FrameGraphics.getMaxFrameSize().height);
+			_status.setOffset(0, -DisplayController.getMessageBayPaintArea().getMinY());
 			_status.setLink(null); // maybe link to a help frame?
-			_status.setFont(Font.decode(Text.MONOSPACED_FONT));
+			_status.setFont(new Font(Text.MONOSPACED_FONT));
 		} else {
 			_status.setText(status);
 		}
-		Graphics g = FrameGraphics.createGraphics();
-		if (g != null) {
-			refresh(false, g, Item.DEFAULT_BACKGROUND);
-		}
-	}
-	
-	public static final class Progress {
-		
-		private static final String filled = "\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592\u2592";
-		private static final String unfilled = "\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591";
-		
-		String message;
-		Text text;
-		
-		protected Progress(String text) {
-			this.text = displayMessage(text, null, null, Color.GREEN.darker(), true, false);
-			//this.text.setFont(Font.decode(Text.MONOSPACED_FONT + "-16"));
-			this.message = this.text.getText();
-			this.text.setText(this.message + " [" + unfilled + "] 0%");
-			refresh(false, FrameGraphics.createGraphics(), Item.DEFAULT_BACKGROUND);
-		}
-		
-		public void UpdateMessage(final String text, final int newProgress) throws Exception {
-			this.message = text;
+
+		//invalidateFullBay();
+		DisplayController.requestRefresh(true);
+	}
+
+	/** TODO: Comment. cts16 */
+	public static final class Progress
+	{
+		/** The colour progress bars should be displayed in. */
+		private static final Colour BAR_COLOUR = Colour.GREEN.darker();
+		
+		/** The character used to assemble the uncompleted portions of the progress bar. */
+		private static final char UNCOMPLETED_CHARACTER = '\u2591'; // ░
+		/** The character used to assemble the completed portions of the progress bar. */
+		private static final char COMPLETED_CHARACTER = '\u2592'; // ▒
+		
+		/** What the progress bar should look like when at 100% completion. */
+		private static final String COMPLETED_BAR = Util.nCopiesOf(20, COMPLETED_CHARACTER);
+		/** What the progress bar should look like when at 0% completion. */
+		private static final String UNCOMPLETED_BAR = Util.nCopiesOf(20, UNCOMPLETED_CHARACTER);
+		
+		private String _message;
+		private Text _text;
+		
+		protected Progress(String text)
+		{
+			this._text = displayMessage(text, null, null, BAR_COLOUR, true, false);
+			this._message = this._text.getText();
+			this._text.setText(this._message + " [" + UNCOMPLETED_BAR + "] 0%");
+			DisplayController.requestRefresh(true);
+		}
+		
+		public void UpdateMessage(final String text, final int newProgress) throws Exception
+		{
+			this._message = text;
 			set(newProgress);
 		}
 		
-		public String GetMessage() {
-			return message;
+		public String GetMessage()
+		{
+			return _message;
 		}
 		
@@ -493,10 +465,11 @@
 		 * @throws Exception if progress out of bounds
 		 */
-		public boolean set(int progress) throws Exception {
+		public boolean set(int progress) throws Exception
+		{
 			if(progress < 0 || progress > 100) throw new Exception("Progress value out of bounds");
 			int p = progress / 5;
-			if(isMessageItem(this.text)) {
-				this.text.setText(this.message + " [" + filled.substring(0, p) + unfilled.substring(p) + "] " + progress + "%");
-				refresh(false, FrameGraphics.createGraphics(), Item.DEFAULT_BACKGROUND);
+			if(isMessageItem(this._text)) {
+				this._text.setText(this._message + " [" + COMPLETED_BAR.substring(0, p) + UNCOMPLETED_BAR.substring(p) + "] " + progress + "%");
+				DisplayController.requestRefresh(true);
 				return true;
 			}
@@ -504,7 +477,56 @@
     	}
 	}
+
+	/** TODO: Comment. cts16 */
+	public synchronized static Progress displayProgress(String message)
+	{
+		return new Progress(message);
+	}
 	
-	public synchronized static Progress displayProgress(String message) {
-		return new Progress(message);
+	/** Remembers the arguments to a displayMessage call for later use. */ 
+	private static class DelayedMessage {
+		
+		private String _message;
+		private String _link;
+		private List<String> _actions;
+		private Colour _colour;
+		private boolean _displayAlways;
+		private boolean _redraw;
+		
+		public DelayedMessage(String message, String link, List<String> actions, Colour color, boolean displayAlways, boolean redraw)
+		{
+			_message = message;
+			_link = link;
+			if (actions == null) {
+				_actions = null;
+			} else {
+				_actions =  new LinkedList<String>();
+				_actions.addAll(actions);
+			}
+			_colour = color == null ? null : color.clone();
+			_displayAlways = displayAlways;
+			_redraw = redraw;
+		}
+		
+		public void display()
+		{
+			displayMessage(_message, _link, _actions, _colour, _displayAlways, _redraw);
+		}
+		
+	}
+	
+	private static void delayMessage(String message, String link, List<String> actions, Colour color, boolean displayAlways, boolean redraw)
+	{
+		_delayedMessages.add(new DelayedMessage(message, link, actions, color, displayAlways, redraw));
+	}
+	
+	public static void showDelayedMessages()
+	{
+		if (isReady()) {
+			for (DelayedMessage message : _delayedMessages) message.display();
+			_delayedMessages.clear();
+			invalidateFullBay();
+			DisplayController.requestRefresh(true);
+		}
 	}
 
Index: /trunk/src/org/expeditee/gui/Overlay.java
===================================================================
--- /trunk/src/org/expeditee/gui/Overlay.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/Overlay.java	(revision 1102)
@@ -20,12 +20,19 @@
 
 import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
 
 import org.expeditee.items.UserAppliedPermission;
+import org.expeditee.items.widgets.Widget;
 
+/** TODO: Comment. cts16 */
 public class Overlay {
+	/** TODO: Comment. cts16 */
 	public Frame Frame;
 
+	/** TODO: Comment. cts16 */
 	public UserAppliedPermission permission;
 
+	/** TODO: Comment. cts16 */
 	public Overlay(Frame overlay, UserAppliedPermission level) {
 		Frame = overlay;
@@ -34,7 +41,7 @@
 
 	@Override
-	public boolean equals(Object o) {
-		if (o == null || o.getClass() != Overlay.class)
-			return false;
+	public boolean equals(Object o)
+	{
+		if (!(o instanceof Overlay)) return false;
 
 		return ((Overlay) o).Frame == Frame;
@@ -42,9 +49,13 @@
 
 	@Override
-	public int hashCode() {
+	public int hashCode()
+	{
+		// TODO: Comment. cts16
 		return 0;
 	}
-	
-	public static Overlay getOverlay(Collection<Overlay>overlays, Frame frame){
+
+	/** TODO: Comment. cts16 */
+	public static Overlay getOverlay(Collection<Overlay> overlays, Frame frame)
+	{
 		// Check the frame is in the list of overlays
 		for (Overlay o : overlays) {
Index: /trunk/src/org/expeditee/gui/Popup.java
===================================================================
--- /trunk/src/org/expeditee/gui/Popup.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/Popup.java	(revision 1102)
@@ -19,126 +19,185 @@
 package org.expeditee.gui;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.LayoutManager;
-
-import javax.swing.JComponent;
-import javax.swing.JPanel;
-
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.EnforcedClipStack.EnforcedClipKey;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Lifetime;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gui.PopupManager.PopupAnimator;
 import org.expeditee.items.ItemUtils;
 
 /**
+ * A Custom swing pop-up in Expeditee.
  * 
- * A Custom swing popup in Expeditee.
- * 
- * Expeditee popus can be re-used. Popups are always heavyweight (i.e. uses invalidation).
+ * Expeditee pop-ups can be re-used. Pop-ups are always heavyweight (i.e. uses invalidation).
  * 
  * @see {@link PopupManager}
  * 
  * @author Brook Novak
- * 
  */
-public abstract class Popup extends JPanel {
-	
+public abstract class Popup
+{
 	//Mike says: Can we get the border for the IW to which this popup corresponds?
-	// Brook says: Would be nice - but popups are actually independant from widgets
+	// Brook says: Would be nice - but popups are actually independent from widgets
 	//   =>Now: It is up to the user of the popup to set the border thickness
-	private static final BasicStroke DEFAULT_STROKE = new BasicStroke(2.0f);
-	
-	private BasicStroke _borderStroke = DEFAULT_STROKE;
-	private Color _borderColor = Color.BLACK;
-	
-	private boolean _isReadyToPaint = false;
+	private static final Stroke DEFAULT_STROKE = new Stroke(2.0f);
+	
+	private Stroke _borderStroke = DEFAULT_STROKE;
+	private Colour _borderColour = Colour.BLACK;
+	private Fill _backgroundFill = new Fill(Colour.WHITE);
+	
+	private PopupAnimator _animator = null;
+	
+	private Lifetime _autoHideTime = new Lifetime(Lifetime.INFINITE_LIFETIME);
+	private Runnable _autoHideRoutine = new Runnable()
+	{
+		@Override
+		public void run()
+		{
+			hide();
+			DisplayController.invalidateArea(getBounds());
+			DisplayController.requestRefresh(true);
+		}
+	};
+	
+	private boolean _hidden = true;
+
 	private boolean _consumeBackClick = false;
-	private boolean _autoHide = true;
-
-	/**
-	 * Creates a new popup.
-	 * Autohide is set to true.
-	 * 
-	 */
-	public Popup() {
-		super();
-		setVisible(false);
-	}
-	
-	/**
-	 * Creates a new popup.
-	 * 
-	 * @param layout the LayoutManager to use
-	 */
-	public Popup(LayoutManager layout) {
-		super(layout);
-		setVisible(false);
-	}
-
-	@Override
-	public void paint(Graphics g) {
-		super.paint(g);
-		
-		// Draw border - if not transparent
-		if (_borderStroke != null && _borderColor != null) {
-			g.setColor(_borderColor);
-			((Graphics2D)g).setStroke(_borderStroke);
-			g.drawRect(0, 0, getWidth(), getHeight());
-		}
-	}
-	
-	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);
+
+	/**
+	 * Creates a new pop-up.
+	 * Auto-hide is set to true.
+	 */
+	public Popup(PopupAnimator animator)
+	{
+		setAnimator(animator);
+	}
+	
+	public Popup(PopupAnimator animator, long lifetime)
+	{
+		this(animator);
+		_autoHideTime.setLifetime(lifetime);
+	}
+	
+	public Lifetime getAutoHideTime()
+	{
+		return _autoHideTime;
+	}
+	
+	public void setAnimator(PopupAnimator animator)
+	{
+		_animator = animator;
+	}
+	
+	public PopupAnimator getAnimator()
+	{
+		return _animator;
+	}
+	
+	public boolean isShowing()
+	{
+		return !_hidden;
+	}
+	
+	public void show()
+	{
+		if (_hidden) onShow();
+		
+		if (_animator != null) {
+			_animator.show();
+			if (!_animator.isFinished()) {
+				_autoHideTime.cancelExpiry();
+			} else {
+				_autoHideTime.refresh();
+				_autoHideTime.onExpiry(_autoHideRoutine);
+			}
+		} else {
+			_autoHideTime.refresh();
+			_autoHideTime.onExpiry(_autoHideRoutine);
+		}
+		
+		_hidden = false;
+	}
+
+	public void hide()
+	{
+		if (!_hidden) onHide();
+		
+		if (_animator != null) _animator.hide();
+		_autoHideTime.cancelExpiry();
+		_hidden = true;
+	}
+	
+	public boolean update()
+	{
+		if (_animator != null) {
+			if (!_hidden && !_animator.isFinished()) {
+				if (!_animator.update()) {
+					_autoHideTime.refresh();
+					_autoHideTime.onExpiry(_autoHideRoutine);
 				}
 			}
-		}
-		
-	}
-	
-	/**
-	 * Ensures that AWT painting turned off
-	 */
-	void prepareToPaint() {
-		if (!_isReadyToPaint) {
-			_isReadyToPaint = true;
-			ignoreAWTPainting(this);
-		}
-	}
-	
-	/**
-	 * Invoked when the popup becomes hidden, or when the popup is animating to show but cancelled.
-	 */
-	public void onHide() {} 
-	
-	/**
-	 * Invoked when the popup shows. Note this might not eventuate for animated popups.
-	 */
-	public void onShow() {}
-	
-	/**
-	 * Invoked when popups is going to show.
-	 * This always is invoked first.
-	 */
-	public void onShowing() {}
-
-	public boolean shouldConsumeBackClick() {
+			
+			if (_hidden && !_animator.isFinished()) {
+				return _animator.update();
+			}
+		} else {
+			if (_autoHideTime.hasExpired()) hide();
+		}
+		
+		return false;
+		
+	}
+	
+	public final void paint()
+	{
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		
+		// Make sure the popup isn't hidden
+		AxisAlignedBoxBounds currentBounds = getBounds();
+		if (currentBounds == null) return;
+		
+		// Draw border and background
+		g.drawRectangle(currentBounds, 0.0, _backgroundFill, _borderColour, _borderStroke, null);
+		
+		EnforcedClipKey key = g.pushClip(new Clip(currentBounds));
+		
+		paintInternal();
+		
+		g.popClip(key);
+	}
+	
+	/** Draws the interior paint area of the popup. */
+	protected abstract void paintInternal();
+	
+	/** Gets the bounds of this popup when it's fully shown. */
+	public abstract AxisAlignedBoxBounds getFullBounds();
+	
+	/** Gets the bounds of this popup in its current animated state. */
+	public AxisAlignedBoxBounds getBounds()
+	{
+		if (_animator == null) {
+			if (_autoHideTime.hasExpired()) {
+				return null;
+			} else {
+				return getFullBounds();
+			}
+		}
+		
+		return _animator.getAnimatedBounds(getFullBounds());
+	}
+	
+	/** Invoked when the popup becomes hidden, or when the popup is animating to show but cancelled. */
+	public abstract void onHide();
+	
+	/** Invoked when the popup shows. Note this might not eventuate for animated popups. */
+	public abstract void onShow();
+
+	public boolean shouldConsumeBackClick()
+	{
 		return _consumeBackClick;
 	}
@@ -150,15 +209,7 @@
 	 * 		consume the back-click event.
 	 */
-	protected void setConsumeBackClick(boolean consumeBackClick) {
+	protected void setConsumeBackClick(boolean consumeBackClick)
+	{
 		_consumeBackClick = consumeBackClick;
-	}
-	
-	/**
-	 * @param autoHideOn
-	 * 		Set to True if this popup should auto hide. (The default).
-	 * 		Set to false if this popup should be manually hidden.
-	 */
-	protected void setAudoHide(boolean autoHideOn) {
-		_autoHide = autoHideOn;
 	}
 	
@@ -167,6 +218,7 @@
 	 * 		True if this popup auto hides.
 	 */
-	public boolean doesAutoHide() {
-		return _autoHide;
+	public boolean doesAutoHide()
+	{
+		return _autoHideTime.remainingLifetime() != Lifetime.INFINITE_LIFETIME;
 	}
 	
@@ -177,19 +229,22 @@
 	 * 		The new thickness to set. Null for no border.
 	 */
-	public void setBorderThickness(float thickness) {
+	public void setBorderThickness(float thickness)
+	{
 		assert(thickness >= 0);
 		
-		if (_borderStroke != null && _borderStroke.getLineWidth() == thickness)
-			return;
+		if (_borderStroke != null && _borderStroke.thickness == thickness) return;
 		
 		boolean posInvalidate = true;
 		
-		if (thickness < _borderStroke.getLineWidth()) {
+		if (thickness < _borderStroke.thickness) {
 			invalidateAppearance();
 			posInvalidate = false;
 		}
 		
-		if (thickness == 0) _borderStroke = null;
-		else _borderStroke = new BasicStroke(thickness);
+		if (thickness == 0) {
+			_borderStroke = null;
+		} else {
+			_borderStroke = new Stroke(thickness);
+		}
 		
 		if (posInvalidate) invalidateAppearance();
@@ -201,8 +256,9 @@
 	 * 		The border thickness of this popup. Zero or more.
 	 */
-	public float getBorderThickness() {
+	public float getBorderThickness()
+	{
 		if (_borderStroke == null) return 0.0f;
-		return _borderStroke.getLineWidth();
-
+
+		return _borderStroke.thickness;
 	}
 	
@@ -214,39 +270,38 @@
 	 * 		The new color. Null for transparent.
 	 */
-	public void setBorderColor(Color c) {
-		
-		if (c == null && _borderColor != null) 
+	public void setBorderColor(Colour c)
+	{
+		if (c == null && _borderColour != null)  invalidateAppearance();
+		
+		if (c != _borderColour) {
+			_borderColour = c;
 			invalidateAppearance();
-		
-		if (c != _borderColor) {
-			_borderColor = c;
-			invalidateAppearance();
-		}
-	}
-	
-	/**
-	 * 
+		}
+	}
+	
+	/**
 	 * @return
 	 * 		The border color for the popup. NUll if transparent
 	 */
-	public Color getBorderColor() {
-		return _borderColor;
-	}
-	
-	/**
-	 * Invalidates the whole popup so that it must be fully repainted.
-	 */
-	public void invalidateAppearance() {
-		
-		if (_borderColor != null && _borderStroke != null && _borderStroke.getLineWidth() > 0) { // border
-			FrameGraphics.invalidateArea(ItemUtils.expandRectangle(getBounds(), 
-					(int)Math.ceil(getBorderThickness()) + 1));
+	public Colour getBorderColor()
+	{
+		return _borderColour;
+	}
+	
+	/**
+	 * Invalidates the whole pop-up so that it must be fully repainted.
+	 */
+	public void invalidateAppearance()
+	{
+		AxisAlignedBoxBounds bounds = getBounds();
+		
+		if (bounds == null) return;
+		
+		if (_borderColour != null && _borderStroke != null && _borderStroke.thickness > 0) { // border
+			DisplayController.invalidateArea(ItemUtils.expandRectangle(bounds, (int)Math.ceil(getBorderThickness()) + 1));
 		} else { // no border
-			FrameGraphics.invalidateArea(getBounds());
-		}
-
-	}
-	
-
-	
+			DisplayController.invalidateArea(bounds);
+		}
+
+	}
 }
Index: /trunk/src/org/expeditee/gui/PopupManager.java
===================================================================
--- /trunk/src/org/expeditee/gui/PopupManager.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/PopupManager.java	(revision 1102)
@@ -19,102 +19,94 @@
 package org.expeditee.gui;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.geom.Area;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
-
-import javax.swing.JLayeredPane;
-import javax.swing.SwingUtilities;
+import java.util.List;
+
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.EcosystemManager.Ecosystem;
 
 /**
- * A centralized container for all custom popups in expeditee.
+ * A centralised container for all custom pop-ups in expeditee.
  * 
  * @author Brook Novak
  */
-public final class PopupManager implements DisplayIOObserver {
-	
+public final class PopupManager implements DisplayObserver
+{
 	/** Singleton */
-	private PopupManager() {} 
+	private static PopupManager _instance = null;
+	
+	/**
+	 * @return The singleton instance.
+	 */
+	public static PopupManager getInstance()
+	{
+		// Only valid for Swing ecosystems
+		if (EcosystemManager.getType() != Ecosystem.Swing) return null;
+		
+		// Construct the instance
+		if (_instance == null) _instance = new PopupManager();
+		
+		return _instance;
+	}
 	
 	/** Singleton */
-	private static PopupManager _instance = new PopupManager();
-	
-	/**
-	 * @return The singleton instance.
-	 */
-	public static PopupManager getInstance() {
-		return _instance;
-	}
-	
-	// popup->invoker
-	private HashMap<Popup, Component> _popups = new HashMap<Popup, Component>();
-	// quick ref to invokers
-	private HashSet<Component> _invokers = new HashSet<Component>();
-	
-	private LinkedList<AnimatedPopup> _animatingPopups = new LinkedList<AnimatedPopup>();
-	private AnimationThread _animationThread = null;
-
-	private final int ANIMATION_DURATION = 180; // Tume its takes for a maximize . minimize to animate. In ms.
-	private final int ANIMATION_RATE = 30; // in ms
-	
-	/**
-	 * Determines whether a given point is over a popup.
+	private PopupManager()
+	{
+	} 
+	
+	private LinkedList<Popup> _popups = new LinkedList<Popup>();
+
+	/** Time its takes for a maximise/minimise to animate, in milliseconds. */
+	//private final int ANIMATION_DURATION = 180;
+	/** in milliseconds. TODO: Expand. cts16 */
+	//private final int ANIMATION_RATE = 30;
+	
+	public void add(Popup p)
+	{
+		if (p == null) return;
+
+		synchronized(_popups) {
+			if (!_popups.contains(p)) _popups.add(p);
+		}
+	}
+	
+	public void remove(Popup p)
+	{
+		if (p == null) return;
+
+		synchronized(_popups) {
+			if (_popups.contains(p)) _popups.remove(p);
+		}
+	}
+	
+	public List<Popup> getPopups()
+	{
+		synchronized(_popups) {
+			return new LinkedList<Popup>(_popups);
+		}
+	}
+	
+	/**
+	 * Determines whether a given point is over a pop-up.
 	 * 
 	 * @param p
 	 * 
-	 * @return True if p is over a popup
+	 * @return True if p is over a pop-up
 	 * 
 	 * @throws NullPointerException
 	 * 		If p is null
 	 */
-	public boolean isPointOverPopup(Point p) {
+	public boolean isPointOverPopup(Point p)
+	{
 		if (p == null) throw new NullPointerException("p");
-		for (Popup pp : _popups.keySet()) {
-			if (pp.getBounds().contains(p)) {
-				return true;
+
+		synchronized(_popups) {
+			for (Popup popup : _popups) {
+				if (popup.getBounds().contains(p)) return true;
 			}
 		}
 		
 		return false;
-	}
-	
-	/**
-	 * Tests a component to see if it is in invoker of an existing popup.
-	 * 
-	 * @param c
-	 * 	Must not be null.
-	 * 
-	 * @return
-	 * 		True if c is an invoker
-	 * 
-	 * @throws NullPointerException
-	 * 		If c is null
-	 */
-	public boolean isInvoker(Component c) {
-		if (c == null) throw new NullPointerException("c");
-		return _invokers.contains(c);
-	}
-	
-	/**
-	 * Gets an invoker for a popup
-	 * 
-	 * @param p
-	 * 		The popup to get the invoker for.
-	 * 
-	 * @return
-	 * 		The invoker for the given popup.
-	 * 		Null if popup does not exist.
-	 */
-	public Component getInvoker(Popup p) {
-		if (p == null) throw new NullPointerException("p");
-		return _popups.get(p);
 	}
 	
@@ -130,15 +122,31 @@
 	 * 		If p is null
 	 */
-	public boolean isShowing(Popup p) {
+	public boolean isShowing(Popup p)
+	{
 		if (p == null) throw new NullPointerException("p");
-		return _popups.containsKey(p);
+
+		synchronized(_popups) {
+			return _popups.contains(p) && p.isShowing();
+		}
 	}
 	
 	/**
 	 * @return
-	 * 		True if a poup is showing. False otherwise.
-	 */
-	public boolean isAnyPopupsShowing () {
-		return !_popups.isEmpty();
+	 * 		True if a pop-up is showing. False otherwise.
+	 */
+	public boolean isAnyPopupsShowing()
+	{
+		synchronized(_popups) {
+			return !_popups.isEmpty();
+		}
+	}
+	
+	public void hideAutoHidePopups()
+	{
+		synchronized(_popups) {
+			for (Popup p : _popups) {
+				if (p.doesAutoHide()) p.hide();
+			}
+		}
 	}
 	
@@ -146,10 +154,12 @@
 	 * @return
 	 * 		True if the mouse click event for going back a frame should be consumed
-	 * 		Due to a popup requesting this event to be consumed currently showing.
-	 */
-	public boolean shouldConsumeBackClick() {
-		for (Popup p : _popups.keySet()) {
-			if (p.shouldConsumeBackClick())
-				return true;
+	 * 		due to a pop-up requesting this event to be consumed currently showing.
+	 */
+	public boolean shouldConsumeBackClick()
+	{
+		synchronized(_popups) {
+			for (Popup p : _popups) {
+				if (p.shouldConsumeBackClick()) return true;
+			}
 		}
 		
@@ -157,324 +167,6 @@
 	}
 	
-	/**
-	 * Clears all popups from the browser that are autohidden.
-	 * Stops animations.
-	 */
-	public void hideAutohidePopups() {
-		
-
-		// Get rid of all animations that are not non-auto-hidden pops that are expanding
-		synchronized (_animatingPopups) {
-			
-			LinkedList<AnimatedPopup> animationsToClear = new LinkedList<AnimatedPopup>();
-			
-			for (AnimatedPopup ap : _animatingPopups) {
-				if (!(ap.popup != null && !ap.popup.doesAutoHide())) {
-					animationsToClear.add(ap);
-				}
-			}
-			
-			_animatingPopups.removeAll(animationsToClear);
-			
-		}
-		
-		LinkedList<Popup> popupsToClear = new LinkedList<Popup>();
-		LinkedList<Component> invokersToClear = new LinkedList<Component>();
-
-		// Get ride of the actual popups
-		for (Popup p : _popups.keySet()) {
-			if (p.doesAutoHide()) {
-				
-				popupsToClear.add(p);
-				invokersToClear.add(_popups.get(p));
-				
-				p.invalidateAppearance();
-				p.setVisible(false);
-				Browser._theBrowser.getLayeredPane().remove(p);
-				p.onHide();
-			}
-		}
-		
-		assert (popupsToClear.size() == invokersToClear.size());
-		
-		for (int i = 0; i < popupsToClear.size(); i++) {
-			_popups.remove(popupsToClear.get(i));
-			_invokers.remove(invokersToClear.get(i));
-		}
-		
-
-		
-	}
-	
-	
-	
-//	public void hideAllPopups() {
-//		
-//		for (Popup p : _popups.keySet()) {
-//			invalidatePopup(p);
-//			p.setVisible(false);
-//			Browser._theBrowser.getLayeredPane().remove(p);
-//			p.onHide();
-//		}
-//		_popups.clear();
-//		_invokers.clear();
-//		
-//		// Get rid of all animations
-//		synchronized (_animatingPopups) {
-//			_animatingPopups.clear();
-//		}
-//	}
-	
-	public void frameChanged() {
-		// Remove any popups that are showing on the current frame
-		hideAutohidePopups();
-	}
-
-	/**
-	 * Hides a popup - if not already hidden.
-	 * 
-	 * @param p
-	 * 		Must not be null.
-	 * 
-	 * @throws NullPointerException
-	 * 		If p is null
-	 */
-	public void hidePopup(Popup p) {
-		if (p == null) throw new NullPointerException("p");
-		
-		if (!isShowing(p) && (!p.isVisible() || p.getParent() == null)) return;
-		
-
-		// Cancel any showing animations
-		synchronized (_animatingPopups) {
-			AnimatedPopup toRemove = null;
-			for (AnimatedPopup ap : _animatingPopups) {
-				if (ap.popup == p) {
-					toRemove = ap;
-					break;
-				}
-			}
-			if (toRemove != null)
-				_animatingPopups.remove(toRemove);
-		}
-
-		p.invalidateAppearance();
-		p.setVisible(false);
-		Browser._theBrowser.getLayeredPane().remove(p);
-		Component invoker = _popups.remove(p);
-		if (invoker != null) _invokers.remove(invoker);
-		p.onHide();
-		
-	}
-	
-	/**
-	 * Hides a popup - with animation. - if not already hidden.
-	 * 
-	 * @param p
-	 * 		Must not be null.
-	 * @param animator
-	 * 		Must not be null.
-	 * 
-	 * @throws NullPointerException
-	 * 		If p or animator is null
-	 * 
-	 */
-	public void hidePopup(Popup p, PopupAnimator animator) {
-		
-		if (p == null) throw new NullPointerException("p");
-		if (animator == null) throw new NullPointerException("animator");
-		
-		if (!isShowing(p) && (!p.isVisible() || p.getParent() == null)) return;
-		
-		hidePopup(p);
-		AnimatedPopup ap = new AnimatedPopup(
-				animator, 
-				System.currentTimeMillis(), 
-				null,
-				false,
-				p.getLocation());
-
-		animator.starting(false, p.getBounds());
-		
-		synchronized (_animatingPopups) {
-			_animatingPopups.add(ap);
-		}
-
-		if (_animationThread == null || !_animationThread.isAlive() || _animationThread.willDie) {
-			_animationThread = new AnimationThread();
-			_animationThread.start();
-		}
-	}
-	
-	
-	
-	/**
-	 * Displays a popup at a specific location.
-	 * 
-	 * @param p
-	 * 		Must not be null.
-	 * 
-	 * @param invoker 
-	 * 			The component responsible for showing the popup. can be null.
-	 * 			Used such that when invoker pressed, the popup will not auto hide.
-	 * 
-	 * @param loc
-	 * 		Must not be null.
-	 * 
-	 * @throws NullPointerException
-	 * 		If p or loc is null
-	 * 
-	 */
-	public void showPopup(Popup p, Point loc, Component invoker) {
-		if (p == null) throw new NullPointerException("p");
-		if (loc == null) throw new NullPointerException("animator");
-		
-		
-		if (_popups.containsKey(p)) return;
-
-		p.prepareToPaint();
-		p.setLocation(loc);
-		p.setVisible(true);
-
-		Browser._theBrowser.getLayeredPane().add(p, JLayeredPane.POPUP_LAYER, 0);
-
-		_popups.put(p, invoker);
-		if (invoker != null) _invokers.add(invoker);
-		
-		p.onShowing();
-		p.onShow();
-		
-		// Invalidate the popup border
-		if (p.getBorderThickness() > 0.0f) {
-			p.invalidateAppearance();
-		}
-	}
-	
-	/**
-	 * Displays a popup at a specific location - with animation.
-	 * 
-	 * @param p
-	 * 		Must not be null.
-	 * 
-	 * @param invoker 
-	 * 			The component responsible for showing the popup. can be null.
-	 * 			Used such that when invoker pressed, the popup will not auto hide.
-	 * 
-	 * @param loc
-	 * 		Must not be null.
-	 * 
-	 * @param animator
-	 * 		Must not be null.
-	 * 
-	 * @throws NullPointerException
-	 * 		If p, animator or loc is null
-	 */
-	public void showPopup(Popup p, Point loc, Component invoker, PopupAnimator animator) {
-		if (animator == null)
-			throw new NullPointerException("animator");
-		if (p == null)
-			throw new NullPointerException("p");
-		if (loc == null)
-			throw new NullPointerException("loc");
-		
-		if (_popups.containsKey(p)) return;
-		
-		_popups.put(p, invoker);
-		if (invoker != null) _invokers.add(invoker);
-		
-		
-		AnimatedPopup ap = new AnimatedPopup(
-				animator, 
-				System.currentTimeMillis(), 
-				p,
-				true,
-				loc);
-		
-		
-		animator.starting(true, new Rectangle(loc.x, loc.y, p.getWidth(), p.getHeight()));
-		
-		p.onShowing();
-		
-		synchronized (_animatingPopups) {
-			_animatingPopups.add(ap);
-		}
-
-		if (_animationThread == null || !_animationThread.isAlive() || _animationThread.willDie) {
-			_animationThread = new AnimationThread();
-			_animationThread.start();
-		}
-
-	}
-	
-	/**
-	 * Does a pure asynch animation with no popups involved.
-	 * 
-	 * For example you may want to have an effect such that an item is expanding
-	 * or moving into a new location on the screen.
-	 * 
-	 * @param animator
-	 * 		Must not be null.
-	 * 
-	 * @param target
-	 * 		Must not be null.
-	 * 
-	 * @throws NullPointerException
-	 * 		If animator or target is null
-	 * 
-	 */
-	public void doPureAnimation(PopupAnimator animator, Rectangle target) {
-		
-		if (animator == null)
-			throw new NullPointerException("animator");
-		if (target == null)
-			throw new NullPointerException("target");
-		
-		AnimatedPopup ap = new AnimatedPopup(
-				animator, 
-				System.currentTimeMillis(), 
-				null,
-				false,
-				target.getLocation());
-		
-		
-		animator.starting(true, target);
-
-		synchronized (_animatingPopups) {
-			_animatingPopups.add(ap);
-		}
-
-		if (_animationThread == null || !_animationThread.isAlive() || _animationThread.willDie) {
-			_animationThread = new AnimationThread();
-			_animationThread.start();
-		}
-		
-	}
-	
-
-	/**
-	 * Paints all popups in the browsers popup pane with the given graphics.
-	 * 
-	 * @param g
-	 * 		Where to paint to.
-	 * 
-	 * @param clip
-	 */
-	void paintLayeredPane(Graphics g, Area clip) {
-		 if (Browser._theBrowser == null) return;
-		 
-		Component[] compsOnPopup = Browser._theBrowser.getLayeredPane().getComponentsInLayer(JLayeredPane.POPUP_LAYER);
-
-		for (int i = 0; i < compsOnPopup.length; i++) {
-			Component c = compsOnPopup[i];
-	
-			Point p = c.getLocation();
-
-			if (clip == null || clip.intersects(c.getBounds())) {
-				g.translate(p.x, p.y);
-				c.paint(g);
-				g.translate(-p.x, -p.y);
-			}
-			
-		} 
+	public void frameChanged()
+	{
 	}
 
@@ -482,339 +174,163 @@
 	 * Paints current popup animations to the expeditee browser content pane.
 	 */
-	void paintAnimations() {
-		
-		if (Browser._theBrowser == null
-				|| Browser._theBrowser.g == null) return;
-		
-		Graphics g = Browser._theBrowser.g;
-		
-		synchronized (_animatingPopups) {
-			
-			for (AnimatedPopup ap : _animatingPopups) {
-				ap.animator.paint(g);
-			}
-			
-		}
-	}
-	
-	/**
-	 * Proccesses animation on a dedicated thread.
+	public void paint()
+	{
+		synchronized (_popups) {
+			for (Popup popup : _popups) {
+				popup.update();
+				popup.paint();
+			}
+		}
+	}
+	
+	/**
+	 * Provides animations for a popup when hiding or when showing.
+	 * 
+	 * Note that {@link PopupAnimator#paint(Graphics)} and {@link PopupAnimator#update(float)} 
+	 * will always be invoked at seperate times - so do not have to worry about thread-safety.
+	 * 
+	 * These should only be used once... one per popup at a time.
 	 * 
 	 * @author Brook Novak
-	 *
-	 */
-	private class AnimationThread extends Thread {
-		
-		private boolean willDie = false;
+	 */
+	public static abstract class PopupAnimator
+	{
+		/** True if animating to show the popup, false if to hide. */
+		private boolean _showing = true;
+		
+		/** Whether the animation is currently paused. */
+		private boolean _paused = true;
+		
+		private long _startTime;
+		private long _duration;
+		private long _animationCurrentTime;
+		
+		public PopupAnimator()
+		{
+			_animationCurrentTime = _startTime = System.currentTimeMillis();
+			_duration = getDurationMillis();
+		}
+		
+		/**
+		 * @return False if the animation has finished, true if further updates are required.
+		 */
+		public boolean update()
+		{
+			long currentTime = System.currentTimeMillis();
+			
+			if (currentTime > _startTime + _duration) {
+				currentTime = _startTime + _duration;
+			}
+			
+			// If paused, make sure elapsed time stays constant
+			if (_paused) {
+				_startTime += currentTime - _animationCurrentTime;
+			}
+			
+			_animationCurrentTime = currentTime;
+			
+			return !isFinished();
+		}
+		
+		public void hide()
+		{
+			if (!_showing) return;
+			
+			_showing = false;
+			complementAnimationProgress();
+		}
+		
+		public void show()
+		{
+			if (_showing) return;
+			
+			_showing = true;
+			complementAnimationProgress();
+		}
+		
+		public boolean isShowing()
+		{
+			return _showing;
+		}
+		
+		public void start()
+		{
+			_animationCurrentTime = _startTime = System.currentTimeMillis();
+			unpause();
+		}
+		
+		public void pause()
+		{
+			pause(true);
+		}
+		
+		public void unpause()
+		{
+			pause(false);
+		}
+		
+		public void pause(boolean pause)
+		{
+			_paused = pause;
+		}
+		
+		private void complementAnimationProgress()
+		{
+			_startTime = _animationCurrentTime - ((_startTime + _duration) - _animationCurrentTime);
+		}
+		
+		public float getProgress()
+		{
+			return (_animationCurrentTime - _startTime) / ((float) _duration);
+		}
+		
+		public boolean isFinished()
+		{
+			return _animationCurrentTime != _startTime + _duration;
+		}
+		
+		public abstract long getDurationMillis();
+		
+		public abstract AxisAlignedBoxBounds getAnimatedBounds(AxisAlignedBoxBounds fullBounds);
+		
+	}
+	
+	public static class ExpandShrinkAnimator extends PopupAnimator
+	{
+		public static final long DURATION_MS = 2000;
+		
+		public AxisAlignedBoxBounds _initialBounds = null;
+		
+		public ExpandShrinkAnimator()
+		{
+		}
+		
+		public ExpandShrinkAnimator(AxisAlignedBoxBounds initialBounds)
+		{
+			setInitialBounds(initialBounds);
+		}
+		
+		public void setInitialBounds(AxisAlignedBoxBounds initialBounds)
+		{
+			_initialBounds = initialBounds;
+		}
 		
 		@Override
-		public void run() {
-			
-			
-			 LinkedList<AnimatedPopup> finishedAnimations;
-			 
-			 while (true) {
-			 
-				 // Perform animation logic
-				 finishedAnimations = animate();
-				
-				 // Check if finished all animations
-				 if (finishedAnimations == null) return; // done
-				 
-				 // Check for finalization of animation. That is, adding the popups to the layered pane
-				 boolean needsFinalization = false;
-				 for (AnimatedPopup ap : finishedAnimations) {
-					 if (ap.isShowing) {
-						 needsFinalization = true;
-						 break;
-					 } 
-					 
-					 // FInal invalidation
-					 FrameGraphics.invalidateArea(ap.animator.getCurrentDrawingArea());
-					 
-				 }
-				 
-				 if (needsFinalization) {
-					 SwingUtilities.invokeLater(new AnimationFinalizor(finishedAnimations));
-					 // Will repaint when a popup becomes anchored...
-				 } else {
-					 FrameGraphics.requestRefresh(true);
-				 }
-
-				 // Limit animation rate
-				 try {
-					 sleep(ANIMATION_RATE);
-				 } catch (InterruptedException e) {
-					e.printStackTrace();
-				 }
-			
-			 }
-			
-		}
-		
-		/**
-		 * Performs animations
-		 * @return
-		 */
-		private LinkedList<AnimatedPopup> animate() {
-			
-			LinkedList<AnimatedPopup> finishedPopups = null;
-			
-			synchronized (_animatingPopups) {
-				
-				if (_animatingPopups.isEmpty()) {
-					willDie = true;
-					return null;
-				}
-
-				long currentTime = System.currentTimeMillis();
-				
-				finishedPopups = new LinkedList<AnimatedPopup>();
-				
-				for (AnimatedPopup ap : _animatingPopups) {
-					
-					long duration = currentTime - ap.startTime;
-					
-					if (duration >= ANIMATION_DURATION) { // check if complete
-						
-						finishedPopups.add(ap);
-	
-					} else {
-						
-						float percent = ((float)duration / (float)ANIMATION_DURATION);
-						assert (percent >= 0.0f);
-						assert (percent < 1.0f);
-						
-						Rectangle dirty = ap.animator.update(percent);
-						if (dirty != null)
-							FrameGraphics.invalidateArea(dirty);
-						
-					}
-
-				}
-				
-				_animatingPopups.removeAll(finishedPopups);
-				
-			}
-			
-			return finishedPopups;
-			
-		}
-		
-		/**
-		 * Adds popups to layered pane
-		 * @author Brook Novak
-		 *
-		 */
-		private class AnimationFinalizor implements Runnable {
-
-			private LinkedList<AnimatedPopup> finished;
-			
-			AnimationFinalizor(LinkedList<AnimatedPopup> finished) {
-				this.finished = finished;
-			}
-			
-			public void run() {
-				
-				for (AnimatedPopup ap : finished) {
-					
-					if (ap.isShowing && _popups.containsKey(ap.popup)) {
-
-						ap.popup.prepareToPaint();
-						ap.popup.setLocation(ap.popupLocation);
-						ap.popup.setVisible(true);
-
-						Browser._theBrowser.getLayeredPane().add(ap.popup, JLayeredPane.POPUP_LAYER, 0);
-						
-						ap.popup.onShow();
-						
-						// Invalidate the popup border
-						if (ap.popup.getBorderThickness() > 0.0f) {
-							ap.popup.invalidateAppearance();
-						}
-					}
-					
-				}
-				
-			}
-		}
-	}
-	
-	private class AnimatedPopup {
-		
-		PopupAnimator animator;
-		long startTime;
-		Popup popup = null;
-		boolean isShowing;
-		Point popupLocation;
-		
-		public AnimatedPopup(PopupAnimator animator, long startTime, Popup popup, 
-				boolean isShowing, Point popupLocation) {
-			
-			assert(animator != null);
-			assert(popupLocation != null);
-			
-			// Only have popup if showing
-			assert (!isShowing && popup == null || (isShowing && popup != null));
-			
-			
-			this.animator = animator;
-			this.startTime = startTime;
-			this.popup = popup;
-			this.isShowing = isShowing;
-			this.popupLocation = popupLocation;
-
-		}
-
-	}
-	
-	/**
-	 * Provides animations for a popup when hiding or when showing.
-	 * 
-	 * Note that {@link PopupAnimator#paint(Graphics)} and {@link PopupAnimator#update(float)} 
-	 * will always be invoked at seperate times - so do not have to worry about thread-saefty.
-	 * 
-	 * These should only be used once... one per popup at a time.
-	 * 
-	 * @author Brook Novak
-	 *
-	 */
-	public interface PopupAnimator {
-		
-		/**
-		 * Invoked before showing. Any prepaations are done here.
-		 * 
-		 * @param isShowing
-		 * 		True if this animation will be for a popup that is showing.
-		 * 		False if this animation will be for a popup that is hiding.
-		 * 
-		 * @param popupBounds
-		 * 		The location of the popup. I.E. where it is, or where it will be.
-		 * 
-		 */
-		void starting(boolean isShowing, Rectangle popupBounds);
-		
-		/**
-		 * 
-		 * Called on an animation thread.
-		 * 
-		 * @param percent
-		 * 		The percent complete of the animations.
-		 * 		Rangles from 0 to 1.
-		 * 
-		 * @return dirty area that needs painting for last update... Null for no invalidation
-		 * 		
-		 * 
-		 */
-		Rectangle update(float percent);
-		
-		/**
-		 * Paints the animation - on the swing thread.
-		 * Note that this is always on the content pane - not the expeditee frame buffer.
-		 * 
-		 * @param g
-		 * 
-		 */
-		void paint(Graphics g);
-		
-		
-		/**
-		 * 
-		 * @return
-		 * 		The area which the animation is drawn. Used for final invalidation. Null for no final invaliation
-		 */
-		Rectangle getCurrentDrawingArea();
-		
-	}
-	
-	
-	public class ExpandShrinkAnimator implements PopupAnimator {
-		
-		private boolean isShowing;
-		private Rectangle popupBounds;
-		private Rectangle sourceRectangle;
-		private Rectangle currentRectangle;
-		private Color fillColor;
-		
-		private final Stroke stroke = new BasicStroke(2.0f);
-		
-		/**
-		 * 
-		 * @param sourceRectangle
-		 * @param fillColor
-		 * 		The fill color of the animated rectangle. Null for no fill.
-		 */
-		public ExpandShrinkAnimator(Rectangle sourceRectangle, Color fillColor) {
-			if (sourceRectangle == null) throw new NullPointerException("sourceRectangle");
-			
-			this.fillColor = fillColor;
-			this.sourceRectangle = (Rectangle)sourceRectangle.clone();
-			this.currentRectangle = (Rectangle)sourceRectangle.clone();
-		}
-
-		public void paint(Graphics g) {
-			
-			if (fillColor != null) {
-				g.setColor(fillColor);
-				g.fillRect(currentRectangle.x, currentRectangle.y, currentRectangle.width, currentRectangle.height);
-			}
-			
-			g.setColor(Color.BLACK);
-			((Graphics2D)g).setStroke(stroke);
-			g.drawRect(currentRectangle.x, currentRectangle.y, currentRectangle.width, currentRectangle.height);
-		}
-
-		public void starting(boolean isShowing, Rectangle popupBounds) {
-			this.isShowing = isShowing;
-			this.popupBounds = popupBounds;
-			
-			if (isShowing) {
-				this.currentRectangle = (Rectangle)sourceRectangle.clone();
-			} else {
-				this.currentRectangle = (Rectangle)sourceRectangle.clone();
-			}
-			
-		}
-
-		public Rectangle update(float percent) {
-
-			Rectangle oldBounds = currentRectangle;
-			
-			if (!isShowing) { // if minimizing just reverse percent
-				percent = 1 - percent;
-			}
-			
-			// update X
-			currentRectangle.x = sourceRectangle.x + 
-				(int)((popupBounds.x - sourceRectangle.x) * percent);
-			
-			// update Y
-			currentRectangle.y = sourceRectangle.y + 
-				(int)((popupBounds.y - sourceRectangle.y) * percent);
-			
-			// update width
-			currentRectangle.width = sourceRectangle.width + 
-				(int)((popupBounds.width - sourceRectangle.width) * percent);
-			
-			// update height
-			currentRectangle.height = sourceRectangle.height + 
-				(int)((popupBounds.height - sourceRectangle.height) * percent);
-			
-			int x = Math.min(oldBounds.x, currentRectangle.x);
-			int y = Math.min(oldBounds.y, currentRectangle.y);
-			int width = Math.min(oldBounds.x + oldBounds.width, currentRectangle.x + currentRectangle.width) - x;
-			int height = Math.min(oldBounds.y + oldBounds.height, currentRectangle.y + currentRectangle.height) - y;
-			
-			return new Rectangle(x, y, width, height);
-			
-		}
-		
-		public Rectangle getCurrentDrawingArea() {
-			return currentRectangle;
-		}
-
-
-	}
-	
-
+		public long getDurationMillis() { return DURATION_MS; }
+
+		@Override
+		public AxisAlignedBoxBounds getAnimatedBounds(AxisAlignedBoxBounds fullBounds)
+		{
+			if (_initialBounds == null) {
+				setInitialBounds(fullBounds.clone());
+				_initialBounds.getTopLeft().y += _initialBounds.getSize().height; 
+				_initialBounds.getSize().height = 0;
+			}
+			
+			float percentShown = getProgress();
+			if (!isShowing()) percentShown = 1 - percentShown;
+			
+			return AxisAlignedBoxBounds.lerp(_initialBounds, fullBounds, percentShown);
+		}
+	}
 }
Index: /trunk/src/org/expeditee/gui/Reminders.java
===================================================================
--- /trunk/src/org/expeditee/gui/Reminders.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/Reminders.java	(revision 1102)
@@ -19,10 +19,10 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
 import java.util.Date;
 
+import org.expeditee.Util;
 import org.expeditee.actions.Misc;
+import org.expeditee.core.Colour;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.charts.TimeSeries;
 
 public class Reminders {
@@ -46,5 +46,5 @@
 				}
 
-				Date date = TimeSeries.parseDate(dateString);
+				Date date = Util.parseDate(dateString);
 				long millisToWait = date.getTime() - new Date().getTime();
 				final long adjustedToWait;
@@ -69,5 +69,5 @@
 								MessageBay.displayMessage(
 										"Reminder: " + reminderString, null,
-										Color.red, false, "StopReminder");
+										Colour.RED, false, "StopReminder");
 								Thread.sleep(5000);
 								// newMessage.setColor(new Color(100, 70, 70));
Index: /trunk/src/org/expeditee/gui/Vector.java
===================================================================
--- /trunk/src/org/expeditee/gui/Vector.java	(revision 1101)
+++ /trunk/src/org/expeditee/gui/Vector.java	(revision 1102)
@@ -19,28 +19,38 @@
 package org.expeditee.gui;
 
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Point;
 import java.text.NumberFormat;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Point;
 import org.expeditee.items.Item;
 import org.expeditee.items.UserAppliedPermission;
 
+/**
+ * TODO: Explain WTF this is. cts16
+ */
 public class Vector extends Overlay {
 
+	/** TODO: Comment. cts16 */
 	public Point Origin;
 
+	/** TODO: Comment. cts16 */
 	public float Scale;
 
-	public Color Foreground;
+	/** TODO: Comment. cts16 */
+	public Colour Foreground;
 
-	public Color Background;
-	
+	/** TODO: Comment. cts16 */
+	public Colour Background;
+
+	/** TODO: Comment. cts16 */
 	public Item Source;
-	
+
+	/** TODO: Comment. cts16 */
 	public Dimension Size;
 
-	public Vector(Frame overlay, UserAppliedPermission permission,
-			Float scale, Item source) {
+	/** TODO: Comment. cts16 */
+	public Vector(Frame overlay, UserAppliedPermission permission, Float scale, Item source)
+	{
 		super(overlay, permission);
 		Origin = source.getPosition();
@@ -52,38 +62,46 @@
 
 	@Override
-	public boolean equals(Object o) {
-		if (o == null || o.getClass() != Vector.class)
-			return false;
-		Vector v = (Vector) o;
-
-		return v.Frame == Frame && Origin.equals(v.Origin)
-				&& Scale == v.Scale && Foreground == v.Foreground
-				&& Background == v.Background;
+	public boolean equals(Object o)
+	{
+		if (o instanceof Vector) {
+			Vector v = (Vector) o;
+			return v.Frame == Frame &&
+					Origin.equals(v.Origin) &&
+					Scale == v.Scale &&
+					Foreground.equals(v.Foreground) &&
+					Background.equals(v.Background);
+		}
+		
+		return false;
+		
 	}
 
 	@Override
-	public int hashCode() {
+	public int hashCode()
+	{
 		return 0;
 	}
 
-	/**
-	 * Converts the given x position to be relative to the overlay frame.
-	 * 
-	 * @param x
-	 * @return
-	 */
-	public float getX(int x) {
+	/** Converts the given x position to be relative to the overlay frame. */
+	public float getX(int x)
+	{
 		return (x - Origin.x) / Scale;
 	}
 
-	public float getY(int y) {
+	/** Converts the given y position to be relative to the overlay frame. */
+	public float getY(int y)
+	{
 		return (y - Origin.y) / Scale;
 	}
 
-	public void setSize(int maxX, int maxY) {
+	/** TODO: Comment. cts16 */
+	public void setSize(int maxX, int maxY)
+	{
 		Size = new Dimension(maxX, maxY);
 	}
 
-	public static NumberFormat getNumberFormatter() {
+	/** TODO: Comment. cts16 */
+	public static NumberFormat getNumberFormatter()
+	{
 		NumberFormat nf = NumberFormat.getInstance();
 		nf.setMaximumFractionDigits(4);
Index: /trunk/src/org/expeditee/importer/FileImporter.java
===================================================================
--- /trunk/src/org/expeditee/importer/FileImporter.java	(revision 1101)
+++ /trunk/src/org/expeditee/importer/FileImporter.java	(revision 1102)
@@ -19,8 +19,8 @@
 package org.expeditee.importer;
 
-import java.awt.Point;
 import java.io.File;
 import java.io.IOException;
 
+import org.expeditee.core.Point;
 import org.expeditee.items.Item;
 
Index: /trunk/src/org/expeditee/importer/FilePathImporter.java
===================================================================
--- /trunk/src/org/expeditee/importer/FilePathImporter.java	(revision 1101)
+++ /trunk/src/org/expeditee/importer/FilePathImporter.java	(revision 1102)
@@ -19,8 +19,9 @@
 package org.expeditee.importer;
 
-import java.awt.Point;
 import java.io.File;
 import java.io.IOException;
 
+import org.expeditee.core.Point;
+import org.expeditee.gio.DragAndDropManager;
 import org.expeditee.items.Item;
 
@@ -36,5 +37,5 @@
 	public Item importFile(File f, Point location) throws IOException {
 		if (location != null && f != null) {
-			return FrameDNDTransferHandler.importString(f.getAbsolutePath(), location);			
+			return DragAndDropManager.importString(f.getAbsolutePath(), location);			
 		}
 
Index: /trunk/src/org/expeditee/importer/FrameDNDTransferHandler.java
===================================================================
--- /trunk/src/org/expeditee/importer/FrameDNDTransferHandler.java	(revision 1101)
+++ /trunk/src/org/expeditee/importer/FrameDNDTransferHandler.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.importer;
 
-import java.awt.Point;
 import java.awt.datatransfer.DataFlavor;
 import java.awt.datatransfer.UnsupportedFlavorException;
@@ -32,4 +31,6 @@
 import javax.swing.TransferHandler;
 
+import org.expeditee.core.Point;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.gui.DisplayIO;
 import org.expeditee.gui.FrameGraphics;
@@ -65,6 +66,6 @@
 	}
 
-	private FrameDNDTransferHandler() {
-
+	private FrameDNDTransferHandler()
+	{
 		// Add standard file importers - order from most ideal to last resort
 		// (if competing)
@@ -74,15 +75,12 @@
 		_standardFileImporters.add(new pdfImporter());
 		_standardFileImporters.add(new TextImporter());
-		_standardFileImporters.add(new FilePathImporter()); // Filepath importer
-		// as last resort
+		_standardFileImporters.add(new FilePathImporter()); // Filepath importer as last resort
 
 		try {
-			_URIListDataflavorString = new DataFlavor(
-					"text/uri-list;class=java.lang.String");
-			_URIListDataflavorCharArray = new DataFlavor(
-					"text/uri-list;class=\"[C\"");
-		} catch (ClassNotFoundException e) { // This would never happen,
-			// java.lang.String is always
-			// present
+			_URIListDataflavorString = new DataFlavor("text/uri-list;class=java.lang.String");
+			_URIListDataflavorCharArray = new DataFlavor("text/uri-list;class=\"[C\"");
+			
+		// This would never happen, java.lang.String is always present
+		} catch (ClassNotFoundException e) {
 			e.printStackTrace();
 			_URIListDataflavorString = null;
@@ -104,9 +102,11 @@
 	 *             if importer is null.
 	 */
-	public void addCustomFileImporter(FileImporter importer) {
-		if (importer == null)
-			throw new NullPointerException("importer");
-		if (!_customFileImporters.contains(importer))
+	public void addCustomFileImporter(FileImporter importer)
+	{
+		if (importer == null) throw new NullPointerException("importer");
+		
+		if (!_customFileImporters.contains(importer)) {
 			_customFileImporters.add(importer);
+		}
 
 	}
@@ -121,7 +121,8 @@
 	 *             if importer is null.
 	 */
-	public void removeCustomFileImporter(FileImporter importer) {
-		if (importer == null)
-			throw new NullPointerException("importer");
+	public void removeCustomFileImporter(FileImporter importer)
+	{
+		if (importer == null) throw new NullPointerException("importer");
+		
 		_customFileImporters.remove(importer);
 	}
@@ -135,9 +136,9 @@
 
 		// we only import Strings
-		if (support.isDataFlavorSupported(DataFlavor.stringFlavor)
-				|| support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)
-				|| support.isDataFlavorSupported(_URIListDataflavorString)
-				|| support.isDataFlavorSupported(_URIListDataflavorCharArray)) {
-
+		if (	support.isDataFlavorSupported(DataFlavor.stringFlavor) ||
+				support.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ||
+				support.isDataFlavorSupported(_URIListDataflavorString) ||
+				support.isDataFlavorSupported(_URIListDataflavorCharArray))
+		{
 			// check if the source actions (a bitwise-OR of supported actions)
 			// contains the COPY action
@@ -154,14 +155,13 @@
 
 	@Override
-	public boolean importData(TransferSupport support) {
-
-		if (!canImport(support) || DisplayIO.getCurrentFrame() == null)
-			return false;
-
-		// Get the drop location of where to lot the import
+	public boolean importData(TransferSupport support)
+	{
+		if (!canImport(support) || DisplayIO.getCurrentFrame() == null) return false;
+
+		// Get the location of where to drop the import
 		DropLocation location = support.getDropLocation();
 
-		// Covert it into expeditee space
-		Point expediteeDropPoint = location.getDropPoint();
+		// Convert it into expeditee space
+		Point expediteeDropPoint = SwingConversions.fromSwingPoint(location.getDropPoint());
 
 		try {
@@ -170,6 +170,5 @@
 			// keep trying until first
 			// data flavor recognized.
-			for (DataFlavor df : support.getTransferable()
-					.getTransferDataFlavors()) {
+			for (DataFlavor df : support.getTransferable().getTransferDataFlavors()) {
 
 				System.out.println(df);
@@ -177,6 +176,5 @@
 				if (df == DataFlavor.stringFlavor) { // import as text item
 
-					String str = (String) support.getTransferable()
-							.getTransferData(DataFlavor.stringFlavor);
+					String str = (String) support.getTransferable().getTransferData(DataFlavor.stringFlavor);
 
 					if (str != null && str.length() > 0) {
@@ -185,15 +183,9 @@
 					}
 
-					// Usually Windows and MAC enviroments
-				} else if (df == DataFlavor.javaFileListFlavor
-						|| df.getSubType().equals("x-java-file-list")) { // Windows
-					// has
-					// other
-					// random
-					// types...
-
-					List<? extends File> files = (List<? extends File>) support
-							.getTransferable().getTransferData(
-									DataFlavor.javaFileListFlavor);
+				// Usually Windows and MAC enviroments
+				// Windows has other random types...
+				} else if (df == DataFlavor.javaFileListFlavor || df.getSubType().equals("x-java-file-list")) {
+
+					List<? extends File> files = (List<? extends File>) support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
 
 					importFileList(files, expediteeDropPoint);
@@ -201,9 +193,8 @@
 					return true;
 
-					// Usually GNOME and KDE enviroments
+				// Usually GNOME and KDE enviroments
 				} else if (df.equals(_URIListDataflavorString)) {
 
-					String data = (String) support.getTransferable()
-							.getTransferData(_URIListDataflavorString);
+					String data = (String) support.getTransferable().getTransferData(_URIListDataflavorString);
 
 					List<File> files = textURIListToFileList(data);
@@ -215,6 +206,5 @@
 				} else if (df.equals(_URIListDataflavorCharArray)) {
 
-					char[] data = (char[]) support.getTransferable()
-							.getTransferData(_URIListDataflavorCharArray);
+					char[] data = (char[]) support.getTransferable().getTransferData(_URIListDataflavorCharArray);
 
 					String uriString = new String(data);
@@ -229,6 +219,5 @@
 
 		} catch (UnsupportedFlavorException e) {
-			MessageBay
-					.displayMessage("Drag and drop for that type of data is not supported");
+			MessageBay.displayMessage("Drag and drop for that type of data is not supported");
 		} catch (IOException e) {
 			e.printStackTrace();
@@ -246,14 +235,13 @@
 	 * 
 	 * @param expediteeDropPoint
-	 *            The location in the current ecpeditee frame of where to drop
+	 *            The location in the current expeditee frame of where to drop
 	 *            the text item.
 	 */
-	public static Text importString(String text, Point expediteeDropPoint) {
-
+	public static Text importString(String text, Point expediteeDropPoint)
+	{
 		assert (DisplayIO.getCurrentFrame() != null);
 		assert (text != null && text.length() > 0);
 
-		Text importedTextItem = new Text(DisplayIO.getCurrentFrame()
-				.getNextItemID(), text);
+		Text importedTextItem = new Text(DisplayIO.getCurrentFrame().getNextItemID(), text);
 		importedTextItem.setPosition(expediteeDropPoint);
 
@@ -264,10 +252,10 @@
 	}
 
-	public void importFileList(List<? extends File> files,
-			Point expediteeDropPoint) throws IOException {
-
-		Point currentPoint = expediteeDropPoint.getLocation();
-
-		for (File fileToImport : files) { // import files one by one
+	public void importFileList(List<? extends File> files, Point expediteeDropPoint) throws IOException
+	{
+		Point currentPoint = new Point(expediteeDropPoint);
+
+		 // import files one by one
+		for (File fileToImport : files) {
 
 			Item lastItem = importFile(fileToImport, currentPoint);
@@ -296,5 +284,6 @@
 	 * @throws IOException
 	 */
-	public Item importFile(File f, Point expediteeDropPoint) throws IOException {
+	public Item importFile(File f, Point expediteeDropPoint) throws IOException
+	{
 		assert (f != null);
 
@@ -302,22 +291,18 @@
 		// importing routines...
 		Item lastCreatedItem;
-		if (null == (lastCreatedItem = performFileImport(_customFileImporters,
-				f, expediteeDropPoint))) {
-
+		if (null == (lastCreatedItem = performFileImport(_customFileImporters, f, expediteeDropPoint))) {
 			// Standard file importing
-			lastCreatedItem = performFileImport(_standardFileImporters, f,
-					expediteeDropPoint);
-
-		}
+			lastCreatedItem = performFileImport(_standardFileImporters, f, expediteeDropPoint);
+		}
+		
 		return lastCreatedItem;
 	}
 
-	private Item performFileImport(List<FileImporter> importers, File f,
-			Point expediteeDropPoint) throws IOException {
-
+	private Item performFileImport(List<FileImporter> importers, File f, Point expediteeDropPoint) throws IOException
+	{
 		for (FileImporter fi : importers) {
 			Item lastCreated = fi.importFile(f, expediteeDropPoint);
-			if (lastCreated != null)
-				return lastCreated;
+			
+			if (lastCreated != null) return lastCreated;
 		}
 
@@ -326,4 +311,6 @@
 
 	/**
+	 * Converts a string formatted as a list of URIs into a list of Files.
+	 * 
 	 * Code adopted from SUN - java BUG ID 4899516 workaround for KDE/GNOME
 	 * Desktops
@@ -334,10 +321,9 @@
 	 * @return The list of FILES in the uriListString. Never null.
 	 */
-	private List<File> textURIListToFileList(String uriListString) {
-
+	private List<File> textURIListToFileList(String uriListString)
+	{
 		List<File> fileList = new LinkedList<File>();
 
-		for (StringTokenizer st = new StringTokenizer(uriListString, "\r\n"); st
-				.hasMoreTokens();) {
+		for (StringTokenizer st = new StringTokenizer(uriListString, "\r\n"); st.hasMoreTokens();) {
 
 			String s = st.nextToken();
Index: /trunk/src/org/expeditee/importer/ImageImporter.java
===================================================================
--- /trunk/src/org/expeditee/importer/ImageImporter.java	(revision 1101)
+++ /trunk/src/org/expeditee/importer/ImageImporter.java	(revision 1102)
@@ -19,7 +19,4 @@
 package org.expeditee.importer;
 
-import java.awt.Color;
-import java.awt.Point;
-import java.awt.Rectangle;
 import java.io.File;
 import java.io.IOException;
@@ -27,7 +24,10 @@
 import java.util.HashSet;
 
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.FrameKeyboardActions;
-import org.expeditee.gui.FrameMouseActions;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gio.DragAndDropManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.items.Item;
@@ -65,5 +65,5 @@
 		}
 
-		Color borderColor = null;
+		Colour borderColor = null;
 		float thickness = 0;
 		String size = "";
@@ -72,8 +72,8 @@
 			for (Item i : enclosure) {
 				if (i.isLineEnd() && i.isEnclosed()) {
-					DisplayIO.getCurrentFrame().removeAllItems(enclosure);
-					Rectangle rect = i.getEnclosedRectangle();
+					DisplayController.getCurrentFrame().removeAllItems(enclosure);
+					AxisAlignedBoxBounds rect = i.getEnclosedBox();
 					size = " " + Math.round(rect.getWidth());
-					location = new Point(rect.x, rect.y);
+					location = new Point(rect.getMinX(), rect.getMinY());
 					thickness = i.getThickness();
 					borderColor = i.getColor();
@@ -81,13 +81,12 @@
 				}
 			}
-			FrameMouseActions.deleteItems(enclosure, false);
+			StandardGestureActions.deleteItems(enclosure, false);
 		}
 
-		Text source = FrameDNDTransferHandler.importString("@i: " + fullPath
-				+ size, location);
+		Text source = DragAndDropManager.importString("@i: " + fullPath + size, location);
 		source.setThickness(thickness);
 		source.setBorderColor(borderColor);
 
-		FrameKeyboardActions.Refresh();
+		StandardGestureActions.Refresh();
 		Collection<? extends XRayable> pictures = source.getEnclosures();
 		if (pictures.size() == 0)
Index: /trunk/src/org/expeditee/importer/TextImporter.java
===================================================================
--- /trunk/src/org/expeditee/importer/TextImporter.java	(revision 1101)
+++ /trunk/src/org/expeditee/importer/TextImporter.java	(revision 1102)
@@ -19,6 +19,4 @@
 package org.expeditee.importer;
 
-import java.awt.Color;
-import java.awt.Point;
 import java.io.BufferedReader;
 import java.io.File;
@@ -26,4 +24,8 @@
 import java.io.IOException;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.gio.DragAndDropManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameCreator;
 import org.expeditee.gui.FrameGraphics;
@@ -44,6 +46,5 @@
 		final String fullPath = f.getAbsolutePath();
 
-		final Text source = FrameDNDTransferHandler.importString(f.getPath(),
-				location);
+		final Text source = DragAndDropManager.importString(f.getPath(), location);
 
 		// Create a frameCreator to write the text
@@ -54,6 +55,5 @@
 				try {
 					// Open a file stream to the file
-					BufferedReader br = new BufferedReader(new FileReader(
-							fullPath));
+					BufferedReader br = new BufferedReader(new FileReader(fullPath));
 
 					MessageBay.displayMessage("Importing " + f.getName() + "...");
@@ -67,6 +67,6 @@
 					frames.save();
 					source.setLink(frames.getName());
-					MessageBay.displayMessage(f.getName() + " import complete", Color.GREEN);
-					FrameGraphics.requestRefresh(true);
+					MessageBay.displayMessage(f.getName() + " import complete", Colour.GREEN);
+					DisplayController.requestRefresh(true);
 				} catch (Exception e) {
 					e.printStackTrace();
@@ -75,5 +75,5 @@
 			}
 		}.start();
-		FrameGraphics.refresh(true);
+		DisplayController.requestRefresh(true);
 		return source;
 	}
Index: /trunk/src/org/expeditee/importer/pdfImporter.java
===================================================================
--- /trunk/src/org/expeditee/importer/pdfImporter.java	(revision 1101)
+++ /trunk/src/org/expeditee/importer/pdfImporter.java	(revision 1102)
@@ -19,10 +19,4 @@
 package org.expeditee.importer;
 
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
@@ -31,7 +25,11 @@
 import java.nio.channels.FileChannel;
 
-import javax.imageio.ImageIO;
-
-import org.expeditee.gui.Browser;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
+import org.expeditee.core.Point;
+import org.expeditee.gio.DragAndDropManager;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameCreator;
@@ -54,5 +52,5 @@
 		final int x = 0;
 		final int y = 60;
-		final int width = Browser._theBrowser.getSize().width;
+		final int width = EcosystemManager.getGraphicsManager().getWindowSize().width;
 		System.out.println(width);
 		
@@ -65,5 +63,5 @@
 		}
 		
-		final Text link = FrameDNDTransferHandler.importString(name, location);
+		final Text link = DragAndDropManager.importString(name, location);
 		link.setLink(name+"1");
 		
@@ -97,5 +95,5 @@
 					Frame _currentFrame=null;
 					Text nextButton=null, prevButton=null;
-					final float spacing=((Text)FrameCreator.createButton("Next", null, null, 10F, 10F)).getBoundsWidth() + 30F;
+					final int spacing=((Text)FrameCreator.createButton("Next", null, null, 10, 10)).getBoundsWidth() + 30;
 		      
 		      //make images from the pdf pages, write frames with those images
@@ -128,19 +126,15 @@
 			      }
 			      //generate the image
-			      Image img = page.getImage(w, h, //width & height
-				      new Rectangle(0, 0, (int)page.getBBox().getWidth(), (int)page.getBBox().getHeight()), //clip rect
-				      null, //null for the ImageObserver
-				      true, //fill background with white
-				      true //block until drawing is done
-				      );
+			      Image img = Image.createImage(w, h, page);
 			      //Create a buffered image to store the image in
-			      BufferedImage bimg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB);
-			      Graphics g = bimg.createGraphics();
+			      Image bimg = Image.createImage(img.getWidth(), img.getHeight(), false);
+			      GraphicsManager g = EcosystemManager.getGraphicsManager();
 			      //Paint the image onto the buffered image
-			      g.drawImage(img, 0, 0, null);
-			      g.dispose();
+			      g.pushDrawingSurface(bimg);
+			      g.drawImage(img, new Point(0, 0));
+			      g.popDrawingSurface();
 			      //save it as a file
 			      File out = new File(framesetPath+i+".png");
-			      ImageIO.write(bimg, "png", out);
+			      bimg.writeToDisk("png", out);
 			      //generate a frame with that image
 			      System.out.println(width);
@@ -150,10 +144,10 @@
 						{
 						  //put a next button on the previous frame (points to current frame)
-						  nextButton=(Text)FrameCreator.createButton("Next", null, null, 10F, 10F);
+						  nextButton=(Text)FrameCreator.createButton("Next", null, null, 10, 10);
 							nextButton.setID(_currentFrame.getNextItemID());
 							nextButton.addAction("next");
 							_currentFrame.addItem(nextButton);
 							//put a previous button on the current frame (points to previous frame)
-							prevButton=(Text)FrameCreator.createButton("Prev", null, null, (i<pages)?spacing:10F, 10F);
+							prevButton=(Text)FrameCreator.createButton("Prev", null, null, (i<pages)?spacing:10, 10);
 							prevButton.setID(currentFrame.getNextItemID());
 							prevButton.addAction("previous");
@@ -162,5 +156,5 @@
 						else
 						{
-							prevButton=(Text)FrameCreator.createButton("Home", null, null, (i<pages)?spacing:10F, 10F);
+							prevButton=(Text)FrameCreator.createButton("Home", null, null, (i<pages)?spacing:10, 10);
 							prevButton.setID(currentFrame.getNextItemID());
 							prevButton.addAction("GotoHome");
@@ -171,11 +165,11 @@
 						if(i<pages) currentFrame = FrameIO.CreateFrame(frameset.getFramesetName(), name, null);
 					}
-					prevButton=(Text)FrameCreator.createButton("Home", null, null, spacing, 10F);
+					prevButton=(Text)FrameCreator.createButton("Home", null, null, spacing, 10);
 					prevButton.setID(currentFrame.getNextItemID());
 					prevButton.addAction("gotohome");
 					currentFrame.addItem(prevButton);
 					FrameIO.SaveFrame(currentFrame,true);
-					MessageBay.displayMessage(f.getName() + " import complete", Color.GREEN);
-					FrameGraphics.requestRefresh(true);
+					MessageBay.displayMessage(f.getName() + " import complete", Colour.GREEN);
+					DisplayController.requestRefresh(true);
 				} catch (Exception e) {
 					e.printStackTrace();
@@ -184,5 +178,5 @@
 			}
 		}.start();
-		FrameGraphics.refresh(true);
+		DisplayController.requestRefresh(true);
 		//return source;
 		return link;
Index: /trunk/src/org/expeditee/io/AbstractHTMLWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/AbstractHTMLWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/AbstractHTMLWriter.java	(revision 1102)
@@ -19,6 +19,4 @@
 package org.expeditee.io;
 
-import java.awt.Color;
-import java.awt.Font;
 import java.io.File;
 import java.io.IOException;
@@ -26,4 +24,6 @@
 import java.util.List;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Font;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -88,6 +88,5 @@
 			return;
 
-		writer.write(styleName + " { font-family: "
-				+ Conversion.getCssFontFamily(font.getFamily()));
+		writer.write(styleName + " { font-family: " + Conversion.getCssFontFamily(font.getFamilyName()));
 
 		// writer.write("; font-size: " + Math.round(style.getSize()) + "px");
@@ -104,5 +103,5 @@
 			writer.write("; font-style: normal");
 		}
-		Color c = style.getBackgroundColor();
+		Colour c = style.getBackgroundColor();
 		if (c != null) {
 			writer.write("; background-color: " + Conversion.getCssColor(c));
Index: /trunk/src/org/expeditee/io/Conversion.java
===================================================================
--- /trunk/src/org/expeditee/io/Conversion.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/Conversion.java	(revision 1102)
@@ -19,7 +19,4 @@
 package org.expeditee.io;
 
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Point;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -29,4 +26,7 @@
 
 import org.expeditee.actions.Actions;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Font;
+import org.expeditee.core.Point;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -43,7 +43,7 @@
 public class Conversion {
 
-	public static final int RGB_MAX = 255;
-
-	private static final float RGB_CONVERSION_FACTOR = 2.55F;
+	public static final short RGB_MAX = Colour.COMPONENT_MAX_VALUE;
+
+	private static final float RGB_CONVERSION_FACTOR = RGB_MAX / 100.0f;
 
 	/**
@@ -56,5 +56,5 @@
 	 * @return The Color object corresponding to the given code
 	 */
-	public static Color getColor(String colorCode, Color current) {
+	public static Colour getColor(String colorCode, Colour current) {
 		if (colorCode == null) {
 			return null;
@@ -66,5 +66,5 @@
 
 		// check if its a normal rgb code ie. 100 0 40
-		Color rgb = getRGBColor(colorCode, current);
+		Colour rgb = getRGBColor(colorCode, current);
 		if (rgb != null)
 			return rgb;
@@ -104,8 +104,8 @@
 			return null;
 
-		return new Color(color[0], color[1], color[2]);
-	}
-
-	private static Color getRGBColor(String colorCode, Color current) {
+		return new Colour(color[0], color[1], color[2]);
+	}
+
+	private static Colour getRGBColor(String colorCode, Colour current) {
 		int color[] = new int[4];
 		// Assert.assertTrue(color.length == 3);
@@ -135,5 +135,5 @@
 				color[i] = toRGB(color[i]);
 			}
-			return new Color(color[0], color[1], color[2], color[3]);
+			return new Colour(color[0], color[1], color[2], color[3]);
 		} catch (Exception e) {
 			return null;
@@ -175,5 +175,5 @@
 	 *         is black.
 	 */
-	public static String getExpediteeColorCode(Color color) {
+	public static String getExpediteeColorCode(Colour color) {
 		if (color == null)
 			return null;
@@ -195,6 +195,6 @@
 	 */
 	public static String getExpediteeFontCode(Font font) {
-		String fontName = font.getFamily();
-		String code = font.getFamily() + '_';
+		String fontName = font.getFamilyName();
+		String code = font.getFamilyName() + '_';
 
 		for (int i = 0; i < Text.FONT_WHEEL.length; i++) {
@@ -206,11 +206,11 @@
 
 		switch (font.getStyle()) {
-		case Font.BOLD:
+		case BOLD:
 			code += "b";
 			break;
-		case Font.PLAIN:
+		case PLAIN:
 			code += "r";
 			break;
-		case Font.ITALIC:
+		case ITALIC:
 			code += "i";
 			break;
@@ -237,8 +237,7 @@
 
 		int separator = fontCode.indexOf('_');
-		String code = Text.FONT_WHEEL[0];
+		String familyName = Text.FONT_WHEEL[0];
 		if (separator > 0) {
-			code = Actions.getCapitalizedFontName(fontCode.substring(0,
-					separator)) + '-';
+			familyName = Actions.getCapitalizedFontName(fontCode.substring(0, separator));
 			fontCode = fontCode.substring(separator);
 		} else {
@@ -246,41 +245,33 @@
 			for (int i = 0; i < Text.FONT_CHARS.length; i++) {
 				if (c == Text.FONT_CHARS[i]) {
-					code = Text.FONT_WHEEL[i] + '-';
+					familyName = Text.FONT_WHEEL[i];
 					break;
 				}
 			}
 		}
+		
+		Font font = new Font(familyName);
 
 		switch (fontCode.charAt(1)) {
 		case 'r':
-			code += "Plain";
+			font.setStyle(Font.Style.PLAIN);
 			break;
 		case 'b':
-			code += "Bold";
+			font.setStyle(Font.Style.BOLD);
 			break;
 		case 'i':
-			code += "Italic";
+			font.setStyle(Font.Style.ITALIC);
 			break;
 		case 'p':
-			code += "BoldItalic";
+			font.setStyle(Font.Style.BOLD_ITALIC);
 			break;
 		}
-
-		code += "-";
-
-		Font font = null;
 
 		try {
 			int size = Integer.parseInt(fontCode.substring(2));
-			// double dsize = size * FONT_SCALE;
-			// if (dsize - ((int) dsize) > FONT_ROUNDING)
-			// dsize = Math.ceil(dsize);
-
-			// code += (int) dsize;
-			code += size;
-
-			font = Font.decode(code);
+			
+			font.setSize(size);
 		} catch (NumberFormatException nfe) {
-			font = Font.decode(fontCode);
+			// Just keep going
 		}
 
@@ -362,5 +353,5 @@
 		}
 
-		if (type.equals(Color.class)) {
+		if (type.equals(Colour.class)) {
 			if (value.length() == 0)
 				return null;
@@ -368,9 +359,9 @@
 			try {
 				// Try to decode the string as a hex or octal color code
-				return Color.decode(value);
+				return Colour.decode(value);
 			} catch (NumberFormatException nfe) {
 				try {
-					// Try to find the field in the Color class with the same name as the given string
-					Field[] fields = java.awt.Color.class.getFields();
+					// Try to find the field in the Colour class with the same name as the given string
+					Field[] fields = Colour.class.getFields();
 					Field field = null;
 					for (int i = 0; i < fields.length; i++) {
@@ -380,7 +371,7 @@
 						}
 					}
-					return (Color) field.get(null);
+					return (Colour) field.get(null);
 				} catch (Exception e) {
-					return getColor(value, (Color) orig);
+					return getColor(value, (Colour) orig);
 				}
 			}
@@ -388,6 +379,5 @@
 
 		if (type.equals(int.class)) {
-			if (orig instanceof Integer
-					&& (value.startsWith("+") || value.startsWith("-"))) {
+			if (orig instanceof Integer && (value.startsWith("+") || value.startsWith("-"))) {
 				value = value.replace("+", "");
 
@@ -395,6 +385,5 @@
 			}
 
-			if (value.length() == 0 || value.equals("null"))
-				return Item.DEFAULT_INTEGER;
+			if (value.length() == 0 || value.equals("null")) return Item.DEFAULT_INTEGER;
 
 			return Integer.decode(value);
@@ -427,9 +416,8 @@
 
 		if (type.equals(Integer.class)) {
-			if (orig instanceof Integer
-					&& (value.startsWith("+") || value.startsWith("-"))) {
+			if (orig instanceof Integer && (value.startsWith("+") || value.startsWith("-"))) {
 				value = value.replace("+", "");
 
-				Integer newValue = ((Integer) orig) + Integer.parseInt(value);
+				Integer newValue = ((Integer) orig) + Integer.valueOf((int) Double.parseDouble(value));
 				if (newValue <= 0)
 					return null;
@@ -440,5 +428,5 @@
 				return null;
 
-			return Integer.parseInt(value);
+			return Integer.valueOf((int) Double.parseDouble(value));
 		}
 
@@ -700,6 +688,6 @@
 
 		// convert colors
-		if (output instanceof Color)
-			return getExpediteeColorCode((Color) output);
+		if (output instanceof Colour)
+			return getExpediteeColorCode((Colour) output);
 
 		// covert points
@@ -737,7 +725,7 @@
 	}
 
-	public static String getCssColor(Color c) {
+	public static String getCssColor(Colour c) {
 		assert (c != null);
-		return "rgb(" + c.getRed() + "," + c.getGreen() + "," + c.getBlue()
+		return "rgb(" + c.getRed255() + "," + c.getGreen255() + "," + c.getBlue255()
 				+ ")";
 	}
Index: /trunk/src/org/expeditee/io/DefaultFrameReader.java
===================================================================
--- /trunk/src/org/expeditee/io/DefaultFrameReader.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/DefaultFrameReader.java	(revision 1102)
@@ -19,7 +19,4 @@
 package org.expeditee.io;
 
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.Point;
 import java.io.BufferedReader;
 import java.io.FileInputStream;
@@ -32,6 +29,10 @@
 import java.util.LinkedList;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Font;
+import org.expeditee.core.Point;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.Constraint;
+import org.expeditee.items.Dot;
 import org.expeditee.items.DotType;
 import org.expeditee.items.Item;
@@ -42,4 +43,5 @@
 
 public abstract class DefaultFrameReader implements FrameReader {
+	
 	protected static LinkedHashMap<Character, Method> _ItemTags = null;
 	
@@ -53,5 +55,6 @@
 	protected static Class[] pFloat = { float.class };
 	protected static Class[] pFloatO = { Float.class };
-	protected static Class[] pColor = { Color.class };
+	protected static Class[] pDouble = { double.class };
+	protected static Class[] pColor = { Colour.class };
 	protected static Class[] pBool = { boolean.class };
 	protected static Class[] pFont = { Font.class };
@@ -63,4 +66,5 @@
 	protected static Class[] pJustification = { Justification.class };
 	protected static Class[] pPermission = { PermissionPair.class };
+	protected static Class[] pDotType = { DotType.class };
 	
 	public DefaultFrameReader(){
@@ -100,8 +104,8 @@
 					pColor));
 
-			_ItemTags.put('R', Item.class.getMethod("setAnchorLeft", pFloatO));
-			_ItemTags.put('H', Item.class.getMethod("setAnchorRight", pFloatO));
-			_ItemTags.put('N', Item.class.getMethod("setAnchorTop", pFloatO));
-			_ItemTags.put('I', Item.class.getMethod("setAnchorBottom", pFloatO));
+			_ItemTags.put('R', Item.class.getMethod("setAnchorLeft", pIntO));
+			_ItemTags.put('H', Item.class.getMethod("setAnchorRight", pIntO));
+			_ItemTags.put('N', Item.class.getMethod("setAnchorTop", pIntO));
+			_ItemTags.put('I', Item.class.getMethod("setAnchorBottom", pIntO));
 
 			_ItemTags.put('P', Item.class.getMethod("setPosition", pPoint));
@@ -123,5 +127,5 @@
 			_ItemTags.put('e', Item.class.getMethod("setFillColor", pColor));
 			_ItemTags.put('E', Item.class.getMethod("setGradientColor", pColor));
-			_ItemTags.put('Q', Item.class.getMethod("setGradientAngle", pInt));
+			_ItemTags.put('Q', Item.class.getMethod("setGradientAngle", pDouble));
 			
 			_ItemTags.put('i', Item.class.getMethod("setFillPattern", pString));
@@ -136,6 +140,6 @@
 			_ItemTags.put('j', Item.class.getMethod("setArrow", pArrow));
 
-			_ItemTags.put('v', Item.class.getMethod("setDotType", new Class[]{DotType.class}));
-			_ItemTags.put('z', Item.class.getMethod("setFilled", pBool));
+			_ItemTags.put('v', Dot.class.getMethod("setDotType", pDotType));
+			_ItemTags.put('z', Dot.class.getMethod("setFilled", pBool));
 			
 			_ItemTags.put('f', Text.class.getMethod("setFont", pFont));
Index: /trunk/src/org/expeditee/io/DefaultFrameWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/DefaultFrameWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/DefaultFrameWriter.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.io;
 
-import java.awt.Desktop;
 import java.io.BufferedOutputStream;
 import java.io.File;
@@ -33,4 +32,5 @@
 
 import org.expeditee.agents.WriteTree;
+import org.expeditee.gio.EcosystemManager;
 import org.expeditee.gui.Browser;
 import org.expeditee.gui.Frame;
@@ -258,13 +258,6 @@
 			_writer.close();
 		}
-		try {
-			if (Browser._theBrowser.isMinimumVersion6()) {
-				if (Desktop.isDesktopSupported()) {
-					Desktop.getDesktop().open(new File(_output));
-				}
-			}
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
+		String errorMessage = EcosystemManager.getMiscManager().open(_output);
+		if (errorMessage != null) System.err.println(errorMessage);
 		return " exported to " + _output;
 	}
Index: /trunk/src/org/expeditee/io/ExaReader.java
===================================================================
--- /trunk/src/org/expeditee/io/ExaReader.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ExaReader.java	(revision 1102)
@@ -173,5 +173,5 @@
 					// refresh the last item loaded
 					if(item != null) {
-						item.updatePolygon();
+						item.invalidateBounds();
 						item.invalidateAll();
 					}
@@ -200,5 +200,5 @@
 		// refresh the last item loaded
 		if(item != null) {
-			item.updatePolygon();
+			item.invalidateBounds();
 			item.invalidateAll();
 		}
Index: /trunk/src/org/expeditee/io/ExaWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/ExaWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ExaWriter.java	(revision 1102)
@@ -29,5 +29,4 @@
 
 import org.expeditee.gui.AttributeUtils;
-import org.expeditee.gui.AttributeUtils.Attribute;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.Constraint;
Index: /trunk/src/org/expeditee/io/ExpClipReader.java
===================================================================
--- /trunk/src/org/expeditee/io/ExpClipReader.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ExpClipReader.java	(revision 1102)
@@ -25,5 +25,6 @@
 import java.util.List;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Point;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
@@ -37,5 +38,5 @@
 import org.expeditee.items.Line;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 
 /**
@@ -52,4 +53,9 @@
 	private int dX, dY;
 	
+	public ExpClipReader(Point p)
+	{
+		this(p.x, p.y);
+	}
+	
 	public ExpClipReader(int dX, int dY) {
 		super("");
@@ -63,5 +69,5 @@
 	 */
 	public static void updateItems(List<Item> items) {
-		if(FrameGraphics.isXRayMode()) {
+		if(DisplayController.isXRayMode()) {
 			return;
 		}
@@ -72,8 +78,7 @@
 				continue;
 			}
-			if (ItemUtils.startsWithTag(item,
-					ItemUtils.TAG_IMAGE, true)) {
+			if (ItemUtils.startsWithTag(item, ItemUtils.TAG_IMAGE, true)) {
 				if (!item.hasEnclosures()) {
-					items.add(ItemUtils.CreatePicture((Text) item, DisplayIO.getCurrentFrame()));
+					items.add(ItemUtils.CreatePicture((Text) item));
 				}
 				// check for frame images
@@ -83,5 +88,5 @@
 					&& !item.getAbsoluteLink()
 							.equalsIgnoreCase(
-									DisplayIO.getCurrentFrame().getName())) {
+									DisplayController.getCurrentFrame().getName())) {
 				if (item.hasEnclosures()) {
 					// item.setHidden(true);
@@ -90,5 +95,5 @@
 					// image.refresh();
 				} else {
-					items.add(new FrameImage((Text) item, DisplayIO.getCurrentFrame(), null));
+					items.add(new FrameImage((Text) item, null));
 				}
 			} else if (ItemUtils.startsWithTag(item,
@@ -97,5 +102,5 @@
 					&& !item.getAbsoluteLink()
 							.equalsIgnoreCase(
-									DisplayIO.getCurrentFrame().getName())) {
+									DisplayController.getCurrentFrame().getName())) {
 				if (item.hasEnclosures()) {
 					// image =
@@ -107,5 +112,5 @@
 					// frame which already has a bitmap dont
 					// recreate the bitmap
-					items.add(new FrameBitmap((Text) item, DisplayIO.getCurrentFrame(), null));
+					items.add(new FrameBitmap((Text) item, null));
 				}
 			} else if (ItemUtils.startsWithTag(item, "@c")) {
@@ -116,10 +121,9 @@
 				}
 				// Check for interactive widgets
-			} else if (ItemUtils.startsWithTag(item,
-					ItemUtils.TAG_IWIDGET)) {
+			} else if (ItemUtils.startsWithTag(item, ItemUtils.TAG_IWIDGET)) {
 				items.remove(item);
-				item.setParent(DisplayIO.getCurrentFrame());
+				item.setParent(DisplayController.getCurrentFrame());
 				try {
-					items.addAll(InteractiveWidget.createWidget((Text) item).getItems());
+					items.addAll(Widget.createWidget((Text) item).getItems());
 				} catch (Exception e) {
 					System.err.println("Failed to create widget");
@@ -176,10 +180,10 @@
 			while(index < lines.length && !(lines[++index].equals("Z"))) {
 				if (isValidLine(lines[index])) {
-					java.awt.Point idtype = separateValues(lines[index].substring(2));
+					Point idtype = separateValues(lines[index].substring(2));
 					// The next line must be the endpoints
 					if (index >= lines.length)
 						throw new Exception("Unexpected end of file");
 					++index;
-					java.awt.Point startend = separateValues(lines[index].substring(2));
+					Point startend = separateValues(lines[index].substring(2));
 					int start = startend.x;
 					int end = startend.y;
@@ -199,10 +203,10 @@
 			while(index < lines.length && !(lines[++index].equals("Z"))) {
 				if (isValidLine(lines[index])) {
-					java.awt.Point idtype = separateValues(lines[index].substring(2));
+					Point idtype = separateValues(lines[index].substring(2));
 					// The next line must be the endpoints
 					if (index >= lines.length)
 						throw new Exception("Unexpected end of file");
 					++index;
-					java.awt.Point startend = separateValues(lines[index].substring(2));
+					Point startend = separateValues(lines[index].substring(2));
 	
 					Item a = _linePoints.get(startend.x);
Index: /trunk/src/org/expeditee/io/ExpClipWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/ExpClipWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ExpClipWriter.java	(revision 1102)
@@ -23,9 +23,10 @@
 import java.util.List;
 
+import org.expeditee.core.Point;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.Item;
 import org.expeditee.items.Line;
 import org.expeditee.items.XRayable;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.items.widgets.WidgetEdge;
@@ -41,4 +42,9 @@
 	private int dX, dY;
 
+	public ExpClipWriter(Point p)
+	{
+		this(p.x, p.y);
+	}
+	
 	public ExpClipWriter(int dX, int dY) {
 		super();
@@ -60,5 +66,5 @@
 	public void output(List<Item> items) throws IOException {
 		// switch to savable items
-		LinkedList<InteractiveWidget> widgets = new LinkedList<InteractiveWidget>();
+		LinkedList<Widget> widgets = new LinkedList<Widget>();
 		// make an array to iterate over instead of the list so we don't get stuck when we remove items from the list
 		Item[] tmpitems = items.toArray(new Item[0]);
@@ -72,5 +78,5 @@
 				}
 			} else if (i instanceof WidgetCorner) {
-				InteractiveWidget iw = ((WidgetCorner)i).getWidgetSource();
+				Widget iw = ((WidgetCorner)i).getWidgetSource();
 				if(!widgets.contains(iw)) {
 					widgets.add(iw);
@@ -78,5 +84,5 @@
 				items.remove(i);
 			} else if (i instanceof WidgetEdge) {
-				InteractiveWidget iw = ((WidgetEdge)i).getWidgetSource();
+				Widget iw = ((WidgetEdge)i).getWidgetSource();
 				if(!widgets.contains(iw)) {
 					widgets.add(iw);
@@ -90,5 +96,5 @@
 			}
 		}
-		for (InteractiveWidget iw : widgets) {
+		for (Widget iw : widgets) {
 			items.add(iw.getSource());
 		}
Index: /trunk/src/org/expeditee/io/ExpReader.java
===================================================================
--- /trunk/src/org/expeditee/io/ExpReader.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ExpReader.java	(revision 1102)
@@ -27,4 +27,5 @@
 import java.util.List;
 
+import org.expeditee.core.Point;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.Constraint;
@@ -130,10 +131,10 @@
 			while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
 				if (isValidLine(next)) {
-					java.awt.Point idtype = separateValues(next.substring(2));
+					Point idtype = separateValues(next.substring(2));
 					// The next line must be the endpoints
 					if (!_reader.ready())
 						throw new Exception("Unexpected end of file");
 					next = _reader.readLine();
-					java.awt.Point startend = separateValues(next.substring(2));
+					Point startend = separateValues(next.substring(2));
 					int start = startend.x;
 					int end = startend.y;
@@ -153,10 +154,10 @@
 			while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
 				if (isValidLine(next)) {
-					java.awt.Point idtype = separateValues(next.substring(2));
+					Point idtype = separateValues(next.substring(2));
 					// The next line must be the endpoints
 					if (!_reader.ready())
 						throw new Exception("Unexpected end of file");
 					next = _reader.readLine();
-					java.awt.Point startend = separateValues(next.substring(2));
+					Point startend = separateValues(next.substring(2));
 
 					Item a = _linePoints.get(startend.x);
@@ -233,11 +234,9 @@
 
 		Method toRun = _ItemTags.get(tag);
-		if (toRun == null)
-			System.out.println("Error accessing tag method: " + tag);
+		if (toRun == null) System.out.println("Error accessing tag method: " + tag);
 		Object[] vals = Conversion.Convert(toRun, value);
 
 		try {
-			if (vals != null)
-				toRun.invoke(item, vals);
+			if (vals != null) toRun.invoke(item, vals);
 		} catch (Exception e) {
 			System.out.println("Error running tag method: " + tag);
@@ -297,9 +296,9 @@
 
 	// Returns a point from a String containing two ints separated by a space
-	protected java.awt.Point separateValues(String line) {
+	protected Point separateValues(String line) {
 		int x = Integer.parseInt(line.substring(0, line.indexOf(" ")));
 		int y = Integer.parseInt(line.substring(line.indexOf(" ") + 1));
 
-		return new java.awt.Point(x, y);
+		return new Point(x, y);
 	}
 
Index: /trunk/src/org/expeditee/io/HTMLWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/HTMLWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/HTMLWriter.java	(revision 1102)
@@ -19,10 +19,14 @@
 package org.expeditee.io;
 
-import java.awt.Image;
-import java.awt.image.BufferedImage;
 import java.io.IOException;
 import java.util.List;
 
 import org.expeditee.actions.Misc;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Image;
+import org.expeditee.core.Point;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.FrameIO;
 import org.expeditee.items.FramePicture;
@@ -65,11 +69,14 @@
 			image = pic.getImage();
 			// Crop the image
-			BufferedImage bufferedImage = new BufferedImage(pic
-					.getUnscaledWidth(), pic.getUnscaledHeight(),
-					BufferedImage.TYPE_INT_ARGB);
-			bufferedImage.getGraphics().drawImage(image, 0, 0,
-					pic.getUnscaledWidth(), pic.getUnscaledHeight(),
-					pic.getStart().x, pic.getStart().y, pic.getEnd().x,
-					pic.getEnd().y, null);
+			Image bufferedImage = Image.createImage(pic.getUnscaledWidth(), pic.getUnscaledHeight());
+			GraphicsManager g = EcosystemManager.getGraphicsManager();
+			g.pushDrawingSurface(bufferedImage);
+			g.drawImage(image,
+						new Point(0, 0),
+						new Dimension(pic.getUnscaledWidth(), pic.getUnscaledHeight()),
+						0.0,
+						pic.getStart(),
+						new Dimension(pic.getEnd().x - pic.getStart().x, pic.getEnd().y - pic.getStart().y));
+			g.popDrawingSurface();
 			image = bufferedImage;
 		} else {
@@ -81,10 +88,9 @@
 		// If its a bufferedImage then just write it out to the files directory
 		// This means it is probably a FrameImage
-		if (image instanceof BufferedImage) {
+		if (!image.isStoredOnDisk()) {
 			String link = pic.getAbsoluteLink();
-			// Account for the possiblitly of an unlinked buffered image
+			// Account for the possibility of an unlinked buffered image
 			fileName = link == null ? ("Image" + pic.getID()) : link;
-			fileName = Misc.SaveImage((BufferedImage) image, "PNG",
-					FrameIO.EXPORTS_DIR + filesFolder, fileName);
+			fileName = Misc.SaveImage(image, "PNG",	FrameIO.EXPORTS_DIR + filesFolder, fileName);
 		} else {// It is a normal Image stored somewhere
 			fileName = pic.getName();
Index: /trunk/src/org/expeditee/io/ItemSelection.java
===================================================================
--- /trunk/src/org/expeditee/io/ItemSelection.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ItemSelection.java	(revision 1102)
@@ -19,25 +19,17 @@
 package org.expeditee.io;
 
-
-import java.awt.Image;
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
-import java.awt.datatransfer.UnsupportedFlavorException;
-import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
-import javax.imageio.ImageIO;
-
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Image;
+import org.expeditee.gio.ClipboardManager.ClipboardData;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FreeItems;
 import org.expeditee.gui.MessageBay;
@@ -53,6 +45,6 @@
  * @author jts21
  */
-public class ItemSelection implements Transferable {
-	
+public class ItemSelection {
+	// TODO : Tidy commented code once tested. cts16
 	/**
 	 * Class used for storing data which can be used to reconstruct expeditee objects from the clipboard
@@ -68,57 +60,8 @@
 		// exp save data
 		public String items;
-	}
-	
-	public static final DataFlavor expDataFlavor = new DataFlavor(ExpDataHandler.class, "expDataHandler");
-	
-	private static final int STRING = 0;
-    private static final int IMAGE = 1;
-    private static final int EXP_DATA = 2;
-	
-	private static final DataFlavor[] flavors = {
-        DataFlavor.stringFlavor,
-        DataFlavor.imageFlavor,
-        expDataFlavor
-    };
-	
-	private String data;
-	private Image image;
-	private ExpDataHandler expData;
-	
-	public ItemSelection(String data, Image image, ExpDataHandler expData) {
-        this.data = data;
-        this.image = image;
-        this.expData = expData;
-    }
-	
-	@Override
-	public DataFlavor[] getTransferDataFlavors() {
-		return (DataFlavor[])flavors.clone();
-	}
-
-	@Override
-	public boolean isDataFlavorSupported(DataFlavor flavor) {
-		for (int i = 0; i < flavors.length; i++) {
-            if (flavor.equals(flavors[i])) {
-                return true;
-            }
-        }
-        return false;
-	}
-
-	@Override
-	public Object getTransferData(DataFlavor flavor)
-			throws UnsupportedFlavorException, IOException {
-        if (flavor.equals(flavors[STRING])) {
-            return (Object)data;
-        } else if (flavor.equals(flavors[IMAGE])) {
-        	return (Object)image;
-        } else if (flavor.equals(flavors[EXP_DATA])) {
-            return (Object)expData;
-        } else {
-            throw new UnsupportedFlavorException(flavor);
-        }
-	}
-	
+		public Image image;
+		public String text;
+	}
+
 	private static List<Item> getAllToCopy() {
 		List<Item> tmp = new ArrayList<Item>(FreeItems.getInstance());
@@ -128,5 +71,5 @@
 				if(! toCopy.contains(c)) {
 					toCopy.add(c);
-					FrameMouseActions.pickup(c);
+					StandardGestureActions.pickup(c);
 				}
 			}
@@ -142,8 +85,8 @@
 		
 		// remove the items attached to the cursor
-		DisplayIO.getCurrentFrame().removeAllItems(toCopy);
+		DisplayController.getCurrentFrame().removeAllItems(toCopy);
 		FreeItems.getInstance().clear();
 		
-		FrameGraphics.refresh(false);
+		DisplayController.requestRefresh(false);
 	}
 	
@@ -161,5 +104,5 @@
 			return;
 		}
-		
+
 		StringBuilder clipboardText = new StringBuilder();
 		ExpDataHandler expData = new ExpDataHandler();
@@ -179,5 +122,5 @@
 		
 		// get expeditee item data
-		ExpClipWriter ecw = new ExpClipWriter(FrameMouseActions.getX(), FrameMouseActions.getY());
+		ExpClipWriter ecw = new ExpClipWriter(EcosystemManager.getInputManager().getCursorPosition());
 		try {
 			ecw.output(items);
@@ -186,9 +129,16 @@
 		}
 		expData.items = ecw.getFileContents();
+		expData.image = image;
+		expData.text = clipboardText.toString();
+		
+		// Format the data for the clipboard
+		ClipboardData clipboardData = new ClipboardData(expData, expData.image, expData.text);
+		
 		// System.out.println(expData.items); 
-		
+
 		// write out to clipboard
-		ItemSelection selection = new ItemSelection(clipboardText.toString(), image, expData);
-		Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, null);
+		//ItemSelection selection = new ItemSelection(clipboardText.toString(), image, expData);
+		//Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, null);
+		EcosystemManager.getClipboardManager().set(clipboardData);
 	}
 	
@@ -196,7 +146,8 @@
 	 * Generates items from the clipboard data
 	 *  TODO: Enable pasting raw image data (would require saving the data as an image file and generating a Text item pointing to it)
+	 *  TODO: Above TODO seems to be done? cts16
 	 */
 	public static void paste() {
-		if(FreeItems.itemsAttachedToCursor()) {
+		if(FreeItems.hasItemsAttachedToCursor()) {
 			MessageBay.displayMessage("Drop any items being carried on the cursor, then try pasting again");
 			return;
@@ -204,29 +155,32 @@
 		String type = "";
 		FreeItems f = FreeItems.getInstance();
-		Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
-		Transferable content = c.getContents(null);
+		//Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
+		//Transferable content = c.getContents(null);
+		ClipboardData content = EcosystemManager.getClipboardManager().get();
+		
 		try {
-			if(content.isDataFlavorSupported(ItemSelection.expDataFlavor)) {	// Expeditee data
+			if (content.data instanceof ExpDataHandler) {	// Expeditee data
 				type = "Expeditee ";
-				ExpDataHandler expData = (ExpDataHandler)content.getTransferData(ItemSelection.expDataFlavor);
+				ExpDataHandler expData = (ExpDataHandler) content.data;
 				if(expData != null) {
-					List<Item> items = new ExpClipReader(FrameMouseActions.getX(), FrameMouseActions.getY()).read(expData.items);
+					List<Item> items = new ExpClipReader(EcosystemManager.getInputManager().getCursorPosition()).read(expData.items);
 					// generate new IDs and pickup
-					FrameMouseActions.pickup(ItemUtils.CopyItems(items));
+					StandardGestureActions.pickup(ItemUtils.CopyItems(items));
 				}
-			} else if(content.isDataFlavorSupported(DataFlavor.imageFlavor)) {	// Image data
+			} else if (content.imageRepresentation != null) {	// Image data
 				// System.out.println("IZ PIKTUR");
 				type = "Image ";
-				BufferedImage img = (BufferedImage)content.getTransferData(DataFlavor.imageFlavor);
-				int hashcode = Arrays.hashCode(img.getData().getPixels(0, 0, img.getWidth(), img.getHeight(), (int[])null));
+				Image img = content.imageRepresentation;
+				//int hashcode = Arrays.hashCode(img.getData().getPixels(0, 0, img.getWidth(), img.getHeight(), (int[])null));
+				int hashcode = img.hashCode();
 				File out = new File(FrameIO.IMAGES_PATH + Integer.toHexString(hashcode) + ".png");
 				out.mkdirs();
-				ImageIO.write(img, "png", out);
-				Text item = DisplayIO.getCurrentFrame().createNewText("@i: " + out.getPath());
+				img.writeToDisk("png", out);
+				Text item = DisplayController.getCurrentFrame().createNewText("@i: " + out.getPath());
 				f.add(item);
 				ExpClipReader.updateItems(f);
-			} else if(content.isDataFlavorSupported(DataFlavor.stringFlavor)) {	// Plain text
+			} else if (content.stringRepresentation != null) {	// Plain text
 				type = "Plain Text ";
-				String clip = ((String) content.getTransferData(DataFlavor.stringFlavor));
+				String clip = content.stringRepresentation;
 				// Covert the line separator char when pasting in
 				// windows (\r\n) or max (\r)
@@ -235,7 +189,7 @@
 				String[] items = clip.split("\n\n");
 				Item item, prevItem = null;
-				final int x = DisplayIO.getMouseX();
-				final int y = DisplayIO.getMouseY();
-				final Text template = DisplayIO.getCurrentFrame().getItemTemplate();
+				final int x = DisplayController.getMouseX();
+				final int y = DisplayController.getMouseY();
+				final Text template = DisplayController.getCurrentFrame().getItemTemplate();
 				for(int i = 0; i < items.length; i++) {
 					// System.out.println(items[i]);
Index: /trunk/src/org/expeditee/io/ItemWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/ItemWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ItemWriter.java	(revision 1102)
@@ -28,5 +28,5 @@
 import org.expeditee.items.Picture;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.WidgetEdge;
 
@@ -115,5 +115,5 @@
 	}
 
-	protected void writeWidget(InteractiveWidget toWrite) throws IOException {
+	protected void writeWidget(Widget toWrite) throws IOException {
 	}
 
Index: /trunk/src/org/expeditee/io/JavaWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/JavaWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/JavaWriter.java	(revision 1102)
@@ -19,33 +19,11 @@
 package org.expeditee.io;
 
-import java.awt.Desktop;
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.geom.Area;
-import java.io.File;
 import java.io.IOException;
 import java.io.Writer;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
-import org.expeditee.gui.Browser;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameUtils;
-import org.expeditee.io.flowlayout.AreaPolygon;
-import org.expeditee.io.flowlayout.DimensionExtent;
 import org.expeditee.io.flowlayout.XGroupItem;
-import org.expeditee.io.flowlayout.XItem;
-import org.expeditee.io.flowlayout.XOrderedLine;
-import org.expeditee.io.flowlayout.XRawItem;
-import org.expeditee.io.flowlayout.YOverlappingItemsShadow;
-import org.expeditee.io.flowlayout.YOverlappingItemsSpan;
-import org.expeditee.io.flowlayout.YOverlappingItemsTopEdge;
 import org.expeditee.items.Item;
-import org.expeditee.items.ItemUtils;
 import org.expeditee.items.Text;
 
Index: /trunk/src/org/expeditee/io/KMSReader.java
===================================================================
--- /trunk/src/org/expeditee/io/KMSReader.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/KMSReader.java	(revision 1102)
@@ -29,9 +29,9 @@
 import java.util.LinkedHashMap;
 
+import org.expeditee.core.Point;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.MessageBay;
 import org.expeditee.items.Constraint;
 import org.expeditee.items.Dot;
-import org.expeditee.items.DotType;
 import org.expeditee.items.Item;
 import org.expeditee.items.Line;
@@ -107,5 +107,5 @@
 			_ItemTags.put("e", Item.class.getMethod("setFillColor", pColor));
 			_ItemTags.put("E", Item.class.getMethod("setGradientColor", pColor));
-			_ItemTags.put("Q", Item.class.getMethod("setGradientAngle", pInt));
+			_ItemTags.put("Q", Item.class.getMethod("setGradientAngle", pDouble));
 			
 			_ItemTags.put("i", Item.class.getMethod("setFillPattern", pString));
@@ -267,5 +267,5 @@
 
 		// get the line ID and type
-		java.awt.Point idtype = separateValues(s);
+		Point idtype = separateValues(s);
 
 		// get the end points
@@ -273,5 +273,5 @@
 		_data.remove("s");
 
-		java.awt.Point startend = separateValues(s);
+		Point startend = separateValues(s);
 
 		int start = startend.x;
@@ -299,6 +299,6 @@
 	 */
 	private void createConstraint() {
-		java.awt.Point idtype = separateValues(_data.get("C"));
-		java.awt.Point startend = separateValues(_data.get("s"));
+		Point idtype = separateValues(_data.get("C"));
+		Point startend = separateValues(_data.get("s"));
 
 		Item a = _linePoints.get(startend.x);
@@ -398,9 +398,9 @@
 
 	// returns two ints separated by a space from the given String
-	private java.awt.Point separateValues(String line) {
+	private Point separateValues(String line) {
 		int x = Integer.parseInt(line.substring(0, line.indexOf(" ")));
 		int y = Integer.parseInt(line.substring(line.indexOf(" ") + 1));
 
-		return new java.awt.Point(x, y);
+		return new Point(x, y);
 	}
 
Index: /trunk/src/org/expeditee/io/PDF2Writer.java
===================================================================
--- /trunk/src/org/expeditee/io/PDF2Writer.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/PDF2Writer.java	(revision 1102)
@@ -19,9 +19,4 @@
 package org.expeditee.io;
 
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Image;
-import java.awt.Polygon;
-import java.awt.geom.AffineTransform;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -34,4 +29,11 @@
 import java.util.Set;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Image;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
@@ -145,5 +147,5 @@
 
 	public PDF2Writer() {
-		_pageSize = FrameGraphics.getMaxSize();
+		_pageSize = DisplayController.getFramePaintArea().getSize();
 		_pdfDocument = new Document(new Rectangle(_pageSize.width, _pageSize.height));
 	}
@@ -233,5 +235,5 @@
 		// set bg color
 		PdfContentByte cb = _pdfWriter.getDirectContent();
-		cb.setColorFill(starting.getPaintBackgroundColor());
+		cb.setColorFill(SwingConversions.toSwingColor(starting.getPaintBackgroundColor()));
 		cb.rectangle(0, 0, _pageSize.width, _pageSize.height);
 		cb.fill();
@@ -239,16 +241,16 @@
 	}
 	
-	private void drawPolygon(PdfContentByte cb, Polygon poly, Color fill, Color line, float lineThickness) {
+	private void drawPolygon(PdfContentByte cb, PolygonBounds poly, Colour fill, Colour line, float lineThickness) {
 		if(poly != null) {
-			cb.moveTo(poly.xpoints[0], _height - poly.ypoints[0]);
-			for(int i = 1; i < poly.npoints; i++) {
-				cb.lineTo(poly.xpoints[i], _height - poly.ypoints[i]);
+			cb.moveTo(poly.toArray()[0].x, _height - poly.toArray()[0].y);
+			for(int i = 1; i < poly.toArray().length; i++) {
+				cb.lineTo(poly.toArray()[i].x, _height - poly.toArray()[i].y);
 			}
 			cb.closePath();
 			if(fill != null) {
-				cb.setColorFill(fill);
+				cb.setColorFill(SwingConversions.toSwingColor(fill));
 				if(lineThickness > 0) {
     				cb.setLineWidth(lineThickness);
-    				cb.setColorStroke(line);
+    				cb.setColorStroke(SwingConversions.toSwingColor(line));
     				cb.fillStroke();
     			} else {
@@ -257,5 +259,5 @@
 			} else {
 				cb.setLineWidth(lineThickness);
-				cb.setColorStroke(line);
+				cb.setColorStroke(SwingConversions.toSwingColor(line));
 				cb.stroke();
 			}
@@ -269,7 +271,6 @@
 		if (hasLink) {
 			
-			Color lineColor = Color.BLACK, fillColor = null;
-			Polygon poly = i.getLinkPoly();
-			poly = new Polygon(poly.xpoints, poly.ypoints, poly.npoints);
+			Colour lineColor = Colour.BLACK, fillColor = null;
+			PolygonBounds poly = new PolygonBounds(i.getLinkBounds().getPolygon(16));
 			poly.translate((int) (x - Item.LEFT_MARGIN), (int) (_height - y - i.getBoundsHeight() / 2));
 			
@@ -298,7 +299,8 @@
 	protected void writeText(Text text) throws IOException {
 		PdfContentByte cb = _pdfWriter.getDirectContent();
-		Font font = FontFactory.getFont(
-				Conversion.getPdfFont(text.getFamily()), text.getSize(), text
-						.getPaintFont().getStyle(), text.getPaintColor());
+		Font font = FontFactory.getFont(Conversion.getPdfFont(text.getFamily()),
+										text.getSize(),
+										SwingConversions.toSwingFontStyle(text.getPaintFont().getStyle()),
+										SwingConversions.toSwingColor(text.getPaintColor()));
 		
 		// we draw some text on a certain position
@@ -318,5 +320,5 @@
 		try {
 			PdfContentByte cb = _pdfWriter.getDirectContent();
-			com.lowagie.text.Image iTextImage = com.lowagie.text.Image.getInstance(image, null);
+			com.lowagie.text.Image iTextImage = com.lowagie.text.Image.getInstance(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(image), null);
 			float angle = (float) (pic.getRotate() * Math.PI / 180);
 			double sin = Math.sin(angle), cos = Math.cos(angle);
@@ -339,8 +341,8 @@
 		PdfContentByte cb = _pdfWriter.getDirectContent();
 		cb.circle(circle.getCenter().getX(), _pdfWriter.getPageSize().getHeight() - circle.getCenter().getY(), (float) circle.getRadius());
-		cb.setColorFill(circle.getFillColor());
+		cb.setColorFill(SwingConversions.toSwingColor(circle.getFillColor()));
 		if(circle.getThickness() > 0) {
 			cb.setLineWidth(circle.getThickness());
-			cb.setColorStroke(circle.getPaintColor());
+			cb.setColorStroke(SwingConversions.toSwingColor(circle.getPaintColor()));
 			cb.fillStroke();
 		} else {
@@ -377,10 +379,10 @@
 			}
 			cb.closePath();
-			Color fill = currentItem.getFillColor();
+			Colour fill = currentItem.getFillColor();
 			if(fill != null) {
-    			cb.setColorFill(fill);
+    			cb.setColorFill(SwingConversions.toSwingColor(fill));
     			if(currentItem.getThickness() > 0) {
     				cb.setLineWidth(currentItem.getThickness());
-    				cb.setColorStroke(currentLine.getPaintColor());
+    				cb.setColorStroke(SwingConversions.toSwingColor(currentLine.getPaintColor()));
     				cb.fillStroke();
     			} else {
@@ -389,5 +391,5 @@
 			} else if(currentItem.getThickness() > 0) {
 				cb.setLineWidth(currentItem.getThickness());
-				cb.setColorStroke(currentLine.getPaintColor());
+				cb.setColorStroke(SwingConversions.toSwingColor(currentLine.getPaintColor()));
 				cb.stroke();
 			}
@@ -403,5 +405,5 @@
 					if(l.getThickness() >= 0) {
 						cb.setLineWidth(l.getThickness());
-						cb.setColorStroke(l.getPaintColor());
+						cb.setColorStroke(SwingConversions.toSwingColor(l.getPaintColor()));
 						cb.stroke();
 					}
Index: /trunk/src/org/expeditee/io/PDFWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/PDFWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/PDFWriter.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.io;
 
-import java.awt.Image;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -25,4 +24,7 @@
 import java.util.List;
 
+import org.expeditee.core.Image;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.Item;
@@ -54,7 +56,8 @@
 		if (UserSettings.Style.get().size() > 0) {
 			Text text = UserSettings.Style.get().get(0);
-			_bodyFont = FontFactory.getFont(Conversion.getPdfFont(text
-					.getFamily()), text.getSize(), text.getPaintFont()
-					.getStyle(), text.getColor());
+			_bodyFont = FontFactory.getFont(Conversion.getPdfFont(text.getFamily()),
+											text.getSize(),
+											SwingConversions.toSwingFontStyle(text.getPaintFont().getStyle()),
+											SwingConversions.toSwingColor(text.getColor()));
 		}
 		_pdfDocument = new Document();
@@ -114,7 +117,8 @@
 
 			if (font == null) {
-				font = FontFactory.getFont(Conversion.getPdfFont(text
-						.getFamily()), text.getSize(), text.getPaintFont()
-						.getStyle(), text.getColor());
+				font = FontFactory.getFont(Conversion.getPdfFont(text.getFamily()),
+											text.getSize(),
+											SwingConversions.toSwingFontStyle(text.getPaintFont().getStyle()),
+											SwingConversions.toSwingColor(text.getColor()));
 			}
 			
@@ -130,5 +134,5 @@
 		Image image = pic.getCroppedImage();
 		try {
-			_pdfDocument.add(com.lowagie.text.Image.getInstance(image, null));
+			_pdfDocument.add(com.lowagie.text.Image.getInstance(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(image), null));
 		} catch (DocumentException e) {
 			// TODO Auto-generated catch block
Index: /trunk/src/org/expeditee/io/PdfFramesetWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/PdfFramesetWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/PdfFramesetWriter.java	(revision 1102)
@@ -19,7 +19,5 @@
 package org.expeditee.io;
 
-import java.awt.Dimension;
 import java.awt.Graphics2D;
-import java.awt.Image;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -28,4 +26,11 @@
 import java.util.List;
 
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Image;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
@@ -35,5 +40,5 @@
 import org.expeditee.items.Picture;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.settings.UserSettings;
 
@@ -59,8 +64,8 @@
 	private boolean _showFrameNames;
 
-	public PdfFramesetWriter(long firstFrame, long maxFrame,
-			boolean showFrameNames) {
+	public PdfFramesetWriter(long firstFrame, long maxFrame, boolean showFrameNames)
+	{
 		super(firstFrame, maxFrame);
-		Dimension d = FrameGraphics.getMaxSize();
+		Dimension d = DisplayController.getFramePaintArea().getSize();
 		_pdfDocument = new Document(new Rectangle(d.width, d.height));
 		_showFrameNames = showFrameNames;
@@ -130,10 +135,11 @@
 		// we tell the ContentByte we're ready to draw text
 		cb.beginText();
-		Font font = FontFactory.getFont(
-				Conversion.getPdfFont(text.getFamily()), text.getSize(), text
-						.getPaintFont().getStyle(), text.getPaintColor());
+		Font font = FontFactory.getFont(Conversion.getPdfFont(text.getFamily()),
+										text.getSize(),
+										SwingConversions.toSwingFontStyle(text.getPaintFont().getStyle()),
+										SwingConversions.toSwingColor(text.getPaintColor()));
 		cb.setFontAndSize(font.getBaseFont(), text.getSize());
 		// cb.setColorStroke(text.getPaintColor());
-		cb.setColorFill(text.getPaintColor());
+		cb.setColorFill(SwingConversions.toSwingColor(text.getPaintColor()));
 
 		// we draw some text on a certain position
@@ -158,5 +164,5 @@
 			PdfContentByte cb = _pdfWriter.getDirectContent();
 			com.lowagie.text.Image iTextImage = com.lowagie.text.Image
-					.getInstance(image, null);
+					.getInstance(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(image), null);
 			iTextImage.setAbsolutePosition(pic.getX(), _pdfWriter.getPageSize()
 					.getHeight()
@@ -175,8 +181,10 @@
 //			cb.setColorFill(fill);
 //		}
-		Graphics2D g = cb.createGraphicsShapes(
+/*		Graphics2D g = cb.createGraphicsShapes(
 				FrameGraphics.getMaxSize().width,
-				FrameGraphics.getMaxSize().height);
-		lineEnd.paint(g);
+				FrameGraphics.getMaxSize().height);*/
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		Image temp = EcosystemManager.getImageManager().createImage(DisplayController.getFramePaintArea().getSize());
+		lineEnd.paint();
 //		if (fill != null) {
 //			g.setPaint(fill);
@@ -191,20 +199,25 @@
 	
 	@Override
-	protected void writeCircle(Circle toWrite) throws IOException {
-		PdfContentByte cb = _pdfWriter.getDirectContent();
-		Graphics2D g = cb.createGraphicsShapes(
-				FrameGraphics.getMaxSize().width,
-				FrameGraphics.getMaxSize().height);
-		toWrite.paint(g);
+	protected void writeCircle(Circle toWrite) throws IOException
+	{
+		PdfContentByte cb = _pdfWriter.getDirectContent();
+		Graphics2D g = cb.createGraphicsShapes(DisplayController.getFramePaintArea().getWidth(), DisplayController.getFramePaintArea().getHeight());
+		Image temp = EcosystemManager.getImageManager().createImage(DisplayController.getFramePaintArea().getSize());
+		EcosystemManager.getGraphicsManager().pushDrawingSurface(temp);
+		toWrite.paint();
+		EcosystemManager.getGraphicsManager().popDrawingSurface();
+		g.drawImage(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(temp), 0, 0, null);
 	}
 	
-	
-	@Override
-	protected void writeWidget(InteractiveWidget toWrite) throws IOException {
-		PdfContentByte cb = _pdfWriter.getDirectContent();
-		Graphics2D g = cb.createGraphicsShapes(
-				FrameGraphics.getMaxSize().width,
-				FrameGraphics.getMaxSize().height);
-		toWrite.paint(g);
+	@Override
+	protected void writeWidget(Widget toWrite) throws IOException
+	{
+		PdfContentByte cb = _pdfWriter.getDirectContent();
+		Graphics2D g = cb.createGraphicsShapes(DisplayController.getFramePaintArea().getWidth(), DisplayController.getFramePaintArea().getHeight());
+		Image temp = EcosystemManager.getImageManager().createImage(DisplayController.getFramePaintArea().getSize());
+		EcosystemManager.getGraphicsManager().pushDrawingSurface(temp);
+		toWrite.paint();
+		EcosystemManager.getGraphicsManager().popDrawingSurface();
+		g.drawImage(SwingMiscManager.getIfUsingSwingImageManager().getInternalImage(temp), 0, 0, null);
 	}
 }
Index: /trunk/src/org/expeditee/io/ProxyAuth.java
===================================================================
--- /trunk/src/org/expeditee/io/ProxyAuth.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ProxyAuth.java	(revision 1102)
@@ -24,4 +24,6 @@
 public class ProxyAuth extends Authenticator {
 
+	public static final int MAX_ATTEMPTS = 5;
+	
 	private String httpUser = null, httpPass = null, httpsUser = null, httpsPass = null;
 	private int attempts = 0;
@@ -37,5 +39,5 @@
 		// stop it from breaking from a redirect loop
 		attempts++;
-		if(attempts > 5) {
+		if(attempts > MAX_ATTEMPTS) {
 			return null;
 		}
Index: /trunk/src/org/expeditee/io/ProxyWriter.java
===================================================================
--- /trunk/src/org/expeditee/io/ProxyWriter.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/ProxyWriter.java	(revision 1102)
@@ -19,10 +19,11 @@
 package org.expeditee.io;
 
-import java.awt.Toolkit;
-import java.awt.datatransfer.StringSelection;
 import java.io.BufferedWriter;
 import java.io.IOException;
 import java.io.PipedWriter;
 import java.io.Writer;
+
+import org.expeditee.gio.ClipboardManager.ClipboardData;
+import org.expeditee.gio.EcosystemManager;
 
 public class ProxyWriter extends BufferedWriter {
@@ -55,10 +56,8 @@
 	public void flush() throws IOException {
 		if (_contents != null) {
-			StringSelection selection = new StringSelection(_contents
-					.toString());
-			Toolkit.getDefaultToolkit().getSystemClipboard().setContents(
-					selection, null);
-		} else
+			EcosystemManager.getClipboardManager().set(ClipboardData.fromString(_contents.toString()));
+		} else {
 			super.flush();
+		}
 	}
 
Index: /trunk/src/org/expeditee/io/StreamGobbler.java
===================================================================
--- /trunk/src/org/expeditee/io/StreamGobbler.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/StreamGobbler.java	(revision 1102)
@@ -19,9 +19,5 @@
 package org.expeditee.io;
 
-
-import java.util.*;
 import java.io.*;
-
-import javax.swing.SwingUtilities;
 
 import org.expeditee.gui.MessageBay;
@@ -82,5 +78,5 @@
             	// MessageBay is on the AWT event thread, so need to use 'invokeLater' to avoid thread deadlock
             	Runnable updateMessageBayTask = new UpdateMessageBay(type,line);
-                SwingUtilities.invokeLater(updateMessageBayTask);
+                updateMessageBayTask.run();
             	
             }
Index: /trunk/src/org/expeditee/io/WebParser.java
===================================================================
--- /trunk/src/org/expeditee/io/WebParser.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/WebParser.java	(revision 1102)
@@ -19,7 +19,4 @@
 package org.expeditee.io;
 
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
@@ -45,5 +42,4 @@
 import javafx.beans.value.ObservableValue;
 import javafx.concurrent.Worker.State;
-import javafx.embed.swing.SwingFXUtils;
 import javafx.scene.SnapshotParameters;
 import javafx.scene.image.WritableImage;
@@ -51,13 +47,16 @@
 import javafx.scene.web.WebView;
 
-import javax.imageio.ImageIO;
-
 import netscape.javascript.JSObject;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Font;
+import org.expeditee.core.Image;
+import org.expeditee.core.InOutReference;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.swing.SwingMiscManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
@@ -303,6 +302,6 @@
 		try {
 			
-			final int verticalScrollPerPage = (int) (FrameGraphics.getMaxFrameSize().getHeight() * 0.85);
-			final int horizontalScrollPerPage = (int) (FrameGraphics.getMaxFrameSize().getWidth() * 0.85);
+			final int verticalScrollPerPage = (int) (DisplayController.getFramePaintArea().getHeight() * 0.85);
+			final int horizontalScrollPerPage = (int) (DisplayController.getFramePaintArea().getWidth() * 0.85);
 						
 			Platform.runLater(new Runnable() {
@@ -320,9 +319,9 @@
 			final Object notifier = new Object();
 						
-			final MutableInt verticalCount = new MutableInt(0);
-			final MutableInt horizontalCount = new MutableInt(0);
+			final InOutReference<Integer> verticalCount = new InOutReference<Integer>(0);
+			final InOutReference<Integer> horizontalCount = new InOutReference<Integer>(0);
 			
-			final MutableInt pagesVertical = new MutableInt(1);
-			final MutableInt pagesHorizontal = new MutableInt(1);
+			final InOutReference<Integer> pagesVertical = new InOutReference<Integer>(1);
+			final InOutReference<Integer> pagesHorizontal = new InOutReference<Integer>(1);
 
 			final String pageTitle;
@@ -341,10 +340,10 @@
 			frameset.getTitleItem().setSize(14);
 
-			WebParser.addButton("Return to original frame", frame.getName(), null, 200, frameset, null, 0f, 10f, null);
-
-			Text link = DisplayIO.getCurrentFrame().addText(FrameMouseActions.getX(), FrameMouseActions.getY(), pageTitle, null);
+			WebParser.addButton("Return to original frame", frame.getName(), null, 200, frameset, null, 0, 10, null);
+
+			Text link = DisplayController.getCurrentFrame().addText(DisplayController.getMouseX(), DisplayController.getMouseY(), pageTitle, null);
 			link.setLink(frameset.getName());
 
-			FrameMouseActions.pickup(link);
+			StandardGestureActions.pickup(link);
 
 			// Timer that fires every time JFX is redrawn. After a few redraws, the handle method of this takes a screenshot of the page,
@@ -364,5 +363,5 @@
 						this.stop();
 						
-						verticalCount.setValue(verticalCount.getValue() + 1);
+						verticalCount.set(verticalCount.get() + 1);
 
 						frameToAddTo = FrameIO.CreateFrame(frameToAddTo.getFramesetName(), pageTitle, null);
@@ -395,12 +394,15 @@
 
 						// Getting a BufferedImage from the JavaFX image
-						BufferedImage image = SwingFXUtils.fromFXImage(img, null);
+						//BufferedImage image = SwingFXUtils.fromFXImage(img, null);
+						Image image = SwingMiscManager.getImageForJavaFXImage(img);
 
 						try {
-							int hashcode = Arrays.hashCode(image.getData().getPixels(0, 0, image.getWidth(), image.getHeight(), (int[]) null));
-
+							// TODO: tidy. cts16
+							//int hashcode = Arrays.hashCode(image.getData().getPixels(0, 0, image.getWidth(), image.getHeight(), (int[]) null));
+							int hashcode = image.hashCode();
+							
 							File out = new File(FrameIO.IMAGES_PATH + "webpage-" + Integer.toHexString(hashcode) + ".png");
 							out.mkdirs();
-							ImageIO.write(image, "png", out);
+							image.writeToDisk("png", out);
 
 							// Adding the image to the frame
@@ -408,23 +410,23 @@
 							
 							// Adding thumbnail to the overview page
-							Text thumb = frameset.addText((int) (thumbWidth * 1.1 * horizontalCount.getValue()) + 10,
-									(int) ((((float) thumbWidth / image.getWidth()) * image.getHeight()) * 1.1 * verticalCount.getValue()),
+							Text thumb = frameset.addText((int) (thumbWidth * 1.1 * horizontalCount.get()) + 10,
+									(int) ((((float) thumbWidth / image.getWidth()) * image.getHeight()) * 1.1 * verticalCount.get()),
 									"@i: " + out.getName() + " " + thumbWidth, 
 									null);
 							
 							thumb.setLink(frameToAddTo.getName());
-							thumb.setBorderColor(Color.lightGray);
+							thumb.setBorderColor(Colour.LIGHT_GREY);
 							thumb.setThickness(1);
 
 							// Button to go to the next frame/page
-							WebParser.addButton("Next", null, "next", 70, frameToAddTo, null, 0f, 10f, null);
+							WebParser.addButton("Next", null, "next", 70, frameToAddTo, null, 0, 10, null);
 
 							// Button to go to the previous frame/page
-							if (verticalCount.getValue() > 1 || horizontalCount.getValue() > 0) {
-								WebParser.addButton("Previous", null, "previous", 70, frameToAddTo, null, 85f, 10f, null);
+							if (verticalCount.get() > 1 || horizontalCount.get() > 0) {
+								WebParser.addButton("Previous", null, "previous", 70, frameToAddTo, null, 85, 10, null);
 							}
 
 							// Button to return to the index/overview page
-							WebParser.addButton("Index", frameset.getName(), null, 70, frameToAddTo, null, null, 10f, 5f);
+							WebParser.addButton("Index", frameset.getName(), null, 70, frameToAddTo, null, null, 10, 5);
 
 							FrameIO.SaveFrame(frameToAddTo);
@@ -435,5 +437,5 @@
 						}
 
-						image.flush();
+						image.releaseImage();
 
 						synchronized (notifier) {
@@ -468,13 +470,13 @@
 						// but if the webpage fits in a single converted page, there's no need for any overlap, so just use 1 as the number of pages
 						if((Boolean) webEngine.executeScript("document.documentElement.scrollHeight > window.innerHeight")) {
-							pagesVertical.setValue((int) Math.ceil((Integer) webEngine.executeScript("document.documentElement.scrollHeight") / (float) verticalScrollPerPage));
+							pagesVertical.set((int) Math.ceil((Integer) webEngine.executeScript("document.documentElement.scrollHeight") / (float) verticalScrollPerPage));
 						}
 						
 						if((Boolean) webEngine.executeScript("document.documentElement.scrollWidth > window.innerWidth")) {
-							pagesHorizontal.setValue((int) Math.ceil((Integer) webEngine.executeScript("document.documentElement.scrollWidth") / (float) horizontalScrollPerPage));
+							pagesHorizontal.set((int) Math.ceil((Integer) webEngine.executeScript("document.documentElement.scrollWidth") / (float) horizontalScrollPerPage));
 						}
 						
 						System.out.println(webEngine.executeScript("document.documentElement.scrollWidth") + "/" + horizontalScrollPerPage);
-						System.out.println(pagesVertical.getValue() + "x" + pagesHorizontal.getValue());
+						System.out.println(pagesVertical.get() + "x" + pagesHorizontal.get());
 						
 						// Setting up the element that contains the CSS to hide all text. Also hiding readability mode buttons.
@@ -628,5 +630,5 @@
 
 			// Loop that scrolls the page horizontally
-			for(int i = 0; i < pagesHorizontal.getValue() && browserWidget.isParserRunning(); i++) {
+			for(int i = 0; i < pagesHorizontal.get() && browserWidget.isParserRunning(); i++) {
 								
 				Platform.runLater(new Runnable() {
@@ -647,8 +649,8 @@
 				
 				// Loop that scrolls the page vertically (for each horizontal scroll position)
-				for(int j = 0; j < pagesVertical.getValue()  && browserWidget.isParserRunning(); j++) {
+				for(int j = 0; j < pagesVertical.get()  && browserWidget.isParserRunning(); j++) {
 					
 					try {
-						progressBar.set((int) (50 + ((float)(j+1)/(pagesVertical.getValue() * pagesHorizontal.getValue())  + ((float)(i) / pagesHorizontal.getValue())) * 50));
+						progressBar.set((int) (50 + ((float)(j+1)/(pagesVertical.get() * pagesHorizontal.get())  + ((float)(i) / pagesHorizontal.get())) * 50));
 					} catch (Exception e) {
 						e.printStackTrace();
@@ -698,6 +700,6 @@
 				}
 
-				horizontalCount.setValue(horizontalCount.getValue() + 1);
-				verticalCount.setValue(0);
+				horizontalCount.set(horizontalCount.get() + 1);
+				verticalCount.set(0);
 			}
 
@@ -742,5 +744,5 @@
 	 * @return A Color object that should match the rgb string passed int. Returns null if alpha is 0
 	 */
-	private static Color rgbStringToColor(String rgbString) {
+	private static Colour rgbStringToColor(String rgbString) {
 
 		if (rgbString == null) {
@@ -764,5 +766,5 @@
 
 		if (components[3] > 0) {
-			return new Color(components[0], components[1], components[2], components[3]);
+			return Colour.FromRGBA255(components[0], components[1], components[2], components[3]);
 		} else {
 			return null;
@@ -854,5 +856,5 @@
 
 					Boolean fontFound = false;
-					Font font = new Font(null);
+					Font font = null;
 
 					// Looping through all font-families listed in the element's CSS until one that is installed is
@@ -869,14 +871,19 @@
 						
 						// Regex will remove any inverted commas surrounding multi-word typeface names
-						font = new Font(typefaces[j].replaceAll("^'|'$", ""), Font.PLAIN, 12);
-						
-						// If the font isn't found, Java just uses Font.DIALOG, so this check checks whether the font was found
-						if (!(font.getFamily().toLowerCase().equals(Font.DIALOG.toLowerCase()))) {
+						String familyName = typefaces[j].replaceAll("^'|'$", "");
+						font = new Font(familyName);
+						font.setStyle(Font.Style.PLAIN);
+						font.setSize(12);
+						
+						// Check whether the font was found
+						if (EcosystemManager.getFontManager().getActualFont(font).getFamilyName().toLowerCase().equals(familyName.toLowerCase())) {
 							fontFound = true;
 						}
 					}
 
-					if (font.getFamily().toLowerCase().equals(Font.DIALOG.toLowerCase())) {
-						font = new Font("Times New Roman", Font.PLAIN, 12);
+					if (!fontFound) {
+						font = new Font("Times New Roman");
+						font.setStyle(Font.Style.PLAIN);
+						font.setSize(12);
 					}
 
@@ -975,5 +982,5 @@
 					String bgColorString = (String) style.call("getPropertyValue", new Object[] { "background-color" });
 
-					Color bgColor = rgbStringToColor(bgColorString);
+					Colour bgColor = rgbStringToColor(bgColorString);
 
 					// If the element has a background color then add it (to Expeditee) as a rectangle with that background color
@@ -1077,13 +1084,11 @@
 		HttpURLConnection connection = (HttpURLConnection) (imgUrl.openConnection());
 
-		// Spoofing a widely accepted User Agent, since some sites refuse to serve non-webbrowser clients
-		connection.setRequestProperty("User-Agent", "Mozilla/5.0");
-
-		BufferedImage img = ImageIO.read(connection.getInputStream());
-
-		int hashcode = Arrays.hashCode(img.getData().getPixels(0, 0, img.getWidth(), img.getHeight(), (int[]) null));
+		Image img = Image.getImage(connection);
+		
+		int hashcode = img.hashCode();
+		
 		File out = new File(FrameIO.IMAGES_PATH + Integer.toHexString(hashcode) + ".png");
 		out.mkdirs();
-		ImageIO.write(img, "png", out);
+		img.writeToDisk("png", out);
 
 		if (repeat == null && cropEndX == null && cropStartX == null && cropEndY == null && cropStartY == null) {
@@ -1153,5 +1158,5 @@
 		text.setPosition(x, y);
 
-		Picture pic = ItemUtils.CreatePicture(text, frame);
+		Picture pic = ItemUtils.CreatePicture(text);
 		
 		float invScale = 1 / pic.getScale();
@@ -1324,5 +1329,5 @@
 
 				Boolean fontFound = false;
-				Font font = new Font(null);
+				Font font = null;
 
 				// Looping through all font-families listed in the element's CSS until one that is installed is
@@ -1342,14 +1347,19 @@
 
 					// Regex will remove any inverted commas surrounding multi-word typeface names
-					font = new Font(typefaces[j].replaceAll("^'|'$", ""), Font.PLAIN, 12);
+					String familyName = typefaces[j].replaceAll("^'|'$", "");
+					font = new Font(familyName);
+					font.setStyle(Font.Style.PLAIN);
+					font.setSize(12);
 
 					// If the font isn't found, Java just uses Font.DIALOG, so this check checks whether the font was found
-					if (!(font.getFamily().toLowerCase().equals(Font.DIALOG.toLowerCase()))) {
+					if (EcosystemManager.getFontManager().getActualFont(font).getFamilyName().toLowerCase().equals(familyName.toLowerCase())) {
 						fontFound = true;
 					}
 				}
 
-				if (font.getFamily().toLowerCase().equals(Font.DIALOG.toLowerCase())) {
-					font = new Font("Times New Roman", Font.PLAIN, 12);
+				if (!fontFound) {
+					font = new Font("Times New Roman");
+					font.setStyle(Font.Style.PLAIN);
+					font.setSize(12);
 				}
 
@@ -1464,5 +1474,5 @@
 	 * @param anchorLeft
 	 */
-	private static void addButton(String text, String link, String action, int width, Frame toAddTo, Float anchorTop, Float anchorRight, Float anchorBottom, Float anchorLeft) {
+	private static void addButton(String text, String link, String action, int width, Frame toAddTo, Integer anchorTop, Integer anchorRight, Integer anchorBottom, Integer anchorLeft) {
 		// Button to go to the next frame/page
 		Text button = new Text(text);
@@ -1470,6 +1480,6 @@
 		button.setLink(link);
 		button.addAction(action);
-		button.setBorderColor(new Color(0.7f, 0.7f, 0.7f));
-		button.setBackgroundColor(new Color(0.9f, 0.9f, 0.9f));
+		button.setBorderColor(new Colour(0.7f, 0.7f, 0.7f));
+		button.setBackgroundColor(new Colour(0.9f, 0.9f, 0.9f));
 		button.setThickness(1);
 		button.setLinkMark(false);
@@ -1499,36 +1509,3 @@
 
 	}
-
-
-	private static class MutableBool {
-		private boolean value;
-
-		public MutableBool(boolean value) {
-			this.value = value;
-		}
-
-		public boolean getValue() {
-			return value;
-		}
-
-		public void setValue(boolean value) {
-			this.value = value;
-		}
-	}
-
-	private static class MutableInt {
-		private int value;
-
-		public MutableInt(int value) {
-			this.value = value;
-		}
-
-		public int getValue() {
-			return value;
-		}
-
-		public void setValue(int value) {
-			this.value = value;
-		}
-	}
 }
Index: /trunk/src/org/expeditee/io/flowlayout/DimensionExtent.java
===================================================================
--- /trunk/src/org/expeditee/io/flowlayout/DimensionExtent.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/flowlayout/DimensionExtent.java	(revision 1102)
@@ -19,9 +19,8 @@
 package org.expeditee.io.flowlayout;
 
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.geom.Area;
 import java.util.List;
 
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.PolygonBounds;
 import org.expeditee.items.Item;
 
@@ -44,8 +43,7 @@
 		
 		for (Item item : items) {
-			Area area = item.getArea();
-			Rectangle rect = area.getBounds();
-			int xl = rect.x;
-			int xr = xl + rect.width-1;
+			AxisAlignedBoxBounds bounds = item.getBoundingBox();
+			int xl = bounds.getMinX();
+			int xr = xl + bounds.getWidth()-1;
 			
 			min_x = Math.min(min_x, xl);
@@ -66,8 +64,7 @@
 		
 		for (Item item : items) {
-			Area area = item.getArea();
-			Rectangle rect = area.getBounds();
-			int yt = rect.y;
-			int yb = yt + rect.height-1;
+			AxisAlignedBoxBounds bounds = item.getBoundingBox();
+			int yt = bounds.getMinY();
+			int yb = yt + bounds.getHeight()-1;
 			
 			min_y = Math.min(min_y, yt);
@@ -82,63 +79,33 @@
 
 	
-	public static DimensionExtent calcMinMaxXExtent(Polygon polygon)
+	public static DimensionExtent calcMinMaxXExtent(PolygonBounds polygon)
 	{
 
-		int min_x = Integer.MAX_VALUE;
-		int max_x = Integer.MIN_VALUE;
-		
-		int npoints = polygon.npoints;
-
-		for (int i=0; i<npoints; i++) {
-
-			int x = polygon.xpoints[i];
-
-			min_x = Math.min(min_x, x);
-			max_x = Math.max(max_x, x);
-		}
-		
-		DimensionExtent extent = new DimensionExtent(min_x,max_x);
+		DimensionExtent extent = new DimensionExtent(polygon.getMinX(), polygon.getMaxX());
 		
 		return extent;
 	}
 	
-	public static DimensionExtent calcMinMaxYExtent(Polygon polygon)
+	public static DimensionExtent calcMinMaxYExtent(PolygonBounds polygon)
 	{
 
-		int min_y = Integer.MAX_VALUE;
-		int max_y = Integer.MIN_VALUE;
-		
-		int npoints = polygon.npoints;
-		
-		for (int i=0; i<npoints; i++) {
-
-			int y = polygon.ypoints[i];
-				
-			min_y = Math.min(min_y, y);
-			max_y = Math.max(max_y, y);
-		}
-		
-		DimensionExtent extent = new DimensionExtent(min_y,max_y);
+		DimensionExtent extent = new DimensionExtent(polygon.getMinY(), polygon.getMaxY());
 		
 		return extent;
 	}
 	
-	public static Polygon boundingBoxPolygon(List<Item> items)
+	public static PolygonBounds boundingBoxPolygon(List<Item> items)
 	{
-		DimensionExtent xextent = DimensionExtent.calcMinMaxXExtent(items);
-		DimensionExtent yextent = DimensionExtent.calcMinMaxYExtent(items);
-	
-		int xl=xextent.min;
-		int xr=xextent.max;
-		int yt=yextent.min;
-		int yb=yextent.max;
+		AxisAlignedBoxBounds box = null;
 		
-		int[] xpoints = new int[]{xl,xr,xr,xl};
-		int[] ypoints = new int[]{yt,yt,yb,yb};
+		for (Item i : items) {
+			if (box == null) {
+				box = i.getBoundingBox();
+			} else {
+				box.combineWith(i.getBoundingBox());
+			}
+		}
 		
-		
-		Polygon polygon = new Polygon(xpoints,ypoints,4);
-		
-		return polygon;
+		return new PolygonBounds(box.getBorderLines());
 	}
 }
Index: /trunk/src/org/expeditee/io/flowlayout/XGroupItem.java
===================================================================
--- /trunk/src/org/expeditee/io/flowlayout/XGroupItem.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/flowlayout/XGroupItem.java	(revision 1102)
@@ -19,7 +19,4 @@
 package org.expeditee.io.flowlayout;
 
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -31,4 +28,7 @@
 import java.util.List;
 
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.PolygonBounds;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameUtils;
@@ -110,6 +110,5 @@
 	}
 
-	public XGroupItem(Frame frame, List<Item> y_ordered_items,
-			Polygon enclosing_polygon) {
+	public XGroupItem(Frame frame, List<Item> y_ordered_items, PolygonBounds enclosing_polygon) {
 		this.frame = frame;
 		this.out_of_flow = FlowType.in_flow;
@@ -124,5 +123,5 @@
 		}
 
-		Rectangle enclosing_bounding_rect = enclosing_polygon.getBounds();
+		AxisAlignedBoxBounds enclosing_bounding_rect = AxisAlignedBoxBounds.getEnclosing(enclosing_polygon);
 		initSpanArray(enclosing_bounding_rect);
 
@@ -134,6 +133,5 @@
 		remaining_item_list = new ArrayList<Item>();
 
-		separateYOverlappingItems(frame, y_ordered_items, enclosing_polygon,
-				raw_text_item_list, grouped_item_list, remaining_item_list);
+		separateYOverlappingItems(frame, y_ordered_items, enclosing_polygon, raw_text_item_list, grouped_item_list, remaining_item_list);
 
 		// Step 2: Add in the raw-text items
@@ -161,5 +159,6 @@
 	}
 
-	protected XGroupItem(XGroupItem imprint, Rectangle copy_to_bounding_rect) {
+	protected XGroupItem(XGroupItem imprint, AxisAlignedBoxBounds copy_to_bounding_rect)
+	{
 		super();
 
@@ -192,5 +191,5 @@
 												// straight away?
 
-		this.bounding_rect = new Rectangle(copy_to_bounding_rect); // deep copy
+		this.bounding_rect = new AxisAlignedBoxBounds(copy_to_bounding_rect); // deep copy
 																	// to be on
 																	// the safe
@@ -198,5 +197,5 @@
 	}
 
-	protected void initSpanArray(Rectangle bounding_rect) {
+	protected void initSpanArray(AxisAlignedBoxBounds bounding_rect) {
 		this.bounding_rect = bounding_rect;
 
@@ -533,6 +532,5 @@
 							// to make it appear where the start of the arrow is
 
-							Rectangle start_rect = start_item.getArea()
-									.getBounds();
+							AxisAlignedBoxBounds start_rect = start_item.getBoundingBox();
 
 							XGroupItem xgroup_item_shallow_copy = new XGroupItem(
@@ -630,6 +628,6 @@
 	 * @return
 	 */
-	public Collection<Item> getItemsInNestedEnclosure(Item given_item,
-			AreaPolygon outer_polygon) {
+	public Collection<Item> getItemsInNestedEnclosure(Item given_item, PolygonBounds outer_polygon)
+	{
 		Collection<Item> sameEnclosure = null;
 		Collection<Item> seen = new HashSet<Item>();
@@ -649,5 +647,5 @@
 				seen.addAll(i_enclosing_dots);
 
-				Polygon i_polygon = new Polygon();
+				PolygonBounds i_polygon = new PolygonBounds();
 				for (int di = 0; di < i_enclosing_dots.size(); di++) {
 					Item d = i_enclosing_dots.get(di);
@@ -684,5 +682,5 @@
 
 	public void separateYOverlappingItems(Frame frame, List<Item> item_list,
-			Polygon enclosing_polygon, List<Text> raw_text_item_list,
+			PolygonBounds enclosing_polygon, List<Text> raw_text_item_list,
 			List<XGroupItem> grouped_item_list, List<Item> remaining_item_list) {
 		final List<Item> origonal_item_list = new ArrayList<Item>(item_list);
@@ -692,7 +690,7 @@
 		// of lines/polylines/polygons
 
-		AreaPolygon area_enclosing_polygon = new AreaPolygon(enclosing_polygon);
-
-		List<AreaPolygon> area_enclosed_polygon_list = new ArrayList<AreaPolygon>();
+		PolygonBounds area_enclosing_polygon = new PolygonBounds(enclosing_polygon);
+
+		List<PolygonBounds> area_enclosed_polygon_list = new ArrayList<PolygonBounds>();
 
 		while (item_list.size() > 0) {
@@ -724,6 +722,5 @@
 								.remove(0); // shift
 
-						Polygon enclosed_polygon = enclosure_item
-								.getEnclosedShape();
+						PolygonBounds enclosed_polygon = enclosure_item.getEnclosedShape();
 
 						if (enclosed_polygon != null) {
@@ -739,8 +736,6 @@
 							// group)
 
-							AreaPolygon area_enclosed_polygon = new AreaPolygon(
-									enclosed_polygon);
-							area_enclosed_polygon_list
-									.add(area_enclosed_polygon);
+							PolygonBounds area_enclosed_polygon = new PolygonBounds(enclosed_polygon);
+							area_enclosed_polygon_list.add(area_enclosed_polygon);
 
 							item_list.remove(enclosure_item);
@@ -763,10 +758,7 @@
 							while (item_iterator.hasNext()) {
 								Item item_to_check = item_iterator.next();
-								Point pt_to_check = new Point(
-										item_to_check.getX(),
-										item_to_check.getY());
-
-								if (area_enclosed_polygon
-										.isPerimeterPoint(pt_to_check)) {
+								Point pt_to_check = new Point(item_to_check.getX(), item_to_check.getY());
+
+								if (area_enclosed_polygon.isVertex(pt_to_check)) {
 									items_on_perimeter.add(item_to_check);
 								}
@@ -801,7 +793,7 @@
 		// Sort areas, smallest to largest
 		Collections.sort(area_enclosed_polygon_list,
-				new Comparator<AreaPolygon>() {
-
-					public int compare(AreaPolygon ap1, AreaPolygon ap2) {
+				new Comparator<PolygonBounds>() {
+
+					public int compare(PolygonBounds ap1, PolygonBounds ap2) {
 						Double ap1_area = ap1.getArea();
 						Double ap2_area = ap2.getArea();
@@ -817,9 +809,9 @@
 			// ri = remove index pos
 
-			AreaPolygon rpoly = area_enclosed_polygon_list.get(ri);
+			PolygonBounds rpoly = area_enclosed_polygon_list.get(ri);
 
 			for (int ci = ri + 1; ci < area_enclosed_polygon_list.size(); ci++) {
 				// ci = check index pos
-				AreaPolygon cpoly = area_enclosed_polygon_list.get(ci);
+				PolygonBounds cpoly = area_enclosed_polygon_list.get(ci);
 				if (rpoly.completelyContains(cpoly)) {
 					area_enclosed_polygon_list.remove(ci);
@@ -837,8 +829,7 @@
 		// recursive call below
 
-		for (AreaPolygon area_polygon : area_enclosed_polygon_list) {
-
-			Collection<Item> enclosed_items = FrameUtils.getItemsEnclosedBy(
-					frame, area_polygon);
+		for (PolygonBounds area_polygon : area_enclosed_polygon_list) {
+
+			Collection<Item> enclosed_items = FrameUtils.getItemsEnclosedBy(frame, area_polygon);
 			List<Item> enclosed_item_list = new ArrayList<Item>(enclosed_items);
 
@@ -849,5 +840,5 @@
 				// Filter out enclosed-items points that are part of the
 				// polygon's perimeter
-				if (area_polygon.isPerimeterPoint(enclosed_item.getPosition())) {
+				if (area_polygon.isVertex(enclosed_item.getPosition())) {
 					enclosed_item_list.remove(i);
 					// Don't include items the user hasn't asked us to.
@@ -863,6 +854,5 @@
 			// Recursively work on the identified sub-group
 
-			XGroupItem xgroup_item = new XGroupItem(frame, enclosed_item_list,
-					area_polygon);
+			XGroupItem xgroup_item = new XGroupItem(frame, enclosed_item_list, area_polygon);
 
 			grouped_item_list.add(xgroup_item);
Index: /trunk/src/org/expeditee/io/flowlayout/XItem.java
===================================================================
--- /trunk/src/org/expeditee/io/flowlayout/XItem.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/flowlayout/XItem.java	(revision 1102)
@@ -19,12 +19,12 @@
 package org.expeditee.io.flowlayout;
 
-import java.awt.Point;
-import java.awt.Rectangle;
 
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
 import org.expeditee.items.Item;
 
 public abstract class XItem 
 {
-	protected Rectangle bounding_rect;
+	protected AxisAlignedBoxBounds bounding_rect;
 		
 	protected XItem()
@@ -33,5 +33,5 @@
 	}
 	
-	protected XItem(Rectangle imprint_bounding_rect)
+	protected XItem(AxisAlignedBoxBounds imprint_bounding_rect)
 	{
 		this.bounding_rect = imprint_bounding_rect;
@@ -40,5 +40,5 @@
 	public int getX()
 	{
-		return bounding_rect.x;
+		return bounding_rect.getMinX();
 	}
 	
@@ -46,10 +46,10 @@
 	{
 		// name alias for getX()
-		return bounding_rect.x;
+		return bounding_rect.getMinX();
 	}
 	
 	public int getY()
 	{
-		return bounding_rect.y;
+		return bounding_rect.getMinY();
 	}
 	
@@ -57,33 +57,33 @@
 	{
 		// name alias for getY()
-		return bounding_rect.y;
+		return bounding_rect.getMinY();
 	}
 	
 	public int getBoundingYBot()
 	{
-		return bounding_rect.y + bounding_rect.height -1;
+		return bounding_rect.getMaxY();
 	}
 	
 	public int getBoundingXRight()
 	{
-		return bounding_rect.x + bounding_rect.width -1;
+		return bounding_rect.getMaxX();
 	}
 	
 	public int getBoundingWidth()
 	{
-		return bounding_rect.width;
+		return bounding_rect.getWidth();
 	}
 	
 	public int getBoundingHeight()
 	{
-		return bounding_rect.height;
+		return bounding_rect.getHeight();
 	}
 	
-	public Rectangle getBoundingRect()
+	public AxisAlignedBoxBounds getBoundingRect()
 	{
 		return bounding_rect;
 	}
 	
-	public Rectangle setBoundingRect(Rectangle rect)
+	public AxisAlignedBoxBounds setBoundingRect(AxisAlignedBoxBounds rect)
 	{
 		return bounding_rect = rect;
Index: /trunk/src/org/expeditee/io/flowlayout/XOrderedLine.java
===================================================================
--- /trunk/src/org/expeditee/io/flowlayout/XOrderedLine.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/flowlayout/XOrderedLine.java	(revision 1102)
@@ -19,7 +19,8 @@
 package org.expeditee.io.flowlayout;
 
-import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.List;
+
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
 
 public class XOrderedLine 
@@ -83,6 +84,6 @@
 		{
 			// Simple case => want to insert based on the new_item's xl position
-			Rectangle rect = new_item.getBoundingRect();
-			int xl = rect.x;
+			AxisAlignedBoxBounds rect = new_item.getBoundingRect();
+			int xl = rect.getMinX();
 			orderedMergeItem(xl,new_item);
 		}
Index: /trunk/src/org/expeditee/io/flowlayout/XRawItem.java
===================================================================
--- /trunk/src/org/expeditee/io/flowlayout/XRawItem.java	(revision 1101)
+++ /trunk/src/org/expeditee/io/flowlayout/XRawItem.java	(revision 1102)
@@ -41,5 +41,5 @@
 		else {
 			// Just in case it isn't a text item
-			bounding_rect = item.getArea().getBounds();
+			bounding_rect = item.getBoundingBox();
 		}
 		
Index: /trunk/src/org/expeditee/items/Circle.java
===================================================================
--- /trunk/src/org/expeditee/items/Circle.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/Circle.java	(revision 1102)
@@ -19,11 +19,17 @@
 package org.expeditee.items;
 
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.geom.Point2D;
 import java.util.Collection;
 import java.util.LinkedList;
+
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.CombinationBoxBounds;
+import org.expeditee.core.bounds.EllipticalBounds;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.EcosystemManager;
 
 /**
@@ -42,5 +48,6 @@
 	 * @param _source
 	 */
-	public Circle(Text source) {
+	public Circle(Text source)
+	{
 		super(source);
 		// Collection<Item> connected = source.getAllConnected();
@@ -50,5 +57,5 @@
 		_center.addEnclosure(this);
 		_line.setHidden(true);
-		updatePolygon();
+		invalidateBounds();
 	}
 
@@ -87,11 +94,8 @@
 
 	@Override
-	public Polygon getEnclosedShape() {
+	public PolygonBounds getEnclosedShape() {
 		// assert(_poly != null);
 		// Ensure that vector items will gradient fill are painted OK!!
-		if (_poly == null) {
-			updatePolygon();
-		}
-		return _poly;
+		return ((EllipticalBounds) updateBounds()).getPolygon(16);
 	}
 
@@ -138,5 +142,5 @@
 		newCircle._line.setVisible(_line.isVisible());
 		newCircle._source.setVisible(_source.isVisible());
-		newCircle.updatePolygon();
+		newCircle.invalidateBounds();
 		return newCircle;
 	}
@@ -152,9 +156,9 @@
 
 	@Override
-	public boolean contains(int x, int y) {
+	public boolean contains(Point p) {
 		double radius = getRadius();
 
-		double distance = Math.sqrt(Math.pow(Math.abs(_center.getX() - x), 2)
-				+ Math.pow(Math.abs(_center.getY() - y), 2));
+		double distance = Math.sqrt(Math.pow(Math.abs(_center.getX() - p.x), 2)
+				+ Math.pow(Math.abs(_center.getY() - p.y), 2));
 
 		return Math.abs(distance - radius) < getGravity() * 2;
@@ -167,52 +171,40 @@
 	 */
 	@Override
-	public void paint(Graphics2D g) {
+	public void paint() {
 		int radius = (int) Math.round(getRadius());
-		int diameter = radius * 2;
-		Color fillColor = getFillColor();
-		if (fillColor != null) {
-			setFillPaint(g);
-			g.fillOval(_center.getX() - radius, _center.getY() - radius,
-					diameter, diameter);
+		Point centre = new Point(_center.getX(), _center.getY());
+		Dimension diameters = new Dimension(radius * 2, radius * 2);
+		Fill fill = new Fill(getFillColor());
+		Colour lineColour = null;
+		Stroke lineStroke = null;
+		if (isHighlighted()) {
+			lineColour = getHighlightColor();
+			lineStroke = HIGHLIGHT_STROKE;
+		} else if (getThickness() > 0 || getFillColor() == null) {
+			lineColour = getPaintColor();
+			lineStroke = _line.getStroke();
 		}
-		if (getThickness() > 0 || fillColor == null) {
-			Color lineColor = getPaintColor();
-			g.setColor(lineColor);
-			g.setStroke(_line.getStroke());
-			g.drawOval(_center.getX() - radius, _center.getY() - radius,
-					diameter, diameter);
+		
+		EcosystemManager.getGraphicsManager().drawOval(centre, diameters, 0.0f, fill, lineColour, lineStroke);
+		
+		if (isHighlighted()) {
+			_center.paint();
 		}
-		// Arc version, same result but allows for portions of the circle to be
-		// drawn
-		// g.drawArc(end.getX() - (distance / 2), end.getY() - (distance / 2),
-		// distance, distance, 0, 360);
-
-		if (isHighlighted()) {
-			// Flag the background color of the circle so that the item will be
-			// drawn with alternate color if the background is the same as
-			// the highlight}
-			_center.paint(g);
-			Color highlightColor = getHighlightColor();
-			g.setColor(highlightColor);
-			g.setStroke(HIGHLIGHT_STROKE);
-			g.drawOval(_center.getX() - radius, _center.getY() - radius,
-					diameter, diameter);
-		}
-	}
-
-	@Override
-	public void setHighlightMode(HighlightMode mode, Color color) {
-		_center.setHighlightMode(mode, color);
-		super.setHighlightMode(mode, color);
-	}
-
-	@Override
-	public int setHighlightColor(Color c) {
+	}
+
+	@Override
+	public void setHighlightModeAndColour(HighlightMode mode, Colour color) {
+		_center.setHighlightModeAndColour(mode, color);
+		super.setHighlightModeAndColour(mode, color);
+	}
+
+	@Override
+	public void setHighlightColor(Colour c) {
 		_center.setHighlightColor(c);
-		return super.setHighlightColor(c);
-	}
-
-	@Override
-	public void setFillColor(Color c) {
+		/*return*/ super.setHighlightColor(c);
+	}
+
+	@Override
+	public void setFillColor(Colour c) {
 		super.setFillColor(c);
 		_center.setColor(c);
@@ -221,5 +213,5 @@
 
 	@Override
-	public void setGradientColor(Color c) {
+	public void setGradientColor(Colour c) {
 		super.setGradientColor(c);
 		invalidateCommonTrait(ItemAppearence.GradientColor);
@@ -255,22 +247,7 @@
 	 */
 	@Override
-	public void updatePolygon() {
-		double radius = getRadius();
-		// Approximation of circle for mouse interaction
-		int points = 20;
-
-		double radians = 0.0;
-		int xPoints[] = new int[points];
-		int yPoints[] = new int[xPoints.length];
-
-		for (int i = 0; i < xPoints.length; i++) {
-			xPoints[i] = (int) Math.round(radius * Math.cos(radians));
-			yPoints[i] = (int) Math.round(radius * Math.sin(radians));
-			radians += (2.0 * Math.PI) / xPoints.length;
-		}
-
-		_poly = new Polygon(xPoints, yPoints, xPoints.length);
-		_poly.translate(_center.getX(), _center.getY());
-		return;
+	public EllipticalBounds updateBounds()
+	{
+		return new EllipticalBounds(_center.getPosition(), (int) (getRadius() * 2));
 	}
 
@@ -280,9 +257,8 @@
 	}
 
-	/**
-	 * Resizes the circle from the center.
-	 */
-	@Override
-	public void setSize(float size) {
+	/** Resizes the circle from the center. */
+	@Override
+	public void setSize(float size)
+	{
 		double ratio = size / getRadius();
 		
@@ -290,5 +266,5 @@
 		_source.translate(_center.getPosition(), ratio);
 
-		updatePolygon();
+		invalidateBounds();
 	}
 
@@ -303,7 +279,9 @@
 	}
 
-	@Override
-	public void translate(Point2D origin, double ratio) {
-		updatePolygon();
+	// TODO: Why is this commented out? cts16
+	@Override
+	public void translate(Point origin, double ratio)
+	{
+		invalidateBounds();
 		// _center.translate(origin, ratio);
 		// super.translate(origin, ratio);
@@ -311,5 +289,5 @@
 
 	@Override
-	public Rectangle[] getDrawingArea() {
+	public AxisAlignedBoxBounds getDrawingArea() {
 
 		float thickness = getThickness();
@@ -318,7 +296,7 @@
 		int size = (int) ((2 * radius) + 3.0 + thickness);
 
-		return new Rectangle[] { new Rectangle((int) (_center.getX() - radius
+		return new AxisAlignedBoxBounds((int) (_center.getX() - radius
 				- 0.5 - (thickness / 2.0)), (int) (_center.getY() - radius
-				- 0.5 - (thickness / 2.0)), size, size) };
+				- 0.5 - (thickness / 2.0)), size, size);
 	}
 
Index: /trunk/src/org/expeditee/items/Constraint.java
===================================================================
--- /trunk/src/org/expeditee/items/Constraint.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/Constraint.java	(revision 1102)
@@ -28,4 +28,5 @@
  */
 public class Constraint {
+	
 	public static final int VERTICAL = 2;
 
Index: /trunk/src/org/expeditee/items/Dot.java
===================================================================
--- /trunk/src/org/expeditee/items/Dot.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/Dot.java	(revision 1102)
@@ -19,16 +19,20 @@
 package org.expeditee.items;
 
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Polygon;
-import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.Bounds;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
-import org.expeditee.gui.FrameKeyboardActions;
 
 /**
@@ -70,5 +74,5 @@
 
 	@Override
-	public void setColor(Color c) {
+	public void setColor(Colour c) {
 		super.setColor(c);
 
@@ -79,5 +83,5 @@
 
 	@Override
-	public void setAnchorLeft(Float anchor) {
+	public void setAnchorLeft(Integer anchor) {
 		if (!isLineEnd()) {
 			super.setAnchorLeft(anchor);
@@ -88,6 +92,5 @@
 		invalidateCommonTrait(ItemAppearence.PreMoved);
 		
-		this._anchorLeft = anchor;
-		this._anchorRight = null;
+		this._anchoring.setLeftAnchor(anchor);
 		
 		int oldX = getX();
@@ -102,5 +105,5 @@
 
 	@Override
-	public void setAnchorRight(Float anchor) {
+	public void setAnchorRight(Integer anchor) {
 		if (!isLineEnd()) {
 			super.setAnchorRight(anchor);
@@ -110,11 +113,9 @@
 		invalidateCommonTrait(ItemAppearence.PreMoved);
 		
-		this._anchorRight = anchor;
-		this._anchorLeft = null;
+		this._anchoring.setRightAnchor(anchor);
 		
 		int oldX = getX();
 		if (anchor != null) {
-			float deltaX = FrameGraphics.getMaxFrameSize().width - anchor
-					- getBoundsWidth() - oldX;
+			float deltaX = DisplayController.getFramePaintArea().getWidth() - anchor - getBoundsWidth() - oldX;
 
 			anchorConnected(AnchorEdgeType.Right, deltaX);
@@ -126,5 +127,5 @@
 
 	@Override
-	public void setAnchorTop(Float anchor) {
+	public void setAnchorTop(Integer anchor) {
 		if (!isLineEnd()) {
 			super.setAnchorTop(anchor);
@@ -134,6 +135,5 @@
 		invalidateCommonTrait(ItemAppearence.PreMoved);
 		
-		this._anchorTop = anchor;
-		this._anchorBottom = null;
+		this._anchoring.setTopAnchor(anchor);
 		
 		int oldY = getY();
@@ -148,5 +148,5 @@
 
 	@Override
-	public void setAnchorBottom(Float anchor) {
+	public void setAnchorBottom(Integer anchor) {
 		if (!isLineEnd()) {
 			super.setAnchorBottom(anchor);
@@ -156,11 +156,9 @@
 		invalidateCommonTrait(ItemAppearence.PreMoved);
 		
-		this._anchorBottom = anchor;
-		this._anchorTop = null;
+		this._anchoring.setBottomAnchor(anchor);
 		
 		int oldY = getY();
 		if (anchor != null) {
-			float deltaY = FrameGraphics.getMaxFrameSize().height - anchor
-					- getBoundsHeight() - oldY;
+			float deltaY = DisplayController.getFramePaintArea().getHeight() - anchor - getBoundsHeight() - oldY;
 			anchorConnected(AnchorEdgeType.Bottom, deltaY);
 		}
@@ -173,26 +171,22 @@
 
 	@Override
-	public void paint(Graphics2D g) {
+	public void paint() {
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
 		if (isHighlighted() /* && !FreeItems.getInstance().contains(this) */) {
-			Color highlightColor = getHighlightColor();
-			g.setColor(highlightColor);
-			g.setStroke(DOT_STROKE);
+			Colour highlightColor = getHighlightColor();
+			Fill fill = new Fill(highlightColor);
 			// g.setStroke()
 			// Draw the highlighting rectangle surrounding the dot
 			// this is drawn even if its part of a rectangle
 
-			if (isVectorItem())
-				updatePolygon();
-
-			Rectangle rect = getPolygon().getBounds();
-			if (_mode == HighlightMode.Enclosed ||
-			// Make sure single dots are highlighted filled
-					this.getConnected().size() <= 1)
-				g.fillRect(rect.x, rect.y, rect.width, rect.height);
-			else if (_mode == HighlightMode.Connected){
-				g.setStroke(HIGHLIGHT_STROKE);
-				g.drawRect(rect.x, rect.y, rect.width, rect.height);
-			}else if (_mode == HighlightMode.Normal) {
-				g.fillOval(rect.x, rect.y, rect.width, rect.height);
+			if (isVectorItem()) invalidateBounds();
+
+			AxisAlignedBoxBounds bounds = getBoundingBox();
+			if (_highlightMode == HighlightMode.Enclosed || this.getConnected().size() <= 1) { // Make sure single dots are highlighted filled
+				g.drawRectangle(bounds.getTopLeft(), bounds.getSize(), 0.0f, fill, highlightColor, DOT_STROKE, null);
+			} else if (_highlightMode == HighlightMode.Connected) {
+				g.drawRectangle(bounds.getTopLeft(), bounds.getSize(), 0.0f, null, highlightColor, HIGHLIGHT_STROKE, null);
+			} else if (_highlightMode == HighlightMode.Normal) {
+				g.drawOval(bounds.getCentre(), bounds.getSize(), 0.0f, fill, highlightColor, DOT_STROKE);
 			}
 			// System.out.println(_mode.toString());
@@ -200,75 +194,53 @@
 
 		// dots on lines are hidden
-		if (getLines().size() > 0)
-			return;
-
-		g.setColor(getPaintColor());
+		if (getLines().size() > 0) return;
 
 		int thick = (int) getThickness();
-		if (thick < MINIMUM_DOT_SIZE)
-			thick = MINIMUM_DOT_SIZE;
-
-		int width = thick / 2;
-
+		if (thick < MINIMUM_DOT_SIZE) thick = MINIMUM_DOT_SIZE;
+		
+		Fill fill = _filled ? new Fill(getPaintColor()) : null;
+
+		// TODO: On testing, this code doesn't seem to work (can't change to any type except square). cts16
 		switch (_type) {
-		case circle:
-			if (_filled)
-				g.fillOval(getX() - width, getY() - width, thick, thick);
-			else {
-				g.drawOval(getX() - width, getY() - width, thick, thick);
-			}
-			break;
-		case diamond:
-			int[] x = new int[4];
-			int[] y = new int[4];
-
-			x[0] = x[2] = getX();
-			x[1] = getX() - width;
-			x[3] = getX() + width;
-
-			y[1] = y[3] = getY();
-			y[0] = getY() - width;
-			y[2] = getY() + width;
-
-			if (_filled)
-				g.fillPolygon(x, y, 4);
-			else {
-				g.drawPolygon(x, y, 4);
-			}
-			break;
-		case triangle:
-			x = new int[3];
-			y = new int[3];
-
-			x[0] = getX();
-			x[1] = getX() - width;
-			x[2] = getX() + width;
-
-			y[0] = getY() - width;
-			y[1] = y[2] = getY() + width;
-
-			if (_filled)
-				g.fillPolygon(x, y, 3);
-			else {
-				g.drawPolygon(x, y, 3);
-			}
-			break;
-		case roundSquare:
-			int arc = thick / 2;
-			if (_filled)
-				g.fillRoundRect(getX() - width, getY() - width, thick, thick,
-						arc, arc);
-			else {
-				g.drawRoundRect(getX() - width, getY() - width, thick, thick,
-						arc, arc);
-			}
-			break;
-		default:
-			if (_filled)
-				g.fillRect(getX() - width, getY() - width, thick, thick);
-			else {
-				g.drawRect(getX() - width, getY() - width, thick, thick);
-			}
-
+			case circle:
+				g.drawOval(
+						new Point(getX(), getY()),
+						new Dimension(thick, thick),
+						0.0,
+						fill,
+						getPaintColor(),
+						null
+				);
+				break;
+			case diamond:
+				PolygonBounds diamond = PolygonBounds.getDiamond(thick, thick).translate(getX(), getY()).close();
+				g.drawPolygon(diamond, null, null, 0.0, fill, getPaintColor(), null);
+				break;
+			case triangle:
+				PolygonBounds triangle = PolygonBounds.getTriangle(thick, thick).translate(getX(), getY()).close();
+				g.drawPolygon(triangle, null, null, 0.0, fill, getPaintColor(), null);
+				break;
+			case roundSquare:
+				int arc = thick / 4;
+				g.drawRectangle(
+					new Point(getX(), getY()),
+					new Dimension(thick, thick),
+					0.0,
+					fill,
+					getPaintColor(),
+					null,
+					new Dimension(arc, arc)
+				);
+				break;
+			default:
+				g.drawRectangle(
+						new Point(getX(), getY()),
+						new Dimension(thick, thick),
+						0.0,
+						fill,
+						getPaintColor(),
+						null,
+						null
+				);
 		}
 
@@ -276,19 +248,22 @@
 
 	/**
-	 * Updates the points of the polygon surrounding this Dot
+	 * Updates the bounds surrounding this Dot.
+	 * TODO: Standardise Dot minimum size. cts16
 	 */
-	public void updatePolygon() {
+	public Bounds updateBounds()
+	{
 		int thick = Math.round(getThickness());
+		
 		// Sets a minimum size for the dot
 		thick = Math.max(thick, getGravity() * 2);
+		
+		// Include the gravity in the thickness
+		thick += 2 * getGravity();
+		
 
 		int x = getX() - thick / 2;
 		int y = getY() - thick / 2;
-
-		_poly = new Polygon();
-		_poly.addPoint(x - getGravity(), y - getGravity());
-		_poly.addPoint(x + thick + getGravity(), y - getGravity());
-		_poly.addPoint(x + thick + getGravity(), y + thick + getGravity());
-		_poly.addPoint(x - getGravity(), y + thick + getGravity());
+		
+		return new AxisAlignedBoxBounds(x, y, thick, thick);
 	}
 
@@ -303,14 +278,14 @@
 
 	@Override
-	public int setHighlightColor() {
-		super.setHighlightColor();
-
-		return Item.DEFAULT_CURSOR;
+	public void setHighlightColorToDefault() {
+		super.setHighlightColorToDefault();
+
+		//return Item.DEFAULT_CURSOR;
 	}
 
 	@Override
 	public void setAnnotation(boolean val) {
-		DisplayIO.setCursorPosition(this.getPosition());
-		FrameKeyboardActions.replaceDot(this, '@');
+		DisplayController.setCursorPosition(this.getPosition());
+		Item.replaceDot(this, '@');
 	}
 
@@ -406,8 +381,8 @@
 			if (parent != null && parent != current) {
 				this.setParent(parent);
-				if (DisplayIO.getCurrentSide() == 0)
-					this.setX(this.getX() - DisplayIO.getMiddle());
+				if (DisplayController.getCurrentSide() == DisplayController.TwinFramesSide.LEFT)
+					this.setX(this.getX() - DisplayController.getTwinFramesSeparatorX());
 				else
-					this.setX(this.getX() + DisplayIO.getMiddle());
+					this.setX(this.getX() + DisplayController.getTwinFramesSeparatorX());
 			}
 			break;
@@ -420,5 +395,5 @@
 			if (line.getID() < 0 && !current.getItems().contains(line)) {
 				line.setID(current.getNextItemID());
-				line.setHighlightColor();
+				line.setHighlightColorToDefault();
 				// Mike: Why was this line here?
 				// anchor(line);
@@ -436,5 +411,5 @@
 
 	@Override
-	public void lineColorChanged(Color c) {
+	public void lineColorChanged(Colour c) {
 		if (getColor() != c) {
 			setColor(c);
@@ -450,3 +425,9 @@
 		return super.dontSave();
 	}
+
+	@Override
+	public float getSize()
+	{
+		return getThickness();
+	}
 }
Index: /trunk/src/org/expeditee/items/FrameBitmap.java
===================================================================
--- /trunk/src/org/expeditee/items/FrameBitmap.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/FrameBitmap.java	(revision 1102)
@@ -19,10 +19,8 @@
 package org.expeditee.items;
 
-import java.awt.Color;
-import java.awt.Image;
-import java.awt.image.BufferedImage;
-import java.awt.image.ImageObserver;
 import java.util.List;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -31,6 +29,6 @@
 
 public class FrameBitmap extends FramePicture {
-	public FrameBitmap(Text source, ImageObserver observer, Image image){
-		super(source, observer, image);
+	public FrameBitmap(Text source, Image image){
+		super(source, image);
 	}
 
@@ -59,10 +57,9 @@
 			return false;
 		
-		BufferedImage bi = new BufferedImage(width, height,
-				BufferedImage.TYPE_INT_ARGB);
+		Image bi = Image.createImage(width, height);
 		// now set the bits on the image
-		final int transparent = (new Color(0F, 0F, 0F, 0F)).getRGB();
-		final int main = _source.getPaintColor().getRGB();
-		final Color c = _source.getPaintColor();
+		final int transparent = (new Colour(0F, 0F, 0F, 0F)).getARGB32BitPacked();
+		final int main = _source.getPaintColor().getARGB32BitPacked();
+		final Colour c = _source.getPaintColor();
 		int currentColor = main;
 		int row = 0;
@@ -74,12 +71,12 @@
 					// Space is transparent as is 0
 					if (Character.isDigit(currentPixel)) {
-						int alpha = Math.round((currentPixel - '0') * 25.5F);
-						currentColor = new Color(c.getRed(), c.getGreen(), c
-								.getBlue(), alpha).getRGB();
+						int alpha = Math.round((currentPixel - '0') * (Colour.COMPONENT_MAX_VALUE / 10.0f));
+						currentColor = new Colour(c.getRed(), c.getGreen(), c
+								.getBlue(), alpha).getARGB32BitPacked();
 					}else if (currentPixel != ' ') {
 						currentColor = main;
 					}
 				}
-				bi.setRGB(i, row, currentColor);
+				bi.setPixel(i, row, Colour.fromARGB32BitPacked(currentColor));
 			}
 			row++;
@@ -92,6 +89,5 @@
 	@Override
 	protected Picture createPicture() {
-		return new FrameBitmap((Text) _source.copy(),
-				_imageObserver, _image);
+		return new FrameBitmap((Text) _source.copy(), _image);
 	}
 
Index: /trunk/src/org/expeditee/items/FrameImage.java
===================================================================
--- /trunk/src/org/expeditee/items/FrameImage.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/FrameImage.java	(revision 1102)
@@ -19,7 +19,5 @@
 package org.expeditee.items;
 
-import java.awt.Image;
-import java.awt.image.ImageObserver;
-
+import org.expeditee.core.Image;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
@@ -41,11 +39,11 @@
 	 *            screen.
 	 */
-	public FrameImage(Text source, ImageObserver observer, Image image) {
-		super(source, observer, image);
+	public FrameImage(Text source, Image image) {
+		super(source, image);
 	}
 
 	@Override
 	protected Picture createPicture() {
-		return new FrameImage(_source.copy(), _imageObserver, _image);
+		return new FrameImage(_source.copy(), _image);
 	}
 
@@ -59,6 +57,5 @@
 			return false;
 
-		frame.setBuffer(null);
-		FrameGraphics.UpdateBuffer(frame, false, false);
+		frame.setBuffer(FrameGraphics.getFrameImage(frame, null, null, false, false));
 		_image = frame.getBuffer();
 
@@ -66,5 +63,5 @@
 		// been created to begin with
 		parseSize();
-		updatePolygon();
+		invalidateBounds();
 		return true;
 	}
Index: /trunk/src/org/expeditee/items/FramePicture.java
===================================================================
--- /trunk/src/org/expeditee/items/FramePicture.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/FramePicture.java	(revision 1102)
@@ -19,18 +19,16 @@
 package org.expeditee.items;
 
-import java.awt.Color;
-import java.awt.Image;
-import java.awt.image.ImageObserver;
-
+import org.expeditee.core.Colour;
+import org.expeditee.core.Image;
 import org.expeditee.gui.AttributeValuePair;
 import org.expeditee.gui.Frame;
 
 public abstract class FramePicture extends Picture {
-	protected FramePicture(Text source, ImageObserver observer, Image image) {
-		super(source, observer, image);
+	protected FramePicture(Text source, Image image) {
+		super(source, image);
 	}
 
 	@Override
-	public void setColor(Color c) {
+	public void setColor(Colour c) {
 		super.setColor(c);
 		refresh();
@@ -55,5 +53,5 @@
 			}
 		}
-		updatePolygon();
+		invalidateBounds();
 	}
 	
Index: /trunk/src/org/expeditee/items/Item.java
===================================================================
--- /trunk/src/org/expeditee/items/Item.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/Item.java	(revision 1102)
@@ -19,18 +19,4 @@
 package org.expeditee.items;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.GradientPaint;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Area;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -46,11 +32,24 @@
 import org.expeditee.actions.Misc;
 import org.expeditee.actions.Simple;
+import org.expeditee.core.Anchoring;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Cursor;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.GradientFill;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.Bounds;
+import org.expeditee.core.bounds.EllipticalBounds;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.gui.AttributeValuePair;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameKeyboardActions;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.FreeItems;
@@ -75,161 +74,313 @@
 public abstract class Item implements Comparable<Item>, Runnable {
 
-	public static final Float DEFAULT_THICKNESS = 2f;
-
-	public static final Float MINIMUM_THICKNESS = 0f;
-
-	public static final Float MINIMUM_PAINT_THICKNESS = 1f;
-
-	protected final int JOIN = BasicStroke.JOIN_ROUND;
-
-	protected final int CAP = BasicStroke.CAP_BUTT;
-
-	protected final Stroke DOT_STROKE = new BasicStroke(DEFAULT_THICKNESS,
-			CAP, JOIN, 4.0F);
-
-	protected final Stroke HIGHLIGHT_STROKE = new BasicStroke(
-			MINIMUM_THICKNESS, CAP, JOIN, 4.0F);
-
-	// contains all dots (including this one) that form an enclosure
-	// if this dot is part of an enclosing shape
-	private Collection<Item> _enclosure = null;
-
-	public static final int LEFT_MARGIN = 13;
-
-	// indicates which end the arrowhead should be drawn at
-	protected Polygon _poly = null;
-
-	protected boolean _connectedToAnnotation = false;
-
-	protected boolean _save = true;
-
-	private int _gradientAngle = 0;
-
-	public static final int NEAR_DISTANCE = 15;
-
-	/**
-	 * The default Color to draw highlighting in
-	 */
-	public static final int DEFAULT_HIGHLIGHT_THICKNESS = 2;
-
-	public static final Color DEFAULT_HIGHLIGHT = Color.RED;
-
-	public static final Color DEPRESSED_HIGHLIGHT = Color.GREEN;
-
-	public static final Color ALTERNATE_HIGHLIGHT = Color.BLUE;
-
-	public static final Color LINK_COLOR = Color.BLACK;
-
-	public static final Color ACTION_COLOR = Color.BLACK;
-
-	public static final Color LINK_ACTION_COLOR = Color.RED;
-
-	public static final Color DEFAULT_FOREGROUND = Color.BLACK;
-
-	public static final Color DEFAULT_BACKGROUND = Color.white;
-
-	public static final Color TRANSPARENT = new Color(0, 0, 0, 0);
-
-	/**
-	 * The number of pixels highlighting should extend around Items.
-	 */
-	public static final int XGRAVITY = 3;
-
-	public static final int MARGIN_RIGHT = 2;
-
-	public static final int MARGIN_LEFT = 15;
-
-	protected static final double DEFAULT_ARROWHEAD_RATIO     = 0.3; // used to be 0.5
-
-	public static final double DEFAULT_ARROWHEAD_NIB_PERC  = 0.75; 
-	
-	public static final Color GREEN = Color.GREEN.darker();
-
-	public static final int UNCHANGED_CURSOR = -100;
-
-	public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR;
-
-	public static final int HIDDEN_CURSOR = Cursor.CUSTOM_CURSOR;
-
-	public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR;
-
-	public static final int CROP_CURSOR = Cursor.CROSSHAIR_CURSOR;
-
-	// The default value for integer attributes
-	public static final int DEFAULT_INTEGER = -1;
-
-	protected DotType _type = DotType.square;
-
-	protected boolean _filled = true;
-	
-	private Tooltip _tooltip = new Tooltip();
-
+	public enum HighlightMode {
+		None, // The item has no highlighting
+		Enclosed, // The item is part of the current enclosure
+		Connected, // The item is connected to the current item
+		Disconnect, // The item is a free item
+		Normal // The item is the current item
+	}
+
+	/** Which edge of the window things are anchored to. */
 	public enum AnchorEdgeType {
 		None, Left, Right, Top, Bottom
 	}
-
-	public static void DuplicateItem(Item source, Item dest) {
-		dest.setX(source.getX());
-		dest.setY(source.getY());
-
-		dest.setActions(source.getAction());
-		dest.setActionCursorEnter(source.getActionCursorEnter());
-		dest.setActionCursorLeave(source.getActionCursorLeave());
-		dest.setActionEnterFrame(source.getActionEnterFrame());
-		dest.setActionLeaveFrame(source.getActionLeaveFrame());
-		dest.setActionMark(source.getActionMark());
-
-		dest.setBackgroundColor(source.getBackgroundColor());
-		dest.setBottomShadowColor(source.getBottomShadowColor());
-		dest.setColor(source.getColor());
-		dest.setBorderColor(source.getBorderColor());
-
-		dest.setTooltips(source.getTooltip());
-		dest.setData(source.getData());
-		dest.setTag(source.getTag());
-		dest.setFillColor(source.getFillColor());
-		dest.setGradientColor(source.getGradientColor());
-		dest.setGradientAngle(source.getGradientAngle());
-		dest.setFillPattern(source.getFillPattern());
-
-		dest.setHighlight(source.getHighlight());
-		dest.setLink(source.getLink());
-		dest.setLinkFrameset(source.getLinkFrameset());
-		dest.setLinkMark(source.getLinkMark());
-		dest.setLinkTemplate(source.getLinkTemplate());
-
-		// dest.setMaxWidth(source.getMaxWidth());
-
-		dest.setOffset(source.getOffset());
-		// dest.setOwner(source.getOwner());
-		dest.setThickness(source.getThickness());
-		dest.setSize(source.getSize());
-		dest.setTopShadowColor(source.getTopShadowColor());
-		dest.setLinePattern(source.getLinePattern());
-
-		dest.setFloating(source.isFloating());
-		dest.setArrow(source.getArrowheadLength(), source.getArrowheadRatio(), source.getArrowheadNibPerc());
-
-		dest.setDotType(source.getDotType());
-		dest.setFilled(source.getFilled());
+	
+	public static final float SIZE_NOT_APPLICABLE = Float.NaN;
+	
+	public static final Float DEFAULT_THICKNESS = 2f;
+
+	public static final Float MINIMUM_THICKNESS = 0f;
+
+	public static final Float MINIMUM_PAINT_THICKNESS = 1f;
+
+	protected static final Stroke.JOIN DEFAULT_JOIN = Stroke.JOIN.ROUND;
+
+	protected static final Stroke.CAP DEFAULT_CAP = Stroke.CAP.BUTT;
+
+	protected static final Stroke DOT_STROKE = new Stroke(DEFAULT_THICKNESS, DEFAULT_CAP, DEFAULT_JOIN);
+
+	protected static final Stroke HIGHLIGHT_STROKE = new Stroke(MINIMUM_THICKNESS, DEFAULT_CAP, DEFAULT_JOIN);
+	
+	public static final int LEFT_MARGIN = 13;
+
+	public static final int NEAR_DISTANCE = 15;
+
+	public static final int DEFAULT_HIGHLIGHT_THICKNESS = 2;
+
+	/** The default colour to draw highlighting in */
+	public static final Colour DEFAULT_HIGHLIGHT = Colour.RED;
+
+	public static final Colour DEPRESSED_HIGHLIGHT = Colour.GREEN;
+
+	public static final Colour ALTERNATE_HIGHLIGHT = Colour.BLUE;
+
+	public static final Colour LINK_COLOR = Colour.BLACK;
+
+	public static final Colour ACTION_COLOR = Colour.BLACK;
+
+	public static final Colour LINK_ACTION_COLOR = Colour.RED;
+
+	public static final Colour DEFAULT_FOREGROUND = Colour.BLACK;
+
+	public static final Colour DEFAULT_BACKGROUND = Colour.WHITE;
+
+	public static final Colour TRANSPARENT = new Colour(0, 0, 0, 0);
+
+	/** The number of pixels highlighting should extend around Items. */
+	public static final int XGRAVITY = 3;
+
+	public static final int MARGIN_RIGHT = 2;
+
+	public static final int MARGIN_LEFT = 15;
+
+	protected static final double DEFAULT_ARROWHEAD_RATIO = 0.3; // used to be 0.5
+
+	public static final double DEFAULT_ARROWHEAD_NIB_PERC  = 0.75;
+	
+	public static final Colour GREEN = Colour.GREEN.darker();
+
+	//public static final int UNCHANGED_CURSOR = -100;
+
+	public static final Cursor.CursorType DEFAULT_CURSOR = Cursor.CursorType.DEFAULT;
+
+	public static final Cursor.CursorType HIDDEN_CURSOR = Cursor.CursorType.CUSTOM;
+
+	public static final Cursor.CursorType TEXT_CURSOR = Cursor.CursorType.TEXT;
+
+	public static final Cursor.CursorType CROP_CURSOR = Cursor.CursorType.CROSSHAIR;
+
+	/** The default value for integer attributes */
+	public static final int DEFAULT_INTEGER = -1;
+
+	private static final int BRIGHTNESS = 185;
+
+	/** Contains all dots (including this one) that form an enclosure if this dot is part of an enclosing shape. */
+	private Collection<Item> _enclosure = null;
+
+	/** The area which this item covers (including its gravity). */
+	private Bounds _bounds = null;
+	
+	/** The area this item covered before it was invalidated. */
+	private Bounds _oldBounds = null;
+
+	protected boolean _connectedToAnnotation = false;
+
+	protected boolean _save = true;
+
+	/** The angle of change for gradient colour fills (in radians). */
+	private double _gradientAngle = 0.0;
+	
+	private Tooltip _tooltip = new Tooltip();
+
+	protected Anchoring _anchoring = new Anchoring();
+
+	/** The highlight mode for this item. */
+	protected HighlightMode _highlightMode = HighlightMode.None;
+
+	private Point _offset = new Point(0, 0);
+
+	protected float _x;
+	protected float _y;
+
+	private int _id;
+
+	private Item _editTarget = this;
+
+	private String _creationDate = null;
+
+	/** Whether or not this item should display a mark indicating it has a link. */
+	private boolean _linkMark = true;
+
+	/** Whether or not this item should display a mark indicating it has an action. */
+	private boolean _actionMark = true;
+
+	/** TODO: Appears unused? cts16 */
+	private boolean _highlight = true;
+
+	// private int _maxWidth = -1;
+
+	private String _owner = null;
+
+	private String _link = null;
+	
+	private boolean _linkHistory = true;
+
+	private StringBuffer _tag = new StringBuffer();
+
+	private List<String> _actionCursorEnter = null;
+
+	private List<String> _actionCursorLeave = null;
+
+	private List<String> _actionEnterFrame = null;
+
+	private List<String> _actionLeaveFrame = null;
+
+	private PermissionPair _permissionPair = null;
+	
+	private UserAppliedPermission _overlayPermission = null;
+
+	/** The primary fill colour of this item. A fill colour of null represents transparent. */
+	private Colour _fillColour = null;
+
+	/** The secondary fill colour if this item has a gradient fill. Null represents no gradient. */
+	private Colour _gradientColour = null;
+
+	/** The primary draw colour of this item. Null represents the default colour. */
+	private Colour _foregroundColour = null;
+
+	/** The colour to draw highlights on this item. */
+	protected Colour _highlightColour = DEFAULT_HIGHLIGHT;
+
+	/** The background colour for this item. */
+	private Colour _backgroundColour = null;
+
+	private Colour _colorBorder = null;
+
+	private Colour _colorTopShadow = null;
+
+	private Colour _colorBottomShadow = null;
+
+	/** The shape representing the circle drawn next to link/action items. */
+	private static EllipticalBounds _linkCircle = null;
+
+	/** The shape representing the cross drawn next to invalid links. */ 
+	private static PolygonBounds _linkCircleCross = null;
+
+	private Frame _parent = null;
+	private Frame _oldParent = null;
+
+	protected int _highlightThickness = 2;
+
+	protected int _vectorHighlightThickness = 1;
+
+	// arrowhead parameters
+	private float  _arrowheadLength  = 0;
+	private double _arrowheadRatio   = DEFAULT_ARROWHEAD_RATIO;
+	private double _arrowheadNibPerc = DEFAULT_ARROWHEAD_NIB_PERC;
+	
+	private PolygonBounds _arrowhead = null;
+
+	// the list of lines that this point is part of.
+	private List<Line> _lines = new ArrayList<Line>();
+
+	private int[] _linePattern = null;
+
+	private boolean _floating = false;
+
+	// list of points constrained with this point
+	private List<Constraint> _constraints = new ArrayList<Constraint>();
+
+	private List<String> _actions = null;
+
+	private List<String> _data = null;
+
+	private String _formula = null;
+
+	private String _link_frameset = null;
+
+	private String _link_template = null;
+
+	private String _fillPattern = null;
+
+	private boolean _visible = true;
+
+	private float _thickness = -1.0F;
+
+	protected Collection<XRayable> _enclosures = new HashSet<XRayable>();
+
+	private boolean _deleted = false;
+
+	private Overlay _overlay = null;
+
+	protected AttributeValuePair _attributeValuePair = null;
+
+	private Float _autoStamp = null;
+	
+	private Item _magnetizedItemLeft = null;
+	
+	private Item _magnetizedItemRight = null;
+	
+	private Item _magnetizedItemTop = null;
+	
+	private Item _magnetizedItemBottom = null;
+
+	protected DotType _type = DotType.square;
+
+	protected boolean _filled = true;
+
+	/** Just calls source.duplicateOnto(dest). */
+	public static void DuplicateItem(Item source, Item dest)
+	{
+		if (source == null) return;
+		
+		source.duplicateOnto(dest);
+	}
+	
+	/** Sets the properties of dest so that they match this item's properties. */
+	public void duplicateOnto(Item dest)
+	{
+		if (dest == null) return;
+		
+		dest.setX(this.getX());
+		dest.setY(this.getY());
+
+		dest.setActions(this.getAction());
+		dest.setActionCursorEnter(this.getActionCursorEnter());
+		dest.setActionCursorLeave(this.getActionCursorLeave());
+		dest.setActionEnterFrame(this.getActionEnterFrame());
+		dest.setActionLeaveFrame(this.getActionLeaveFrame());
+		dest.setActionMark(this.getActionMark());
+
+		dest.setBackgroundColor(this.getBackgroundColor());
+		dest.setBottomShadowColor(this.getBottomShadowColor());
+		dest.setColor(this.getColor());
+		dest.setBorderColor(this.getBorderColor());
+
+		dest.setTooltips(this.getTooltip());
+		dest.setData(this.getData());
+		dest.setTag(this.getTag());
+		dest.setFillColor(this.getFillColor());
+		dest.setGradientColor(this.getGradientColor());
+		dest.setGradientAngle(this.getGradientAngle());
+		dest.setFillPattern(this.getFillPattern());
+
+		dest.setHighlight(this.getHighlight());
+		dest.setLink(this.getLink());
+		dest.setLinkFrameset(this.getLinkFrameset());
+		dest.setLinkMark(this.getLinkMark());
+		dest.setLinkTemplate(this.getLinkTemplate());
+
+		// dest.setMaxWidth(this.getMaxWidth());
+
+		dest.setOffset(this.getOffset());
+		// dest.setOwner(this.getOwner());
+		dest.setThickness(this.getThickness());
+		dest.setSize(this.getSize());
+		dest.setTopShadowColor(this.getTopShadowColor());
+		dest.setLinePattern(this.getLinePattern());
+
+		dest.setFloating(this.isFloating());
+		dest.setArrow(this.getArrowheadLength(), this.getArrowheadRatio(), this.getArrowheadNibPerc());
+		dest.setDotType(this.getDotType());
+		dest.setFilled(this.getFilled());
 		/*
 		 * Calling the methods will move the item... This messes things up when
 		 * the user uses backspace to delete a text line end
 		 */
-		// dest._anchorLeft = source._anchorLeft;
-		// dest._anchorRight = source._anchorRight;
-		// dest._anchorTop = source._anchorTop;
-		// dest._anchorBottom = source._anchorBottom;
-		dest.setFormula(source.getFormula());
-		dest._overlay = source._overlay;
-		dest._mode = source._mode;// SelectedMode.None;
-		// dest._highlightColor = source._highlightColor;
-		// dest.setHighlight(source.getHighlight());
-
-		dest._visible = source._visible;
-
-		Frame parent = DisplayIO.getCurrentFrame();
-		if (parent == null)
-			parent = source.getParentOrCurrentFrame();
+		// dest._anchorLeft = this._anchorLeft;
+		// dest._anchorRight = this._anchorRight;
+		// dest._anchorTop = this._anchorTop;
+		// dest._anchorBottom = this._anchorBottom;
+		dest.setFormula(this.getFormula());
+		dest._overlay = this._overlay;
+		dest._highlightMode = this._highlightMode;// SelectedMode.None;
+		// dest._highlightColor = this._highlightColor;
+		// dest.setHighlight(this.getHighlight());
+
+		dest._visible = this._visible;
+
+		Frame parent = DisplayController.getCurrentFrame();
+		if (parent == null) parent = this.getParentOrCurrentFrame();
 		dest.setParent(parent);
 
@@ -246,12 +397,39 @@
 		}
 	}
-
-	public void setGradientAngle(int gradientAngle) {
+	
+	public void setDotType(DotType type) {
+		invalidateAll();
+		_type = type;
+		invalidateAll();
+	}
+
+	public DotType getDotType() {
+		return _type;
+	}
+
+	
+	public void setFilled(boolean filled)
+	{
+		invalidateAll();
+		_filled = filled;
+		invalidateAll();
+	}
+
+	public boolean getFilled() {
+		return _filled;
+	}
+
+	/**
+	 * Sets the angle of colour change for gradient colour fills.
+	 * 
+	 * @param gradientAngle The new angle of colour change.
+	 */
+	public void setGradientAngle(double gradientAngle)
+	{
 		_gradientAngle = gradientAngle;
 
 		for (Line line : _lines) {
 			Item other = line.getOppositeEnd(this);
-			if (other.getGradientAngle() != gradientAngle)
-				other.setGradientAngle(gradientAngle);
+			if (other.getGradientAngle() != gradientAngle) other.setGradientAngle(gradientAngle);
 		}
 
@@ -260,79 +438,59 @@
 	}
 
-	public int getGradientAngle() {
+	/**
+	 * Gets the angle of colour change for gradient fills.
+	 * 
+	 * @return The angle of colour change.
+	 */
+	public double getGradientAngle() {
 		return _gradientAngle;
 	}
 
-	public int getGravity() {
-		if (isVectorItem()) {
-			return 2;
-		}
+	/**
+	 * Gets the gravity for this item. Gravity is the distance from the item at which mouse interaction
+	 * applies to the item (like a small buffer zone so you don't need to click exactly on the item).
+	 * 
+	 * @return The gravity distance for this item.
+	 */
+	public int getGravity()
+	{
+		if (isVectorItem()) return 2;
+		
 		return UserSettings.Gravity.get();
 	}
 
-	public static boolean showLineHighlight() {
+	/**
+	 * Whether or not line highlights should be shown.
+	 * TODO: Not really an item method is it? Goes straight to user settings. Refactor. cts16
+	 * 
+	 * @return <code>true</code> if line highlighting should be shown, <code>false</code> otherwise.
+	 */
+	public static boolean shouldShowLineHighlight()
+	{
 		return UserSettings.LineHighlight.get();
 	}
 
-	public enum HighlightMode {
-		None, Enclosed, Connected, Disconnect, Normal
-	}
-
-	public void setHighlightMode(HighlightMode mode) {
-		setHighlightMode(mode, DEFAULT_HIGHLIGHT);
-	}
-
-	protected Float _anchorLeft = null;
-	protected Float _anchorRight = null;
-
-	protected Float _anchorTop = null;
-	protected Float _anchorBottom = null;
-
-	protected HighlightMode _mode = HighlightMode.None;
-
-	private Point _offset = new Point(0, 0);
-
-	protected float _x;
-	protected float _y;
-
-	private int _id;
-
-	private Item _editTarget = this;
-
-	private String _creationDate = null;
-
-	private boolean _linkMark = true;
-
-	private boolean _actionMark = true;
-
-	private boolean _highlight = true;
-
-	// private int _maxWidth = -1;
-
-	private String _owner = null;
-
-	private String _link = null;
-	
-	private boolean _linkHistory = true;
-
-	private StringBuffer _tag = new StringBuffer();
-
-	private List<String> _actionCursorEnter = null;
-
-	private List<String> _actionCursorLeave = null;
-
-	private List<String> _actionEnterFrame = null;
-
-	private List<String> _actionLeaveFrame = null;
-
-	private PermissionPair _permissionPair = null;
-	
-	private UserAppliedPermission _overlayPermission = null;
-	
-	public void setOverlayPermission(UserAppliedPermission overlayPermission) {
+	/**
+	 * Sets the highlight mode for this item.
+	 * 
+	 * @param mode The new highlight mode.
+	 */
+	public void setHighlightMode(HighlightMode mode)
+	{
+		if (hasPermission(UserAppliedPermission.followLinks) || getEditTarget().hasPermission(UserAppliedPermission.followLinks)) {
+			if (_highlightMode != mode) {
+				_highlightMode = mode;
+				this.invalidateCommonTrait(ItemAppearence.HighlightModeChanged);
+			}
+		}
+	}
+	
+	public void setOverlayPermission(UserAppliedPermission overlayPermission)
+	{
 		_overlayPermission = overlayPermission;
 	}
 
-	public void setPermission(PermissionPair permissionPair) {
+	public void setPermission(PermissionPair permissionPair)
+	{
 		_permissionPair = permissionPair;
 	}
@@ -354,69 +512,4 @@
 	}
 
-	// A fill color of null represents transparent
-	private Color _colorFill = null;
-
-	// A gradient color of null represents NO gradient
-	private Color _colorGradient = null;
-
-	// A fore color of null represents the default color
-	private Color _color = null;
-
-	protected Color _highlightColor = DEFAULT_HIGHLIGHT;
-
-	private Color _colorBackground = null;
-
-	private Color _colorBorder = null;
-
-	private Color _colorTopShadow = null;
-
-	private Color _colorBottomShadow = null;
-
-	// the link\action circle
-	private Polygon _circle = null;
-
-	// the invalid link cross
-	private Polygon _circleCross = null;
-
-	private Frame _parent = null;
-	private Frame _oldParent = null;
-
-	protected int _highlightThickness = 2;
-
-	protected int _vectorHighlightThickness = 1;
-
-	// arrowhead parameters
-	private float  _arrowheadLength  = 0;
-	private double _arrowheadRatio   = DEFAULT_ARROWHEAD_RATIO;
-	private double _arrowheadNibPerc = DEFAULT_ARROWHEAD_NIB_PERC;
-	
-	private Polygon _arrowhead = null;
-
-	// the list of lines that this point is part of.
-	private List<Line> _lines = new ArrayList<Line>();
-
-	private int[] _linePattern = null;
-
-	private boolean _floating = false;
-
-	// list of points constrained with this point
-	private List<Constraint> _constraints = new ArrayList<Constraint>();
-
-	private List<String> _actions = null;
-
-	private List<String> _data = null;
-
-	private String _formula = null;
-
-	private String _link_frameset = null;
-
-	private String _link_template = null;
-
-	private String _fillPattern = null;
-
-	private boolean _visible = true;
-
-	private float _thickness = -1.0F;
-
 	protected Item() {
 		_creationDate = Formatter.getLongDateTime();
@@ -427,28 +520,30 @@
 	 * 
 	 * @param action
-	 *            The action to add to this Item
-	 */
-	public void addAction(String action) {
-		if (action == null || action.equals("")) {
-			return;
-		}
+	 *            The name of the action to add to this Item.
+	 */
+	public void addAction(String action)
+	{
+		if (action == null || action.equals("")) return;
 
 		if (_actions == null) {
 			_actions = new LinkedList<String>();
 		}
+		
 		_actions.add(action);
+		
 		if (_actions.size() == 1) {
-			_poly = null;
+			invalidateBounds();
 			invalidateCommonTrait(ItemAppearence.LinkChanged);
 		}
 	}
 
-	public void addAllConnected(Collection<Item> connected) {
-		if (!connected.contains(this))
-			connected.add(this);
+	public void addAllConnected(Collection<Item> connected)
+	{
+		if (!connected.contains(this)) connected.add(this);
 
 		for (Item item : getConnected()) {
-			if (!connected.contains(item))
+			if (!connected.contains(item)) {
 				item.addAllConnected(connected);
+			}
 		}
 	}
@@ -460,5 +555,6 @@
 	 *            The Constraint to set this Dot as a member of.
 	 */
-	public void addConstraint(Constraint c) {
+	public void addConstraint(Constraint c)
+	{
 		// do not add duplicate constraint
 		if (_constraints.contains(c))
@@ -474,5 +570,6 @@
 	 *            The Line that this Point is an end of.
 	 */
-	public void addLine(Line line) {
+	public void addLine(Line line)
+	{
 		if (_lines.contains(line)) {
 			return;
@@ -490,5 +587,6 @@
 	 *         less than, equal to, or greater than the specified object.
 	 */
-	public int compareTo(Item i) {
+	public int compareTo(Item i)
+	{
 		return getY() - i.getY();
 	}
@@ -499,13 +597,12 @@
 	 * the area and false otherwise.
 	 * 
-	 * @param x
-	 *            The x coordinate to check
-	 * @param y
-	 *            The y coordinate to check
+	 * @param p
+	 *            The coordinate to check
 	 * @return True if the Shape around this Item contains the given x,y pair,
 	 *         false otherwise.
 	 */
-	public boolean contains(int x, int y) {
-		return getPolygon().contains(x, y);
+	public boolean contains(Point p)
+	{
+		return getBounds().contains(p);
 	}
 
@@ -518,10 +615,12 @@
 	public abstract Item copy();
 
-	public void delete() {
+	public void delete()
+	{
 		_deleted = true;
 	}
 
 	@Override
-	public boolean equals(Object o) {
+	public boolean equals(Object o)
+	{
 		if (o == null)
 			return false;
@@ -542,29 +641,36 @@
 	 *         has been assigned.
 	 */
-	public List<String> getAction() {
+	public List<String> getAction()
+	{
 		return _actions;
 	}
 
-	public List<String> getData() {
+	public List<String> getData()
+	{
 		return _data;
 	}
 
-	public List<String> getActionCursorEnter() {
+	public List<String> getActionCursorEnter()
+	{
 		return _actionCursorEnter;
 	}
 
-	public List<String> getActionCursorLeave() {
+	public List<String> getActionCursorLeave()
+	{
 		return _actionCursorLeave;
 	}
 
-	public List<String> getActionEnterFrame() {
+	public List<String> getActionEnterFrame()
+	{
 		return _actionEnterFrame;
 	}
 
-	public List<String> getActionLeaveFrame() {
+	public List<String> getActionLeaveFrame()
+	{
 		return _actionLeaveFrame;
 	};
 
-	public boolean getActionMark() {
+	public boolean getActionMark()
+	{
 		return _actionMark;
 	}
@@ -576,5 +682,6 @@
 	 * @return
 	 */
-	public Collection<Item> getAllConnected() {
+	public Collection<Item> getAllConnected()
+	{
 		Collection<Item> list = new LinkedHashSet<Item>();
 		addAllConnected(list);
@@ -582,9 +689,10 @@
 	}
 
-	public Area getArea() {
+/*	public Area getArea() {
 		return new Area(getPolygon());
-	}
-
-	public String getArrow() {
+	}*/
+
+	public String getArrow()
+	{
 		if (!hasVisibleArrow())
 			return null;
@@ -597,25 +705,31 @@
 	}
 
-	public Polygon getArrowhead() {
+	public PolygonBounds getArrowhead()
+	{
 		return _arrowhead;
 	}
 
-	public float getArrowheadLength() {
+	public float getArrowheadLength()
+	{
 		return _arrowheadLength;
 	}
 
-	public double getArrowheadRatio() {
+	public double getArrowheadRatio()
+	{
 		return _arrowheadRatio;
 	}
 
-	public double getArrowheadNibPerc() {
+	public double getArrowheadNibPerc()
+	{
 		return _arrowheadNibPerc;
 	}
 	
-	public Color getBackgroundColor() {
-		return _colorBackground;
-	}
-
-	public Color getBorderColor() {
+	public Colour getBackgroundColor()
+	{
+		return _backgroundColour;
+	}
+
+	public Colour getBorderColor()
+	{
 		return _colorBorder;
 	}
@@ -628,5 +742,6 @@
 	 *         border.
 	 */
-	public Color getBottomShadowColor() {
+	public Colour getBottomShadowColor()
+	{
 		return _colorBottomShadow;
 	}
@@ -638,6 +753,7 @@
 	 *         returned by getArea().
 	 */
-	public int getBoundsHeight() {
-		return getPolygon().getBounds().height;
+	public int getBoundsHeight()
+	{
+		return AxisAlignedBoxBounds.getEnclosing(getBounds()).getHeight();
 	}
 
@@ -648,60 +764,51 @@
 	 *         by getArea().
 	 */
-	public int getBoundsWidth() {
-		return getPolygon().getBounds().width;
-	}
-
-	// TODO draw the link with a circle rather than a polygon!!
-	public Polygon getLinkPoly() {
-		if (_circle == null) {
-			int points = 16;
-
-			double radians = 0.0;
-			int xPoints[] = new int[points];
-			int yPoints[] = new int[xPoints.length];
-
-			for (int i = 0; i < xPoints.length; i++) {
-				// circle looks best if these values are not related to gravity
-				xPoints[i] = (int) (3.5 * Math.cos(radians)) + 6;// (2 *
-				// GRAVITY);
-				yPoints[i] = (int) (3.5 * Math.sin(radians)) + 3;// GRAVITY;
-				radians += (2.0 * Math.PI) / xPoints.length;
-			}
-
-			_circle = new Polygon(xPoints, yPoints, xPoints.length);
-		}
-
-		return _circle;
-	}
-
-	protected Polygon getCircleCross() {
-
-		if (_circleCross == null) {
-			_circleCross = new Polygon();
-
-			Rectangle bounds = getLinkPoly().getBounds();
-			int x1 = (int) bounds.getMinX();
-			int x2 = (int) bounds.getMaxX();
-			int y1 = (int) bounds.getMinY();
-			int y2 = (int) bounds.getMaxY();
-			int midX = ((x2 - x1) / 2) + x1;
-			int midY = ((y2 - y1) / 2) + y1;
-
-			_circleCross.addPoint(x1, y1);
-			_circleCross.addPoint(x2, y2);
-			_circleCross.addPoint(midX, midY);
-			_circleCross.addPoint(x1, y2);
-			_circleCross.addPoint(x2, y1);
-			_circleCross.addPoint(midX, midY);
-		}
-
-		return _circleCross;
-	}
-
-	public Color getColor() {
-		return _color;
-	}
-
-	public Collection<Item> getConnected() {
+	public int getBoundsWidth()
+	{
+		return AxisAlignedBoxBounds.getEnclosing(getBounds()).getWidth();
+	}
+
+	// TODO: Remove magic constants. cts16
+	public EllipticalBounds getLinkBounds()
+	{
+		if (_linkCircle == null) {
+			_linkCircle = new EllipticalBounds(new Point(6, 3), 7);
+		}
+
+		return _linkCircle;
+	}
+
+	protected PolygonBounds getCircleCross()
+	{
+
+		if (_linkCircleCross == null) {
+			_linkCircleCross = new PolygonBounds();
+
+			EllipticalBounds poly = getLinkBounds();
+			int x1 = poly.getMinX();
+			int x2 = poly.getMaxX();
+			int y1 = poly.getMinY();
+			int y2 = poly.getMaxY();
+			int midX = (x2 + x1) / 2;
+			int midY = (y2 + y1) / 2;
+
+			_linkCircleCross.addPoint(new Point(x1, y1));
+			_linkCircleCross.addPoint(new Point(x2, y2));
+			_linkCircleCross.addPoint(new Point(midX, midY));
+			_linkCircleCross.addPoint(new Point(x1, y2));
+			_linkCircleCross.addPoint(new Point(x2, y1));
+			_linkCircleCross.addPoint(new Point(midX, midY));
+		}
+
+		return _linkCircleCross;
+	}
+
+	public Colour getColor()
+	{
+		return _foregroundColour;
+	}
+
+	public Collection<Item> getConnected()
+	{
 		List<Item> conn = new LinkedList<Item>();
 		conn.add(this);
@@ -711,5 +818,6 @@
 	}
 
-	public String getConstraintIDs() {
+	public String getConstraintIDs()
+	{
 		if (_constraints == null || _constraints.size() == 0)
 			return null;
@@ -732,9 +840,11 @@
 	 * @return a List of Constraints that this Dot is a member of.
 	 */
-	public List<Constraint> getConstraints() {
+	public List<Constraint> getConstraints()
+	{
 		return _constraints;
 	}
 
-	public String getTag() {
+	public String getTag()
+	{
 		if (_tag != null && _tag.length() > 0)
 			return _tag.toString();
@@ -742,17 +852,21 @@
 	}
 
-	public String getDateCreated() {
+	public String getDateCreated()
+	{
 		return _creationDate;
 	}
 
-	public Color getFillColor() {
-		return _colorFill;
-	}
-
-	public String getFillPattern() {
+	public Colour getFillColor()
+	{
+		return _fillColour;
+	}
+
+	public String getFillPattern()
+	{
 		return _fillPattern;
 	}
 
-	public String getFirstAction() {
+	public String getFirstAction()
+	{
 		if (_actions == null || _actions.size() == 0)
 			return null;
@@ -760,11 +874,19 @@
 	}
 
-	public boolean getHighlight() {
+	/**
+	 * Gets the value of <code>_highlight</code> for this item.
+	 * TODO: Appears unused? cts16.
+	 * 
+	 * @return The value of <code>_highlight</code>.
+	 */
+	public boolean getHighlight()
+	{
 		return _highlight;
 	}
 
-	public Color getHighlightColor() {
-		if (_highlightColor.equals(getPaintColor()))
-			return getAlternateHighlightColor();
+	public Colour getHighlightColor()
+	{
+		if (_highlightColour.equals(getPaintColor())) return getAlternateHighlightColor();
+		
 		return getDefaultHighlightColor();
 	}
@@ -774,6 +896,9 @@
 	 * 
 	 * @return The ID of this Item.
-	 */
-	public int getID() {
+	 * 
+	 * TODO: What does it mean to have a negative ID# (as used in TDFC)? cts16
+	 */
+	public int getID()
+	{
 		return _id;
 	}
@@ -784,5 +909,6 @@
 	 * @return The list of Line IDs that this point is part of.
 	 */
-	public String getLineIDs() {
+	public String getLineIDs()
+	{
 		String lineID = null;
 
@@ -797,5 +923,6 @@
 	}
 
-	public int[] getLinePattern() {
+	public int[] getLinePattern()
+	{
 		return _linePattern;
 	}
@@ -807,5 +934,6 @@
 	 *         Lines have been added.
 	 */
-	public List<Line> getLines() {
+	public List<Line> getLines()
+	{
 		return _lines;
 	}
@@ -818,55 +946,68 @@
 	 *         this Item does not link to anything.
 	 */
-	public String getLink() {
+	public String getLink()
+	{
 		return _link;
 	}
 
-	public String getFormula() {
+	public String getFormula()
+	{
 		return _formula;
 	}
 
-	public boolean hasFormula() {
+	public boolean hasFormula()
+	{
 		return _formula != null;
 	}
 
-	public boolean hasAttributeValuePair() {
+	public boolean hasAttributeValuePair()
+	{
 		return _attributeValuePair != null && _attributeValuePair.hasPair();
 	}
 
-	public void setFormula(String formula) {
+	public void setFormula(String formula)
+	{
 		_formula = formula;
 	}
 
-	public boolean calculate(String formula) {
+	public boolean calculate(String formula)
+	{
 		setFormula(formula);
 		return true;
 	}
 
-	public String getLinkFrameset() {
+	public String getLinkFrameset()
+	{
 		return _link_frameset;
 	}
 
-	public boolean getLinkMark() {
+	public boolean getLinkMark()
+	{
 		return _linkMark;
 	}
 
-	public String getLinkTemplate() {
+	public String getLinkTemplate()
+	{
 		return _link_template;
 	}
 
-	// public int getMaxWidth() {
+	// public int getMaxWidth()
+	// {
 	// return _maxWidth;
 	// }
 
-	public Point getOffset() {
+	public Point getOffset()
+	{
 		return _offset;
 	}
 
-	public String getOwner() {
+	public String getOwner()
+	{
 		return _owner;
 	}
 
-	public Color getPaintBackgroundColor() {
-		Color colorBackground = getBackgroundColor();
+	public Colour getPaintBackgroundColor()
+	{
+		Colour colorBackground = getBackgroundColor();
 		if (colorBackground == null) {
 			if (getParent() != null && getParent().getBackgroundColor() != null)
@@ -884,8 +1025,9 @@
 	 * @return The Color of this item (foreground)
 	 */
-	public final Color getPaintColor() {
+	public final Colour getPaintColor()
+	{
 		// If color is null then get the paint foregroundColor for the frame the
 		// item is on which is a color adjusted to suit the background
-		Color color = getColor();
+		Colour color = getColor();
 
 		if (color == null) {
@@ -893,5 +1035,5 @@
 				return getParent().getPaintForegroundColor();
 
-			Frame current = DisplayIO.getCurrentFrame();
+			Frame current = DisplayController.getCurrentFrame();
 			if (current == null) {
 				return DEFAULT_FOREGROUND;
@@ -903,8 +1045,9 @@
 	}
 
-	public final Color getPaintBorderColor() {
+	public final Colour getPaintBorderColor()
+	{
 		// If color is null then get the paint foregroundColor for the frame the
 		// item is on which is a color adjusted to suit the background
-		Color color = getBorderColor();
+		Colour color = getBorderColor();
 
 		if (color == null) {
@@ -912,5 +1055,5 @@
 				return getParent().getPaintForegroundColor();
 
-			Frame current = DisplayIO.getCurrentFrame();
+			Frame current = DisplayController.getCurrentFrame();
 			if (current == null) {
 				return DEFAULT_FOREGROUND;
@@ -922,6 +1065,7 @@
 	}
 
-	protected Color getPaintHighlightColor() {
-		Color highlightColor = getDefaultHighlightColor();
+	protected Colour getPaintHighlightColor()
+	{
+		Colour highlightColor = getDefaultHighlightColor();
 		if (hasVisibleBorder()) {
 			if (getPaintBorderColor().equals(highlightColor)) {
@@ -931,14 +1075,13 @@
 			highlightColor = getDefaultHighlightColor();
 		}
-		if (getParent() != null
-				&& getParent().getPaintBackgroundColor().equals(highlightColor))
+		
+		if (getParent() != null && getParent().getPaintBackgroundColor().equals(highlightColor)) {
 			highlightColor = getParent().getPaintForegroundColor();
+		}
 
 		if (hasVisibleBorder()) {
-			if (highlightColor.equals(getBorderColor())
-					&& getThickness() == getHighlightThickness()) {
-				highlightColor = new Color(highlightColor.getRed(),
-						highlightColor.getGreen(), highlightColor.getBlue(),
-						150);
+			if (highlightColor.equals(getBorderColor()) && getThickness() == getHighlightThickness()) {
+				highlightColor = highlightColor.clone();
+				highlightColor.setAlpha(Colour.FromComponent255(150));
 			}
 		}
@@ -947,35 +1090,35 @@
 	}
 
-	static final int BRIGHTNESS = 185;
-
-	protected Color getDefaultHighlightColor() {
-		if (isVectorItem()
-				&& !this.contains(FrameMouseActions.getX(), FrameMouseActions
-						.getY())) {
-			return new Color(255, BRIGHTNESS, BRIGHTNESS);
-		}
-		return _highlightColor;
-	}
-
-	protected Color getAlternateHighlightColor() {
-		if (isVectorItem()
-				&& !this.contains(FrameMouseActions.getX(), FrameMouseActions
-						.getY())) {
-			return new Color(BRIGHTNESS, BRIGHTNESS, 255);
+	protected Colour getDefaultHighlightColor()
+	{
+		if (isVectorItem() && !this.contains(EcosystemManager.getInputManager().getCursorPosition())) {
+			return Colour.FromRGB255(255, BRIGHTNESS, BRIGHTNESS);
+		}
+		return _highlightColour;
+	}
+
+	protected Colour getAlternateHighlightColor()
+	{
+		if (isVectorItem() && !this.contains(EcosystemManager.getInputManager().getCursorPosition())) {
+			return Colour.FromRGB255(BRIGHTNESS, BRIGHTNESS, 255);
 		}
 		return ALTERNATE_HIGHLIGHT;
 	}
 
-	protected int getHighlightThickness() {
-		if (isVectorItem())
-			return _vectorHighlightThickness;
+	protected int getHighlightThickness()
+	{
+		if (isVectorItem()) return _vectorHighlightThickness;
+		
 		return _highlightThickness;
 	}
 
-	public final Frame getParent() {
+	public final Frame getParent()
+	{
 		return _parent;
 	}
 
-	public final Point getPosition() {
+	/** Gets the position of this item. */
+	public final Point getPosition()
+	{
 		return new Point(getX(), getY());
 	}
@@ -987,6 +1130,7 @@
 	 * @return The size of this Item.
 	 */
-	public float getSize() {
-		return -1.0F;
+	public float getSize()
+	{
+		return SIZE_NOT_APPLICABLE;
 	}
 
@@ -997,21 +1141,26 @@
 	 * @return The Color displayed on the top\left half of this Item's border.
 	 */
-	public Color getTopShadowColor() {
+	public Colour getTopShadowColor()
+	{
 		return _colorTopShadow;
 	}
 
-	public String getTypeAndID() {
+	public String getTypeAndID()
+	{
 		return "T " + getID();
 	}
 
-	public Integer getWidthToSave() {
+	public Integer getWidthToSave()
+	{
 		return getWidth();
 	}
 
-	public Integer getWidth() {
+	public Integer getWidth()
+	{
 		return null;
 	}
 
-	public int getHeight() {
+	public int getHeight()
+	{
 		return 0;
 	}
@@ -1022,5 +1171,6 @@
 	 * @return The X coordinate of this Item on the screen
 	 */
-	public int getX() {
+	public int getX()
+	{
 		return Math.round(_x);
 	}
@@ -1031,9 +1181,11 @@
 	 * @return The Y coordinate of this Item on the screen
 	 */
-	public int getY() {
+	public int getY()
+	{
 		return Math.round(_y);
 	}
 
-	public boolean hasVisibleArrow() {
+	public boolean hasVisibleArrow()
+	{
 		return isLineEnd() && getArrowheadRatio() != 0 && getArrowheadLength() != 0;
 	}
@@ -1046,19 +1198,18 @@
 	 * @return True if the two Shapes overlap, False otherwise.
 	 */
-	public boolean intersects(Polygon p) {
-		if (p == null)
-			return false;
-
-		Area a = new Area(p);
-		Area thisArea = this.getArea();
+	public boolean intersects(PolygonBounds otherBounds)
+	{
+		if (otherBounds == null) return false;
+		
+		Bounds thisBounds = getBounds();
+		
 		// Need to do this check for circles
-		if (a.equals(thisArea))
-			return true;
-
-		a.intersect(thisArea);
+		if (otherBounds.equals(thisBounds)) return true;
+
+		return otherBounds.intersects(thisBounds);
 
 		// Need to check the second equality so that we dont pick up circles
 		// inside other circles
-		return !a.isEmpty() && !a.equals(new Area(p));
+		//return !a.isEmpty() && !a.equals(new Area(p));
 	}
 
@@ -1069,13 +1220,16 @@
 	 * @return True if this Item is an annotation, False otherwise.
 	 */
-	public boolean isAnnotation() {
+	public boolean isAnnotation()
+	{
 		return false;
 	}
 
-	public boolean isFloating() {
+	public boolean isFloating()
+	{
 		return _floating;
 	}
 
-	public boolean isFrameName() {
+	public boolean isFrameName()
+	{
 		if (this.getParent() == null || this.getParent().getNameItem() != this)
 			return false;
@@ -1083,5 +1237,6 @@
 	}
 
-	public boolean isFrameTitle() {
+	public boolean isFrameTitle()
+	{
 		if (this.getParent() == null || this.getParent().getTitleItem() != this)
 			return false;
@@ -1095,8 +1250,9 @@
 	 *         otherwise.
 	 */
-	public boolean isHighlighted() {
+	public boolean isHighlighted()
+	{
 		if (isFloating())
 			return false;
-		return _mode != HighlightMode.None;
+		return _highlightMode != HighlightMode.None;
 	}
 
@@ -1109,5 +1265,6 @@
 	 * @return True if the given framename is proper, false otherwise.
 	 */
-	public boolean isLinkValid() {
+	public boolean isLinkValid()
+	{
 		if (FrameIO.isPositiveInteger(getLink()))
 			return true;
@@ -1118,15 +1275,26 @@
 	}
 
-	public boolean isNear(int x, int y) {
-
-		int xLeft = getPolygon().getBounds().x;
-		int yTop = getPolygon().getBounds().y;
-
-		return (x > xLeft - NEAR_DISTANCE && y > yTop - NEAR_DISTANCE
-				&& x < xLeft + getBoundsWidth() + NEAR_DISTANCE && y < yTop
-				+ getBoundsHeight() + NEAR_DISTANCE);
-	}
-
-	public boolean isOldTag() {
+	/**
+	 * Checks if the given point is 'near' to the item. Here 'near' means within a certain distance
+	 * of the axis-aligned box bounding the item's polygon.
+	 * 
+	 * @param x
+	 * 		The x-coordinate of the point to check.
+	 * 
+	 * @param y
+	 * 		The y-coordinate of the point to check.
+	 * 
+	 * @return
+	 * 		True if the given point is 'near' to the item, false otherwise.
+	 */
+	public boolean isNear(int x, int y)
+	{
+		AxisAlignedBoxBounds box = ItemUtils.expandRectangle(getBoundingBox(), NEAR_DISTANCE * 2);
+		
+		return box.contains(x, y);
+	}
+
+	public boolean isOldTag()
+	{
 		if (this instanceof Text)
 			if (((Text) this).getTextList().get(0).toLowerCase().equals("@old"))
@@ -1153,12 +1321,17 @@
 	 *            The Graphics to draw this Item on.
 	 */
-	public abstract void paint(Graphics2D g);
-	
-	public void setTooltips(final List<String> tooltips) {
-		if(tooltips == null || tooltips.size() == 0) _tooltip = new Tooltip();
-		else for(final String content: tooltips) _tooltip.addTooltip(content, this);
-	}
-	
-	public void setTooltip(final String tooltip) {
+	public abstract void paint();
+	
+	public void setTooltips(final List<String> tooltips)
+	{
+		if (tooltips == null || tooltips.size() == 0) {
+			_tooltip = new Tooltip();
+		} else {
+			for (final String content: tooltips) _tooltip.addTooltip(content, this);
+		}
+	}
+	
+	public void setTooltip(final String tooltip)
+	{
 		if(tooltip != null && tooltip.trim().length() > 0) {
 			_tooltip.addTooltip(tooltip, this);
@@ -1166,79 +1339,92 @@
 	}
 	
-	public List<String> getTooltip() {
+	public List<String> getTooltip()
+	{
 		return _tooltip.asStringList();
 	}
 	
-	public Collection<Text> getTooltipItems() {
+	public Collection<Text> getTooltipItems()
+	{
 		return _tooltip.getTooltips();
 	}
 
-	public void clearTooltips() {
+	public void clearTooltips()
+	{
 		final Frame frame = this.getParent();
-		if(_tooltip != null)
+		if(_tooltip != null) {
 			for(final Text tooltip: _tooltip.getTooltips()) frame.removeItem(tooltip);
-	}
-	
-	public void paintTooltip(final Graphics2D g) {
-		final Rectangle bounds = this.getPolygon().getBounds();
-		int x = bounds.x + bounds.width;
-		if(x + _tooltip.getWidth() > FrameGraphics.getMaxFrameSize().width) {
-			x -= x + _tooltip.getWidth() - FrameGraphics.getMaxFrameSize().width;
-		}
-		int y = bounds.y + bounds.height;
-		if(y + _tooltip.getCollectiveHeight() > FrameGraphics.getMaxFrameSize().height) {
-			y = bounds.y + bounds.height / 2 - _tooltip.getCollectiveHeight();
-		}
+		}
+	}
+	
+	public void paintTooltip()
+	{
+		final Bounds bounds = AxisAlignedBoxBounds.getEnclosing(this.getBoundingBox());
+		Dimension frameSize = DisplayController.getFramePaintArea().getSize();
+		
+		int x = bounds.getMaxX();
+		
+		// If the tooltip goes off the right side of the window, move it left so it's completely on
+		if(x + _tooltip.getWidth() > frameSize.getWidth()) {
+			x = frameSize.getWidth() - _tooltip.getWidth();
+		}
+		
+		int y = bounds.getMaxY();
+		
+		if(y + _tooltip.getCollectiveHeight() > frameSize.getHeight()) {
+			y = (bounds.getMinY() + bounds.getMaxY()) / 2 - _tooltip.getCollectiveHeight();
+		}
+		
 		for(final Text tooltip : _tooltip.getTooltips()) {
 			this.getParent().addItem(tooltip);
 			tooltip.setPosition(x, y);
-			tooltip.paint(g);
+			tooltip.paint();
 			y += tooltip.getHeight();
 		}
 	}
 	
-	public void paintFill(Graphics2D g) {
-		Color fillColor = getFillColor();
+	public void paintFill() {
+		Colour fillColor = getFillColor();
 		if (fillColor != null && getEnclosingDots() != null) {
-			setFillPaint(g);
-			g.fillPolygon(getEnclosedShape());
-		}
-	}
-
-	protected void setFillPaint(Graphics2D g) {
-		Color fillColor = getFillColor();
+			Fill fill = getFill();
+			EcosystemManager.getGraphicsManager().drawPolygon(getEnclosedShape(), null, null, 0.0f, fill, null, null);
+		}
+	}
+
+	protected Fill getFill() {
+		Fill fill;
+		Colour fillColour = getFillColor();
 		if (isFloating()) {
 			// TODO experiment with adding alpha when picking up filled
 			// items... Slows things down quite alot!!
-			fillColor = new Color(fillColor.getRed(), fillColor.getGreen(),
-					fillColor.getBlue(), fillColor.getAlpha());
-		}
-		g.setColor(fillColor);
-		Color gradientColor = getGradientColor();
-		if (gradientColor != null) {
+			// TODO: Does nothing as it stands... cts16
+			fillColour = new Colour(fillColour.getRed(), fillColour.getGreen(),
+					fillColour.getBlue(), fillColour.getAlpha());
+		}
+		Colour gradientColor = getGradientColor();
+		PolygonBounds poly = getEnclosedShape();
+		if (gradientColor != null && poly != null) {
 			/*
 			 * It is slow when painting gradients... modify so this is only done
 			 * once unless it is resized...
 			 */
-			Shape s = getEnclosedShape();
-			if (s != null) {
-				Rectangle b = s.getBounds();
-				double rads = getGradientAngle() * Math.PI / 180;
-				double cos = Math.cos(rads);
-				double sin = Math.sin(rads);
-
-				GradientPaint gp = new GradientPaint((int) (b.x + b.width
-						* (0.2 * cos + 0.5)), (int) (b.y + b.height
-						* (0.2 * sin + 0.5)), fillColor, (int) (b.x + b.width
-						* (-0.8 * cos + 0.5)), (int) (b.y + b.height
-						* (-0.8 * sin + 0.5)), gradientColor);
-				g.setPaint(gp);
-			}
-		}
+			AxisAlignedBoxBounds b = AxisAlignedBoxBounds.getEnclosing(poly);
+			double rads = getGradientAngle();
+			double cos = Math.cos(rads);
+			double sin = Math.sin(rads);
+
+			Point fromPoint = new Point((int) (b.getMinX() + b.getWidth() * (0.2 * cos + 0.5)), (int) (b.getMinY() + b.getHeight() * (0.2 * sin + 0.5)));
+			Point toPoint = new Point((int) (b.getMinX() + b.getWidth() * (-0.8 * cos + 0.5)), (int) (b.getMinY() + b.getHeight() * (-0.8 * sin + 0.5)));
+			
+			fill = new GradientFill(fillColour, fromPoint, gradientColor, toPoint);
+		} else {
+			fill = new Fill(fillColour);
+		}
+		
+		return fill;
 	}
 
 	/**
 	 * This method performs all the actions in an items list. If it contains a
-	 * link as well the link is used as the source frame for all acitons.
+	 * link as well the link is used as the source frame for all actions.
 	 */
 	public void performActions() {
@@ -1268,5 +1454,5 @@
 			// For actions like format they rely on this being set to the
 			// current frame incase the item being activated is on an overlay
-			sourceFrame = DisplayIO.getCurrentFrame();
+			sourceFrame = DisplayController.getCurrentFrame();
 		}
 
@@ -1388,5 +1574,5 @@
 			MessageBay.displayMessage("See SIMPLE doc for ["
 					+ ise.getStatement() + "] statement", ise.getStatement()
-					+ "1", Color.CYAN.darker(), true, null);
+					+ "1", Colour.CYAN.darker(), true, null);
 		} catch (Exception e) {
 			MessageBay.linkedErrorMessage(e.getMessage());
@@ -1394,5 +1580,5 @@
 		Simple.ProgramFinished();
 		// Need to repaint any highlights etc
-		FrameGraphics.requestRefresh(true);
+		DisplayController.requestRefresh(true);
 	}
 
@@ -1414,5 +1600,5 @@
 
 		if (_parent == null)
-			framesetName = DisplayIO.getCurrentFrame().getFramesetName();
+			framesetName = DisplayController.getCurrentFrame().getFramesetName();
 		else
 			framesetName = _parent.getFramesetName();
@@ -1428,14 +1614,15 @@
 	 *            The lines of code to associate with this Item
 	 */
-	public void setActions(List<String> actions) {
+	public void setActions(List<String> actions)
+	{
 		if (actions == null || actions.size() == 0) {
 			invalidateCommonTrait(ItemAppearence.LinkChanged);
 			_actions = null;
-		} else
+		} else {
 			_actions = new LinkedList<String>(actions);
-
-		// Want to resize the highlight box for text items if actions have been
-		// added
-		_poly = null;
+		}
+		
+		// Want to resize the highlight box for text items if actions have been added
+		invalidateBounds();
 		invalidateCommonTrait(ItemAppearence.LinkChanged);
 	}
@@ -1481,11 +1668,10 @@
 	}
 
-	public void setActionMark(boolean val) {
-		if (!val)
-			invalidateCommonTrait(ItemAppearence.LinkChanged);
-		_poly = null;
+	public void setActionMark(boolean val)
+	{
+		if (!val) invalidateCommonTrait(ItemAppearence.LinkChanged);
+		invalidateBounds();
 		_actionMark = val;
-		if (val)
-			invalidateCommonTrait(ItemAppearence.LinkChanged);
+		if (val) invalidateCommonTrait(ItemAppearence.LinkChanged);
 	}
 
@@ -1519,5 +1705,5 @@
 	}
 	
-	public void setArrowhead(Polygon arrow) {
+	public void setArrowhead(PolygonBounds arrow) {
 		_arrowhead = arrow;
 	}
@@ -1538,12 +1724,12 @@
 	}
 
-	public void setBackgroundColor(Color c) {
-		if (c != _colorBackground) {
-			_colorBackground = c;
+	public void setBackgroundColor(Colour c) {
+		if (c != _backgroundColour) {
+			_backgroundColour = c;
 			invalidateCommonTrait(ItemAppearence.BackgroundColorChanged);
 		}
 	}
 
-	public void setBorderColor(Color c) {
+	public void setBorderColor(Colour c) {
 		if (c != _colorBorder) {
 			_colorBorder = c;
@@ -1560,5 +1746,5 @@
 	 *            Item's border.
 	 */
-	public void setBottomShadowColor(Color bottom) {
+	public void setBottomShadowColor(Colour bottom) {
 		_colorBottomShadow = bottom;
 	}
@@ -1569,12 +1755,12 @@
 	 * @param c
 	 */
-	public void setColor(Color c) {
-		if (c != _color) {
-			_color = c;
+	public void setColor(Colour c) {
+		if (c != _foregroundColour) {
+			_foregroundColour = c;
 			invalidateCommonTrait(ItemAppearence.ForegroundColorChanged);
 			if (hasVector()) {
 				// TODO make this more efficient so it only repaints the items
 				// for this vector
-				FrameKeyboardActions.Refresh();
+				StandardGestureActions.Refresh();
 			}
 		}
@@ -1605,7 +1791,7 @@
 	}
 
-	public void setFillColor(Color c) {
-
-		_colorFill = c;
+	public void setFillColor(Colour c) {
+
+		_fillColour = c;
 
 		for (Line line : _lines) {
@@ -1620,6 +1806,7 @@
 	}
 
-	public void setGradientColor(Color c) {
-		_colorGradient = c;
+	public void setGradientColor(Colour c)
+	{
+		_gradientColour = c;
 
 		for (Line line : _lines) {
@@ -1633,6 +1820,6 @@
 	}
 
-	public Color getGradientColor() {
-		return _colorGradient;
+	public Colour getGradientColor() {
+		return _gradientColour;
 	}
 
@@ -1647,4 +1834,10 @@
 	}
 
+	/**
+	 * Sets the value <code>_highlight</code> for this item.
+	 * TODO: Appears unused? cts16
+	 * 
+	 * @param val The new value for <code>_highlight</code>.
+	 */
 	public void setHighlight(boolean val) {
 		_highlight = val;
@@ -1693,19 +1886,17 @@
 	 *            The name of the Frame to link this item to.
 	 */
-	public void setLink(String frameName) {
-		if (frameName == null) {
-			invalidateCommonTrait(ItemAppearence.LinkChanged);
-		}
-
-		// If a link is being removed or set then need to reset poly so the
+	public void setLink(String frameName)
+	{
+		if (frameName == null) invalidateCommonTrait(ItemAppearence.LinkChanged);
+
+		// If a link is being removed or set then need to reset _bounds so the
 		// highlighting is drawn with the correct width
-		if (frameName == null || getLink() == null)
-			_poly = null;
-
-		if (FrameIO.isValidLink(frameName))
+		if (frameName == null || getLink() == null) invalidateBounds();
+
+		if (FrameIO.isValidLink(frameName)) {
 			_link = frameName;
-		else
-			MessageBay.errorMessage("[" + frameName
-					+ "] is not a valid frame name");
+		} else {
+			MessageBay.errorMessage("[" + frameName + "] is not a valid frame name");
+		}
 		// TODO make this throw exceptions etc...
 
@@ -1721,28 +1912,29 @@
 	}
 
-	public void setLinkFrameset(String frameset) {
-		if (frameset == null || FrameIO.isValidFramesetName(frameset))
+	public void setLinkFrameset(String frameset)
+	{
+		if (frameset == null || FrameIO.isValidFramesetName(frameset)) {
 			_link_frameset = frameset;
-		else
-			MessageBay.errorMessage("[" + frameset
-					+ "] is not a valid frameset name");
+		} else {
+			MessageBay.errorMessage("[" + frameset + "] is not a valid frameset name");
+		}
 		// TODO make this throw exceptions etc...
 	}
 
-	public void setLinkMark(boolean val) {
-		if (!val)
-			invalidateCommonTrait(ItemAppearence.LinkChanged);
-		_poly = null;
+	public void setLinkMark(boolean val)
+	{
+		if (!val) invalidateCommonTrait(ItemAppearence.LinkChanged);
+		invalidateBounds();
 		_linkMark = val;
-		if (val)
-			invalidateCommonTrait(ItemAppearence.LinkChanged);
-	}
-
-	public void setLinkTemplate(String template) {
-		if (FrameIO.isValidLink(template))
+		if (val) invalidateCommonTrait(ItemAppearence.LinkChanged);
+	}
+
+	public void setLinkTemplate(String template)
+	{
+		if (FrameIO.isValidLink(template)) {
 			_link_template = template;
-		else
-			MessageBay.errorMessage("[" + template
-					+ "] is not a valid frame name");
+		} else {
+			MessageBay.errorMessage("[" + template + "] is not a valid frame name");
+		}
 		// TODO make this throw exceptions etc...
 	}
@@ -1763,9 +1955,9 @@
 
 	public void setOffset(int x, int y) {
-		_offset.setLocation(x, y);
+		_offset.set(x, y);
 	}
 
 	public void setOffset(Point p) {
-		_offset.setLocation(p);
+		_offset.set(p);
 	}
 
@@ -1805,5 +1997,5 @@
 			}
 		}
-		if (_colorFill != null) {
+		if (_fillColour != null) {
 			invalidateFill(); // only invalidates if has fill
 		}
@@ -1814,8 +2006,4 @@
 	}
 
-	
-	
-	
-	
 	protected void anchorConstraints()
 	{
@@ -1830,12 +2018,10 @@
 					if (isAnchoredY()) {
 						// Make the 'other' item have the same anchor top/bottom values as this
-						other._anchorTop    = _anchorTop;
-						other._anchorBottom = _anchorBottom;
+						other._anchoring.setYAnchor(this._anchoring);
 					}
 				} else if (c.getType() == Constraint.VERTICAL) {
 					if (isAnchoredX()) {
 						// Make the 'other' item have the same anchor left/right values as this
-						other._anchorLeft  = _anchorLeft;
-						other._anchorRight = _anchorRight;
+						other._anchoring.setXAnchor(this._anchoring);
 					}
 				} else if (c.isDiagonal()) {
@@ -1855,10 +2041,10 @@
 	 *            The new Y coordinate
 	 */
-	public void setPosition(float x, float y) {
+	public void setPosition(float x, float y)
+	{
 		float deltaX = x - _x;
 		float deltaY = y - _y;
 
-		if (deltaX == 0 && deltaY == 0)
-			return;
+		if (deltaX == 0 && deltaY == 0) return;
 
 		invalidateCommonTraitForAll(ItemAppearence.PreMoved);
@@ -1868,7 +2054,7 @@
 
 		for (Item i : getEnclosures()) {
-			i.updatePolygon();
-		}
-		updatePolygon();
+			i.invalidateBounds();
+		}
+		invalidateBounds();
 
 		// update the position of any dots that are constrained by this one
@@ -1951,5 +2137,5 @@
 
 		for (Line line : getLines()) {
-			line.updatePolygon();
+			line.invalidateBounds();
 		}
 
@@ -2007,7 +2193,8 @@
 	 *            their thickness set
 	 */
-	public void setThickness(float thick, boolean setConnectedThickness) {
-		if (thick == _thickness)
-			return;
+	public void setThickness(float thick, boolean setConnectedThickness)
+	{
+		if (thick == _thickness) return;
+		
 		boolean bigger = thick > _thickness;
 
@@ -2015,6 +2202,5 @@
 			if (setConnectedThickness) {
 				// TODO is there a more efficient way of doing this?
-				for (Item i : getConnected())
-					i.invalidateCommonTrait(ItemAppearence.Thickness);
+				for (Item i : getConnected()) i.invalidateCommonTrait(ItemAppearence.Thickness);
 			} else {
 				invalidateCommonTrait(ItemAppearence.Thickness);
@@ -2028,14 +2214,11 @@
 		 * etc...
 		 */
-		for (Line line : getLines())
-			line.setThickness(thick, setConnectedThickness);
-
-		if (setConnectedThickness)
-			updatePolygon();
+		for (Line line : getLines()) line.setThickness(thick, setConnectedThickness);
+
+		if (setConnectedThickness) invalidateBounds();
 
 		if (bigger) {
 			if (setConnectedThickness) {
-				for (Item i : getConnected())
-					i.invalidateCommonTrait(ItemAppearence.Thickness);
+				for (Item i : getConnected()) i.invalidateCommonTrait(ItemAppearence.Thickness);
 			} else {
 				invalidateCommonTrait(ItemAppearence.Thickness);
@@ -2050,5 +2233,6 @@
 	 *         set).
 	 */
-	public float getThickness() {
+	public float getThickness()
+	{
 		return _thickness;
 	}
@@ -2062,15 +2246,17 @@
 	 *            Item's border.
 	 */
-	public void setTopShadowColor(Color top) {
+	public void setTopShadowColor(Colour top) {
 		_colorTopShadow = top;
 	}
 
-	public void setWidth(Integer width) throws UnsupportedOperationException {
-		throw new UnsupportedOperationException(
-				"Item type does not support width attribute!");
-	}
-
-	public void setRightMargin(int i, boolean fixWidth) {
+	public void setWidth(Integer width) throws UnsupportedOperationException
+	{
+		throw new UnsupportedOperationException("Item type does not support width attribute!");
+	}
+
+	public void setRightMargin(int i, boolean fixWidth)
+	{
 		int newWidth = i - getX() - Item.MARGIN_LEFT;
+		if (newWidth < 0) newWidth = 0;
 		if (!fixWidth) {
 			newWidth *= -1;
@@ -2113,9 +2299,17 @@
 	 *         means no change)
 	 */
-	public int setHighlightColor() {
-		return setHighlightColor(DEFAULT_HIGHLIGHT);
-	}
-
-	public int setHighlightColor(Color c) {
+	
+	/**
+	 * 
+	 * 
+	 * @return
+	 */
+	public void setHighlightColorToDefault() {
+		setHighlightColor(DEFAULT_HIGHLIGHT);
+	}
+
+	public void setHighlightColor(Colour c) {
+		if (c == null) return;
+		
 		if (!this.isVisible() && this.hasVector()) {
 			for (Item i : this.getParentOrCurrentFrame().getVectorItems()) {
@@ -2128,11 +2322,9 @@
 		_highlightThickness = DEFAULT_HIGHLIGHT_THICKNESS;
 
-		Color selColor = (c != null) ? c : DEFAULT_HIGHLIGHT;
-		if (_highlightColor != c) {
-			_highlightColor = selColor;
+		Colour selColor = (c != null) ? c : DEFAULT_HIGHLIGHT;
+		if (_highlightColour != c) {
+			_highlightColour = selColor;
 			this.invalidateCommonTrait(ItemAppearence.HighlightColorChanged);
 		}
-
-		return Item.UNCHANGED_CURSOR;
 
 	}
@@ -2146,5 +2338,6 @@
 	}
 
-	public abstract void updatePolygon();
+	/** Returns a Bounds which represents the area covered by the item (including its gravity). */
+	public abstract Bounds updateBounds();
 
 	public void setHidden(boolean state) {
@@ -2172,17 +2365,18 @@
 	}
 
-	public void setHighlightMode(HighlightMode mode, Color color) {
-		setHighlightColor(color);
-		if (hasPermission(UserAppliedPermission.followLinks)
-				|| getEditTarget().hasPermission(UserAppliedPermission.followLinks)) {
-			if (_mode != mode) {
-				_mode = mode;
-				this.invalidateCommonTrait(ItemAppearence.HighlightModeChanged);
-			}
-		}
+	/**
+	 * Sets the highlight mode and colour at the same time.
+	 * 
+	 * @param mode The new highlight mode.
+	 * @param colour The new highlight colour.
+	 */
+	public void setHighlightModeAndColour(HighlightMode mode, Colour colour)
+	{
+		setHighlightMode(mode);
+		setHighlightColor(colour);
 	}
 
 	public HighlightMode getHighlightMode() {
-		return _mode;
+		return _highlightMode;
 	}
 
@@ -2191,7 +2385,5 @@
 		// only set the id if we've moved to a different frame, or if the frame already has an item with that id
 		if(!current.equals(_oldParent) || current.getItemWithID(getID()) != null) {
-			int id = _id;
 			setID(current.getNextItemID());
-			// System.out.println(this + " - Set ID to " + _id + " (was " + id + ")");
 		} else {
 			// System.out.println(this + " - Kept old ID of " + _id);
@@ -2239,5 +2431,5 @@
 		// if the item is from an overlay the parent will NOT be null
 		if (getParent() == null) {
-			return DisplayIO.getCurrentFrame();
+			return DisplayController.getCurrentFrame();
 		}
 		return getParent();
@@ -2275,11 +2467,11 @@
 	 *         the enclosed list.
 	 */
-	public Polygon getEnclosedShape() {
-		if (_enclosure == null)
-			return null;
-
-		Polygon poly = new Polygon();
+	public PolygonBounds getEnclosedShape()
+	{
+		if (_enclosure == null) return null;
+
+		PolygonBounds poly = new PolygonBounds();
 		for (Item d : _enclosure) {
-			poly.addPoint(d.getX(), d.getY());
+			poly.addPoint(new Point(d.getX(), d.getY()));
 		}
 
@@ -2332,5 +2524,5 @@
 	 *            the new color for the line
 	 */
-	protected void lineColorChanged(Color c) {
+	protected void lineColorChanged(Colour c) {
 		for (Line l : getLines()) {
 			if (l.getColor() != c)
@@ -2345,17 +2537,20 @@
 	 */
 	public boolean offScreenTopOrLeft() {
-		Rectangle itemRect = getArea().getBounds();
+		Bounds bounds = getBoundingBox();
+		
 		// Check that the bottom right corner of this item is on the screen
-		if (itemRect.x + itemRect.width >= 0
-				&& itemRect.y + itemRect.height >= 0)
+		if (bounds.getMaxX() >= 0 && bounds.getMaxY() >= 0) {
 			return false;
+		}
+		
 		// Check if all the items it is connected to are offscreen
 		for (Item i : getAllConnected()) {
-			Rectangle iRect = i.getArea().getBounds();
+			bounds = i.getBoundingBox();
 			// Check that the bottom right corner of this item is on the screen
-			if (iRect.x + iRect.width >= 0 && iRect.y + iRect.height >= 0) {
+			if (bounds.getMaxX() >= 0 && bounds.getMaxY() >= 0) {
 				return false;
 			}
 		}
+		
 		return true;
 	}
@@ -2374,18 +2569,20 @@
 	}
 
-	public void setAction(String action) {
-		// Want to resize the highlight box for text items if actions are been
-		// added
+	public void setAction(String action)
+	{
+		// Want to resize the highlight box for text items if actions are been added
 		if (action == null || action.length() == 0) {
 			invalidateCommonTrait(ItemAppearence.LinkChanged);
 		}
+		
 		if (_actions == null || _actions.size() == 0) {
-			_poly = null;
+			invalidateBounds();
 			_actions = new LinkedList<String>();
 		} else {
 			_actions.clear();
 		}
-		if (action != null && action.length() > 0)
-			_actions.add(action);
+		
+		if (action != null && action.length() > 0) _actions.add(action);
+		
 		invalidateCommonTrait(ItemAppearence.LinkChanged);
 	}
@@ -2395,5 +2592,5 @@
 	}
 
-	protected Rectangle getLinkDrawArea() {
+	protected AxisAlignedBoxBounds getLinkDrawArea() {
 		return getLinkDrawArea(getX() - LEFT_MARGIN, getY() + getLinkYOffset());
 	}
@@ -2410,6 +2607,6 @@
 	 * @return The drawing area of the link at the given coordinates.
 	 */
-	public Rectangle getLinkDrawArea(int x, int y) {
-		return new Rectangle(x + 2, y - 1, 8, 8);
+	public AxisAlignedBoxBounds getLinkDrawArea(int x, int y) {
+		return new AxisAlignedBoxBounds(x + 2, y - 1, 8, 8);
 	}
 
@@ -2419,6 +2616,6 @@
 	 * @param g
 	 */
-	protected void paintLink(Graphics2D g) {
-		paintLinkGraphic(g, getX() - LEFT_MARGIN, getY() + getLinkYOffset());
+	protected void paintLink() {
+		paintLinkGraphic(getX() - LEFT_MARGIN, getY() + getLinkYOffset());
 	}
 
@@ -2438,45 +2635,46 @@
 	 *            centered)
 	 */
-	public void paintLinkGraphic(Graphics2D g, int x, int y) {
-
-		boolean hasLink = getLink() != null;
+	public void paintLinkGraphic(int x, int y) {
+
+		boolean hasLink = hasLink();
 		boolean hasAction = hasAction();
 
 		if (hasLink || hasAction) {
-			g.setStroke(HIGHLIGHT_STROKE);
+			GraphicsManager g = EcosystemManager.getGraphicsManager();
+			Fill fill = new Fill();
+			Colour colour = null;
+			Point offset = new Point(x, y);
+			
 			if (hasLink && hasAction) {
-				g.setColor(LINK_ACTION_COLOR);
+				colour = LINK_ACTION_COLOR;
 			} else if (hasLink) {
-				g.setColor(LINK_COLOR);
+				colour = LINK_COLOR;
 			} else if (hasAction) {
-				g.setColor(ACTION_COLOR);
+				colour = ACTION_COLOR;
 			}
-
-			AffineTransform at = new AffineTransform();
-			AffineTransform orig = g.getTransform();
-			at.translate(x, y);
-			g.setTransform(at);
-
-			if (getLinkMark() && getLink() != null) {
-				g.drawPolygon(getLinkPoly());
-
+			fill.setColour(colour);
+
+			// Small circles look rubbish without AA. cts16
+			g.setAntialiasing(true);
+			
+			if (hasLink && getLinkMark()) {
+				g.drawOval(offset, getLinkBounds().getDiameters(), 0.0f, null, colour, HIGHLIGHT_STROKE);
+				
 				// if the link is not valid, cross out the circle
-				if (!isLinkValid())
-					g.drawPolygon(getCircleCross());
+				if (!isLinkValid()) {
+					g.drawPolygon(getCircleCross(), offset, null, 0.0f, null, colour, HIGHLIGHT_STROKE);
+				}
 			}
 
-			if (getActionMark() && hasAction()) {
-				g.drawPolygon(getLinkPoly());
-				g.fillPolygon(getLinkPoly());
+			if (hasAction && getActionMark()) {
+				g.drawOval(offset, getLinkBounds().getDiameters(), 0.0f, fill, colour, HIGHLIGHT_STROKE);
 
 				// if the link is not valid, cross out the circle
 				if (!isLinkValid() && getLink() != null) {
-					g.setColor(getParent().getPaintBackgroundColor());
-					g.drawPolygon(getCircleCross());
+					g.drawPolygon(getCircleCross(), offset, null, 0.0f, null, getParent().getPaintBackgroundColor(), HIGHLIGHT_STROKE);
 				}
 			}
-
-			// reset the graphics tranformation
-			g.setTransform(orig);
+			
+			g.setAntialiasing(false);
 		}
 	}
@@ -2539,5 +2737,5 @@
 			return null;
 		// assert (_parent!= null);
-		Frame parent = DisplayIO.getCurrentFrame();
+		Frame parent = DisplayController.getCurrentFrame();
 		assert (parent != null);
 
@@ -2587,9 +2785,9 @@
 		while (!lines.isEmpty()) {
 			Line l = lines.remove();
-			// if we havnt visited the line yet visit it
+			// if we haven't visited the line yet visit it
 			if (!visited.contains(l)) {
 				visited.add(l);
 				Item otherEnd = l.getOppositeEnd(this);
-				// Add all the enexplored lines to our list
+				// Add all the unexplored lines to our list
 				while (!lines.isEmpty()) {
 					l = lines.remove();
@@ -2613,33 +2811,61 @@
 	 *         is part of
 	 */
-	public double getEnclosedArea() {
-		if (_enclosure == null)
-			return 0.0;
-		Rectangle2D box = getEnclosedShape().getBounds2D();
+	public double getEnclosedArea()
+	{
+		AxisAlignedBoxBounds box = getEnclosedBox();
+		if (box == null) return 0.0;
 		return box.getWidth() * box.getHeight();
 	}
 
-	public Rectangle getEnclosedRectangle() {
-		if (_enclosure == null)
-			return null;
-		return getEnclosedShape().getBounds();
-	}
-
-	public int getEnclosureID() {
+	/**
+	 * Gets the box encompassing all points that form an enclosure with this item.
+	 * 
+	 * @return An axis-aligned box around all enclosure points.
+	 */
+	public AxisAlignedBoxBounds getEnclosedBox()
+	{
+		if (_enclosure == null) return null;
+		
+		return AxisAlignedBoxBounds.getEnclosing(getEnclosedShape());
+	}
+
+	public int getEnclosureID()
+	{
 		return _enclosure == null ? 0 : _enclosure.hashCode();
 	}
 
 	/**
-	 * Returns the Shape that surrounds this Item representing this Item's
+	 * Returns the Bounds that surrounds this Item representing this Item's
 	 * 'gravity'.
 	 * 
-	 * @return The Shape (rectangle) surrounding this Item, which represents
+	 * @return The Bounds surrounding this Item, which represents
 	 *         this Items 'gravity'.
 	 */
-	public final Polygon getPolygon() {
-		if (_poly == null)
-			updatePolygon();
-
-		return new Polygon(_poly.xpoints, _poly.ypoints, _poly.npoints);
+	public final Bounds getBounds()
+	{
+		if (_bounds == null) _bounds = updateBounds();
+		
+		// DEBUG
+		if (_bounds == null) {
+			//System.out.println("updateBounds failed!");
+		}
+
+		return _bounds;
+	}
+	
+	public final Bounds getOldBounds()
+	{
+		return _oldBounds;
+	}
+	
+	public final void invalidateBounds()
+	{
+		if (_bounds != null) _oldBounds = _bounds;
+		_bounds = null;
+	}
+	
+	public final AxisAlignedBoxBounds getBoundingBox()
+	{
+		return AxisAlignedBoxBounds.getEnclosing(getBounds());
 	}
 
@@ -2651,13 +2877,13 @@
 	 * @param ratio
 	 */
-	public void translate(Point2D origin, double ratio) {
+	public void translate(Point origin, double ratio) {
 
 		invalidateCommonTraitForAll(ItemAppearence.PreMoved);
 
-		_x = (float) (origin.getX() + ratio * (_x - origin.getX()));
-		_y = (float) (origin.getY() + ratio * (_y - origin.getY()));
-		updatePolygon();
+		_x = (float) (origin.x + ratio * (_x - origin.x));
+		_y = (float) (origin.y + ratio * (_y - origin.y));
+		invalidateBounds();
 		for (Line line : getLines())
-			line.updatePolygon();
+			line.invalidateBounds();
 
 		invalidateCommonTraitForAll(ItemAppearence.PostMoved);
@@ -2698,14 +2924,4 @@
 	}
 
-	Collection<XRayable> _enclosures = new HashSet<XRayable>();
-
-	private boolean _deleted = false;
-
-	private Overlay _overlay = null;
-
-	protected AttributeValuePair _attributeValuePair = null;
-
-	private Float _autoStamp = null;
-
 	/**
 	 * For now there can only be one enclosure per item
@@ -2741,10 +2957,10 @@
 	 *         highlighting bounds
 	 */
-	public Rectangle[] getDrawingArea() {
-
-		return new Rectangle[] { ItemUtils.expandRectangle(getPolygon()
-				.getBounds(), (int) Math.ceil(Math.max(_highlightThickness,
-				getThickness()))) };
-
+	public AxisAlignedBoxBounds getDrawingArea() {
+
+		return ItemUtils.expandRectangle(
+					getBoundingBox(),
+					(int) Math.ceil(Math.max(_highlightThickness, getThickness())) + 1 // + 1 to make sure
+		);
 	}
 
@@ -2754,17 +2970,19 @@
 	 * @return True if area intersects with this items drawing area.
 	 */
-	public final boolean isInDrawingArea(Area area) {
-		for (Rectangle r : getDrawingArea()) {
-			if (area.intersects(r))
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Completetly invalidates the item - so that it should be redrawed. Note:
-	 * This is handled internally, it should be reare to invoke this externally
-	 */
-	public final void invalidateAll() {
+	public final boolean isInDrawingArea(AxisAlignedBoxBounds area)
+	{
+		AxisAlignedBoxBounds drawingArea = getDrawingArea();
+		
+		if (drawingArea == null) return false;
+		
+		return drawingArea.intersects(area);
+	}
+
+	/**
+	 * Completely invalidates the item - so that it should be redrawn. Note:
+	 * This is handled internally, it should be rare to invoke this externally
+	 */
+	public final void invalidateAll()
+	{
 		invalidate(getDrawingArea());
 	}
@@ -2776,7 +2994,7 @@
 	 * @param damagedAreas
 	 */
-	protected final void invalidate(Rectangle[] damagedAreas) {
-		for (Rectangle r : damagedAreas)
-			invalidate(r);
+	protected final void invalidate(Bounds[] damagedAreas)
+	{
+		if (damagedAreas != null) for (Bounds b : damagedAreas) invalidate(b);
 	}
 
@@ -2787,6 +3005,7 @@
 	 * @param damagedAreas
 	 */
-	protected final void invalidate(Rectangle damagedArea) {
-		FrameGraphics.invalidateItem(this, damagedArea);
+	protected final void invalidate(Bounds damagedArea)
+	{
+		if (damagedArea != null) DisplayController.invalidateItem(this, damagedArea);
 	}
 
@@ -2796,9 +3015,9 @@
 	 * @param trait
 	 */
-	public final void invalidateCommonTrait(ItemAppearence trait) {
+	public final void invalidateCommonTrait(ItemAppearence trait)
+	{
 		invalidate(getDamagedArea(trait));
 
-		if (_colorFill != null
-				&& (trait == ItemAppearence.Added || trait == ItemAppearence.Removed)) {
+		if (_fillColour != null && (trait == ItemAppearence.Added || trait == ItemAppearence.Removed)) {
 			invalidateFill();
 		}
@@ -2808,7 +3027,8 @@
 	 * Invalidates fill if has one, even if no color is set.
 	 */
-	public void invalidateFill() {
+	public void invalidateFill()
+	{
 		if (isLineEnd() && _enclosure != null) {
-			invalidate(getEnclosedShape().getBounds());
+			invalidate(getEnclosedBox());
 		}
 	}
@@ -2826,13 +3046,10 @@
 	 * @return The damaged area according to the visual trait that has changed.
 	 */
-	protected Rectangle[] getDamagedArea(ItemAppearence trait) {
-
+	protected AxisAlignedBoxBounds getDamagedArea(ItemAppearence trait)
+	{
 		if (trait == ItemAppearence.LinkChanged)
-			return new Rectangle[] { getLinkDrawArea() }; // Invalidate area
-		// where link is
-		// drawn
+			return getLinkDrawArea(); // Invalidate area where link is drawn
 
 		return getDrawingArea();
-
 	}
 
@@ -2864,7 +3081,7 @@
 	}
 
-	public void setAnchorLeft(Float anchor) {
-		this._anchorLeft = anchor;
-		this._anchorRight = null;
+	public void setAnchorLeft(Integer anchor)
+	{
+		this._anchoring.setLeftAnchor(anchor);
 		if (anchor != null) {
 			anchorConstraints();
@@ -2873,17 +3090,16 @@
 	}
 
-	public void setAnchorRight(Float anchor) {
-		this._anchorRight = anchor;
-		this._anchorLeft = null;
+	public void setAnchorRight(Integer anchor)
+	{
+		this._anchoring.setRightAnchor(anchor);
 		if (anchor != null) {
 			anchorConstraints();
-			setX(FrameGraphics.getMaxFrameSize().width - anchor
-					- getBoundsWidth());
-		}
-	}
-
-	public void setAnchorTop(Float anchor) {
-		this._anchorTop = anchor;
-		this._anchorBottom = null;
+			setX(DisplayController.getFramePaintArea().getMaxX() - anchor - getBoundsWidth());
+		}
+	}
+
+	public void setAnchorTop(Integer anchor)
+	{
+		this._anchoring.setTopAnchor(anchor);
 		if (anchor != null) {
 			anchorConstraints();
@@ -2893,41 +3109,40 @@
 
 
-	public void setAnchorBottom(Float anchor) {
-		this._anchorBottom = anchor;
-		this._anchorTop = null;
+	public void setAnchorBottom(Integer anchor)
+	{
+		this._anchoring.setBottomAnchor(anchor);
 		if (anchor != null) {
 			anchorConstraints();
-			setY(FrameGraphics.getMaxFrameSize().height - anchor);
-		}
-	}
-
-
-	public boolean isAnchored() {
-	    return ((_anchorLeft != null) || (_anchorRight != null) 
-		    || (_anchorTop != null) || (_anchorBottom != null));
+			setY(DisplayController.getFramePaintArea().getMaxY() - anchor);
+		}
+	}
+
+	public boolean isAnchored()
+	{
+	    return _anchoring.isAnchored();
 	}
 
 	public boolean isAnchoredX() {
-	    return ((_anchorLeft != null) || (_anchorRight != null));
+	    return _anchoring.isXAnchored();
 	}
 
 	public boolean isAnchoredY() {
-	    return ((_anchorTop != null) || (_anchorBottom != null));
-	}
-
-	public Float getAnchorLeft() {
-		return _anchorLeft;
-	}
-
-	public Float getAnchorRight() {
-		return _anchorRight;
-	}
-
-	public Float getAnchorTop() {
-		return _anchorTop;
-	}
-
-	public Float getAnchorBottom() {
-		return _anchorBottom;
+	    return _anchoring.isYAnchored();
+	}
+
+	public Integer getAnchorLeft() {
+		return _anchoring.getLeftAnchor();
+	}
+
+	public Integer getAnchorRight() {
+		return _anchoring.getRightAnchor();
+	}
+
+	public Integer getAnchorTop() {
+		return _anchoring.getTopAnchor();
+	}
+
+	public Integer getAnchorBottom() {
+		return _anchoring.getBottomAnchor();
 	}
 
@@ -3024,10 +3239,9 @@
 		// Invalidate them again!!
 		for (Item i : this.getAllConnected()) {
-			i.updatePolygon();
+			i.invalidateBounds();
 			i.invalidateAll();
 		}
 	}
 
-	
 	protected void anchorConnected(AnchorEdgeType anchorEdgeType, Float delta) {
 		
@@ -3087,5 +3301,5 @@
 		// Invalidate them again!!
 		for (Item i : this.getAllConnected()) {
-			i.updatePolygon();
+			i.invalidateBounds();
 			i.invalidateAll();
 		}
@@ -3123,5 +3337,5 @@
 		// DONT PUT SIZE IN HERE CAUSE IT STUFFS UP CIRCLES
 
-		updatePolygon();
+		invalidateBounds();
 	}
 
@@ -3168,29 +3382,4 @@
 		return _autoStamp != null && _autoStamp >= 0.0;
 	}
-
-	public void setDotType(DotType type) {
-		invalidateAll();
-		_type = type;
-		invalidateAll();
-	}
-
-	public DotType getDotType() {
-		return _type;
-	}
-
-	public void setFilled(boolean filled) {
-		invalidateAll();
-		_filled = filled;
-		invalidateAll();
-	}
-
-	public boolean getFilled() {
-		return _filled;
-	}
-		
-	private Item _magnetizedItemLeft = null;
-	private Item _magnetizedItemRight = null;
-	private Item _magnetizedItemTop = null;
-	private Item _magnetizedItemBottom = null;
 	
 	public int getMagnetizedItemLeft() {
@@ -3245,3 +3434,54 @@
 		setMagnetizedItemBottom(this.getParent().getItemWithID(id));
 	}
+
+	/**
+	 * Replaces the given dot item with a text item displaying the given character.
+	 * 
+	 * @param dot
+	 * 		The Dot item to replace.
+	 * 
+	 * @param ch
+	 * 		The character to display as the text for the created Text item.
+	 * 
+	 * @return
+	 * 		The created Text item.
+	 */
+	public static Text replaceDot(Item dot, char ch) {
+		// TODO: Should this make sure 'dot' is actually a Dot and not some other item? cts16
+		Text text = Text.createText(ch);
+		Item.DuplicateItem(dot, text);
+		FrameUtils.setLastEdited(text);
+
+		// Copy the lines list so it can be modified
+		List<Line> lines = new LinkedList<Line>(dot.getLines());
+		for (Line line : lines)
+			line.replaceLineEnd(dot, text);
+		Frame current = dot.getParentOrCurrentFrame();
+		current.removeItem(dot);
+		ItemUtils.EnclosedCheck(current.getItems());
+		return text;
+		// TODO: Should this add the newly-created Text item to the frame? cts16
+	}
+
+	/**
+	 * Replaces the given text item with a dot
+	 */
+	public static Item replaceText(Item text) {
+		Item dot = new Dot(text.getX(), text.getY(), text.getID());
+		Item.DuplicateItem(text, dot);
+
+		List<Line> lines = new LinkedList<Line>();
+		lines.addAll(text.getLines());
+		if (lines.size() > 0)
+			dot.setColor(lines.get(0).getColor());
+		for (Line line : lines) {
+			line.replaceLineEnd(text, dot);
+		}
+		text.delete();
+		Frame current = text.getParentOrCurrentFrame();
+		current.addItem(dot);
+		DisplayController.setCursor(Item.DEFAULT_CURSOR);
+		ItemUtils.EnclosedCheck(current.getItems());
+		return dot;
+	}
 }
Index: /trunk/src/org/expeditee/items/ItemAppearence.java
===================================================================
--- /trunk/src/org/expeditee/items/ItemAppearence.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/ItemAppearence.java	(revision 1102)
@@ -20,5 +20,5 @@
 
 /**
- * Used for invlaidation on items.
+ * Used for invalidation on items.
  * @author Brook Novak
  */
@@ -37,4 +37,6 @@
 	Removed,
 	ToggleDashed,
-	Thickness, GradientColor, BorderColorChanged
+	Thickness,
+	GradientColor,
+	BorderColorChanged
 }
Index: /trunk/src/org/expeditee/items/ItemUtils.java
===================================================================
--- /trunk/src/org/expeditee/items/ItemUtils.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/ItemUtils.java	(revision 1102)
@@ -19,7 +19,4 @@
 package org.expeditee.items;
 
-import java.awt.Color;
-import java.awt.Rectangle;
-import java.awt.image.ImageObserver;
 import java.io.File;
 import java.io.UnsupportedEncodingException;
@@ -34,5 +31,8 @@
 import java.util.Map;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.DisplayController.TwinFramesSide;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameUtils;
@@ -40,5 +40,5 @@
 import org.expeditee.gui.Vector;
 import org.expeditee.items.Item.HighlightMode;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
 import org.expeditee.items.widgets.InteractiveWidgetInitialisationFailedException;
 import org.expeditee.items.widgets.InteractiveWidgetNotAvailableException;
@@ -360,9 +360,9 @@
 	 * 
 	 * @param source
-	 *            The Text file containing the Picture infomation
+	 *            The Text file containing the Picture information
 	 * @return The Picture object representing the file, or Null if the file is
 	 *         not found.
 	 */
-	public static Picture CreatePicture(Text source, ImageObserver observer, boolean tryRemote) {
+	public static Picture CreatePicture(Text source, boolean tryRemote) {
 		String text = source.getText();
 		String path = "";
@@ -424,5 +424,5 @@
        				// call CreatePicture again, but with tryRemote set to false so we won't get into an infinite loop
        				// if something goes wrong with finding the downloaded image
-       				return CreatePicture(source, observer, false);
+       				return CreatePicture(source, false);
        			}
 				return null;
@@ -434,5 +434,5 @@
 
 		try {
-			Picture pic = new Picture(source, fileName, path, size, observer);
+			Picture pic = new Picture(source, fileName, path, size);
 
 			return pic;
@@ -444,6 +444,6 @@
 	}
 	
-	public static Picture CreatePicture(Text source, ImageObserver observer) {
-		return CreatePicture(source, observer, true);
+	public static Picture CreatePicture(Text source) {
+		return CreatePicture(source, true);
 	}
 
@@ -483,5 +483,5 @@
 
 		// Widgets are super special
-		List<InteractiveWidget> widgets = new ArrayList<InteractiveWidget>();
+		List<Widget> widgets = new ArrayList<Widget>();
 
 		for (Item i : toCopy) {
@@ -596,5 +596,5 @@
 			Item start = lineEndMap.get(c.getStart());
 			Item end = lineEndMap.get(c.getEnd());
-			int id = DisplayIO.getCurrentFrame().getNextItemID();
+			int id = DisplayController.getCurrentFrame().getNextItemID();
 			if (start != null && end != null) {
 				new Constraint(start, end, id, c.getType());
@@ -603,8 +603,8 @@
 
 		// BROOK
-		for (InteractiveWidget iw : widgets) {
+		for (Widget iw : widgets) {
 			try {
 
-				InteractiveWidget icopy = iw.copy();
+				Widget icopy = iw.copy();
 				copies.addAll(icopy.getItems());
 
@@ -680,4 +680,5 @@
 		Item copy = origEnd.copy();
 		origEnd.setHighlightMode(HighlightMode.None);
+		origEnd.setHighlightColorToDefault();
 		copy.removeAllLines();
 		copy.removeAllConstraints();
@@ -688,5 +689,5 @@
 
 		// create a new line
-		Frame currentFrame = DisplayIO.getCurrentFrame();
+		Frame currentFrame = DisplayController.getCurrentFrame();
 		Line line = new Line(origEnd, copy, currentFrame.getNextItemID());
 		// if the previous line was constrained then make the new line
@@ -694,6 +695,5 @@
 		// TODO add later a diagonal constraint if getLines() == 3 or 4
 		Collection<Constraint> constraints = origEnd.getConstraints();
-		if (constrain && constraints.size() > 0
-				&& origEnd.getLines().size() == 2) {
+		if (constrain && constraints.size() > 0 && origEnd.getLines().size() == 2) {
 			Integer type = null;
 			for (Constraint c : constraints) {
@@ -710,6 +710,5 @@
 			}
 			if (type != null) {
-				new Constraint(origEnd, copy, currentFrame.getNextItemID(),
-						type);
+				new Constraint(origEnd, copy, currentFrame.getNextItemID(), type);
 			}
 		}
@@ -726,9 +725,9 @@
 
 	public static void New() {
-		EnclosedCheck(DisplayIO.getCurrentFrame().getItems());
+		EnclosedCheck(DisplayController.getCurrentFrame().getItems());
 	}
 
 	public static void Old() {
-		OldEnclosedCheck(DisplayIO.getCurrentFrame().getItems());
+		OldEnclosedCheck(DisplayController.getCurrentFrame().getItems());
 	}
 
@@ -902,12 +901,12 @@
 	 */
 	public static boolean isVisible(Item i) {
-		if (DisplayIO.isTwinFramesOn()) {
-			if (!isVisible(DisplayIO.getFrames()[0], i)) {
-				return isVisible(DisplayIO.getFrames()[1], i);
+		if (DisplayController.isTwinFramesOn()) {
+			if (!isVisible(DisplayController.getFrameOnSide(TwinFramesSide.LEFT), i)) {
+				return isVisible(DisplayController.getFrameOnSide(TwinFramesSide.RIGHT), i);
 			} else {
 				return true;
 			}
 		} else {
-			return isVisible(DisplayIO.getCurrentFrame(), i);
+			return isVisible(DisplayController.getCurrentFrame(), i);
 		}
 	}
@@ -923,23 +922,24 @@
 	 * @return True if visible/free from given frame.
 	 */
-	public static boolean isVisible(Frame fromFrame, Item i) {
-		if (fromFrame == null)
-			return false;
+	public static boolean isVisible(Frame fromFrame, Item i)
+	{
+		if (fromFrame == null) return false;
 
 		Frame parent = i.getParent();
 
-		if (parent == fromFrame)
+		if (parent == fromFrame) {
 			return true;
+		} else if (parent == null) {
+			return FreeItems.getInstance().contains(i) || FreeItems.getCursor().contains(i);
+		}
 		
-		else if (parent == null)
-			return FreeItems.getInstance().contains(i)
-					|| FreeItems.getCursor().contains(i);
-
 		return fromFrame.getAllItems().contains(i) && i.isVisible();
 	}
 
-	public static Rectangle expandRectangle(Rectangle r, int n) {
-		return new Rectangle(r.x - (n >> 1), r.y - (n >> 1), r.width + n,
-				r.height + n);
+	public static AxisAlignedBoxBounds expandRectangle(AxisAlignedBoxBounds r, int n)
+	{
+		if (r == null) return null;
+		
+		return new AxisAlignedBoxBounds(r.getMinX() - (n >> 1), r.getMinY() - (n >> 1), r.getWidth() + n, r.getHeight() + n);
 	}
 
@@ -973,6 +973,6 @@
 		int originX = v.Origin.x;
 		int originY = v.Origin.y;
-		Color defaultForeground = v.Foreground;
-		Color defaultBackground = v.Background;
+		Colour defaultForeground = v.Foreground;
+		Colour defaultBackground = v.Background;
 		UserAppliedPermission permission = v.permission;
 		// TODO should this be checking if the frame has the
@@ -1014,8 +1014,8 @@
 	 * @return List of (unique)widgets in items. Never null.
 	 */
-	public static List<InteractiveWidget> extractWidgets(List<Item> items) {
+	public static List<Widget> extractWidgets(List<Item> items) {
 		assert (items != null);
 
-		List<InteractiveWidget> iWidgets = new LinkedList<InteractiveWidget>();
+		List<Widget> iWidgets = new LinkedList<Widget>();
 
 		for (Item i : items) {
@@ -1053,5 +1053,7 @@
 	 * @param frame
 	 */
-	public static void Justify(Frame frame) {
+	public static void Justify(Frame frame)
+	{
+		if (frame == null) return;
 		EnclosedCheck(frame.getItems());
 		Justify(frame.getItems());
Index: /trunk/src/org/expeditee/items/JSItem.java
===================================================================
--- /trunk/src/org/expeditee/items/JSItem.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/JSItem.java	(revision 1102)
@@ -19,6 +19,4 @@
 package org.expeditee.items;
 
-import java.awt.Graphics2D;
-import java.awt.Polygon;
 import java.util.LinkedList;
 import java.util.List;
@@ -29,6 +27,7 @@
 import javax.script.ScriptException;
 
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.Util;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.gui.DisplayController;
 
 public class JSItem extends XRayable implements JSThreadable {
@@ -64,6 +63,6 @@
     
 	private static Text getSauce(int width, int height) {
-		Text source = new Text(DisplayIO.getCurrentFrame().getNextItemID(), "@js: " + width + " " + height);
-		source.setParent(DisplayIO.getCurrentFrame());
+		Text source = new Text(DisplayController.getCurrentFrame().getNextItemID(), "@js: " + width + " " + height);
+		source.setParent(DisplayController.getCurrentFrame());
 		return source;
 	}
@@ -115,7 +114,9 @@
 
 	@Override
-	public void paint(Graphics2D g) {
-		try {
-	        this.invocable.invokeFunction("paint", (Object)g);
+	public void paint(/*Graphics2D g*/) {
+		try {
+			// Not sure of the consequences of changing this? cts16
+	        //this.invocable.invokeFunction("paint", (Object)g);
+			this.invocable.invokeFunction("paint");
         } catch (Exception e) {
 	        e.printStackTrace();
@@ -130,10 +131,7 @@
 
 	@Override
-	public void updatePolygon() {
-		_poly = new Polygon();
-		_poly.addPoint(getX(), getY());
-		_poly.addPoint(getX() + _width, getY());
-		_poly.addPoint(getX() + _width, getY() + _height);
-		_poly.addPoint(getX(), getY() + _height);
+	public AxisAlignedBoxBounds updateBounds()
+	{
+		return new AxisAlignedBoxBounds(getX(), getY(), _width, _height);
 	}
 	
@@ -158,5 +156,5 @@
 			return;
 		}
-		String[] args = InteractiveWidget.parseArgs(text.substring(index));
+		String[] args = Util.parseArgs(text.substring(index));
 		try {
 			this.scriptEngine.eval("load = " + this.load);
@@ -189,5 +187,5 @@
 		newText.append(_width).append(" ").append(_height);
 		
-		String stateArgs = InteractiveWidget.formatArgs(saveArgs());
+		String stateArgs = Util.formatArgs(saveArgs());
 		if (stateArgs != null) {
 			newText.append(':');
@@ -239,3 +237,9 @@
 	}
 
+	@Override
+	public float getSize() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
 }
Index: /trunk/src/org/expeditee/items/Line.java
===================================================================
--- /trunk/src/org/expeditee/items/Line.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/Line.java	(revision 1102)
@@ -19,15 +19,4 @@
 package org.expeditee.items;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -37,5 +26,15 @@
 import java.util.List;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.Fill;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.CombinationBoxBounds;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
@@ -59,8 +58,7 @@
 
 	
-	public static Polygon createArrowheadPolygon(double x0, double y0, float arrowLength0, double arrowRatio0, double arrowNibPerc0) 
+	public static PolygonBounds createArrowheadPolygon(double x0, double y0, float arrowLength0, double arrowRatio0, double arrowNibPerc0) 
 	{
-		
-		Polygon arrowhead = new Polygon();
+		PolygonBounds arrowhead = new PolygonBounds();
 	    
 		int ix0 = (int)Math.round(x0);
@@ -73,12 +71,9 @@
 		int flange_iy_left = (int) Math.round((y0 - flange_y_width));
 		int flange_iy_right = (int) Math.round((y0 + flange_y_width));
-				
-		
-		arrowhead.addPoint(ix0, iy0);
-		arrowhead.addPoint(flange_ix_project, flange_iy_left);
-		
-		arrowhead.addPoint(ix_nib, iy0);
-		
-		arrowhead.addPoint(flange_ix_project, flange_iy_right);
+		
+		arrowhead.addPoint(new Point(ix0, iy0));
+		arrowhead.addPoint(new Point(flange_ix_project, flange_iy_left));
+		arrowhead.addPoint(new Point(ix_nib, iy0));
+		arrowhead.addPoint(new Point(flange_ix_project, flange_iy_right));
 		
 		return arrowhead;
@@ -95,5 +90,5 @@
 
 	// brush strokes used for painting this line and highlighting
-	private Stroke _lineStroke = new BasicStroke(DEFAULT_THICKNESS, CAP, JOIN, 4.0F);
+	private Stroke _lineStroke = new Stroke(DEFAULT_THICKNESS, DEFAULT_CAP, DEFAULT_JOIN);
 
 	Stroke getStroke() {
@@ -143,12 +138,10 @@
 			for (int i = 0; i < pattern.length; i++)
 				dash[i] = (float) pattern[i];
-			_lineStroke = new BasicStroke(Math.max(thick,
-					MINIMUM_PAINT_THICKNESS), CAP, JOIN, 10f, dash, 0.0f);
+			_lineStroke = new Stroke(Math.max(thick, MINIMUM_PAINT_THICKNESS), DEFAULT_CAP, DEFAULT_JOIN, dash, 0.0f);
 		} else {
-			_lineStroke = new BasicStroke(Math.max(thick,
-					MINIMUM_PAINT_THICKNESS), CAP, JOIN);
-		}
-
-		updatePolygon();
+			_lineStroke = new Stroke(Math.max(thick, MINIMUM_PAINT_THICKNESS), DEFAULT_CAP, DEFAULT_JOIN);
+		}
+
+		invalidateBounds();
 	}
 
@@ -240,5 +233,5 @@
 			_start = start;
 			_start.addLine(this);
-			updatePolygon();
+			invalidateBounds();
 		}
 	}
@@ -258,5 +251,5 @@
 			_end = end;
 			_end.addLine(this);
-			updatePolygon();
+			invalidateBounds();
 		}
 	}
@@ -317,9 +310,7 @@
 			for (int i = 0; i < pattern.length; i++)
 				dash[i] = (float) pattern[i];
-			_lineStroke = new BasicStroke(Math.max(thick, MINIMUM_THICKNESS),
-					CAP, JOIN, 10f, dash, 0.0f);
+			_lineStroke = new Stroke(Math.max(thick, MINIMUM_THICKNESS), DEFAULT_CAP, DEFAULT_JOIN, dash, 0.0f);
 		} else
-			_lineStroke = new BasicStroke(Math.max(thick, MINIMUM_THICKNESS),
-					CAP, JOIN);
+			_lineStroke = new Stroke(Math.max(thick, MINIMUM_THICKNESS), DEFAULT_CAP, DEFAULT_JOIN);
 
 		if (_start.getLinePattern() != pattern)
@@ -333,36 +324,25 @@
 
 	@Override
-	public void paint(Graphics2D g) {
-		if (!isVisible())
-			return;
-
-		// Dont paint lines with thickness 0 if they are the border on a filled
-		// shape
-		if (dontPaint())
-			return;
-
-		g.setColor(getPaintColor());
+	public void paint()
+	{
+		if (!isVisible()) return;
+
+		// Dont paint lines with thickness 0 if they are the border on a filled shape
+		if (dontPaint()) return;
 
 		// if (this._mode == Item.SelectedMode.Disconnect)
 		// System.out.println("Disconnect mode!");
-		g.setStroke(_lineStroke);
 		// Get a path of points
-		int[][][] paths = getPaths();
-		for (int i = 0; i < paths.length; i++) {
-			int[][] path = paths[i];
-			int last = path[0].length - 1;
-			if (path[0][0] == path[0][last] && path[1][0] == path[1][last]) {
-				g.drawPolygon(path[0], path[1], last);
-			} else {
-				g.drawPolyline(path[0], path[1], last + 1);
-			}
-		}
+		PolygonBounds[] paths = getPaths();
+		for (PolygonBounds path : paths) {
+			EcosystemManager.getGraphicsManager().drawPolygon(path, null, null, 0.0f, null, getPaintColor(), _lineStroke);
+		}
+		
 		// paint the arrowhead (if necessary)
-		paintArrows(g);
-
-		if (showLineHighlight() && isHighlighted()) {
-			g.setColor(getHighlightColor());
-			g.setStroke(HIGHLIGHT_STROKE);
-			((Graphics2D) g).draw(this.getArea());
+		paintArrows();
+
+		if (shouldShowLineHighlight() && isHighlighted()) {
+			PolygonBounds poly = (PolygonBounds) getBounds();
+			EcosystemManager.getGraphicsManager().drawPolygon(poly, null, null, 0.0f, null, getHighlightColor(), HIGHLIGHT_STROKE);
 		}
 	}
@@ -371,8 +351,8 @@
 		// enable invisible shapes (for web browser divs) only when XRayMode is off
 		return getThickness() <= 0 && _start.isEnclosed()
-				&& (_start.getFillColor() != null || !FrameGraphics.isXRayMode());
-	}
-
-	protected int[][][] getPaths() {
+				&& (_start.getFillColor() != null || !DisplayController.isXRayMode());
+	}
+
+	protected PolygonBounds[] getPaths() {
 		List<List<Point>> pointPaths = new LinkedList<List<Point>>();
 		Collection<Line> visited = new HashSet<Line>();
@@ -388,22 +368,22 @@
 		}
 		// Put the paths into int arrays
-		int[][][] paths = new int[pointPaths.size()][][];
+		PolygonBounds[] paths = new PolygonBounds[pointPaths.size()];
 		Iterator<List<Point>> iter = pointPaths.iterator();
 
 		for (int i = 0; i < paths.length; i++) {
 			List<Point> pointPath = iter.next();
-			int[][] path = new int[2][pointPath.size()];
+			PolygonBounds path = new PolygonBounds();
 			paths[i] = path;
 			// Add all the x and y's to the array
-			for (int j = 0; j < path[0].length; j++) {
-				path[0][j] = pointPath.get(j).x;
-				path[1][j] = pointPath.get(j).y;
-			}
-		}
+			for (int j = 0; j < pointPath.size(); j++) {
+				path.addPoint(pointPath.get(j).x, pointPath.get(j).y);
+			}
+		}
+		
 		return paths;
 	}
 
-	protected List<Point> getPath(Collection<Line> visited,
-			LinkedList<Line> toExplore) {
+	protected List<Point> getPath(Collection<Line> visited, LinkedList<Line> toExplore)
+	{
 		LinkedList<Point> points = new LinkedList<Point>();
 		// put the start item points into our list
@@ -417,16 +397,14 @@
 	}
 
-	public void paintArrows(Graphics2D g) {
-		if (dontPaint())
-			return;
-
-		g.setColor(getPaintColor());
-		g.setStroke(new BasicStroke(getPaintThickness(), CAP,
-				BasicStroke.JOIN_MITER));
-		paintArrow(g, getStartArrow());
-		paintArrow(g, getEndArrow());
-
+	public void paintArrows()
+	{
+		if (dontPaint()) return;
+
+		paintArrow(getStartArrow());
+		paintArrow(getEndArrow());
+
+		// TODO: What is a virtual spot? cts16
 		if (_virtualSpot != null) {
-			_virtualSpot.paint(g);
+			_virtualSpot.paint();
 			invalidateVirtualSpot();
 			_virtualSpot = null;
@@ -456,11 +434,15 @@
 	 * @return
 	 */
-	private Shape getArrow(Item withArrow, Point startOffset, Point endOffset) {
-		boolean disconnectMode = withArrow._mode == Item.HighlightMode.Disconnect;
+	private PolygonBounds getArrow(Item withArrow, Point startOffset, Point endOffset)
+	{
+		boolean disconnectMode = withArrow._highlightMode == Item.HighlightMode.Disconnect;
+		
 		// only draw an arrowhead if necessary
-		if (!(this._mode == Item.HighlightMode.Disconnect && disconnectMode)
-				&& (!withArrow.hasVisibleArrow() || withArrow.getLines().size() > 1))
+		if (	!(this._highlightMode == Item.HighlightMode.Disconnect && disconnectMode) &&
+				(!withArrow.hasVisibleArrow() || withArrow.getLines().size() > 1))
+		{
 			return null;
-
+		}
+		
 		int x0, x1, y0, y1;
 
@@ -475,5 +457,5 @@
 		
 		// set the size of the disconnect indicator arrowhead
-		if (this._mode == Item.HighlightMode.Disconnect) {
+		if (this._highlightMode == Item.HighlightMode.Disconnect) {
 			arrowLength  = 15;
 			arrowRatio   = 0.3;
@@ -494,6 +476,6 @@
 		// The length of the line must at least be as long as the arrow or we
 		// wont show the arrow
-		if (length <= MINIMUM_ARROW_HEAD_LENGTH)
-			return null;
+		if (length <= MINIMUM_ARROW_HEAD_LENGTH) return null;
+		
 		if (arrowLength == AUTO_ARROWHEAD_LENGTH) {
 			arrowLength = getAutoArrowheadLength(length);
@@ -508,35 +490,25 @@
 
 		// only calculate the arrowhead polygon if necessary
-		Polygon arrowhead = withArrow.getArrowhead();
+		PolygonBounds arrowhead = withArrow.getArrowhead();
 		if (arrowhead == null || disconnectMode) {
-			arrowhead = createArrowheadPolygon(x0,y0,arrowLength,arrowRatio,arrowNibPerc); 
+			arrowhead = createArrowheadPolygon(x0, y0, arrowLength, arrowRatio, arrowNibPerc); 
 			
 			if (!disconnectMode)
-				withArrow.setArrowhead(arrowhead);
-		}
+				withArrow.setArrowhead(new PolygonBounds(arrowhead));
+		}
+		arrowhead = arrowhead.clone();
 		double rad = calcAngle((float) x0, (float) y0, (float) x1, (float) y1);
-		arrowhead.translate((x0 + length) - arrowhead.xpoints[0], y0
-				- arrowhead.ypoints[0]);
-		AffineTransform tx = AffineTransform.getRotateInstance(rad, x0, y0);
-		
-        int[] rx = new int[arrowhead.npoints];
-        int[] ry = new int[arrowhead.npoints];
-        
-        for(int i = 0; i < arrowhead.npoints; i++){
-            Point2D p = new Point2D.Double(arrowhead.xpoints[i], arrowhead.ypoints[i]);
-            tx.transform(p,p);
-            rx[i] = (int) p.getX();
-            ry[i] = (int) p.getY();
-        }
-        
-        return new Polygon(rx, ry, arrowhead.npoints);
+		arrowhead.translate((x0 + length) - arrowhead.toArray()[0].x, y0 - arrowhead.toArray()[0].y);
+		arrowhead.rotate(rad, x0, y0);
+		
+		return arrowhead;
 	}
 	
-	public Polygon getStartArrow() {
-		return (Polygon) getArrow(_start, _startOffset, _endOffset);
+	public PolygonBounds getStartArrow() {
+		return getArrow(_start, _startOffset, _endOffset);
 	}
 	
-	public Polygon getEndArrow() {
-		return (Polygon) getArrow(_end, _endOffset, _startOffset);
+	public PolygonBounds getEndArrow() {
+		return getArrow(_end, _endOffset, _startOffset);
 	}
 
@@ -544,5 +516,9 @@
 	 * Based on code from DeSL (Arrow2D) http://sourceforge.net/projects/desl/
 	 */
-	private void paintArrow(Graphics2D g, Shape arrow) {
+	private void paintArrow(PolygonBounds arrow)
+	{
+		Colour arrowColour = getPaintColor();
+		Fill arrowFill = new Fill(arrowColour);
+		Stroke arrowStroke = new Stroke(getPaintThickness(), DEFAULT_CAP, Stroke.JOIN.MITER);
 		
 		if(arrow == null) {
@@ -557,8 +533,8 @@
 		// ****
 		
-		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-		
-		g.draw(arrow);
-		g.fill(arrow);
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		
+		g.setAntialiasing(true);
+		g.drawPolygon(arrow.close(), null, null, 0.0f, arrowFill, arrowColour, arrowStroke);
 	
 	}
@@ -630,4 +606,9 @@
 		return temp;
 	}
+	
+	public Item getEndPointToDisconnect(Point p)
+	{
+		return getEndPointToDisconnect(p.x, p.y);
+	}
 
 	public Item getEndPointToDisconnect(int x, int y) {
@@ -653,21 +634,21 @@
 
 		if (distStart < NORMAL_THRESHHOLD) {
-			start._mode = Item.HighlightMode.Normal;
+			start._highlightMode = Item.HighlightMode.Normal;
 			return start;
 		} else if (distEnd < NORMAL_THRESHHOLD) {
-			end._mode = Item.HighlightMode.Normal;
+			end._highlightMode = Item.HighlightMode.Normal;
 			return end;
 		} else if (distStart < DISCONNECT_THRESHHOLD) {
 			if (start.getLines().size() > 1
 					|| start.getConstraints().size() > 0)
-				start._mode = Item.HighlightMode.Disconnect;
+				start._highlightMode = Item.HighlightMode.Disconnect;
 			else
-				start._mode = Item.HighlightMode.Normal;
+				start._highlightMode = Item.HighlightMode.Normal;
 			return start;
 		} else if (distEnd < DISCONNECT_THRESHHOLD) {
 			if (end.getLines().size() > 1 || end.getConstraints().size() > 0)
-				end._mode = Item.HighlightMode.Disconnect;
+				end._highlightMode = Item.HighlightMode.Disconnect;
 			else
-				end._mode = Item.HighlightMode.Normal;
+				end._highlightMode = Item.HighlightMode.Normal;
 			return end;
 		}
@@ -677,8 +658,8 @@
 
 	@Override
-	public int setHighlightColor() {
-		super.setHighlightColor();
-
-		return Item.UNCHANGED_CURSOR;
+	public void setHighlightColorToDefault() {
+		super.setHighlightColorToDefault();
+
+		//return Item.UNCHANGED_CURSOR;
 	}
 
@@ -690,5 +671,5 @@
 	 */
 	@Override
-	public void setColor(Color c) {
+	public void setColor(Colour c) {
 		super.setColor(c);
 
@@ -698,5 +679,5 @@
 
 	@Override
-	public Color getFillColor() {
+	public Colour getFillColor() {
 		return _start.getFillColor();
 	}
@@ -882,24 +863,56 @@
 	private Item _virtualSpot = null;
 
-	public void showVirtualSpot(Item orig, int mouseX, int mouseY) {
-		if (orig.getLines().size() != 1)
-			return;
+	public void showVirtualSpot(Item orig, int mouseX, int mouseY)
+	{
+		if (orig.getLines().size() != 1) return;
 
 		// lines that are in 'connected' mode, also cannot be attached
-		if (orig.getLines().get(0).getOppositeEnd(orig).isFloating())
-			return;
+		if (orig.getLines().get(0).getOppositeEnd(orig).isFloating()) return;
 
 		Item spot = new Dot(-1, orig.getX(), orig.getY());
 		Item.DuplicateItem(orig, spot);
 		spot.setThickness(Math.max(this.getThickness(), 5));
-		if (this.getColor() != Color.RED)
-			spot.setColor(Color.RED);
-		else
-			spot.setColor(Color.BLUE);
-
+		if (!this.getColor().equals(Colour.RED)) {
+			spot.setColor(Colour.RED);
+		} else {
+			spot.setColor(Colour.BLUE);
+		}
+		
 		// unhighlight all the dots
 		for (Item conn : getAllConnected()) {
 			conn.setHighlightMode(Item.HighlightMode.None);
-		}
+			conn.setHighlightColorToDefault();
+		}
+
+		// calculate nearest point on line from spot
+		org.expeditee.core.Line line = new org.expeditee.core.Line(_start.getPosition(), _end.getPosition());
+		Point nearest = line.getPointNearestTo(spot.getPosition());
+
+		// position spot on the line
+		spot.setPosition(nearest);
+		_virtualSpot = spot;
+		invalidateVirtualSpot();
+	}
+
+	public void showVirtualSpot(int mouseX, int mouseY) {
+		Item spot = new Dot(mouseX, mouseY, -1);
+		spot.setThickness(Math.max(this.getThickness(), 5));
+		if (DEFAULT_HIGHLIGHT.equals(this.getColor()))
+			spot.setColor(ALTERNATE_HIGHLIGHT);
+		else
+			spot.setColor(DEFAULT_HIGHLIGHT);
+
+
+		// calculate nearest point on line from spot
+		org.expeditee.core.Line line = new org.expeditee.core.Line(_start.getPosition(), _end.getPosition());
+		Point nearest = line.getPointNearestTo(spot.getPosition());
+
+		// position spot on the line
+		spot.setPosition(nearest);
+		_virtualSpot = spot;
+		invalidateVirtualSpot();
+	}
+
+	public Item forceMerge(Item spot, int mouseX, int mouseY) {
 
 		// calculate nearest point on line from spot
@@ -930,76 +943,4 @@
 		// position spot on the line
 		spot.setPosition((int) x, (int) y);
-		_virtualSpot = spot;
-		invalidateVirtualSpot();
-	}
-
-	public void showVirtualSpot(int mouseX, int mouseY) {
-		Item spot = new Dot(mouseX, mouseY, -1);
-		spot.setThickness(Math.max(this.getThickness(), 5));
-		if (DEFAULT_HIGHLIGHT.equals(this.getColor()))
-			spot.setColor(ALTERNATE_HIGHLIGHT);
-		else
-			spot.setColor(DEFAULT_HIGHLIGHT);
-
-		// calculate nearest point on line from spot
-		double slope1;
-		double slope2;
-		double x, y;
-
-		slope1 = (_start.getY() - _end.getY() * 1.0)
-				/ (_start.getX() - _end.getX());
-		slope2 = -1 / slope1;
-
-		// if the line is horizontal
-		if (slope1 == 0) {
-			x = spot.getX();
-			y = _start.getY();
-			// if the line is vertical
-		} else if (slope2 == 0) {
-			x = _start.getX();
-			y = spot.getY();
-			// otherwise, the line is sloped
-		} else {
-			x = (-1 * slope2 * spot.getX() + spot.getY() - _start.getY() + slope1
-					* _start.getX())
-					/ (slope1 - slope2);
-			y = slope1 * (x - _start.getX()) + _start.getY();
-		}
-
-		// position spot on the line
-		spot.setPosition((int) x, (int) y);
-		_virtualSpot = spot;
-		invalidateVirtualSpot();
-	}
-
-	public Item forceMerge(Item spot, int mouseX, int mouseY) {
-
-		// calculate nearest point on line from spot
-		double slope1;
-		double slope2;
-		double x, y;
-
-		slope1 = (_start.getY() - _end.getY() * 1.0)
-				/ (_start.getX() - _end.getX());
-		slope2 = -1 / slope1;
-
-		// if the line is horizontal
-		if (slope1 == 0) {
-			x = spot.getX();
-			y = _start.getY();
-			// if the line is vertical
-		} else if (slope2 == 0) {
-			x = _start.getX();
-			y = spot.getY();
-			// otherwise, the line is sloped
-		} else {
-			x = (-1 * slope2 * spot.getX() + spot.getY() - _start.getY() + slope1
-					* _start.getX())
-					/ (slope1 - slope2);
-			y = slope1 * (x - _start.getX()) + _start.getY();
-		}
-
-		// position spot on the line
-		spot.setPosition((int) x, (int) y);
 
 		// Keep constraints
@@ -1018,5 +959,5 @@
 		Line temp = copy();
 
-		Frame currentFrame = DisplayIO.getCurrentFrame();
+		Frame currentFrame = DisplayController.getCurrentFrame();
 		temp.setID(currentFrame.getNextItemID());
 		temp.setEndItem(_end);
@@ -1101,9 +1042,9 @@
 
 	@Override
-	public void updatePolygon() {
-		_poly = new Polygon();
-
-		Rectangle one;
-		Rectangle two;
+	public PolygonBounds updateBounds() {
+		PolygonBounds ret = new PolygonBounds();
+
+		AxisAlignedBoxBounds one;
+		AxisAlignedBoxBounds two;
 
 		/**
@@ -1121,12 +1062,12 @@
 			Item e = new Dot(_end.getX(), _end.getY(), -1);
 
-			one = s.getPolygon().getBounds();
-			two = e.getPolygon().getBounds();
+			one = AxisAlignedBoxBounds.getEnclosing(s.getBounds());
+			two = AxisAlignedBoxBounds.getEnclosing(e.getBounds());
 		} else {
 			Item s = new Dot(_start.getX(), _start.getY(), -1);
 			Item e = new Dot(_end.getX(), _end.getY(), -1);
 
-			one = e.getPolygon().getBounds();
-			two = s.getPolygon().getBounds();
+			one = AxisAlignedBoxBounds.getEnclosing(e.getBounds());
+			two = AxisAlignedBoxBounds.getEnclosing(s.getBounds());
 			/*
 			 * one = _end.getPolygon().getBounds(); two =
@@ -1136,17 +1077,18 @@
 
 		// if one is above two
-		if (one.getY() < two.getY()) {
-			_poly.addPoint((int) one.getMaxX(), (int) one.getMinY());
-			_poly.addPoint((int) two.getMaxX(), (int) two.getMinY());
-			_poly.addPoint((int) two.getMinX(), (int) two.getMaxY());
-			_poly.addPoint((int) one.getMinX(), (int) one.getMaxY());
+		if (one.getMinY() < two.getMinY()) {
+			ret.addPoint(one.getMaxX(), one.getMinY());
+			ret.addPoint(two.getMaxX(), two.getMinY());
+			ret.addPoint(two.getMinX(), two.getMaxY());
+			ret.addPoint(one.getMinX(), one.getMaxY());
 			// if one is below two
 		} else {
-			_poly.addPoint((int) one.getMinX(), (int) one.getMinY());
-			_poly.addPoint((int) two.getMinX(), (int) two.getMinY());
-			_poly.addPoint((int) two.getMaxX(), (int) two.getMaxY());
-			_poly.addPoint((int) one.getMaxX(), (int) one.getMaxY());
-		}
-
+			ret.addPoint(one.getMinX(), one.getMinY());
+			ret.addPoint(two.getMinX(), two.getMinY());
+			ret.addPoint(two.getMaxX(), two.getMaxY());
+			ret.addPoint(one.getMaxX(), one.getMaxY());
+		}
+		
+		return ret.close();
 	}
 
@@ -1199,5 +1141,5 @@
 
 	public double getLength() {
-		return getLength(_start.getPosition(), _end.getPosition());
+		return Point.distanceBetween(_start.getPosition(), _end.getPosition());
 	}
 
@@ -1210,10 +1152,10 @@
 	}
 
-	public static double getLength(Point p1, Point p2) {
-		return Point.distance(p1.x, p1.y, p2.x, p2.y);
-	}
-
-	@Override
-	public Rectangle[] getDrawingArea() { // TODO: CACHE - LIKE UPDATE POLYGON
+/*	public static double getLength(Point p1, Point p2) {
+		return Point.distance(p1, p2);
+	}*/
+
+	@Override
+	public AxisAlignedBoxBounds getDrawingArea() { // TODO: CACHE - LIKE UPDATE POLYGON
 
 		float currentThickness = this.getThickness() + 4;
@@ -1236,5 +1178,5 @@
 		y -= halfThickness;
 
-		Rectangle bounds = new Rectangle(x, y, w, h);
+		AxisAlignedBoxBounds bounds = new AxisAlignedBoxBounds(x, y, w, h);
 
 		// TODO: Cap bounds
@@ -1257,5 +1199,5 @@
 			 overall as opposed to advanced/expensive calculations for getting exact
 			 bounding box */
-			Rectangle arrowBounds = new Rectangle(_end.getX() - nArrowLength,
+			AxisAlignedBoxBounds arrowBounds = new AxisAlignedBoxBounds(_end.getX() - nArrowLength,
 					_end.getY() - nArrowLength, 2 * nArrowLength,
 					2 * nArrowLength);
@@ -1263,12 +1205,12 @@
 			if (currentThickness > 0.0f) {
 
-				arrowBounds = new Rectangle(arrowBounds.x - halfThickness,
-						arrowBounds.y - halfThickness, arrowBounds.width
-								+ thickness, arrowBounds.height + thickness);
-			}
-
-			return new Rectangle[] { bounds, arrowBounds };
+				arrowBounds = new AxisAlignedBoxBounds(arrowBounds.getMinX() - halfThickness,
+						arrowBounds.getMinY() - halfThickness, arrowBounds.getWidth()
+								+ thickness, arrowBounds.getHeight() + thickness);
+			}
+
+			return bounds.combineWith(arrowBounds);
 		} else {
-			return new Rectangle[] { bounds };
+			return bounds;
 		}
 
@@ -1294,3 +1236,9 @@
 	public void scale(Float scale, int originX, int originY) {
 	}
+
+	@Override
+	public float getSize()
+	{
+		return getThickness();
+	}
 }
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/AttractTextAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/AttractTextAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/AttractTextAction.java	(revision 1102)
@@ -1,6 +1,5 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import java.awt.Point;
-
+import org.expeditee.core.Point;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.items.Item;
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/BackspaceAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/BackspaceAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/BackspaceAction.java	(revision 1102)
@@ -1,5 +1,5 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -15,17 +15,17 @@
 		if(item.getParent() == null || !this.isSpIDERCodePage(item.getParent())) return false;
 		if(item == null || ((Text) item).isEmpty()) {
-			final Text temp = DisplayIO.getCurrentFrame().createNewText(".");
+			final Text temp = DisplayController.getCurrentFrame().createNewText(".");
 			callback(temp);
 			if(temp.getMagnetizedItemLeft() != -1) 
-				DisplayIO.setTextCursor((Text) temp.getParent().getItemWithID(temp.getMagnetizedItemLeft()), Text.END);
+				DisplayController.setTextCursor((Text) temp.getParent().getItemWithID(temp.getMagnetizedItemLeft()), Text.END);
 			else if(temp.getMagnetizedItemTop() != -1) 
-				DisplayIO.setTextCursor((Text) temp.getParent().getItemWithID(temp.getMagnetizedItemTop()), Text.END);
+				DisplayController.setTextCursor((Text) temp.getParent().getItemWithID(temp.getMagnetizedItemTop()), Text.END);
 			temp.delete();
 			callback(temp);
 			return true;
-		} else if(item.getMagnetizedItemLeft() != -1 && TextLogic.XIsBeforeCharacters((Text) item, DisplayIO.getMouseX())) {
+		} else if(item.getMagnetizedItemLeft() != -1 && TextLogic.XIsBeforeCharacters((Text) item, DisplayController.getMouseX())) {
 			new LastItemAction().exec(item);
 			return true;
-		} else if(item.getMagnetizedItemTop() != -1 && TextLogic.XIsBeforeCharacters((Text) item, DisplayIO.getMouseX())) {
+		} else if(item.getMagnetizedItemTop() != -1 && TextLogic.XIsBeforeCharacters((Text) item, DisplayController.getMouseX())) {
 			callback(item);
 			final Line currentLine = Line.getLineFromToken(item);
@@ -33,5 +33,5 @@
 			if(lastLine != null && Paragraph.getParagraphFromLine(lastLine).contains(currentLine)) {
 				lastLine.appendLine(currentLine);
-				DisplayIO.setTextCursor((Text) item, Text.HOME);
+				DisplayController.setTextCursor((Text) item, Text.HOME);
 				callback(item);
 				return true;
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/DeleteAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/DeleteAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/DeleteAction.java	(revision 1102)
@@ -1,5 +1,5 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -15,17 +15,17 @@
 		if(item.getParent() == null || !this.isSpIDERCodePage(item.getParent())) return false;
 		if(item == null || ((Text) item).isEmpty()) {
-			final Text temp = DisplayIO.getCurrentFrame().createNewText(".");
+			final Text temp = DisplayController.getCurrentFrame().createNewText(".");
 			callback(temp);
 			if(temp.getMagnetizedItemRight() != -1) 
-				DisplayIO.setTextCursor((Text) temp.getParent().getItemWithID(temp.getMagnetizedItemRight()), Text.HOME);
+				DisplayController.setTextCursor((Text) temp.getParent().getItemWithID(temp.getMagnetizedItemRight()), Text.HOME);
 			else if(temp.getMagnetizedItemBottom() != -1) 
-				DisplayIO.setTextCursor((Text) temp.getParent().getItemWithID(temp.getMagnetizedItemBottom()), Text.HOME);
+				DisplayController.setTextCursor((Text) temp.getParent().getItemWithID(temp.getMagnetizedItemBottom()), Text.HOME);
 			temp.delete();
 			callback(temp);
 			return true;
-		} else if(item.getMagnetizedItemRight() != -1 && TextLogic.XIsAfterCharacters((Text) item, DisplayIO.getMouseX())) {
+		} else if(item.getMagnetizedItemRight() != -1 && TextLogic.XIsAfterCharacters((Text) item, DisplayController.getMouseX())) {
 			new NextItemAction().exec(item);
 			return true;
-		} else if(item.getMagnetizedItemBottom() != -1 && TextLogic.XIsAfterCharacters((Text) item, DisplayIO.getMouseX())) {
+		} else if(item.getMagnetizedItemBottom() != -1 && TextLogic.XIsAfterCharacters((Text) item, DisplayController.getMouseX())) {
 			callback(item);
 			final Line currentLine = Line.getLineFromToken(item);
@@ -33,5 +33,5 @@
 			if(nextLine != null && Paragraph.getParagraphFromLine(currentLine).contains(nextLine)) {
 				currentLine.appendLine(nextLine);
-				DisplayIO.setTextCursor((Text) item, Text.END);
+				DisplayController.setTextCursor((Text) item, Text.END);
 				callback(item);
 				return true;
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/DownALineAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/DownALineAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/DownALineAction.java	(revision 1102)
@@ -1,5 +1,5 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -19,5 +19,5 @@
 		final int nextLineLength = 
 				nextLine.get(nextLine.size() - 1).getX() + nextLine.get(nextLine.size() - 1).getBoundsWidth() - nextLine.get(0).getX();
-		final int distanceThroughCurrentLine = DisplayIO.getMouseX() - startOfThisLine.getX();
+		final int distanceThroughCurrentLine = DisplayController.getMouseX() - startOfThisLine.getX();
 		if(distanceThroughCurrentLine <= nextLineLength) {
 			Item beneith = nextLine.get(0);
@@ -43,6 +43,6 @@
 		if(toMoveTo instanceof Text) {
 			final Text asText = (Text) toMoveTo;
-			DisplayIO.setTextCursor(asText, Text.END);
-		} else DisplayIO.setCursorPosition(toMoveTo.getPosition(), false);
+			DisplayController.setTextCursor(asText, Text.END);
+		} else DisplayController.setCursorPosition(toMoveTo.getPosition(), false);
 		return true;
 	}
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/LastItemAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/LastItemAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/LastItemAction.java	(revision 1102)
@@ -1,5 +1,5 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameUtils;
@@ -44,10 +44,10 @@
 //			DisplayIO.setCursorPosition(position.x + asText.getPixelBoundsUnion().width, position.y, false);
 //			FrameGraphics.refresh(false);
-			DisplayIO.setTextCursor((Text)toMoveTo, Text.END);
+			DisplayController.setTextCursor((Text)toMoveTo, Text.END);
 			if(FrameUtils.getCurrentItem() != toMoveTo) {
 				Line.getLineFromToken(toMoveFrom).deltaX(1);
 				moveCursor(toMoveTo, toMoveFrom);
 			}
-		} else DisplayIO.setCursorPosition(toMoveTo.getPosition(), false);
+		} else DisplayController.setCursorPosition(toMoveTo.getPosition(), false);
 		return true;
 	}
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/NextItemAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/NextItemAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/NextItemAction.java	(revision 1102)
@@ -1,5 +1,5 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -34,5 +34,5 @@
 			return false;
 		//System.err.println("Next item requests move to item with text: " + toMoveTo.getText());
-		DisplayIO.setTextCursor((Text)toMoveTo, Text.HOME);
+		DisplayController.setTextCursor((Text)toMoveTo, Text.HOME);
 		return true;
 	}
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/RepelTextAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/RepelTextAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/RepelTextAction.java	(revision 1102)
@@ -1,7 +1,6 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import java.awt.Point;
-
-import org.expeditee.gui.Browser;
+import org.expeditee.core.Point;
+import org.expeditee.gio.EcosystemManager;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.items.Item;
@@ -45,5 +44,5 @@
 			return false;
 		} else {
-			final int charDistance = Browser._theBrowser.getFontMetrics(((Text)item).getFont()).stringWidth("X");
+			final int charDistance = EcosystemManager.getTextLayoutManager().getStringWidth(((Text)item).getFont(), "X");
 			final Line tokensToMove = Line.getLineFromToken(item);
 			tokensToMove.removeFirst();
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/RepelTextDownAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/RepelTextDownAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/RepelTextDownAction.java	(revision 1102)
@@ -1,7 +1,6 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import java.awt.Point;
-
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Point;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameIO;
 import org.expeditee.gui.FrameUtils;
@@ -28,5 +27,5 @@
 				(FrameUtils.getCurrentItem().getPosition().equals(item.getPosition()) 
 				&& remainderOfLine.size() > 0 
-				&& TextLogic.XIsTowardsRight(DisplayIO.getMouseX(), (Text) remainderOfLine.getFirst()))) {
+				&& TextLogic.XIsTowardsRight(DisplayController.getMouseX(), (Text) remainderOfLine.getFirst()))) {
 			remainderOfLine.removeFirst();
 		}
@@ -42,15 +41,15 @@
 		if(!remainderOfLine.isEmpty() && currentParagraph.contains(nextLine) && MergeSameLineParagraphCollisions) { 
 			nextLine.prependLine(remainderOfLine);
-			DisplayIO.setTextCursor((Text) remainderOfLine.getFirst(), Text.HOME);
+			DisplayController.setTextCursor((Text) remainderOfLine.getFirst(), Text.HOME);
 			callback(remainderOfLine.getFirst());
 			FrameIO.SaveFrame(remainderOfLine.getLast().getParent());
 		} else if(!remainderOfLine.isEmpty()) {
 			newLineAt = currentParagraph.split(currentLine);
-			final Point first = remainderOfLine.getBoundingBox().getLocation();
+			final Point first = remainderOfLine.getBoundingBox().getTopLeft();
 			for(final Item token : remainderOfLine) {
 				double newX = token.getX() - first.getX() + newLineAt.getX();
 				token.setPosition((float) newX, (float) newLineAt.getY());
 			}
-			DisplayIO.setTextCursor((Text) remainderOfLine.getFirst(), Text.HOME);
+			DisplayController.setTextCursor((Text) remainderOfLine.getFirst(), Text.HOME);
 			callback(remainderOfLine.getFirst());
 			FrameIO.SaveFrame(remainderOfLine.getLast().getParent());
@@ -58,5 +57,5 @@
 				//3a No. Move the cursor
 			newLineAt = currentParagraph.split(currentLine);
-			DisplayIO.setCursorPosition(newLineAt);
+			DisplayController.setCursorPosition(newLineAt);
 		}
 		
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/UpALineAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/UpALineAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/UpALineAction.java	(revision 1102)
@@ -1,5 +1,5 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
@@ -19,5 +19,5 @@
 		final int lastLineLength = 
 				lastLine.get(lastLine.size() - 1).getX() + lastLine.get(lastLine.size() - 1).getBoundsWidth() - lastLine.get(0).getX();
-		final int distanceThroughCurrentLine = DisplayIO.getMouseX() - startOfThisLine.getX();
+		final int distanceThroughCurrentLine = DisplayController.getMouseX() - startOfThisLine.getX();
 		if(distanceThroughCurrentLine <= lastLineLength) {
 			Item above = lastLine.get(0);
@@ -37,6 +37,6 @@
 		if(toMoveTo instanceof Text) {
 			final Text asText = (Text) toMoveTo;
-			DisplayIO.setTextCursor(asText, Text.END);
-		} else DisplayIO.setCursorPosition(toMoveTo.getPosition(), false);
+			DisplayController.setTextCursor(asText, Text.END);
+		} else DisplayController.setCursorPosition(toMoveTo.getPosition(), false);
 		return true;
 	}
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Actions/VerticalTabAction.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Actions/VerticalTabAction.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Actions/VerticalTabAction.java	(revision 1102)
@@ -1,6 +1,6 @@
 package org.expeditee.items.MagneticConstraint.Actions;
 
-import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Item;
 import org.expeditee.items.MagneticConstraint.MagneticConstraintAction;
@@ -12,5 +12,5 @@
 	public boolean exec(final Item item) {
 		if(item.getParent() == null || !this.isSpIDERCodePage(item.getParent())) return false;
-		final int tabWidth = Browser._theBrowser.getFontMetrics(Browser._theBrowser.getFont()).stringWidth("          ");
+		final int tabWidth = EcosystemManager.getTextLayoutManager().getStringWidth(null, "     ");
 		tab(item, tabWidth);
 		return true;
@@ -20,5 +20,5 @@
 	public boolean invert(Item item) {
 		if(item.getParent() == null || !this.isSpIDERCodePage(item.getParent())) return false;
-		final int tabWidth = -(Browser._theBrowser.getFontMetrics(Browser._theBrowser.getFont()).stringWidth("     "));
+		final int tabWidth = -(EcosystemManager.getTextLayoutManager().getStringWidth(null, "     "));
 		tab(item, tabWidth);
 		return true;
@@ -27,10 +27,10 @@
 	private void tab(final Item item, final int tabWidth) {
 		if(item == null) {
-			DisplayIO.setCursorPosition(DisplayIO.getMouseX() + tabWidth, DisplayIO.getMouseY());
+			DisplayController.setCursorPosition(DisplayController.getMouseX() + tabWidth, DisplayController.getMouseY());
 		} else {
 			final Line postTabLine = Line.getLineFromToken(item);
 			postTabLine.deltaX(tabWidth);
 			if(postTabLine.size() > 0)
-				DisplayIO.setCursorPosition(postTabLine.get(0).getPosition());
+				DisplayController.setCursorPosition(postTabLine.get(0).getPosition());
 		}
 	}
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/BoxLogic.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/BoxLogic.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/BoxLogic.java	(revision 1102)
@@ -1,9 +1,9 @@
 package org.expeditee.items.MagneticConstraint.Utilities;
 
-import java.awt.Rectangle;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.Dot;
@@ -40,9 +40,9 @@
 			final int bottomPos = Math.max(canditate.getStartItem().getY(),
 					canditate.getEndItem().getY());
-			final Rectangle itemHitBox = item.getArea().getBounds();
-			if (topPos < itemHitBox.getY() && bottomPos > itemHitBox.getY()) {
-				if (itemHitBox.getX() + itemHitBox.getWidth() > canditate
-						.getStartItem().getX()
-						&& itemHitBox.getX() < canditate.getStartItem().getX()) {
+			final AxisAlignedBoxBounds itemHitBox = item.getBoundingBox();
+			if (topPos < itemHitBox.getMinY() && bottomPos > itemHitBox.getMinY()) {
+				if (itemHitBox.getMinX() + itemHitBox.getWidth() > canditate.getStartItem().getX() &&
+						itemHitBox.getMinX() < canditate.getStartItem().getX())
+				{
 					return true;
 				}
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/Line.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/Line.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/Line.java	(revision 1102)
@@ -1,7 +1,7 @@
 package org.expeditee.items.MagneticConstraint.Utilities;
 
-import java.awt.Rectangle;
 import java.util.LinkedList;
 
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
 import org.expeditee.items.Item;
 
@@ -18,6 +18,6 @@
 	
 	public Line prependLine(final Line line) {
-		final int x = this.getBoundingBox().x;
-		final int width = line.getBoundingBox().width;
+		final int x = this.getBoundingBox().getMinX();
+		final int width = line.getBoundingBox().getWidth();
 		this.deltaX(width);
 		line.setX(x);
@@ -27,6 +27,6 @@
 	
 	public Line appendLine(final Line line) {
-		final int x = this.getBoundingBox().x;
-		final int width = this.getBoundingBox().width;
+		final int x = this.getBoundingBox().getMinX();
+		final int width = this.getBoundingBox().getWidth();
 		line.setX(x + width);
 		line.setY(this.getFirst().getY());
@@ -83,12 +83,12 @@
 	}
 	
-	public Rectangle getBoundingBox() {
+	public AxisAlignedBoxBounds getBoundingBox() {
 //		final Rectangle rect = new Rectangle(this.getFirst().getX(), this.getFirst().getY(), this.getFirst().getBoundsWidth(), this.getFirst().getBoundsHeight());
 //		for(final Item token : this) 
 //			rect.add(new Rectangle(token.getX(), token.getY(), token.getBoundsWidth(), token.getBoundsHeight()));
 //		return rect;
-		final Rectangle rect = this.getFirst().getArea().getBounds();
+		final AxisAlignedBoxBounds rect = this.getFirst().getBoundingBox();
 		for(final Item token : this)
-			rect.add(token.getArea().getBounds());
+			rect.combineWith(token.getBoundingBox());
 		return rect;
 	}
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/Paragraph.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/Paragraph.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/Paragraph.java	(revision 1102)
@@ -1,6 +1,8 @@
 package org.expeditee.items.MagneticConstraint.Utilities;
 
-import java.awt.*;
 import java.util.LinkedList;
+
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
 import org.expeditee.items.Text;
 
@@ -30,7 +32,10 @@
 	}
 	
-	public Rectangle getBoundingBox() {
-		final Rectangle rect = new Rectangle();
-		for(final Line ln : this) rect.add(ln.getBoundingBox());
+	public AxisAlignedBoxBounds getBoundingBox() {
+		AxisAlignedBoxBounds rect = null;
+		for(final Line ln : this) {
+			if (rect == null) rect = ln.getBoundingBox();
+			else rect.combineWith(ln.getBoundingBox());
+		}
 		return rect;
 	}
@@ -50,6 +55,6 @@
 		if(nextLine == null) {
 			//2a. No; then we simply need to calculate the position of where it would be and return that.
-			final Rectangle boundingBox = splitAt.getBoundingBox();
-			return new Point((int)boundingBox.getX(), (int)boundingBox.getMaxY() + lineHeight);
+			final AxisAlignedBoxBounds boundingBox = splitAt.getBoundingBox();
+			return new Point((int)boundingBox.getMinX(), (int)boundingBox.getMaxY() + lineHeight);
 		}
 		//3. Get paragraph starting from the next line
@@ -58,5 +63,5 @@
 		if(!this.containsAll(paragraphStartingAtNextLine)) {
 			//4b. No; then we simply need to calculate the position of the next line and return that.
-			final Rectangle boundingBox = splitAt.getBoundingBox();
+			final AxisAlignedBoxBounds boundingBox = splitAt.getBoundingBox();
 			return new Point(((Text) splitAt.getFirst()).getX(), (int)boundingBox.getMaxY() + lineHeight);
 		} 
@@ -66,5 +71,5 @@
 		//6. Return the position of the new line we have made space for.
 		
-		final Rectangle boundingBox = splitAt.getBoundingBox();
+		final AxisAlignedBoxBounds boundingBox = splitAt.getBoundingBox();
 		final int x = ((Text) splitAt.getFirst()).getX();
 		return new Point(x, (int)boundingBox.getMaxY() + lineHeight);
@@ -72,5 +77,5 @@
 	
 	private static int getLineHeight(final Line line) {
-		return (int) (line.get(0).getArea().getBounds().getHeight() * 1.2);
+		return (int) (line.get(0).getBoundingBox().getHeight() * 1.2);
 	}
 	
@@ -89,9 +94,9 @@
 	private static boolean isInSameParagraph(final Line thisLine, final Line nextLine, final int lineHeight) {
 		if(!XGroupLogic.areInSameXGroup(thisLine.get(0), nextLine.get(0))) return false;
-		final Rectangle thisLineBoundingBox = thisLine.getBoundingBox();
-		final Rectangle nextLineBoundingBox = nextLine.getBoundingBox();
-		final Point toAdd = new Point(Math.min((int)thisLineBoundingBox.getX(),(int) nextLineBoundingBox.getX()), (int)thisLineBoundingBox.getMaxY() + lineHeight);
-		final Rectangle overlappingSection = new Rectangle(thisLineBoundingBox);
-		overlappingSection.add(toAdd);
+		final AxisAlignedBoxBounds thisLineBoundingBox = thisLine.getBoundingBox();
+		final AxisAlignedBoxBounds nextLineBoundingBox = nextLine.getBoundingBox();
+		final Point toAdd = new Point(Math.min((int)thisLineBoundingBox.getMinX(),(int) nextLineBoundingBox.getMinX()), (int)thisLineBoundingBox.getMaxY() + lineHeight);
+		final AxisAlignedBoxBounds overlappingSection = new AxisAlignedBoxBounds(thisLineBoundingBox);
+		overlappingSection.combineWith(toAdd);
 		return overlappingSection.intersects(nextLineBoundingBox);
 	}
Index: /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/TextLogic.java
===================================================================
--- /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/TextLogic.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/MagneticConstraint/Utilities/TextLogic.java	(revision 1102)
@@ -1,6 +1,6 @@
 package org.expeditee.items.MagneticConstraint.Utilities;
 
-import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Text;
 
@@ -9,5 +9,5 @@
 	public static boolean XIsTowardsRight(final int x, final Text text) {
 		if(text.getPixelBoundsUnion() == null) return false;
-		final double distanceThroughText = x - text.getPixelBoundsUnion().getX();
+		final double distanceThroughText = x - text.getPixelBoundsUnion().getMinX();
 		return /*text.getText().length() == 1 ||*/ distanceThroughText > (text.getPixelBoundsUnion().getWidth() / 2);
 	}
@@ -15,5 +15,5 @@
 	public static boolean XIsTowardsLeft(final Text text, final int x) {
 		if(text.getPixelBoundsUnion() == null) return false;
-		final double distanceThroughText = x - text.getPixelBoundsUnion().getX();
+		final double distanceThroughText = x - text.getPixelBoundsUnion().getMinX();
 		return distanceThroughText < (text.getPixelBoundsUnion().getWidth() / 2);
 	}
@@ -21,6 +21,6 @@
 	public static boolean XIsBeforeCharacters(final Text text, final int x) {
 		try {
-			final int firstLetterWidth = Browser._theBrowser.getFontMetrics(Browser._theBrowser.getFont()).stringWidth(text.getText().substring(0, 1));
-			final double distanceThroughText = x - text.getPixelBoundsUnion().getX();
+			final int firstLetterWidth = EcosystemManager.getTextLayoutManager().getStringWidth(null, text.getText().substring(0, 1));
+			final double distanceThroughText = x - text.getPixelBoundsUnion().getMinX();
 			return firstLetterWidth > distanceThroughText;
 		} catch (NullPointerException e) {
@@ -33,5 +33,5 @@
 	public static boolean XIsAfterCharacters(final Text text, final int x) {
 		try {
-			final double distanceThroughText = x - text.getPixelBoundsUnion().getX();
+			final double distanceThroughText = x - text.getPixelBoundsUnion().getMinX();
 			return distanceThroughText > text.getPixelBoundsUnion().getWidth();
 		} catch (NullPointerException e) {
@@ -41,5 +41,5 @@
 	
 	public static int GetInsertionIndexSelected(final Text text) {
-		return text.getCharPosition(0, DisplayIO.getMouseX()).getInsertionIndex();
+		return text.getCharPosition(0, DisplayController.getMouseX()).getInsertionIndex();
 	}
 }
Index: /trunk/src/org/expeditee/items/Picture.java
===================================================================
--- /trunk/src/org/expeditee/items/Picture.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/Picture.java	(revision 1102)
@@ -19,28 +19,7 @@
 package org.expeditee.items;
 
-import java.awt.AlphaComposite;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Point;
-import java.awt.Polygon;
-import java.awt.Rectangle;
-import java.awt.Shape;
-import java.awt.Stroke;
-import java.awt.Toolkit;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.Point2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.CropImageFilter;
-import java.awt.image.FilteredImageSource;
-import java.awt.image.ImageObserver;
-import java.awt.image.PixelGrabber;
 import java.io.File;
 import java.io.IOException;
 import java.text.DecimalFormat;
-
-import javax.imageio.ImageIO;
-import javax.swing.ImageIcon;
 
 import org.apache.commons.cli.CommandLine;
@@ -49,11 +28,20 @@
 import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Clip;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Dimension;
+import org.expeditee.core.EnforcedClipStack.EnforcedClipKey;
+import org.expeditee.core.Image;
+import org.expeditee.core.Point;
+import org.expeditee.core.Stroke;
+import org.expeditee.core.bounds.AxisAlignedBoxBounds;
+import org.expeditee.core.bounds.CombinationBoxBounds;
+import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FrameUtils;
-import org.expeditee.items.widgets.InteractiveWidget;
-import org.expeditee.stats.Logger;
 
 /**
@@ -75,4 +63,6 @@
  */
 public class Picture extends XRayable {
+	
+	private static final float CROPPING_COMPOSITE_ALPHA = 0.5f;
 
 	private static final int MINIMUM_WIDTH = 10;
@@ -114,10 +104,6 @@
 	private String _fileName = null;
 
-	// used to repaint animated GIF images, among other things.
-	protected ImageObserver _imageObserver = null;
-
-	protected Picture(Text source, ImageObserver observer, Image image) {
+	protected Picture(Text source, Image image) {
 		super(source);
-		_imageObserver = observer;
 		_image = image;
 
@@ -150,8 +136,7 @@
 	 *            screen.
 	 */
-	public Picture(Text source, String fileName, String path, String size,
-			ImageObserver observer) {
+	public Picture(Text source, String fileName, String path, String size)
+	{
 		super(source);
-		_imageObserver = observer;
 		_fileName = fileName;
 		_path = path;
@@ -226,9 +211,9 @@
 
 		// set the default values for start and end
-		_start.setLocation(0, 0);
+		_start.set(0, 0);
 		if (_image == null)
-			_end.setLocation(0, 0);
+			_end.set(0, 0);
 		else
-			_end.setLocation(_image.getWidth(null), _image.getHeight(null));
+			_end.set(_image.getWidth(), _image.getHeight());
 		size = size.trim();
 		String sizeLower = size.toLowerCase();
@@ -272,5 +257,5 @@
 		try {
 			if (size.length() == 0) {
-				size = "" + _image.getWidth(null);
+				size = "" + _image.getWidth();
 				_source.setText(getTagText() + size);
 				return;
@@ -293,8 +278,18 @@
 	}
 
+	public void setStartCrop(Point p)
+	{
+		if (p != null) setStartCrop(p.x, p.y);
+	}
+	
 	public void setStartCrop(int x, int y) {
 		invalidateCroppedArea();
 		_cropStart = new Point(x - getX(), y - getY());
 		invalidateCroppedArea();
+	}
+
+	public void setEndCrop(Point p)
+	{
+		if (p != null) setEndCrop(p.x, p.y);
 	}
 
@@ -312,6 +307,7 @@
 			int startY = getY() + topLeft.y - _highlightThickness;
 			int border = 2 * _highlightThickness;
-			invalidate(new Rectangle(startX, startY, bottomRight.x - topLeft.x
-					+ 2 * border, bottomRight.y - topLeft.y + 2 * border));
+			// TODO: Why invalidate specific area just before invalidateAll? cts16
+			invalidate(new AxisAlignedBoxBounds(startX, startY,
+					bottomRight.x - topLeft.x + 2 * border, bottomRight.y - topLeft.y + 2 * border));
 			invalidateAll();
 		} else {
@@ -325,7 +321,7 @@
 	}
 
-	public Point getBottomRightCrop() {
-		return new Point(Math.max(_cropStart.x, _cropEnd.x), Math.max(
-				_cropStart.y, _cropEnd.y));
+	public Point getBottomRightCrop()
+	{
+		return new Point(Math.max(_cropStart.x, _cropEnd.x), Math.max(_cropStart.y, _cropEnd.y));
 	}
 
@@ -335,8 +331,13 @@
 		invalidateCroppedArea();
 	}
-
-	public boolean isCropTooSmall() {
-		if (_cropStart == null || _cropEnd == null)
-			return true;
+	
+	public boolean isBeingCropped()
+	{
+		return (_cropStart != null && _cropEnd != null);
+	}
+
+	public boolean isCropTooSmall()
+	{
+		if (!isBeingCropped()) return true;
 
 		int cropWidth = Math.abs(_cropEnd.x - _cropStart.x);
@@ -353,5 +354,6 @@
 	}
 
-	public void updatePolygon() {
+	public PolygonBounds updateBounds()
+	{
 		if (_image == null) {
 			refresh();
@@ -360,5 +362,4 @@
 		
 		Point[] ori = new Point[4];
-		Point2D[] rot = new Point2D[4];
 		Point centre = new Point();
 
@@ -393,7 +394,7 @@
 			centre.y = base_y + (bottomRight.y - topLeft.y) / 2;
 			
-			Rectangle clip = new Rectangle(topLeft.x + base_x,
+			AxisAlignedBoxBounds clip = new AxisAlignedBoxBounds(topLeft.x + base_x,
 					topLeft.y + base_y, bottomRight.x - topLeft.x,
-					bottomRight.y - topLeft.y).getBounds();
+					bottomRight.y - topLeft.y);
 //			_poly.addPoint((int) clip.getMinX() - 1, (int) clip.getMinY() - 1);
 //			_poly.addPoint((int) clip.getMinX() - 1, (int) clip.getMaxY());
@@ -408,10 +409,11 @@
 		}
 		
-		AffineTransform.getRotateInstance(Math.PI * _rotate / 180, centre.x, centre.y).transform(ori, 0, rot, 0, 4);
-		
-		_poly = new Polygon();
-		for(Point2D p : rot) {
-			_poly.addPoint((int)p.getX(), (int)p.getY());
-		}
+		PolygonBounds poly = new PolygonBounds();
+		for (Point p : ori) {
+			poly.addPoint(p);
+		}
+		poly.rotate(Math.PI * _rotate / 180, centre);
+		
+		return poly.close();
 	}
 
@@ -454,23 +456,23 @@
 	 */
 	@Override
-	protected void paintLink(Graphics2D g) {
-		if (FrameGraphics.isAudienceMode())
-			return;
-		super.paintLink(g);
-	}
-	
-	public void paintImageTiling(Graphics2D g) {
-		if (_image == null) {
-			return;
-		}
-		
-		int iw = _image.getWidth(null);
-		int ih = _image.getHeight(null);
-		if(iw <= 0 || ih <= 0) {
-			return;
-		}
-		
-		int base_x = (_anchorLeft!=null) ? _anchorLeft : _source.getX();
-		int base_y = (_anchorTop!=null) ? _anchorTop : _source.getY();
+	protected void paintLink()
+	{
+		if (DisplayController.isAudienceMode()) return;
+		super.paintLink();
+	}
+	
+	/**
+	 * Paint the image repeatedly tiled over the drawing area.
+	 */
+	public void paintImageTiling()
+	{	
+		if (_image == null) return;
+		
+		int iw = _image.getWidth();
+		int ih = _image.getHeight();
+		if(iw <= 0 || ih <= 0) return;
+		
+		int base_x = (_anchorLeft != null) ? _anchorLeft : _source.getX();
+		int base_y = (_anchorTop != null) ? _anchorTop : _source.getY();
 		
 		int dX1 = base_x;
@@ -479,10 +481,9 @@
 		int dY2 = base_y + getHeight();
 		
-		BufferedImage tmp = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
-		Graphics2D g2d = tmp.createGraphics();
+		Image tmp = Image.createImage(getWidth(), getHeight());
+		EcosystemManager.getGraphicsManager().pushDrawingSurface(tmp);
+
 		int offX = (tmp.getWidth() - getWidth()) / 2;
 		int offY = (tmp.getHeight() - getHeight()) / 2;
-		
-		// g2d.rotate(rotate, tmp.getWidth() / 2, tmp.getHeight() / 2);
 		
 		int cropStartX = _start.x;
@@ -491,4 +492,5 @@
     		cropEndX = iw;
     	}
+    	
 		for(int x = dX1; x < dX2; ) {
 			// end - start = (cropEnd - cropStart) * scale
@@ -506,4 +508,5 @@
         		cropEndY = ih;
         	}
+        	
 			for(int y = dY1; y < dY2; ) {
 				int h = (int) ((cropEndY - cropStartY) * _scale);
@@ -518,5 +521,12 @@
 				int sy = _flipY ? cropEndY : cropStartY;
 				int ey = _flipY ? cropStartY : cropEndY;
-				g2d.drawImage(_image, x - dX1 + offX, y - dY1 + offY, endX - dX1 + offX, endY - dY1 + offY, sx, sy, ex, ey, null);
+				
+				Point topLeft = new Point(x - dX1 + offX, y - dY1 + offY);
+				Dimension size = new Dimension(endX - x, endY - y);
+				Point cropTopLeft = new Point(sx, sy);
+				Dimension cropSize = new Dimension(ex - sx, ey - sy);
+				if (cropSize.width > 0 && cropSize.height > 0) {
+					EcosystemManager.getGraphicsManager().drawImage(_image, topLeft, size, 0.0, cropTopLeft, cropSize);
+				}
 				
 				cropStartY = 0;
@@ -531,84 +541,71 @@
 			x = endX;
 		}
-		
-		AffineTransform at = new AffineTransform();
-		at.translate(dX1, dY1);
-		at.rotate(Math.PI * _rotate / 180, tmp.getWidth() / 2, tmp.getHeight() / 2);
-		g.drawImage(tmp, at, _imageObserver);
-		// g.drawImage(tmp, dX1, dY1, dX2, dY2, 0, 0, tmp.getWidth(), tmp.getHeight(), _imageObserver);
-	}
-
-	@Override
-	public void paint(Graphics2D g) {
-		if (_image == null)
-			return;
-
-		paintLink(g);
-
-		// if we are showing the cropping, then show the original as transparent
+
+		EcosystemManager.getGraphicsManager().popDrawingSurface();
+		EcosystemManager.getGraphicsManager().drawImage(tmp, new Point(dX1, dY1), null, Math.PI * _rotate / 180);
+		tmp.releaseImage();
+	}
+
+	@Override
+	public void paint()
+	{
+		if (_image == null) return;
+
+		paintLink();
+		
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+
+		// if we are showing the cropping
 		if (_showCropping && !isCropTooSmall()) {
-			// show the full image as transparent
-			float alpha = .5f;
-			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
-					alpha));
-			
-			paintImageTiling(g);
-
-			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
-					1.0f));
+			// show the uncropped area as transparent
+			g.setCompositeAlpha(CROPPING_COMPOSITE_ALPHA);
+			paintImageTiling();
+			g.setCompositeAlpha(1.0f);
+			
 			// show the cropped area normally
 			Point topLeft = getTopLeftCrop();
 			Point bottomRight = getBottomRightCrop();
-			int base_x = (_anchorLeft!=null) ? _anchorLeft : _source.getX();
-			int base_y = (_anchorTop!=null) ? _anchorTop : _source.getY();
-			
-			Shape clip = new Rectangle(base_x + topLeft.x, base_y + topLeft.y,
-					bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
-			g.setColor(getPaintHighlightColor());
-			g.draw(clip);
-			g.setClip(clip);
-
-			paintImageTiling(g);
-			
-			g.draw(clip);
-			// if the image is cropped, but we are not showing the cropping
-			// otherwise, paint normally
+			int base_x = (_anchorLeft != null) ? _anchorLeft : _source.getX();
+			int base_y = (_anchorTop != null) ? _anchorTop : _source.getY();
+			
+			Clip clip = new Clip(new AxisAlignedBoxBounds(	base_x + topLeft.x,
+																	base_y + topLeft.y,
+																	bottomRight.x - topLeft.x,
+																	bottomRight.y - topLeft.y));
+			EnforcedClipKey key = g.pushClip(clip);
+			paintImageTiling();
+			g.popClip(key);
+
+			// Draw an outline for the crop selection box
+			g.drawRectangle(clip.getBounds(), 0.0, null, getPaintHighlightColor(), HIGHLIGHT_STROKE, null);
+
+		// otherwise, paint normally
 		} else {
-			paintImageTiling(g);
-		}
-
+			paintImageTiling();
+		}
+
+		PolygonBounds poly = (PolygonBounds) getBounds();
+		
 		if (hasVisibleBorder()) {
-			g.setColor(getPaintBorderColor());
-			Stroke borderStroke = new BasicStroke(getThickness(), CAP, JOIN);
-			g.setStroke(borderStroke);
-			g.drawPolygon(getPolygon());
+			Stroke borderStroke = new Stroke(getThickness(), DEFAULT_CAP, DEFAULT_JOIN);
+			g.drawPolygon(poly, null, null, 0.0, null, getPaintBorderColor(), borderStroke);
 		}
 
 		if (isHighlighted()) {
-			Stroke borderStroke = new BasicStroke(1, CAP, JOIN);
-			g.setStroke(borderStroke);
-			g.setColor(getHighlightColor());
-			g.drawPolygon(getPolygon());
-		}
-		
-		//System.out.print("p_");	
-	}
-
-	@Override
-	public Color getHighlightColor() {
-		if (_highlightColor.equals(getBorderColor()))
-			return ALTERNATE_HIGHLIGHT;
-		return _highlightColor;
-	}
-
-	@Override
-	public int setHighlightColor() {
-		super.setHighlightColor();
-
-		return Item.DEFAULT_CURSOR;
-	}
-
-	protected Picture createPicture() {
-		return ItemUtils.CreatePicture((Text) _source.copy(), _imageObserver);
+			Stroke borderStroke = new Stroke(1, DEFAULT_CAP, DEFAULT_JOIN);
+			g.drawPolygon(poly, null, null, 0.0, null, getHighlightColor(), borderStroke);
+		}
+	}
+
+	@Override
+	public Colour getHighlightColor()
+	{
+		if (_highlightColour.equals(getBorderColor())) return ALTERNATE_HIGHLIGHT;
+		return _highlightColour;
+	}
+
+	protected Picture createPicture()
+	{
+		return ItemUtils.CreatePicture((Text) _source.copy());
 	}
 
@@ -617,5 +614,5 @@
 		Picture p = createPicture();
 		p._image = _image;
-		p._mode = _mode;
+		p._highlightMode = _highlightMode;
 		// Doing Duplicate item duplicates link mark which we dont want to do
 		// when in audience mode because the linkMark will be copied incorrectly
@@ -632,6 +629,6 @@
 			int endX = Math.round(bottomRight.x / _scale + _start.x);
 			int endY = Math.round(bottomRight.y / _scale + _start.y);
-			int width = _image.getWidth(null);
-			int height = _image.getHeight(null);
+			int width = _image.getWidth();
+			int height = _image.getHeight();
 			// adjust our start and end if the user has dragged outside of the
 			// shape
@@ -663,5 +660,5 @@
 
 		p.updateSource();
-		p.updatePolygon();
+		p.invalidateBounds();
 
 		return p;
@@ -678,6 +675,6 @@
 	public void scaleCrop() {
 		// scale crop values to within image bounds
-		int iw = _image.getWidth(null);
-		int ih = _image.getHeight(null);
+		int iw = _image.getWidth();
+		int ih = _image.getHeight();
 		if(iw > 0 || ih > 0) {
 			while(_start.x >= iw) {
@@ -723,9 +720,8 @@
 			_scale = oldScale;
 		} else {
-			_source.translate(new Point2D.Float(FrameMouseActions.MouseX,
-					FrameMouseActions.MouseY), multiplier);
+			_source.translate(EcosystemManager.getInputManager().getCursorPosition(), multiplier);
 		}
 		updateSource();
-		updatePolygon();
+		invalidateBounds();
 		// Make sure items that are resized display the border
 		invalidateAll();
@@ -753,8 +749,5 @@
 		}
 		
-		return Toolkit.getDefaultToolkit().createImage(
-				new FilteredImageSource(_image.getSource(),
-						new CropImageFilter(_start.x, _start.y,
-								getUnscaledWidth(), getUnscaledHeight())));
+		return Image.createImageAsCroppedCopy(_image, _start.x, _start.y, getUnscaledWidth(), getUnscaledHeight());
 	}
 
@@ -771,5 +764,5 @@
 	 */
 	public boolean isCropped() {
-		return (_end.x != 0 && _end.x != _image.getWidth(null)) || (_end.y != 0 && _end.y != _image.getHeight(null)) || _start.y != 0 || _start.x != 0;
+		return (_end.x != 0 && _end.x != _image.getWidth()) || (_end.y != 0 && _end.y != _image.getHeight()) || _start.y != 0 || _start.x != 0;
 	}
 
@@ -779,4 +772,5 @@
 		// (notably.bmp) hence, we try this first, then if it fails we try
 		// ImageIO
+		/*
 		try {
 			_image = new ImageIcon(_path).getImage();
@@ -785,5 +779,5 @@
 
 		// if ImageIcon failed to read the image
-		if (_image == null || _image.getWidth(null) <= 0) {
+		if (_image == null || _image.getWidth() <= 0) {
 			try {
 				_image = ImageIO.read(new File(_path));
@@ -795,4 +789,6 @@
 			}
 		}
+*/
+		_image = Image.getImage(_path);
 		return true;
 	}
@@ -827,5 +823,5 @@
 	@Override
 	public boolean getLinkMark() {
-		return !FrameGraphics.isAudienceMode() && _source.getLinkMark();
+		return !DisplayController.isAudienceMode() && _source.getLinkMark();
 	}
 
@@ -892,6 +888,6 @@
 		// If the image is cropped add the position for the start and finish of
 		// the crop to the soure text
-		if (_start.x > 0 || _start.y > 0 || _end.x != _image.getWidth(null)
-				|| _end.y != _image.getHeight(null)) {
+		if (_start.x > 0 || _start.y > 0 || _end.x != _image.getWidth()
+				|| _end.y != _image.getHeight()) {
 			newText.append(" ").append(_start.x).append(" ").append(_start.y);
 			newText.append(" ").append(_end.x).append(" ").append(_end.y);
@@ -912,5 +908,5 @@
 
 	@Override
-	public void translate(Point2D origin, double ratio) {
+	public void translate(Point origin, double ratio) {
 		_scale *= ratio;
 		updateSource();
@@ -919,17 +915,14 @@
 
 	@Override
-	public Rectangle[] getDrawingArea() {
-
-		Rectangle[] da = super.getDrawingArea();
+	public AxisAlignedBoxBounds getDrawingArea() {
+
+		AxisAlignedBoxBounds da = super.getDrawingArea();
 
 		if (getLink() != null || hasAction()) {
-			Rectangle[] da2 = new Rectangle[da.length + 1];
-			System.arraycopy(da, 0, da2, 0, da.length);
-			da2[da.length] = getLinkPoly().getBounds();
-			da2[da.length].translate(getX() - LEFT_MARGIN, getY()
-					+ getLinkYOffset());
-			da2[da.length].width += 2;
-			da2[da.length].height += 2;
-			da = da2;
+			AxisAlignedBoxBounds linkBounds = AxisAlignedBoxBounds.getEnclosing(getLinkBounds());
+			linkBounds.getTopLeft().add(getX() - LEFT_MARGIN, getY() + getLinkYOffset());
+			linkBounds.getSize().width += 2;
+			linkBounds.getSize().height += 2;
+			da.combineWith(linkBounds);
 		}
 
@@ -963,5 +956,5 @@
 		_rotate = rotate;
 		updateSource();
-		updatePolygon();
+		invalidateBounds();
 	}
 	
@@ -970,8 +963,6 @@
 	}
 
-	public boolean MouseOverBackgroundPixel(int mouseX, int mouseY, Color bg_col)
-	{
-		int[] pixels = new int[1];
-		 
+	public boolean MouseOverBackgroundPixel(int mouseX, int mouseY, Colour bg_col)
+	{
 		int base_x = (_anchorLeft!=null) ? _anchorLeft : _source.getX();
 		int base_y = (_anchorTop!=null) ? _anchorTop : _source.getY();
@@ -979,31 +970,13 @@
 		int y = mouseY - base_y;
 		
-		// Consider making this a slightly larger area to check, say 3 x 3?
-		// Back op if all are the same sought after color?
-		PixelGrabber grabber = new PixelGrabber(_image, x,y, 1, 1, pixels, 0, 1);
-		
-		// The following might be a better approach, as it sets the color model
-		// when getPixels() is called, however, it might return an int[] or byte[]
-		// array (handled as Object), as so some extra complexity would exist in
-		// handling the returned result
-		
-		//PixelGrabber pg = new PixelGrabber(_image, mouseX, mouseY, 1, 1, true);
-		
-		try {
-			grabber.grabPixels(0);
-		} 
-		catch (Exception e) {
-			e.printStackTrace();
-		}
-		
-	
-		int c = pixels[0];
-		int c_red    = (c & 0x00ff0000) >> 16;
-		int c_green  = (c & 0x0000ff00) >> 8;
-		int c_blue   =  c & 0x000000ff;
-		
-		int bg_red   = (bg_col!=null) ? bg_col.getRed()   : 0xff;
-		int bg_green = (bg_col!=null) ? bg_col.getGreen() : 0xff;
-		int bg_blue  = (bg_col!=null) ? bg_col.getBlue()  : 0xff;
+		Colour c = _image.getPixel(x, y);
+
+		int c_red    = c.getRed255();
+		int c_green  = c.getGreen255();
+		int c_blue   = c.getBlue255();
+		
+		int bg_red   = (bg_col!=null) ? bg_col.getRed255()   : 0xff;
+		int bg_green = (bg_col!=null) ? bg_col.getGreen255() : 0xff;
+		int bg_blue  = (bg_col!=null) ? bg_col.getBlue255()  : 0xff;
 		
 		int red_diff   = Math.abs(c_red   - bg_red);
Index: /trunk/src/org/expeditee/items/Tooltip.java
===================================================================
--- /trunk/src/org/expeditee/items/Tooltip.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/Tooltip.java	(revision 1102)
@@ -9,48 +9,77 @@
 import org.expeditee.settings.templates.TemplateSettings;
 
+/**
+ * TODO: Comment. cts16
+ * 
+ * @author cts16
+ */
 public class Tooltip {
+
+	/** TODO: Comment. cts16 */
+	private Map<Text, Item> _tooltipItems = new HashMap<Text, Item>();
 	
-	Tooltip() { }
-	
-	private Map<Text, Item> tooltipItems = new HashMap<Text, Item>();
-	
-	public Text addTooltip(String content, final Item toItem) {
-		if(content.trim().toLowerCase().startsWith("text") && content.contains(":")) 
+	/** TODO: Comment. cts16 */
+	Tooltip()
+	{
+	}
+
+	/** TODO: Comment. cts16 */
+	public Text addTooltip(String content, final Item toItem)
+	{
+		if(content.trim().toLowerCase().startsWith("text") && content.contains(":")) {
 			content = content.substring(content.indexOf(':') + 1);
+		}
 		final Text tooltip = TemplateSettings.TooltipTemplate.get().copy();
+		tooltip.setWidth(Integer.MAX_VALUE); // Tooltip shouldn't be width-limited
 		tooltip.setText(content);
 		return addTooltip(tooltip, toItem);
 	}
-	
-	public Text addTooltip(final Text tooltip, final Item toItem) {
-		tooltipItems.put(tooltip, toItem);
+
+	/** TODO: Comment. cts16 */
+	public Text addTooltip(final Text tooltip, final Item toItem)
+	{
+		_tooltipItems.put(tooltip, toItem);
 		return tooltip;
 	}
-	
-	public Collection<Text> getTooltips() { return tooltipItems.keySet(); }
-	
-	public List<String> asStringList() { 
+
+	/** TODO: Comment. cts16 */
+	public Collection<Text> getTooltips()
+	{
+		return _tooltipItems.keySet();
+	}
+
+	/** TODO: Comment. cts16 */
+	public List<String> asStringList()
+	{ 
 		final List<String> ret = new LinkedList<String>();
-		for(final Text tooltip: tooltipItems.keySet()) ret.add(tooltip.getText());
+		for(final Text tooltip: _tooltipItems.keySet()) ret.add(tooltip.getText());
 		return ret;
 	}
-	
-	public int getWidth() {
+
+	/** TODO: Comment. cts16 */
+	public int getWidth()
+	{
 		int max = 0;
-		for(final Text tooltip: tooltipItems.keySet()) 
+		for(final Text tooltip: _tooltipItems.keySet()) {
 			if(tooltip.getBoundsWidth() > max) max = tooltip.getBoundsWidth();
+		}
 		return max;
 	}
 
-	public int getHeight() {
+	/** TODO: Comment. cts16 */
+	public int getHeight()
+	{
 		int max = 0;
-		for(final Text tooltip: tooltipItems.keySet()) 
+		for(final Text tooltip: _tooltipItems.keySet()) {
 			if(tooltip.getBoundsWidth() > max) max = tooltip.getBoundsHeight();
+		}
 		return max;
 	}
-	
-	public int getCollectiveHeight() {
+
+	/** TODO: Comment. cts16 */
+	public int getCollectiveHeight()
+	{
 		int height = 0;
-		for(final Text tooltip: tooltipItems.keySet()) height += tooltip.getBoundsHeight();
+		for(final Text tooltip: _tooltipItems.keySet()) height += tooltip.getBoundsHeight();
 		return height;
 	}
Index: /trunk/src/org/expeditee/items/XRayable.java
===================================================================
--- /trunk/src/org/expeditee/items/XRayable.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/XRayable.java	(revision 1102)
@@ -19,10 +19,11 @@
 package org.expeditee.items;
 
-import java.awt.Color;
-import java.awt.geom.Point2D;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameGraphics;
 
@@ -101,10 +102,10 @@
 	
 	@Override
-	public Color getColor() {
+	public Colour getColor() {
 		return _source.getColor();
 	}
 
 	@Override
-	public void setColor(Color c) {
+	public void setColor(Colour c) {
 		_source.setColor(c);
 		invalidateCommonTrait(ItemAppearence.ForegroundColorChanged);
@@ -112,15 +113,15 @@
 	
 	@Override
-	public void setBackgroundColor(Color c) {
+	public void setBackgroundColor(Colour c) {
 		_source.setBackgroundColor(c);
 	}
 	
 	@Override
-	public void setFillColor(Color c) {
+	public void setFillColor(Colour c) {
 		_source.setFillColor(c);
 	}
 	
 	@Override
-	public void setBorderColor(Color c) {
+	public void setBorderColor(Colour c) {
 		_source.setBorderColor(c);
 		invalidateCommonTrait(ItemAppearence.BorderColorChanged);
@@ -128,5 +129,5 @@
 	
 	@Override
-	public void setGradientColor(Color c) {
+	public void setGradientColor(Colour c) {
 		_source.setGradientColor(c);
 	}
@@ -153,20 +154,20 @@
 	
 	@Override
-	public Float getAnchorLeft() {
+	public Integer getAnchorLeft() {
 	        return _source.getAnchorLeft();
 	}
 	
 	@Override
-	public Float getAnchorRight() {
+	public Integer getAnchorRight() {
 		return _source.getAnchorRight();
 	}
 
 	@Override
-	public Float getAnchorTop() {
+	public Integer getAnchorTop() {
 		return _source.getAnchorTop();
 	}
 
 	@Override
-	public Float getAnchorBottom() {
+	public Integer getAnchorBottom() {
 		return _source.getAnchorBottom();
 	}
@@ -174,5 +175,5 @@
 	
 	@Override
-	public Color getBorderColor() {
+	public Colour getBorderColor() {
 		return _source.getBorderColor();
 	}
@@ -186,15 +187,15 @@
 	
 	@Override
-	public Color getBackgroundColor() {
+	public Colour getBackgroundColor() {
 		return _source.getBackgroundColor();
 	}
 	
 	@Override
-	public Color getFillColor() {
+	public Colour getFillColor() {
 		return _source.getFillColor();
 	}
 	
 	@Override
-	public Color getGradientColor() {
+	public Colour getGradientColor() {
 		return _source.getGradientColor();
 	}
@@ -226,5 +227,5 @@
 			invalidateAll();
 		_source.setLink(frameName);
-		updatePolygon();
+		invalidateBounds();
 		//TODO: only invalidate the link bit
 		invalidateAll();
@@ -239,5 +240,5 @@
 			invalidateAll();
 		_source.setActions(action);
-		updatePolygon();
+		invalidateBounds();
 		invalidateAll();
 	}
@@ -252,7 +253,7 @@
 	
 	@Override
-	public void translate(Point2D origin, double ratio){
+	public void translate(Point origin, double ratio){
 		//_source.translate(origin, ratio);
-		updatePolygon();
+		invalidateBounds();
 	}
 	
@@ -279,5 +280,5 @@
 
 	@Override
-	public void setAnchorTop(Float anchor) {
+	public void setAnchorTop(Integer anchor) {
 		_source.setAnchorTop(anchor);
 		if (anchor != null)
@@ -286,20 +287,20 @@
 
 	@Override
-	public void setAnchorBottom(Float anchor) {
+	public void setAnchorBottom(Integer anchor) {
 		_source.setAnchorBottom(anchor);
 		if (anchor != null)
-			_source.setY(FrameGraphics.getMaxFrameSize().height - getHeight() - anchor);
-	}
-
-	
-	@Override
-	public void setAnchorLeft(Float anchor) {
+			_source.setY(DisplayController.getFramePaintArea().getHeight() - getHeight() - anchor);
+	}
+
+	
+	@Override
+	public void setAnchorLeft(Integer anchor) {
 		_source.setAnchorLeft(anchor);
 	}
 
 	@Override
-	public void setAnchorRight(Float anchor) {
+	public void setAnchorRight(Integer anchor) {
 		_source.setAnchorRight(anchor);
-		_source.setX(FrameGraphics.getMaxFrameSize().width - anchor - this.getWidth());
+		_source.setX(DisplayController.getFramePaintArea().getWidth() - anchor - this.getWidth());
 	}
 	
Index: /trunk/src/org/expeditee/items/widgets/ButtonWidget.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/ButtonWidget.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/ButtonWidget.java	(revision 1102)
@@ -1,5 +1,4 @@
 package org.expeditee.items.widgets;
 import java.awt.BorderLayout;
-import java.awt.Color;
 import java.awt.Dimension;
 import java.net.URL;
@@ -9,4 +8,6 @@
 import javax.swing.border.EmptyBorder;
 
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.items.Text;
 
@@ -14,9 +15,9 @@
 
 //Will be the default class for Rubbish Bin, Reset and Undo Button Widgets
-public class ButtonWidget extends InteractiveWidget{
-
+public class ButtonWidget extends SwingWidget
+{
 	protected JButton clicked_ = new JButton("");	
 	protected SVGIcon icon_ = null;
-	
+
 	public ButtonWidget(int dimension, String filePath, Text source, String[] args)
 	{
@@ -25,12 +26,13 @@
 				
 		clicked_.setBorder(new EmptyBorder(0, 0, 0, 0));
-		clicked_.setBackground(Color.white);
+		clicked_.setBackground(SwingConversions.toSwingColor(Colour.WHITE));
 		
 		Dimension size = new Dimension(dimension, dimension);
 		icon_ = new SVGIcon();
-		try{
+		
+		try {
 			URL imageURL = ClassLoader.getSystemResource(filePath);		
 			icon_.setSvgURI(imageURL.toURI());
-			//This STILL works, unsure why. Don't remove it has an affect on the button appearance.		
+			// This STILL works, unsure why. Don't remove it has an affect on the button appearance.
 			icon_.setUseAntiAlias(true);
 			icon_.setScaleToFit(true);
@@ -39,8 +41,6 @@
 			_swingComponent.add(clicked_);
 			this.setWidgetEdgeThickness(0.0f);
-			this.setWidgetEdgeColor(Color.white);	
-		}
-		catch(Exception e){
-			
+			this.setWidgetEdgeColor(Colour.WHITE);	
+		} catch(Exception e) {
 			//Set a default image if image is missing
 			System.out.println("Unable to load image from directory");			
@@ -49,18 +49,24 @@
 
 	@Override
-	protected String[] getArgs() {
+	protected String[] getArgs()
+	{
 		// TODO Auto-generated method stub
 		return null;
 	}
-	public boolean itemHeldWhileClicked(InteractiveWidget bw) {
+	
+	public boolean itemHeldWhileClicked(Widget bw)
+	{
 		// TODO Auto-generated method stub
 		return false;
 	}
-	public boolean getdropInteractableStatus(){
+	
+	public boolean getdropInteractableStatus()
+	{
 		return false;
 	}
 
 	@Override
-	boolean setPositions(WidgetCorner src, float x, float y) {
+	public boolean setPositions(WidgetCorner src, float x, float y)
+	{
 		boolean result = super.setPositions(src, x, y);
 
Index: /trunk/src/org/expeditee/items/widgets/DataFrameWidget.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/DataFrameWidget.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/DataFrameWidget.java	(revision 1102)
@@ -19,6 +19,4 @@
 package org.expeditee.items.widgets;
 
-import java.awt.Color;
-import java.awt.Graphics;
 import java.util.Collection;
 import java.util.HashSet;
@@ -26,5 +24,9 @@
 import javax.swing.JComponent;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.GraphicsManager;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
@@ -34,5 +36,5 @@
 import org.expeditee.items.Text;
 
-public abstract class DataFrameWidget extends InteractiveWidget implements
+public abstract class DataFrameWidget extends SwingWidget implements
 		FrameObserver {
 
@@ -118,5 +120,5 @@
 	public void update() {
 		Frame parent = getParentFrame();
-		if (parent != null && parent == DisplayIO.getCurrentFrame()) {
+		if (parent != null && parent == DisplayController.getCurrentFrame()) {
 			refresh();
 		}
@@ -166,9 +168,9 @@
 	}
 
-	protected void paintInFreeSpace(Graphics g) {
-		super.paintInFreeSpace(g);
-		g.setFont(((Text) getSource()).getFont());
-		g.setColor(Color.WHITE);
-		g.drawString(this.getClass().getSimpleName(), getX() + 10, getY() + 20);
+	protected void paintInFreeSpace()
+	{
+		super.paintInFreeSpace();
+		GraphicsManager g = EcosystemManager.getGraphicsManager();
+		g.drawString(this.getClass().getSimpleName(), new Point(getX() + 10, getY() + 20), ((Text) getSource()).getFont(), Colour.WHITE);
 
 	}
Index: /trunk/src/org/expeditee/items/widgets/HeavyDutyInteractiveWidget.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/HeavyDutyInteractiveWidget.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/HeavyDutyInteractiveWidget.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.items.widgets;
 
-import java.awt.Color;
 import java.awt.Font;
 import java.awt.FontMetrics;
@@ -33,7 +32,10 @@
 import javax.swing.SwingUtilities;
 
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingGraphicsManager;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.gui.Browser;
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.FrameGraphics;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FreeItems;
 import org.expeditee.items.Item;
@@ -53,5 +55,5 @@
  * until expeditee allocates a thread to begin loading. The swing component is set as not-visible.
  * 
- * At the the loading stage, a loadable widget proccesses its load task and renders a
+ * At the the loading stage, a loadable widget processes its load task and renders a
  * load message/bar.
  * 
@@ -59,11 +61,11 @@
  * 
  * When a HeavyDutyInteractiveWidget becomes visible / is anchored, it will register itself for saving at the next
- * save point according to SaveEntityManager. Heavey duty widgets will only save at the save points 
+ * save point according to SaveEntityManager. Heavy duty widgets will only save at the save points 
  * if the widget still belongs to a frame (i.e. is not removed) and is anchored.
  * 
- * Heavey duty widgets can also have an expiry on how long they should stay cached for. If they do have an 
+ * Heavy duty widgets can also have an expiry on how long they should stay cached for. If they do have an 
  * expiry then it they unload once expired, and will re-load once in view again. Must take care for
  * unloadable widgets because you must check your unloadable elements to whether they are unloaded or not
- * every time your widget accessess them.
+ * every time your widget accesses them.
  * 
  * When a heavy duty widget is deleted - any data consuming memory can be dumped temporarily if needed.
@@ -72,5 +74,5 @@
  *
  */
-public abstract class HeavyDutyInteractiveWidget extends InteractiveWidget implements LoadableEntity, SaveableEntity {
+public abstract class HeavyDutyInteractiveWidget extends SwingWidget implements LoadableEntity, SaveableEntity {
 	
 	/** load finished */
@@ -90,9 +92,9 @@
 	private static final String PENDING_MESSAGE = "Pending";
 	
-	private static final Color LOAD_BAR_PROGRESS_COLOR = new Color(103, 171, 203);
-	private static final Color LOAD_BAR_INDETERM_COLOR = Color.ORANGE;
-	private static final Color LOAD_BAR_HIGHLIGHT_COLOR = new Color(240, 240, 240);
-	private static final Color LOAD_SCREEN_COLOR = Color.LIGHT_GRAY;
-	private static final Color LOAD_SCREEN_COLOR_FREESPACE = FREESPACE_BACKCOLOR;
+	private static final Colour LOAD_BAR_PROGRESS_COLOR = Colour.FromRGB255(103, 171, 203);
+	private static final Colour LOAD_BAR_INDETERM_COLOR = Colour.ORANGE;
+	private static final Colour LOAD_BAR_HIGHLIGHT_COLOR = Colour.FromRGB255(240, 240, 240);
+	private static final Colour LOAD_SCREEN_COLOR = Colour.LIGHT_GREY;
+	private static final Colour LOAD_SCREEN_COLOR_FREESPACE = FREESPACE_BACKCOLOR;
 	
 	private static final Font LOAD_NORMAL_FONT = new Font("Arial", Font.BOLD, 12);
@@ -140,5 +142,6 @@
 	 */
 	protected HeavyDutyInteractiveWidget(Text source, JComponent component,
-			int minWidth, int maxWidth, int minHeight, int maxHeight, int cacheDepth, boolean skipLoad) {
+			int minWidth, int maxWidth, int minHeight, int maxHeight, int cacheDepth, boolean skipLoad)
+	{
 		super(source, component, minWidth, maxWidth, minHeight, maxHeight);
 		
@@ -173,5 +176,5 @@
 	 * 
 	 * @param percent 
-	 * 		Must be between 0.0 and 1.0 inclusive for percentage. Or neagtive if indeterminant.
+	 * 		Must be between 0.0 and 1.0 inclusive for percentage. Or negative if indeterminate.
 	 * 
 	 * @throws IllegalArgumentException
@@ -182,5 +185,6 @@
 	 * 		
 	 */
-	protected final void updateLoadPercentage(float percent) {
+	protected final void updateLoadPercentage(float percent)
+	{
 		if (percent > 1.0f) 
 			throw new IllegalArgumentException("loadState is larger than 1.0");
@@ -199,5 +203,6 @@
 	 * @return The current load state.
 	 */
-	protected float getLoadState() {
+	protected float getLoadState()
+	{
 		return loadState;
 	}
@@ -206,5 +211,6 @@
 	 * @return True if in a loading phase.
 	 */
-	protected boolean isInLoadProgress() {
+	protected boolean isInLoadProgress()
+	{
 		return loadState <= 1.0f;
 	}
@@ -226,36 +232,45 @@
 		
 		// Re-render loading state
-		FrameGraphics.invalidateArea(_swingComponent.getBounds());
-		FrameGraphics.requestRefresh(true);
+		DisplayController.invalidateArea(getBounds());
+		DisplayController.requestRefresh(true);
 	}
 	
 	@Override
-	public void paintInFreeSpace(Graphics g) {
-		if (loadState == LOAD_STATE_COMPLETED) super.paintInFreeSpace(g);
-		else paintLoadScreen(g, LOAD_SCREEN_COLOR_FREESPACE);
+	public void paintInFreeSpace() {
+		if (loadState == LOAD_STATE_COMPLETED) super.paintInFreeSpace();
+		else paintLoadScreen(LOAD_SCREEN_COLOR_FREESPACE);
 	}
 
 	@Override
-	public void paint(Graphics g) {
+	protected final void paintSwingWidget(Graphics2D g)
+	{
 		if (loadState == LOAD_STATE_COMPLETED) {
-			super.paint(g);
+			paintHeavyDutyWidget(g);
 		} else {
-			paintLoadScreen(g, LOAD_SCREEN_COLOR);
-			this.paintLink((Graphics2D)g);
-		}
-		
-	}
-	
-	/**
-	 * Rendersthe load bar / load messages
+			paintLoadScreen(LOAD_SCREEN_COLOR);
+		}
+		
+	}
+	
+	/** Can be overridden to provide custom drawing. */
+	protected void paintHeavyDutyWidget(Graphics2D g)
+	{
+		super.paintSwingWidget(g);
+	}
+	
+	/**
+	 * Renders the load bar / load messages
 	 * 
 	 * @param g
 	 */
-	private void paintLoadScreen(Graphics g, Color backgroundColor) {
+	private void paintLoadScreen(Colour backgroundColor) {
 
 		if (Browser._theBrowser == null) return;
 		
+		SwingGraphicsManager manager = SwingMiscManager.getIfUsingSwingGraphicsManager();
+		Graphics g = manager.getCurrentSurface();
+		
 		// Render shaded window over widget
-		g.setColor(backgroundColor);
+		g.setColor(SwingConversions.toSwingColor(backgroundColor));
 		g.fillRect(getX(), getY(), getWidth(), getHeight());
 		
@@ -291,8 +306,8 @@
 		Rectangle tmpClip = (clipBackUp != null) ? clipBackUp.getBounds() : 
 			new Rectangle(0, 0, 
-					Browser._theBrowser.getContentPane().getWidth(), 
-					Browser._theBrowser.getContentPane().getHeight());
-			
-		g.setClip(tmpClip.intersection(getBounds()));
+					manager.getContentPane().getWidth(), 
+					manager.getContentPane().getHeight());
+			
+		g.setClip(tmpClip.intersection(SwingConversions.toSwingRectangle(getBounds())));
 	
 		
@@ -300,6 +315,6 @@
 
 			GradientPaint gp = new GradientPaint(
-					0, barY + (int)(BAR_HEIGHT * 0.8), LOAD_BAR_INDETERM_COLOR,
-					0, barY, LOAD_BAR_HIGHLIGHT_COLOR);
+					0, barY + (int)(BAR_HEIGHT * 0.8), SwingConversions.toSwingColor(LOAD_BAR_INDETERM_COLOR),
+					0, barY, SwingConversions.toSwingColor(LOAD_BAR_HIGHLIGHT_COLOR));
 			((Graphics2D)g).setPaint(gp);
 		
@@ -311,6 +326,6 @@
 			
 			GradientPaint gp = new GradientPaint(
-					0, barY + (int)(BAR_HEIGHT * 0.8), LOAD_BAR_PROGRESS_COLOR,
-					0, barY, LOAD_BAR_HIGHLIGHT_COLOR);
+					0, barY + (int)(BAR_HEIGHT * 0.8), SwingConversions.toSwingColor(LOAD_BAR_PROGRESS_COLOR),
+					0, barY, SwingConversions.toSwingColor(LOAD_BAR_HIGHLIGHT_COLOR));
 			((Graphics2D)g).setPaint(gp);
 			
@@ -319,11 +334,11 @@
 		} 
 		
-		g.setColor(Color.DARK_GRAY);
+		g.setColor(SwingConversions.toSwingColor(Colour.DARK_GREY));
 		g.drawRect(barX, barY, barWidth, BAR_HEIGHT);
 		
 		if (loadState == LOAD_STATE_FAILED) 
-			g.setColor(Color.RED);
-		
-		else g.setColor(Color.BLACK);
+			g.setColor(SwingConversions.toSwingColor(Colour.RED));
+		
+		else g.setColor(SwingConversions.toSwingColor(Colour.BLACK));
 		
 
@@ -638,6 +653,6 @@
 			// Re-render loading state - if not expired
 			if (!expired) {
-				FrameGraphics.invalidateArea(new Rectangle(getX(), getY(), getWidth(), getHeight()));
-				FrameGraphics.requestRefresh(true);
+				DisplayController.invalidateArea(getBounds());
+				DisplayController.requestRefresh(true);
 			}
 		}
@@ -680,5 +695,5 @@
 			
 			// Only load if in view
-			if (!isFloating() && getParentFrame() != DisplayIO.getCurrentFrame())
+			if (!isFloating() && getParentFrame() != DisplayController.getCurrentFrame())
 				return;
 			
Index: /trunk/src/org/expeditee/items/widgets/JSWidget.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/JSWidget.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/JSWidget.java	(revision 1102)
@@ -32,5 +32,5 @@
 import javax.swing.JPanel;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.JSThreadable;
@@ -75,6 +75,6 @@
     
 	private static Text getSauce() {
-		Text source = new Text(DisplayIO.getCurrentFrame().getNextItemID(), "@iw: org.expeditee.items.widgets.JSWidget");
-		source.setParent(DisplayIO.getCurrentFrame());
+		Text source = new Text(DisplayController.getCurrentFrame().getNextItemID(), "@iw: org.expeditee.items.widgets.JSWidget");
+		source.setParent(DisplayController.getCurrentFrame());
 		return source;
 	}
@@ -172,5 +172,5 @@
     
     @Override
-	protected void paintLink(Graphics2D g) {
+	protected void paintLink() {
     	return;
 	}
Index: /trunk/src/org/expeditee/items/widgets/JfxBrowser.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/JfxBrowser.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/JfxBrowser.java	(revision 1102)
@@ -76,6 +76,7 @@
 import netscape.javascript.JSObject;
 
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.FrameMouseActions;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FreeItems;
 import org.expeditee.gui.MessageBay;
@@ -468,5 +469,5 @@
 				public void handle(KeyEvent e) {
 					// Hiding the cursor when typing, to be more Expeditee-like
-					DisplayIO.setCursor(org.expeditee.items.Item.HIDDEN_CURSOR);
+					DisplayController.setCursor(org.expeditee.items.Item.HIDDEN_CURSOR);
 				}
 			});
@@ -481,7 +482,7 @@
 					}
 					// Checking if the user has been typing - if so, move the cursor to the caret position
-					if (DisplayIO.getCursor() == Item.HIDDEN_CURSOR) {
-						DisplayIO.setCursor(org.expeditee.items.Item.TEXT_CURSOR);
-						DisplayIO.setCursorPosition(getCoordFromCaret(JfxBrowser.this._urlField));
+					if (DisplayController.getCursor() == Item.HIDDEN_CURSOR) {
+						DisplayController.setCursor(org.expeditee.items.Item.TEXT_CURSOR);
+						DisplayController.setCursorPosition(SwingConversions.fromSwingPoint(getCoordFromCaret(JfxBrowser.this._urlField)));
 					} else {
 						// Otherwise, move the caret to the cursor location
@@ -523,8 +524,8 @@
                 public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean newValue) {
 					if(newValue.booleanValue()) {
-						DisplayIO.setCursor(org.expeditee.items.Item.TEXT_CURSOR);
+						DisplayController.setCursor(org.expeditee.items.Item.TEXT_CURSOR);
 					} else {
 						// Restoring the standard cursor, since it is changed to a text cursor when focus is gained
-						DisplayIO.setCursor(org.expeditee.items.Item.DEFAULT_CURSOR);
+						DisplayController.setCursor(org.expeditee.items.Item.DEFAULT_CURSOR);
 					}
                 }
@@ -545,9 +546,9 @@
 					if (e.getButton() == MouseButton.SECONDARY) {
 						// Right mouse button released, so copy the selection (i.e. don't remove the original)
-						item = DisplayIO.getCurrentFrame().createNewText(JfxBrowser.this._urlField.getSelectedText());
-						FrameMouseActions.pickup(item);
+						item = DisplayController.getCurrentFrame().createNewText(JfxBrowser.this._urlField.getSelectedText());
+						StandardGestureActions.pickup(item);
 					} else if (e.getButton() == MouseButton.MIDDLE) {
 						// Middle mouse button released, so copy the selection then remove it from the URL field
-						item = DisplayIO.getCurrentFrame().createNewText(JfxBrowser.this._urlField.getSelectedText());
+						item = DisplayController.getCurrentFrame().createNewText(JfxBrowser.this._urlField.getSelectedText());
 						JfxBrowser.this._urlField.setText(
 								JfxBrowser.this._urlField.getText().substring(0, JfxBrowser.this._urlField.getSelection().getStart())
@@ -555,5 +556,5 @@
 										JfxBrowser.this._urlField.getText().length()));
 
-						FrameMouseActions.pickup(item);
+						StandardGestureActions.pickup(item);
 					}
                 }
@@ -660,6 +661,6 @@
     									
     									if (((String) style.call("getPropertyValue", new Object[] { "background-image" })).startsWith("url(")) {
-    										pic = WebParser.getBackgroundImageFromNode(node, style, DisplayIO.getCurrentFrame(), null,
-    											(float) FrameMouseActions.getX(), (float) FrameMouseActions.getY(), width, height);
+    										pic = WebParser.getBackgroundImageFromNode(node, style, DisplayController.getCurrentFrame(), null,
+    											(float) DisplayController.getMouseX(), (float) DisplayController.getMouseY(), width, height);
     										
     									} else {
@@ -667,6 +668,6 @@
     										if(node.getNodeName().toLowerCase().equals("img") && 
     												(imgSrc = ((JSObject) node).getMember("src").toString()) != null) {
-    											pic = WebParser.getImageFromUrl(imgSrc, null, DisplayIO.getCurrentFrame(),
-    													(float) FrameMouseActions.getX(), (float) FrameMouseActions.getY(), (int) width, null, null, null, null, null, 0, 0);
+    											pic = WebParser.getImageFromUrl(imgSrc, null, DisplayController.getCurrentFrame(),
+    													(float) DisplayController.getMouseX(), (float) DisplayController.getMouseY(), (int) width, null, null, null, null, null, 0, 0);
     										} else {
     											return;
@@ -685,6 +686,6 @@
     									}
     									
-    									pic.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
-                                		FrameMouseActions.pickup(pic);
+    									pic.setXY(DisplayController.getMouseX(), DisplayController.getMouseY());
+                                		StandardGestureActions.pickup(pic);
                             		} catch (Exception e1) {
     	                                // TODO Auto-generated catch block
@@ -714,23 +715,23 @@
 											+ ((JSObject)node).getMember("height")
 											+ ":" + src);
-									t.setParent(DisplayIO.getCurrentFrame());
-									t.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
+									t.setParent(DisplayController.getCurrentFrame());
+									t.setXY(DisplayController.getMouseX(), DisplayController.getMouseY());
 									JfxMedia media = new JfxMedia(t, new String[] { src });
-									FrameMouseActions.pickup(media.getItems());
+									StandardGestureActions.pickup(media.getItems());
 									
 								} else if(node.getNodeName().toLowerCase().equals("a") && ((JSObject)node).getMember("href") != null) {
 									// If a link is right clicked, copy the text content and give it an action to create 
 									// a new frame containing a browser pointing to the linked page
-									Text t = DisplayIO.getCurrentFrame().createNewText(((String) ((JSObject)node).getMember("textContent")).trim());
+									Text t = DisplayController.getCurrentFrame().createNewText(((String) ((JSObject)node).getMember("textContent")).trim());
 									t.addAction("createFrameWithBrowser " + (String) ((JSObject)node).getMember("href"));
-									t.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
-									FrameMouseActions.pickup(t);
+									t.setXY(DisplayController.getMouseX(), DisplayController.getMouseY());
+									StandardGestureActions.pickup(t);
 								}
 							}
 						} else {
 							// Copy text and attach to cursor
-							Text t = DisplayIO.getCurrentFrame().createNewText(selection);
-							t.setXY(FrameMouseActions.getX(), FrameMouseActions.getY());
-							FrameMouseActions.pickup(t);
+							Text t = DisplayController.getCurrentFrame().createNewText(selection);
+							t.setXY(DisplayController.getMouseX(), DisplayController.getMouseY());
+							StandardGestureActions.pickup(t);
 						}
 					}
@@ -871,5 +872,5 @@
 	public void getFrame() {
 		try {
-			WebParser.parsePageSimple(this, _webEngine, _webView, DisplayIO.getCurrentFrame());
+			WebParser.parsePageSimple(this, _webEngine, _webView, DisplayController.getCurrentFrame());
 		} catch (Exception e) {
 			e.printStackTrace();
@@ -886,5 +887,5 @@
 			new Thread(new Runnable() {
 				public void run() {
-					WebParser.parsePageSimple(JfxBrowser.this, JfxBrowser.this._webEngine, JfxBrowser.this._webView, DisplayIO.getCurrentFrame());
+					WebParser.parsePageSimple(JfxBrowser.this, JfxBrowser.this._webEngine, JfxBrowser.this._webView, DisplayController.getCurrentFrame());
 				}
 			}).start();
@@ -954,5 +955,5 @@
 		}
 
-		final int x = FrameMouseActions.getX() - this.getX(), y = FrameMouseActions.getY() - this.getY();
+		final int x = DisplayController.getMouseX() - this.getX(), y = DisplayController.getMouseY() - this.getY();
 		if(!this._urlField.getBoundsInParent().contains(x, y)) {
 			// fails if not clicking on urlField
Index: /trunk/src/org/expeditee/items/widgets/MemoryMonitor.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/MemoryMonitor.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/MemoryMonitor.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.items.widgets;
 
-import java.awt.Color;
 import java.awt.Font;
 import java.awt.Graphics;
@@ -27,4 +26,7 @@
 import javax.swing.SwingUtilities;
 
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
+import org.expeditee.gio.swing.SwingMiscManager;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.Text;
@@ -36,5 +38,5 @@
  *
  */
-public class MemoryMonitor extends InteractiveWidget {
+public class MemoryMonitor extends SwingWidget {
 	
 	private long totalMemoryInBytes;
@@ -63,6 +65,6 @@
 	
 	@Override
-	public void paint(Graphics g) {
-		
+	public void paintSwingWidget(Graphics2D g)
+	{
 		int height = getHeight();
 		int width = getWidth();
@@ -70,26 +72,24 @@
 		int memHeight = (int)(height * currentMemoryUsage);
 		
-		Color memColor;
+		Colour memColor;
 		if (currentMemoryUsage > 0.8f) {
-			memColor = Color.RED;
+			memColor = Colour.RED;
 		} else if (currentMemoryUsage > 0.5f) {
-			memColor = Color.ORANGE;
+			memColor = Colour.ORANGE;
 		} else  {
-			memColor = Color.GREEN;
+			memColor = Colour.GREEN;
 		}
 		
-		g.setColor(memColor);
+		g.setColor(SwingConversions.toSwingColor(memColor));
 		g.fillRect(getX(), getY() + height - memHeight, width, memHeight);
 		
-		g.setColor(Color.WHITE);
+		g.setColor(SwingConversions.toSwingColor(Colour.WHITE));
 		g.fillRect(getX(), getY(), width, height - memHeight);
 		
 		int percent = (int)(currentMemoryUsage * 100.0f);
 		
-		g.setColor(Color.BLACK);
+		g.setColor(SwingConversions.toSwingColor(Colour.BLACK));
 		g.setFont(USAGE_FONT);
 		g.drawString(percent + "%", getX() + 12, getY() + (height / 2) + 8);
-		
-		paintLink((Graphics2D)g);
 	}
 
Index: /trunk/src/org/expeditee/items/widgets/Password.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/Password.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/Password.java	(revision 1102)
@@ -32,5 +32,5 @@
  * @author jts21
  */
-public class Password extends InteractiveWidget {
+public class Password extends SwingWidget {
 
 	private JPasswordField passwordField;
Index: /trunk/src/org/expeditee/items/widgets/RefreshButton.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/RefreshButton.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/RefreshButton.java	(revision 1102)
@@ -4,5 +4,5 @@
 import java.awt.event.ActionListener;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
@@ -20,10 +20,10 @@
 	        public void actionPerformed(ActionEvent e) {	        	
 	         
-	           Frame f = DisplayIO.getCurrentFrame();	  
+	           Frame f = DisplayController.getCurrentFrame();	  
 	           try{
 	        	   FrameIO.ForceSaveFrame(f);
 	        	   Frame g = FrameIO.LoadRestoreFrame(f);	
-	        	   DisplayIO.setCurrentFrame(g, false);
-		           FrameGraphics.refresh(true);
+	        	   DisplayController.setCurrentFrame(g, false);
+		           DisplayController.requestRefresh(true);
 	           }
 	           catch(Exception e1){
Index: /trunk/src/org/expeditee/items/widgets/RubbishBin.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/RubbishBin.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/RubbishBin.java	(revision 1102)
@@ -4,57 +4,69 @@
 import java.awt.event.ActionListener;
 
-import org.expeditee.gui.DisplayIO;
-import org.expeditee.gui.FrameMouseActions;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FreeItems;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
 
-//When the Rubbish Bin Widget is clicked by any of the mouse buttons, whatever is currently being picked up by the mouse is destroyed
-public class RubbishBin extends ButtonWidget{	
-		
-	public RubbishBin(Text source, String[] args){	
-					
+/**
+ * When the Rubbish Bin Widget is clicked by any of the mouse buttons,
+ * whatever is currently being picked up by the mouse is destroyed.
+ * 
+ * @author cts16
+ */
+public class RubbishBin extends ButtonWidget
+{	
+	public RubbishBin(Text source, String[] args)
+	{
 		super(80, "org/expeditee/assets/images/bin.svg", source, args);
 
-		clicked_.addActionListener(new ActionListener() {
-	        public void actionPerformed(ActionEvent e) {	
+		clicked_.addActionListener(new ActionListener()
+		{
+	        public void actionPerformed(ActionEvent e)
+	        {	
 	        	
 	        }          
-	     });		
+		});		
 	}
-	public boolean ItemsLeftClickDropped() {
-		
+	
+	public boolean ItemsLeftClickDropped()
+	{
 		//Find what the mouse was holding at the time and delete it
 		Item freeItems = FreeItems.getItemAttachedToCursor();
-		if( freeItems != null){
-			freeItems.setParent(DisplayIO.getCurrentFrame());
+		
+		if( freeItems != null) {
+			freeItems.setParent(DisplayController.getCurrentFrame());
 			
-			try{
-			
-			FrameMouseActions.delete(freeItems);		
-			}
-			catch(Exception e){
-				
+			try {
+				StandardGestureActions.delete(freeItems, null, null, false);		
+			} catch(Exception e) {
 				e.printStackTrace();
 			}			
 		}
+		
 		return true;
 	}
 	
 	@Override
-	protected String[] getArgs() {
+	protected String[] getArgs()
+	{
 		// TODO Auto-generated method stub
 		return null;
 	}
-	//this should be a generic method for any widget that is clicked while an item is being held
-	public boolean itemHeldWhileClicked(InteractiveWidget iw){
-			
+	
+	/**
+	 * This should be a generic method for any widget that is clicked while an item is being held.
+	 */
+	public boolean itemHeldWhileClicked(Widget iw)
+	{
 		ItemsLeftClickDropped();
-		return true;
-			
-	}
-	public boolean getdropInteractableStatus(){
+		
 		return true;
 	}
 	
+	public boolean getdropInteractableStatus()
+	{
+		return true;
+	}
 }
Index: /trunk/src/org/expeditee/items/widgets/SampleWidget2.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/SampleWidget2.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/SampleWidget2.java	(revision 1102)
@@ -19,6 +19,4 @@
 package org.expeditee.items.widgets;
 
-
-import java.awt.Color;
 import java.awt.FlowLayout;
 import java.awt.Font;
@@ -32,7 +30,9 @@
 import javax.swing.JToggleButton;
 
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.items.Text;
 
-public class SampleWidget2 extends InteractiveWidget {
+public class SampleWidget2 extends SwingWidget {
 	
 	private JComboBox _combo;
@@ -47,5 +47,5 @@
 		
 		JPanel p = new JPanel(new FlowLayout());
-		p.setBackground(new Color(255,228,195));
+		p.setBackground(SwingConversions.toSwingColor(Colour.FromRGB255(255,228,195)));
 
 		JLabel lbl = new JLabel("This is an example InteractiveWidget!");
Index: /trunk/src/org/expeditee/items/widgets/Undo.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/Undo.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/Undo.java	(revision 1102)
@@ -4,5 +4,5 @@
 import java.awt.event.ActionListener;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.items.Text;
 
@@ -17,5 +17,5 @@
 	        public void actionPerformed(ActionEvent e) {
 	        		           
-	           DisplayIO.getCurrentFrame().undo();		     
+	           DisplayController.getCurrentFrame().undo();		     
 	        }          
 	     });		
Index: /trunk/src/org/expeditee/items/widgets/WidgetCacheManager.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/WidgetCacheManager.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/WidgetCacheManager.java	(revision 1102)
@@ -25,5 +25,5 @@
 import java.util.Set;
 
-import org.expeditee.gui.DisplayIOObserver;
+import org.expeditee.gui.DisplayObserver;
 import org.expeditee.gui.FrameIO;
 
@@ -37,5 +37,5 @@
  *
  */
-public final class WidgetCacheManager implements DisplayIOObserver {
+public final class WidgetCacheManager implements DisplayObserver {
 	
 	private static HashMap<HeavyDutyInteractiveWidget, Integer> transientWidgets = new HashMap<HeavyDutyInteractiveWidget, Integer>();
Index: /trunk/src/org/expeditee/items/widgets/WidgetCorner.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/WidgetCorner.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/WidgetCorner.java	(revision 1102)
@@ -19,9 +19,9 @@
 package org.expeditee.items.widgets;
 
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Polygon;
 import java.util.List;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.PolygonBounds;
 import org.expeditee.items.Dot;
 import org.expeditee.items.ItemParentStateChangedEvent;
@@ -30,7 +30,7 @@
 public class WidgetCorner extends Dot {
 
-	private InteractiveWidget _widgetSource;
-
-	WidgetCorner(int x, int y, int id, InteractiveWidget widgetSource) {
+	private Widget _widgetSource;
+
+	WidgetCorner(int x, int y, int id, Widget widgetSource) {
 		super(x, y, id);
 
@@ -38,11 +38,4 @@
 			throw new NullPointerException("widgetSource");
 		_widgetSource = widgetSource;
-	}
-
-	@Override
-	public void updatePolygon() {
-		super.updatePolygon();
-		if (_widgetSource != null)
-			_widgetSource.onBoundsChanged();
 	}
 
@@ -81,28 +74,30 @@
 
 	@Override
-	public void onParentStateChanged(ItemParentStateChangedEvent e) {
+	public void onParentStateChanged(ItemParentStateChangedEvent e)
+	{
 		super.onParentStateChanged(e);
 		_widgetSource.onParentStateChanged(e);
 	}
 
-	public InteractiveWidget getWidgetSource() {
+	public Widget getWidgetSource() {
 		return _widgetSource;
 	}
 
 	@Override
-	public void paint(Graphics2D g) {
+	public void paint()
+	{
 		// For fixed widgets, always have corner selected with connected context
-		HighlightMode tmp = _mode; // save mode
-		if (_mode == HighlightMode.Normal && _widgetSource.isFixedSize()) {
-			_mode = HighlightMode.Connected; // draw as connected context for
+		HighlightMode tmp = _highlightMode; // save mode
+		if (_highlightMode == HighlightMode.Normal && _widgetSource.isFixedSize()) {
+			_highlightMode = HighlightMode.Connected; // draw as connected context for
 			// fixed widgets
 		}
-		super.paint(g);
-		_mode = tmp; // restore mode
-	}
-
-	@Override
-	public void paintFill(Graphics2D g) {
-		_widgetSource.paintFill(g); // only paints a fill if floating
+		super.paint();
+		_highlightMode = tmp; // restore mode
+	}
+
+	@Override
+	public void paintFill() {
+		_widgetSource.paintFill(); // only paints a fill if floating
 	}
 
@@ -127,5 +122,5 @@
 
 	@Override
-	public void setArrowhead(Polygon arrow) {
+	public void setArrowhead(PolygonBounds arrow) {
 	}
 
@@ -139,5 +134,5 @@
 
 	@Override
-	public void setBackgroundColor(Color c) {
+	public void setBackgroundColor(Colour c) {
 		if (_widgetSource != null) {
 			super.setBackgroundColor(c);
@@ -147,9 +142,9 @@
 
 	@Override
-	public void setBottomShadowColor(Color bottom) {
-	}
-
-	@Override
-	public void setFillColor(Color c) {
+	public void setBottomShadowColor(Colour bottom) {
+	}
+
+	@Override
+	public void setFillColor(Colour c) {
 	}
 
@@ -186,40 +181,38 @@
 	}
 
-	public void setAnchorCornerX(Float anchorLeft, Float anchorRight) {
-		_anchorLeft = anchorLeft;
-		_anchorRight = anchorRight;
-	}
-	
-	public void setAnchorCornerY(Float anchorTop, Float anchorBottom) {
-		_anchorTop = anchorTop;
-		_anchorBottom= anchorBottom;
-	}
-	
-	@Override
-	public void setAnchorLeft(Float anchor) {
+	public void setAnchorCornerX(Integer anchorLeft, Integer anchorRight)
+	{
+		_anchoring.setLeftAnchor(anchorLeft);
+		_anchoring.setRightAnchor(anchorRight);
+	}
+	
+	public void setAnchorCornerY(Integer anchorTop, Integer anchorBottom)
+	{
+		_anchoring.setTopAnchor(anchorTop);
+		_anchoring.setBottomAnchor(anchorBottom);
+	}
+	
+	@Override
+	public void setAnchorLeft(Integer anchor) {
 		_widgetSource.setAnchorLeft(anchor);
-		_anchorLeft = anchor;
-		_anchorRight = null;
-	}
-
-	@Override
-	public void setAnchorRight(Float anchor) {
+		_anchoring.setLeftAnchor(anchor);
+	}
+
+	@Override
+	public void setAnchorRight(Integer anchor) {
 		_widgetSource.setAnchorRight(anchor);
-		_anchorLeft = null;
-		_anchorRight = anchor;
-	}
-	
-	@Override
-	public void setAnchorTop(Float anchor) {
+		_anchoring.setRightAnchor(anchor);
+	}
+	
+	@Override
+	public void setAnchorTop(Integer anchor) {
 		_widgetSource.setAnchorTop(anchor);
-		_anchorTop = anchor;
-		_anchorBottom = null;
-	}
-
-	@Override
-	public void setAnchorBottom(Float anchor) {
+		_anchoring.setTopAnchor(anchor);
+	}
+
+	@Override
+	public void setAnchorBottom(Integer anchor) {
 		_widgetSource.setAnchorBottom(anchor);
-		_anchorTop = null;
-		_anchorBottom = anchor;
+		_anchoring.setBottomAnchor(anchor);
 	}
 	
@@ -251,7 +244,7 @@
 
 	@Override
-	public boolean contains(int x, int y) {
-		return super.contains(x, y)
-				&& !_widgetSource.getBounds().contains(x, y);
+	public boolean contains(Point p)
+	{
+		return super.contains(p) && !_widgetSource.getBounds().contains(p);
 	}
 
@@ -268,5 +261,5 @@
 
 	@Override
-	public void setColor(Color color) {
+	public void setColor(Colour color) {
 		if (_widgetSource != null) {
 			super.setColor(color);
Index: /trunk/src/org/expeditee/items/widgets/WidgetEdge.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/WidgetEdge.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/WidgetEdge.java	(revision 1102)
@@ -19,8 +19,9 @@
 package org.expeditee.items.widgets;
 
-import java.awt.Color;
-import java.awt.Polygon;
 import java.util.List;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.core.bounds.PolygonBounds;
 import org.expeditee.items.Item;
 import org.expeditee.items.Line;
@@ -28,5 +29,5 @@
 
 /**
- * Widget edges define the boundries of an interactive widget.
+ * Widget edges define the boundaries of an interactive widget.
  * 
  * @author Brook Novak
@@ -34,8 +35,8 @@
 public class WidgetEdge extends Line {
 
-	private InteractiveWidget _widgetSource;
+	private Widget _widgetSource;
 
 	WidgetEdge(WidgetCorner start, WidgetCorner end, int id,
-			InteractiveWidget widgetSource) {
+			Widget widgetSource) {
 		super(start, end, id);
 		
@@ -45,5 +46,5 @@
 	}
 
-	public InteractiveWidget getWidgetSource() {
+	public Widget getWidgetSource() {
 		return _widgetSource;
 	}
@@ -89,5 +90,5 @@
 
 	@Override
-	public void setArrowhead(Polygon arrow) {
+	public void setArrowhead(PolygonBounds arrow) {
 	}
 
@@ -101,9 +102,9 @@
 
 	@Override
-	public void setBottomShadowColor(Color bottom) {
-	}
-
-	@Override
-	public void setFillColor(Color c) {
+	public void setBottomShadowColor(Colour bottom) {
+	}
+
+	@Override
+	public void setFillColor(Colour c) {
 	}
 
@@ -121,20 +122,20 @@
 	
 	@Override
-	public void setAnchorTop(Float anchor) {
+	public void setAnchorTop(Integer anchor) {
 		_widgetSource.setAnchorTop(anchor);
 	}
 
 	@Override
-	public void setAnchorBottom(Float anchor) {
+	public void setAnchorBottom(Integer anchor) {
 		_widgetSource.setAnchorBottom(anchor);
 	}
 
 	@Override
-	public void setAnchorLeft(Float anchor) {
+	public void setAnchorLeft(Integer anchor) {
 		_widgetSource.setAnchorLeft(anchor);
 	}
 
 	@Override
-	public void setAnchorRight(Float anchor) {
+	public void setAnchorRight(Integer anchor) {
 		_widgetSource.setAnchorRight(anchor);
 	}
@@ -156,30 +157,30 @@
 	
 	@Override
-	public Float getAnchorTop() {
+	public Integer getAnchorTop() {
 		return _widgetSource.getSource().getAnchorTop();
 	}
 
 	@Override
-	public Float getAnchorBottom() {
+	public Integer getAnchorBottom() {
 		return _widgetSource.getSource().getAnchorBottom();
 	}
 	
 	@Override
-	public Float getAnchorLeft() {
+	public Integer getAnchorLeft() {
 		return _widgetSource.getSource().getAnchorLeft();
 	}
 
 	@Override
-	public Float getAnchorRight() {
+	public Integer getAnchorRight() {
 		return _widgetSource.getSource().getAnchorRight();
 	}
 	
 	@Override
-	public boolean contains(int x, int y) {
-		return super.contains(x, y) && !_widgetSource.getBounds().contains(x, y);
-	}
-
-	@Override
-	public Polygon getEnclosedShape() {
+	public boolean contains(Point p) {
+		return super.contains(p) && !_widgetSource.getBounds().contains(p);
+	}
+
+	@Override
+	public PolygonBounds getEnclosedShape() {
 		return getStartItem().getEnclosedShape();
 	}
@@ -219,5 +220,5 @@
 	
 	@Override
-	public void setBackgroundColor(Color c) {
+	public void setBackgroundColor(Colour c) {
 		if (_widgetSource != null) {
 			super.setBackgroundColor(c);
@@ -227,5 +228,5 @@
 	
 	@Override
-	public void setColor(Color c) {
+	public void setColor(Colour c) {
 		if (_widgetSource != null) {
 			super.setColor(c);
Index: /trunk/src/org/expeditee/items/widgets/charts/AbstractCategory.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/charts/AbstractCategory.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/charts/AbstractCategory.java	(revision 1102)
@@ -19,7 +19,8 @@
 package org.expeditee.items.widgets.charts;
 
-import java.awt.Color;
 import java.util.Collection;
 
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.gui.AttributeValuePair;
 import org.expeditee.items.Text;
@@ -49,5 +50,5 @@
 			Collection<Text> items, boolean swap) {
 		boolean foundData = false;
-		Color newColor = null;
+		Colour newColor = null;
 		for (Text i : items) {
 			try {
@@ -61,5 +62,5 @@
 									categoryName);
 							if (_paints.get(attribute) == null) {
-								_paints.put(attribute, i.getBackgroundColor());
+								_paints.put(attribute, SwingConversions.toSwingColor(i.getBackgroundColor()));
 							}
 						} else {
@@ -77,5 +78,5 @@
 		}
 		if (foundData && !swap) {
-			_paints.put(categoryName, newColor);
+			_paints.put(categoryName, SwingConversions.toSwingColor(newColor));
 		}
 		return foundData;
Index: /trunk/src/org/expeditee/items/widgets/charts/AbstractChart.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/charts/AbstractChart.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/charts/AbstractChart.java	(revision 1102)
@@ -20,9 +20,7 @@
 
 import java.awt.BasicStroke;
-import java.awt.Color;
 import java.awt.Component;
 import java.awt.Font;
 import java.awt.Paint;
-import java.awt.Point;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
@@ -35,10 +33,13 @@
 import javax.swing.JPanel;
 
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.gui.ColorUtils;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.gui.FrameKeyboardActions;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FunctionKey;
 import org.expeditee.items.Text;
@@ -103,16 +104,15 @@
 				case SizeUp:
 					invalidateLink();
-					FrameKeyboardActions.SetSize(getFirstCorner(), 1, false,
-							true, false);
+					StandardGestureActions.SetSize(getFirstCorner(), 1, false, true, false);
 					invalidateSelf();
-					FrameGraphics.refresh(true);
+					DisplayController.requestRefresh(true);
 					// FrameGraphics.requestRefresh(true);
 					break;
 				case SizeDown:
 					invalidateLink();
-					FrameKeyboardActions.SetSize(getFirstCorner(), -1, false,
+					StandardGestureActions.SetSize(getFirstCorner(), -1, false,
 							true, false);
 					invalidateSelf();
-					FrameGraphics.refresh(true);
+					DisplayController.requestRefresh(true);
 					// FrameGraphics.ForceRepaint();
 					// FrameGraphics.refresh(true);
@@ -125,5 +125,5 @@
 							setSourceFillColor(null);
 						} else {
-							Color newColor = ColorUtils.getNextColor(
+							Colour newColor = ColorUtils.getNextColor(
 									getSource().getFillColor(),
 									TemplateSettings.BackgroundColorWheel.get(), null);
@@ -134,5 +134,5 @@
 							setBackgroundColor(null);
 						} else {
-							Color newColor = ColorUtils.getNextColor(
+							Colour newColor = ColorUtils.getNextColor(
 									getSource().getColor(), TemplateSettings.ColorWheel.get(),
 									null);
@@ -141,4 +141,6 @@
 					}
 					break;
+				default:
+					break;
 				}
 			}
@@ -148,5 +150,5 @@
 
 			public void keyTyped(KeyEvent e) {
-				FrameKeyboardActions.processChar(e.getKeyChar(), e
+				StandardGestureActions.processChar(e.getKeyChar(), e
 						.isShiftDown());
 			}
@@ -155,5 +157,5 @@
 
 			public void mouseClicked(MouseEvent e) {
-				FrameMouseActions.getInstance().mouseClicked(translateEvent(e));
+				//StandardGestureActions.mouseClicked(translateEvent(e));
 			}
 
@@ -167,5 +169,5 @@
 
 			public void mousePressed(MouseEvent e) {
-				FrameMouseActions.getInstance().mousePressed(translateEvent(e));
+				//StandardGestureActions.mousePressed(translateEvent(e));
 			}
 
@@ -180,6 +182,5 @@
 
 			public void mouseReleased(MouseEvent e) {
-				FrameMouseActions.getInstance()
-						.mouseReleased(translateEvent(e));
+				//StandardGestureActions.mouseReleased(translateEvent(e));
 			}
 
@@ -272,7 +273,7 @@
 				if (foundData |= addCategoryData(categoryName, linkFrame
 						.getNonAnnotationText(true), swap)) {
-					Color backgroundColor = category.getBackgroundColor();
+					Colour backgroundColor = category.getBackgroundColor();
 					if (backgroundColor != null)
-						_paints.put(categoryName, backgroundColor);
+						_paints.put(categoryName, SwingConversions.toSwingColor(backgroundColor));
 					addSubject(linkFrame);
 				}
@@ -307,5 +308,5 @@
 
 	@Override
-	public void setBackgroundColor(Color c) {
+	public void setBackgroundColor(Colour c) {
 		super.setBackgroundColor(c);
 		if (_chart == null)
@@ -314,10 +315,10 @@
 			_chart.setBackgroundPaint(JFreeChart.DEFAULT_BACKGROUND_PAINT);
 		} else {
-			_chart.setBackgroundPaint(c);
-		}
-	}
-
-	@Override
-	public void setSourceColor(Color c) {
+			_chart.setBackgroundPaint(SwingConversions.toSwingColor(c));
+		}
+	}
+
+	@Override
+	public void setSourceColor(Colour c) {
 		super.setSourceColor(c);
 		if (_chart == null)
@@ -326,5 +327,5 @@
 			_chart.getTitle().setPaint(TextTitle.DEFAULT_TEXT_PAINT);
 		} else {
-			_chart.getTitle().setPaint(c);
+			_chart.getTitle().setPaint(SwingConversions.toSwingColor(c));
 		}
 		for (Title t : _chart.getSubtitles()) {
@@ -332,5 +333,5 @@
 				t.setPaint(TextTitle.DEFAULT_TEXT_PAINT);
 			} else {
-				t.setPaint(c);
+				t.setPaint(SwingConversions.toSwingColor(c));
 			}
 		}
@@ -338,13 +339,13 @@
 		if (legend != null) {
 			if (c == null) {
-				legend.setFrame(new BlockBorder(Color.black));
+				legend.setFrame(new BlockBorder(SwingConversions.toSwingColor(Colour.BLACK)));
 			} else {
-				legend.setFrame(new BlockBorder(c));
-			}
-		}
-	}
-
-	@Override
-	public void setSourceBorderColor(Color c) {
+				legend.setFrame(new BlockBorder(SwingConversions.toSwingColor(c)));
+			}
+		}
+	}
+
+	@Override
+	public void setSourceBorderColor(Colour c) {
 		super.setSourceBorderColor(c);
 		if (_chart == null)
@@ -353,10 +354,10 @@
 			_chart.getPlot().setOutlinePaint(Plot.DEFAULT_OUTLINE_PAINT);
 		} else {
-			_chart.getPlot().setOutlinePaint(c);
-		}
-	}
-
-	@Override
-	public void setSourceFillColor(Color c) {
+			_chart.getPlot().setOutlinePaint(SwingConversions.toSwingColor(c));
+		}
+	}
+
+	@Override
+	public void setSourceFillColor(Colour c) {
 		super.setSourceFillColor(c);
 		if (_chart == null)
@@ -368,7 +369,7 @@
 				legend.setBackgroundPaint(null);
 		} else {
-			_chart.getPlot().setBackgroundPaint(c);
+			_chart.getPlot().setBackgroundPaint(SwingConversions.toSwingColor(c));
 			if (legend != null)
-				legend.setBackgroundPaint(c);
+				legend.setBackgroundPaint(SwingConversions.toSwingColor(c));
 		}
 	}
@@ -387,5 +388,5 @@
 		if (legend != null) {
 			legend.setFrame(new BlockBorder(newThickness, newThickness,
-					newThickness, newThickness, getSource().getPaintColor()));
+					newThickness, newThickness, SwingConversions.toSwingColor(getSource().getPaintColor())));
 			legend.setItemFont(legend.getItemFont().deriveFont(fontSize));
 			float pad = newThickness + 1;
Index: /trunk/src/org/expeditee/items/widgets/charts/AbstractPie.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/charts/AbstractPie.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/charts/AbstractPie.java	(revision 1102)
@@ -20,6 +20,7 @@
 
 import java.awt.BasicStroke;
-import java.awt.Color;
 
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.gui.AttributeValuePair;
 import org.expeditee.gui.Frame;
@@ -85,5 +86,5 @@
 				try {
 					_data.setValue(avp.getAttribute(), avp.getDoubleValue());
-					_paints.put(avp.getAttribute(), t.getBackgroundColor());
+					_paints.put(avp.getAttribute(), SwingConversions.toSwingColor(t.getBackgroundColor()));
 				} catch (NumberFormatException nfe) {
 
@@ -94,5 +95,5 @@
 
 	@Override
-	public void setSourceBorderColor(Color c) {
+	public void setSourceBorderColor(Colour c) {
 		super.setSourceBorderColor(c);
 		if (getChart() == null)
@@ -106,18 +107,18 @@
 			plot.setShadowPaint(PiePlot.DEFAULT_SHADOW_PAINT);
 		} else {
-			plot.setBaseSectionOutlinePaint(c);
-			plot.setLabelLinkPaint(c);
-			plot.setLabelOutlinePaint(c);
-			Color newC = c.darker();
-			Color faded = new Color(newC.getRed(), newC.getGreen(), newC
-					.getBlue(), 128);
+			plot.setBaseSectionOutlinePaint(SwingConversions.toSwingColor(c));
+			plot.setLabelLinkPaint(SwingConversions.toSwingColor(c));
+			plot.setLabelOutlinePaint(SwingConversions.toSwingColor(c));
+			Colour newC = c.darker();
+			Colour faded = new Colour(newC.getRed(), newC.getGreen(), newC
+					.getBlue(), Colour.FromComponent255(128));
 
-			plot.setLabelShadowPaint(faded);
-			plot.setShadowPaint(c);
+			plot.setLabelShadowPaint(SwingConversions.toSwingColor(faded));
+			plot.setShadowPaint(SwingConversions.toSwingColor(c));
 		}
 	}
 
 	@Override
-	public void setSourceColor(Color c) {
+	public void setSourceColor(Colour c) {
 		super.setSourceColor(c);
 		if (getChart() == null)
@@ -127,5 +128,5 @@
 			plot.setLabelPaint(PiePlot.DEFAULT_LABEL_PAINT);
 		} else {
-			plot.setLabelPaint(c);
+			plot.setLabelPaint(SwingConversions.toSwingColor(c));
 		}
 	}
Index: /trunk/src/org/expeditee/items/widgets/charts/AbstractValueAxis.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/charts/AbstractValueAxis.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/charts/AbstractValueAxis.java	(revision 1102)
@@ -20,7 +20,8 @@
 
 import java.awt.BasicStroke;
-import java.awt.Color;
 import java.awt.Stroke;
 
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.gui.Frame;
 import org.expeditee.items.Text;
@@ -56,5 +57,5 @@
 
 	@Override
-	public void setSourceColor(Color c) {
+	public void setSourceColor(Colour c) {
 		super.setSourceColor(c);
 		if (getChart() == null)
@@ -70,13 +71,13 @@
 					.setTickLabelPaint(Axis.DEFAULT_TICK_LABEL_PAINT);
 		} else {
-			plot.getDomainAxis().setLabelPaint(c);
-			plot.getRangeAxis().setLabelPaint(c);
-			plot.getDomainAxis().setTickLabelPaint(c);
-			plot.getRangeAxis().setTickLabelPaint(c);
+			plot.getDomainAxis().setLabelPaint(SwingConversions.toSwingColor(c));
+			plot.getRangeAxis().setLabelPaint(SwingConversions.toSwingColor(c));
+			plot.getDomainAxis().setTickLabelPaint(SwingConversions.toSwingColor(c));
+			plot.getRangeAxis().setTickLabelPaint(SwingConversions.toSwingColor(c));
 		}
 	}
 
 	@Override
-	public void setSourceBorderColor(Color c) {
+	public void setSourceBorderColor(Colour c) {
 		super.setSourceBorderColor(c);
 		if (getChart() == null)
@@ -89,9 +90,9 @@
 			plot.getRangeAxis().setTickMarkPaint(Plot.DEFAULT_OUTLINE_PAINT);
 		} else {
-			Color brighter = c.brighter();
-			plot.setDomainGridlinePaint(brighter);
-			plot.setRangeGridlinePaint(brighter);
-			plot.getDomainAxis().setTickMarkPaint(c);
-			plot.getRangeAxis().setTickMarkPaint(c);
+			Colour brighter = c.brighter();
+			plot.setDomainGridlinePaint(SwingConversions.toSwingColor(brighter));
+			plot.setRangeGridlinePaint(SwingConversions.toSwingColor(brighter));
+			plot.getDomainAxis().setTickMarkPaint(SwingConversions.toSwingColor(c));
+			plot.getRangeAxis().setTickMarkPaint(SwingConversions.toSwingColor(c));
 		}
 	}
Index: /trunk/src/org/expeditee/items/widgets/charts/AbstractXY.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/charts/AbstractXY.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/charts/AbstractXY.java	(revision 1102)
@@ -19,8 +19,9 @@
 package org.expeditee.items.widgets.charts;
 
-import java.awt.Color;
 import java.util.Collection;
 import java.util.HashSet;
 
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.gui.AttributeValuePair;
 import org.expeditee.items.Item;
@@ -55,5 +56,5 @@
 			Collection<Text> items, boolean swap) {
 		XYSeries newSeries = new XYSeries(categoryName);
-		Color categoryColor = null;
+		Colour categoryColor = null;
 		boolean foundData = false;
 		Collection<Item> seen = new HashSet<Item>();
@@ -123,5 +124,5 @@
 		if (foundData) {
 			_data.addSeries(newSeries);
-			_paints.put(categoryName, categoryColor);
+			_paints.put(categoryName, SwingConversions.toSwingColor(categoryColor));
 		}
 		return foundData;
Index: /trunk/src/org/expeditee/items/widgets/charts/Polar.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/charts/Polar.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/charts/Polar.java	(revision 1102)
@@ -19,6 +19,6 @@
 package org.expeditee.items.widgets.charts;
 
-import java.awt.Color;
-
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.items.Text;
 import org.jfree.chart.ChartFactory;
@@ -43,5 +43,5 @@
 
 	@Override
-	public void setSourceColor(Color c) {
+	public void setSourceColor(Colour c) {
 		super.setSourceColor(c);
 		if (getChart() == null)
@@ -53,5 +53,5 @@
 			plot.setAngleLabelPaint(Axis.DEFAULT_AXIS_LABEL_PAINT);
 		} else {
-			plot.setAngleLabelPaint(c);
+			plot.setAngleLabelPaint(SwingConversions.toSwingColor(c));
 		}
 	}
Index: /trunk/src/org/expeditee/items/widgets/charts/TimeSeries.java
===================================================================
--- /trunk/src/org/expeditee/items/widgets/charts/TimeSeries.java	(revision 1101)
+++ /trunk/src/org/expeditee/items/widgets/charts/TimeSeries.java	(revision 1102)
@@ -19,5 +19,4 @@
 package org.expeditee.items.widgets.charts;
 
-import java.awt.Color;
 import java.text.DateFormat;
 import java.text.ParseException;
@@ -27,4 +26,7 @@
 import java.util.Date;
 
+import org.expeditee.Util;
+import org.expeditee.core.Colour;
+import org.expeditee.gio.swing.SwingConversions;
 import org.expeditee.gui.AttributeValuePair;
 import org.expeditee.gui.Frame;
@@ -100,5 +102,5 @@
 			String startDateString = dataFrame.getAnnotationValue("start");
 			if (startDateString != null) {
-				_startDate = parseDate(startDateString);
+				_startDate = Util.parseDate(startDateString);
 			}
 		} catch (Exception e) {
@@ -135,5 +137,5 @@
 
 		boolean foundData = false;
-		Color newColor = null;
+		Colour newColor = null;
 		for (Text i : items) {
 			if (!i.isLineEnd()) {
@@ -157,5 +159,5 @@
 						RegularTimePeriod rtp = null;
 						if (attribute == null) {
-							Date date = parseDate(avp.getAttribute());
+							Date date = Util.parseDate(avp.getAttribute());
 							rtp = _periodType.getConstructor(
 									new Class[] { Date.class }).newInstance(
@@ -212,27 +214,7 @@
 		if (foundData) {
 			_data.addSeries(newSeries);
-			_paints.put(categoryName, newColor);
+			_paints.put(categoryName, SwingConversions.toSwingColor(newColor));
 		}
 		return foundData;
 	}
-
-	/**
-	 * @param avp
-	 * @return
-	 * @throws ParseException
-	 */
-	public static Date parseDate(String dateString) throws ParseException {
-		// Select the best match for a date or time format
-		DateFormat df = null;
-		if (dateString.length() > Formatter.DATE_FORMAT
-				.length()) {
-			df = new SimpleDateFormat(Formatter.DATE_TIME_FORMAT);
-		} else if (dateString.length() <= Formatter.TIME_FORMAT.length()) {
-			df = new SimpleDateFormat(Formatter.TIME_FORMAT);
-		}else {
-			df = new SimpleDateFormat(Formatter.DATE_FORMAT);
-		}
-		Date date = df.parse(dateString);
-		return date;
-	}
 }
Index: /trunk/src/org/expeditee/reflection/PackageLoader.java
===================================================================
--- /trunk/src/org/expeditee/reflection/PackageLoader.java	(revision 1101)
+++ /trunk/src/org/expeditee/reflection/PackageLoader.java	(revision 1102)
@@ -36,271 +36,269 @@
 public class PackageLoader {
 
-    // The following is adapted from:
-    // http://stackoverflow.com/questions/1456930/how-do-i-read-all-classes-from-a-java-package-in-the-classpath
-
-    public static List<Class<?>> getClassesNew(String packageName)
-	    throws ClassNotFoundException {
-
-	ClassLoader classLoader = Thread.currentThread()
-		.getContextClassLoader();
-
-	ArrayList<String> names = new ArrayList<String>();
-	;
-	final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
-
-	String realPackageName = packageName;
-	packageName = packageName.replace(".", "/");
-	URL packageURL = classLoader.getResource(packageName);
-
-	if (packageURL.getProtocol().equals("jar")) {
-
-	    // build jar file name, then loop through zipped entries
-
-	    String jarFileNameUndecoded = packageURL.getFile();
-
-	    try {
-		JarURLConnection ju_connection = (JarURLConnection) packageURL
-			.openConnection();
-		JarFile jf = ju_connection.getJarFile();
-
-		Enumeration<JarEntry> jarEntries = jf.entries();
-		while (jarEntries.hasMoreElements()) {
-		    String entryName = jarEntries.nextElement().getName();
-
-		    if (entryName.startsWith(packageName)) {
-
-			if (entryName.endsWith(".class")
-				&& !entryName.contains("$")) {
-
-			    // Deal with situation where the class found might
-			    // be a further sub-package
-			    // e.g. for "org.expeditee.action"
-			    // there is:
-			    // org/expeditee/action/widgets/Chart.class
-			    // which would produce a value of 'entryName' as
-			    // widgets/Chart.class
-
-			    entryName = entryName.substring(0,
-				    entryName.length() - 6); // 6 = '.class'
-			    entryName = entryName.replace('/', '.');
-
-			    names.add(entryName);
-			    classes.add(Class.forName(entryName));
-			}
-		    }
+	// The following is adapted from:
+	// http://stackoverflow.com/questions/1456930/how-do-i-read-all-classes-from-a-java-package-in-the-classpath
+
+	public static List<Class<?>> getClassesNew(String packageName) throws ClassNotFoundException
+	{
+		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+
+		ArrayList<String> names = new ArrayList<String>();
+
+		final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
+
+		String realPackageName = packageName;
+		packageName = packageName.replace(".", "/");
+		URL packageURL = classLoader.getResource(packageName);
+
+		if (packageURL.getProtocol().equals("jar")) {
+
+			// build jar file name, then loop through zipped entries
+
+			String jarFileNameUndecoded = packageURL.getFile();
+
+			try {
+				JarURLConnection ju_connection = (JarURLConnection) packageURL
+						.openConnection();
+				JarFile jf = ju_connection.getJarFile();
+
+				Enumeration<JarEntry> jarEntries = jf.entries();
+				while (jarEntries.hasMoreElements()) {
+					String entryName = jarEntries.nextElement().getName();
+
+					if (entryName.startsWith(packageName)) {
+
+						if (entryName.endsWith(".class")
+								&& !entryName.contains("$")) {
+
+							// Deal with situation where the class found might
+							// be a further sub-package
+							// e.g. for "org.expeditee.action"
+							// there is:
+							// org/expeditee/action/widgets/Chart.class
+							// which would produce a value of 'entryName' as
+							// widgets/Chart.class
+
+							entryName = entryName.substring(0,
+									entryName.length() - 6); // 6 = '.class'
+							entryName = entryName.replace('/', '.');
+
+							names.add(entryName);
+							classes.add(Class.forName(entryName));
+						}
+					}
+				}
+			} catch (Exception e) {
+				System.err.println("Failed to decode jar file: "
+						+ jarFileNameUndecoded);
+				e.printStackTrace();
+			}
+		} else if (packageURL.getProtocol().equals("bundleresource")) {
+			try {
+				final URLConnection urlConnection = packageURL.openConnection();
+				final Class<?> c = urlConnection.getClass();
+				final java.lang.reflect.Method toInvoke = c.getMethod("getFileURL");
+				final URL fileURL = (URL)toInvoke.invoke(urlConnection);
+				final File folder = new File(fileURL.getFile());
+				final List<String> files = findFiles(folder);
+				for (final String s : files) {
+					String entryName = realPackageName + s;
+					if (entryName.endsWith(".class") && !entryName.contains("$")) {
+						entryName = entryName.substring(0, entryName.lastIndexOf('.'));
+						entryName = entryName.replace('/', '.');
+						names.add(entryName);
+						try {
+							final Class<?> tmpc = Class.forName(entryName);
+							classes.add(tmpc);
+						} catch (NoClassDefFoundError e) {
+							System.err.println("Unable to instantiate class " + entryName);
+							System.err.println(e.getMessage());
+						}
+					}
+				}
+			} catch (final Exception e) {
+				System.err.println("Failed to process file: " + packageName);
+				e.printStackTrace();
+			}
+		} else {
+			// loop through files in classpath
+
+			String packageURLString = packageURL.toString();
+			try {
+				URI uri = new URI(packageURLString);
+				File folder = new File(uri.getPath());
+
+				List<String> files = findFiles(folder);
+				for (String s : files) {
+					String entryName = realPackageName + s;
+
+					if (entryName.endsWith(".class")
+							&& !entryName.contains("$")) {
+						entryName = entryName.substring(0,
+								entryName.lastIndexOf('.'));
+						entryName = entryName.replace('/', '.');
+
+						names.add(entryName);
+						classes.add(Class.forName(entryName));
+					}
+				}
+			} catch (Exception e) {
+				System.err.println("Failed to process file: "
+						+ packageURLString);
+				e.printStackTrace();
+			}
 		}
-	    } catch (Exception e) {
-		System.err.println("Failed to decode jar file: "
-			+ jarFileNameUndecoded);
-		e.printStackTrace();
-	    }
-	} else if (packageURL.getProtocol().equals("bundleresource")) {
-	    try {
-		final URLConnection urlConnection = packageURL.openConnection();
-		final Class<?> c = urlConnection.getClass();
-		final java.lang.reflect.Method toInvoke = c.getMethod("getFileURL");
-		final URL fileURL = (URL)toInvoke.invoke(urlConnection);
-		final File folder = new File(fileURL.getFile());
-		final List<String> files = findFiles(folder);
-		for (final String s : files) {
-		    String entryName = realPackageName + s;
-		    if (entryName.endsWith(".class") && !entryName.contains("$")) {
-			entryName = entryName.substring(0, entryName.lastIndexOf('.'));
-			entryName = entryName.replace('/', '.');
-			names.add(entryName);
+
+		return classes;
+	}
+
+	/**
+	 * Finds all files in a directory and it's subdirectories
+	 * 
+	 * @param directory
+	 *            The folder to start in
+	 * 
+	 * @return A list of Strings containing file paths relative to the starting
+	 *         directory
+	 */
+	private static List<String> findFiles(File directory) {
+		List<String> files = new LinkedList<String>();
+		for (File f : directory.listFiles()) {
+			if (f.isDirectory()) {
+				for (String s : findFiles(f)) {
+					files.add(f.getName() + "/" + s);
+				}
+			} else {
+				files.add(f.getName());
+			}
+		}
+		return files;
+	}
+
+	public static List<Class<?>> getClasses(final String pckgname)
+			throws ClassNotFoundException {
+
+		final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
+
+		// Must be a forward slash for loading resources
+		final String packagePath = pckgname.replace('.', '/');
+
+		if (System.getProperty("eclipse.expeditee.home") == null) {
+			final ClassLoader cld = Thread.currentThread()
+					.getContextClassLoader();
+			if (cld == null) {
+				throw new ClassNotFoundException("Can't get class loader.");
+			}
+			URL resource = null;
 			try {
-			    final Class<?> tmpc = Class.forName(entryName);
-			    classes.add(tmpc);
-			} catch (NoClassDefFoundError e) {
-			    System.err.println("Unable to instantiate class " + entryName);
-			    System.err.println(e.getMessage());
-			}
-		    }
+				final Enumeration<URL> resources = cld
+						.getResources(packagePath);
+				while (resources.hasMoreElements()) {
+					URL url = resources.nextElement();
+					resource = url;
+				}
+			} catch (IOException e) {
+				System.err
+				.println("A IO Error has occured when trying to use the ContextClassLoader"
+						+ System.getProperty("line.separator")
+						+ "Are you running from within Eclipse? (or just not with Jar)  Then make sure your"
+						+ " 'eclipse.expeditee.home' property is set correctly.  It is currently: '"
+						+ System.getProperty("eclipse.expeditee.home")
+						+ "'"
+						+ System.getProperty("line.separator")
+						+ "You can set it by adding a VM argument.  "
+						+ "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn");
+				e.printStackTrace();
+			}
+			if (resource == null) {
+				throw new ClassNotFoundException("No resource for "
+						+ packagePath);
+			}
+			final File directory = new File(resource.getFile());
+
+			final int splitPoint = directory.getPath().indexOf('!');
+			if (splitPoint > 0) {
+				String jarName = directory.getPath().substring(
+						"file:".length(), splitPoint);
+				// Windows HACK
+				if (jarName.indexOf(":") >= 0)
+					jarName = jarName.substring(1);
+
+				if (jarName.indexOf("%20") > 0) {
+					jarName = jarName.replace("%20", " ");
+				}
+				// System.out.println("JarName:" + jarName);
+				try {
+					final JarFile jarFile = new JarFile(jarName);
+					final Enumeration<?> entries = jarFile.entries();
+					while (entries.hasMoreElements()) {
+						final ZipEntry entry = (ZipEntry) entries.nextElement();
+						final String className = entry.getName();
+						if (className.startsWith(packagePath)) {
+							if (className.endsWith(".class")
+									&& !className.contains("$")) {
+								// The forward slash below is a forwards slash
+								// for
+								// both windows and linux
+
+								String class_forname = className.substring(0,
+										className.length() - 6);
+								class_forname = class_forname.replace('/', '.');
+
+								classes.add(Class.forName(class_forname));
+							}
+						}
+					}
+					try {
+						jarFile.close();
+					} catch (IOException e) {
+						System.err
+						.println("Error attempting to close Jar file");
+						e.printStackTrace();
+					}
+				} catch (IOException e) {
+					System.err.println("Error Instantiating Jar File Object");
+					e.printStackTrace();
+				}
+			} else {
+
+				System.err
+				.println("A Error has occured when trying to use a Jar file to find actions or agents."
+						+ System.getProperty("line.separator")
+						+ "Are you running from within Eclipse? (or just not with Jar)  Then make sure your"
+						+ " 'eclipse.expeditee.home' property is set correctly.  It is currently: '"
+						+ System.getProperty("eclipse.expeditee.home")
+						+ "'"
+						+ System.getProperty("line.separator")
+						+ "You can set it by adding a VM argument.  "
+						+ "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn");
+			}
+		} else {
+			String eclipse_expeditee_home = System.getProperty(
+					"eclipse.expeditee.home", "");
+			String full_package_path = eclipse_expeditee_home + File.separator
+					+ "bin" + File.separator + packagePath;
+
+			final File directory = new File(full_package_path);
+
+			if (directory.exists()) {
+				// Get the list of the files contained in the package
+				String[] files = directory.list();
+				for (int i = 0; i < files.length; i++) {
+					// we are only interested in .class files
+					if (files[i].endsWith(".class") && !files[i].contains("$")
+							&& !files[i].equals("Actions.class")) {
+						// removes the .class extension
+						classes.add(Class.forName(pckgname
+								+ files[i].substring(0, files[i].length() - 6)));
+					}
+				}
+			} else {
+				throw new ClassNotFoundException("The package '" + pckgname
+						+ "' in the directory '" + directory
+						+ "' does not appear to be a valid package");
+			}
 		}
-	    } catch (final Exception e) {
-		System.err.println("Failed to process file: " + packageName);
-		e.printStackTrace();
-	    }
-	} else {
-	    // loop through files in classpath
-
-	    String packageURLString = packageURL.toString();
-	    try {
-		URI uri = new URI(packageURLString);
-		File folder = new File(uri.getPath());
-
-		List<String> files = findFiles(folder);
-		for (String s : files) {
-		    String entryName = realPackageName + s;
-
-		    if (entryName.endsWith(".class")
-			    && !entryName.contains("$")) {
-			entryName = entryName.substring(0,
-				entryName.lastIndexOf('.'));
-			entryName = entryName.replace('/', '.');
-
-			names.add(entryName);
-			classes.add(Class.forName(entryName));
-		    }
-		}
-	    } catch (Exception e) {
-		System.err.println("Failed to process file: "
-			+ packageURLString);
-		e.printStackTrace();
-	    }
+		return classes;
 	}
 
-	return classes;
-    }
-
-    /**
-     * Finds all files in a directory and it's subdirectories
-     * 
-     * @param directory
-     *            The folder to start in
-     * 
-     * @return A list of Strings containing file paths relative to the starting
-     *         directory
-     */
-    private static List<String> findFiles(File directory) {
-	List<String> files = new LinkedList<String>();
-	for (File f : directory.listFiles()) {
-	    if (f.isDirectory()) {
-		for (String s : findFiles(f)) {
-		    files.add(f.getName() + "/" + s);
-		}
-	    } else {
-		files.add(f.getName());
-	    }
-	}
-	return files;
-    }
-
-    public static List<Class<?>> getClasses(final String pckgname)
-	    throws ClassNotFoundException {
-
-	final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
-
-	// Must be a forward slash for loading resources
-	final String packagePath = pckgname.replace('.', '/');
-
-	if (System.getProperty("eclipse.expeditee.home") == null) {
-	    final ClassLoader cld = Thread.currentThread()
-		    .getContextClassLoader();
-	    if (cld == null) {
-		throw new ClassNotFoundException("Can't get class loader.");
-	    }
-	    URL resource = null;
-	    try {
-		final Enumeration<URL> resources = cld
-			.getResources(packagePath);
-		while (resources.hasMoreElements()) {
-		    URL url = resources.nextElement();
-		    resource = url;
-		}
-	    } catch (IOException e) {
-		System.err
-			.println("A IO Error has occured when trying to use the ContextClassLoader"
-				+ System.getProperty("line.separator")
-				+ "Are you running from within Eclipse? (or just not with Jar)  Then make sure your"
-				+ " 'eclipse.expeditee.home' property is set correctly.  It is currently: '"
-				+ System.getProperty("eclipse.expeditee.home")
-				+ "'"
-				+ System.getProperty("line.separator")
-				+ "You can set it by adding a VM argument.  "
-				+ "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn");
-		e.printStackTrace();
-	    }
-	    if (resource == null) {
-		throw new ClassNotFoundException("No resource for "
-			+ packagePath);
-	    }
-	    final File directory = new File(resource.getFile());
-
-	    final int splitPoint = directory.getPath().indexOf('!');
-	    if (splitPoint > 0) {
-		String jarName = directory.getPath().substring(
-			"file:".length(), splitPoint);
-		// Windows HACK
-		if (jarName.indexOf(":") >= 0)
-		    jarName = jarName.substring(1);
-
-		if (jarName.indexOf("%20") > 0) {
-		    jarName = jarName.replace("%20", " ");
-		}
-		// System.out.println("JarName:" + jarName);
-		try {
-		    final JarFile jarFile = new JarFile(jarName);
-		    final Enumeration<?> entries = jarFile.entries();
-		    while (entries.hasMoreElements()) {
-			final ZipEntry entry = (ZipEntry) entries.nextElement();
-			final String className = entry.getName();
-			if (className.startsWith(packagePath)) {
-			    if (className.endsWith(".class")
-				    && !className.contains("$")) {
-				// The forward slash below is a forwards slash
-				// for
-				// both windows and linux
-
-				String class_forname = className.substring(0,
-					className.length() - 6);
-				class_forname = class_forname.replace('/', '.');
-
-				classes.add(Class.forName(class_forname));
-			    }
-			}
-		    }
-		    try {
-			jarFile.close();
-		    } catch (IOException e) {
-			System.err
-				.println("Error attempting to close Jar file");
-			e.printStackTrace();
-		    }
-		} catch (IOException e) {
-		    System.err.println("Error Instantiating Jar File Object");
-		    e.printStackTrace();
-		}
-	    } else {
-
-		System.err
-			.println("A Error has occured when trying to use a Jar file to find actions or agents."
-				+ System.getProperty("line.separator")
-				+ "Are you running from within Eclipse? (or just not with Jar)  Then make sure your"
-				+ " 'eclipse.expeditee.home' property is set correctly.  It is currently: '"
-				+ System.getProperty("eclipse.expeditee.home")
-				+ "'"
-				+ System.getProperty("line.separator")
-				+ "You can set it by adding a VM argument.  "
-				+ "Example: -Declipse.expeditee.home=D:\\Desktop\\Research\\expeditee-svn");
-	    }
-	} else {
-	    String eclipse_expeditee_home = System.getProperty(
-		    "eclipse.expeditee.home", "");
-	    String full_package_path = eclipse_expeditee_home + File.separator
-		    + "bin" + File.separator + packagePath;
-
-	    final File directory = new File(full_package_path);
-
-	    if (directory.exists()) {
-		// Get the list of the files contained in the package
-		String[] files = directory.list();
-		for (int i = 0; i < files.length; i++) {
-		    // we are only interested in .class files
-		    if (files[i].endsWith(".class") && !files[i].contains("$")
-			    && !files[i].equals("Actions.class")) {
-			// removes the .class extension
-			classes.add(Class.forName(pckgname
-				+ files[i].substring(0, files[i].length() - 6)));
-		    }
-		}
-	    } else {
-		throw new ClassNotFoundException("The package '" + pckgname
-			+ "' in the directory '" + directory
-			+ "' does not appear to be a valid package");
-	    }
-	}
-	return classes;
-    }
-
 }
Index: /trunk/src/org/expeditee/settings/Settings.java
===================================================================
--- /trunk/src/org/expeditee/settings/Settings.java	(revision 1101)
+++ /trunk/src/org/expeditee/settings/Settings.java	(revision 1102)
@@ -26,5 +26,4 @@
 
 import org.expeditee.gui.AttributeValuePair;
-import org.expeditee.gui.DisplayIO;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameCreator;
@@ -32,5 +31,4 @@
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
-import org.expeditee.items.Item;
 import org.expeditee.items.Text;
 import org.expeditee.items.widgets.Password;
@@ -56,14 +54,11 @@
 			// populate map of settings
 			for(Field f : clazz.getFields()) {
-				// only allow valid types
-				if(! Setting.class.isAssignableFrom(f.getType())) {
-					continue;
-				}
+				// Only allow classes that inherit from Setting
+				if(!Setting.class.isAssignableFrom(f.getType())) continue;
+				
 				try {
 					Setting s = (Setting) f.get(null);
 	                settings.put(f.getName().toLowerCase(), s);
-	                if(s instanceof VariableSetting) {
-	                	settingsList.add((VariableSetting) s);
-	                }
+	                if (s instanceof VariableSetting) settingsList.add((VariableSetting) s);
 	                orderedEntries.add(f.getName());
                 } catch (Exception e) {
@@ -71,5 +66,7 @@
                 }
 			}
+			
 			Method m = null;
+			
 			try {
 				m = clazz.getMethod("onParsed", Text.class);
@@ -77,22 +74,27 @@
 				// System.err.println(clazz.getName() + " has no onParsed(Text t) callback");
 			}
+			
 			this.onParsed = m;
 		}
 	}
+	
 	private static HashMap<String, PageDescriptor> _pages = new HashMap<String, PageDescriptor>();
 
 	private static boolean _init = false;
-	public static void Init() {
+	
+	public static void Init()
+	{
 		if(_init) return;
+		
 		_init = true;
+		
 		try {
 			for(Class<?> clazz : PackageLoader.getClassesNew(SETTINGS_PACKAGE)) {
 				// Ignore this class since it's the controller
-				if(clazz.equals(Settings.class)) {
-					continue;
-				}
-				String settingsPage = clazz.getPackage().getName().toLowerCase().substring(SETTINGS_PACKAGE_PARENT.length());
+				if(clazz.equals(Settings.class)) continue;
+				
+				String settingsPageName = clazz.getPackage().getName().toLowerCase().substring(SETTINGS_PACKAGE_PARENT.length());
 				// System.out.println(settingsPage + " : " + clazz.getName());
-				_pages.put(settingsPage, new PageDescriptor(clazz));
+				_pages.put(settingsPageName, new PageDescriptor(clazz));
 			}
 
@@ -100,22 +102,19 @@
 			e.printStackTrace();
 		}
-		FrameUtils.ParseProfile(FrameIO.LoadProfile(UserSettings.ProfileName.get()));
-	}
-	
-	/**
-	 * Parses the settings tree, then resets any settings that were not set
-	 */
-	public static void parseSettings(Text text) {
+	}
+	
+	/** Parses the settings tree, then resets any settings that were not set. */
+	public static void parseSettings(Text text)
+	{
 		List<VariableSetting> set = parseSettings(text, "");
 		List<VariableSetting> toDefault = new LinkedList<VariableSetting>();
-		for(PageDescriptor pd : _pages.values()) {
-			toDefault.addAll(pd.settingsList);
-		}
+		
+		for(PageDescriptor pd : _pages.values()) toDefault.addAll(pd.settingsList);
+		
 		toDefault.removeAll(set);
+		
 		for(VariableSetting s : toDefault) {
 			try {
-				// System.out.println("Resetting " + s.getTooltip());
 	            s.reset();
-	            // System.out.println("Set " + f.getName() + " to default value " + f.get(null));
             } catch (Exception e) {
 	            e.printStackTrace();
@@ -135,13 +134,13 @@
 		
 		List<VariableSetting> set = new LinkedList<VariableSetting>();
+		
 		Frame child = text.getChild();
-		if(child == null) {
-			return set;
-		}
+		
+		if(child == null) return set;
+		
 		String settingsPage = prefix + text.getText().trim().toLowerCase().replaceAll("^@", "");
 		PageDescriptor pd = _pages.get(settingsPage);
-		if(pd == null) {
-			return set;
-		}
+		if(pd == null) return set;
+		
 		try {
 			// set the fields
@@ -160,4 +159,5 @@
 				}
 			}
+			
 			// parse all the settings items on this page
 			for(Text t : items) {				
@@ -186,8 +186,7 @@
 							}
 						}
-						// System.out.println(s);
-						if(s == null) {
-							continue;
-						}
+
+						if(s == null) continue;
+						
 						if(validPages.size() > 1) {
 							StringBuffer warnMessage = new StringBuffer("Found multiple matching settings in the following settings subpages: ");
@@ -202,19 +201,22 @@
 						}
 					}
-					if(s.setSetting(t) && s instanceof VariableSetting) {
-						set.add((VariableSetting) s);
-					}
+					
+					if(s.setSetting(t) && s instanceof VariableSetting) set.add((VariableSetting) s);
+					
 				} catch (Exception e) {
 					e.printStackTrace();
 				}
 			}
+			
 			// call the onParsed method if one exists
 			if(pd.onParsed != null) {
 				pd.onParsed.invoke(null, text);
 			}
+			
         } catch (Exception e) {
             e.printStackTrace();
             return set;
         }
+		
 		// if the page was a settings page, check if it has any subpages
 		for(Text t : child.getTextItems()) {
@@ -224,14 +226,12 @@
 	}
 	
-	public static void generateSettingsTree(Text link) {
+	public static void generateSettingsTree(Text link)
+	{
 		generateSettingsTree("settings", link);
 	}
 	
-	/**
-	 * 
-	 * Generates settings tree
-	 * 
-	 */
-	private static void generateSettingsTree(String page, Text text) {
+	/** Generates settings tree */
+	private static void generateSettingsTree(String page, Text text)
+	{
 		FrameCreator frames = new FrameCreator(text.getParentOrCurrentFrame().getFramesetName(), text.getParentOrCurrentFrame().getPath(), page, false, false);
 		// Frame frame = FrameIO.CreateFrame(text.getParentOrCurrentFrame().getFramesetName(), page, null);
Index: /trunk/src/org/expeditee/settings/network/proxy/ProxySettings.java
===================================================================
--- /trunk/src/org/expeditee/settings/network/proxy/ProxySettings.java	(revision 1101)
+++ /trunk/src/org/expeditee/settings/network/proxy/ProxySettings.java	(revision 1102)
@@ -23,5 +23,6 @@
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
-import org.expeditee.items.widgets.InteractiveWidget;
+import org.expeditee.items.widgets.Widget;
+import org.expeditee.items.widgets.JavaFXSwingWidget;
 import org.expeditee.items.widgets.Password;
 import org.expeditee.items.widgets.WidgetCorner;
@@ -52,5 +53,5 @@
 						if (passwordWidget == null) {
 							try {
-								passwordWidget = (Password) InteractiveWidget.createWidget((Text) i);
+								passwordWidget = (Password) Widget.createWidget((Text) i);
 								if (Pass.get() != null) {
 									// MessageBay.displayMessage("pass was defined multiple times!", Color.ORANGE);
@@ -65,5 +66,5 @@
 			} else if(i instanceof WidgetCorner || i instanceof WidgetEdge) {
 				if(passwordWidget == null) {
-					InteractiveWidget iw;
+					Widget iw;
 					if(i instanceof WidgetCorner) {
 						iw = ((WidgetCorner)i).getWidgetSource();
@@ -73,4 +74,6 @@
 					if(iw instanceof Password) {
 						passwordWidget = (Password) iw;
+					} else if (iw instanceof JavaFXSwingWidget && ((JavaFXSwingWidget) iw).getSwingWidget() instanceof Password) {
+						passwordWidget = (Password) ((JavaFXSwingWidget) iw).getSwingWidget();
 					}
 					if(Pass.get() != null) {
Index: /trunk/src/org/expeditee/settings/templates/TemplateSettings.java
===================================================================
--- /trunk/src/org/expeditee/settings/templates/TemplateSettings.java	(revision 1101)
+++ /trunk/src/org/expeditee/settings/templates/TemplateSettings.java	(revision 1102)
@@ -19,7 +19,6 @@
 package org.expeditee.settings.templates;
 
-import java.awt.Color;
-
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.core.Colour;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameUtils;
@@ -50,11 +49,11 @@
 				i.setParent(null);
 			}
-			DisplayIO.setCursor(Item.HIDDEN_CURSOR);
-			DisplayIO.setCursor(Item.DEFAULT_CURSOR);
+			DisplayController.setCursor(Item.HIDDEN_CURSOR);
+			DisplayController.setCursor(Item.DEFAULT_CURSOR);
 		}
 	};
 	
-	public static final ArraySetting<Color> ColorWheel = new ArraySetting<Color>("The colours of items in the child frame are used to populate the colour wheel",
-			new Color[] { Color.BLACK, Color.RED, Color.BLUE, Item.GREEN, Color.MAGENTA, Color.YELLOW.darker(), Color.WHITE }) {
+	public static final ArraySetting<Colour> ColorWheel = new ArraySetting<Colour>("The colours of items in the child frame are used to populate the colour wheel",
+			new Colour[] { Colour.BLACK, Colour.RED, Colour.BLUE, Item.GREEN, Colour.MAGENTA, Colour.YELLOW.darker(), Colour.WHITE }) {
 		@Override
 		public boolean setSetting(Text text) {
@@ -68,7 +67,7 @@
 	};
 	
-	public static final ArraySetting<Color> FillColorWheel = new ArraySetting<Color>("The colours of items in the child frame are used to populate the colour wheel",
-			new Color[] { new Color(255, 150, 150), new Color(150, 150, 255), new Color(150, 255, 150),
-			new Color(255, 150, 255), new Color(255, 255, 100), Color.WHITE, Color.BLACK }) {
+	public static final ArraySetting<Colour> FillColorWheel = new ArraySetting<Colour>("The colours of items in the child frame are used to populate the colour wheel",
+			new Colour[] { Colour.FromRGB255(255, 150, 150), Colour.FromRGB255(150, 150, 255), Colour.FromRGB255(150, 255, 150),
+			Colour.FromRGB255(255, 150, 255), Colour.FromRGB255(255, 255, 100), Colour.WHITE, Colour.BLACK }) {
 		@Override
 		public boolean setSetting(Text text) {
@@ -82,8 +81,8 @@
 	};
 	
-	public static final ArraySetting<Color> BackgroundColorWheel = new ArraySetting<Color>("The colours of items in the child frame are used to populate the colour wheel",
-			new Color[] { new Color(235, 235, 235), new Color(225, 225, 255), new Color(195, 255, 255),
-			new Color(225, 255, 225), new Color(255, 255, 195), new Color(255, 225, 225),
-			new Color(255, 195, 255), Color.WHITE, Color.GRAY, Color.DARK_GRAY, Color.BLACK, null }) {
+	public static final ArraySetting<Colour> BackgroundColorWheel = new ArraySetting<Colour>("The colours of items in the child frame are used to populate the colour wheel",
+			new Colour[] { Colour.FromRGB255(235, 235, 235), Colour.FromRGB255(225, 225, 255), Colour.FromRGB255(195, 255, 255),
+					Colour.FromRGB255(225, 255, 225), Colour.FromRGB255(255, 255, 195), Colour.FromRGB255(255, 225, 225),
+					Colour.FromRGB255(255, 195, 255), Colour.WHITE, Colour.GREY, Colour.DARK_GREY, Colour.BLACK, null }) {
 		@Override
 		public boolean setSetting(Text text) {
@@ -107,5 +106,5 @@
 		public Text generateText() {
 			Text t = new Text("AnnotationTemplate");
-    		t.setColor(Color.gray);
+    		t.setColor(Colour.GREY);
     		return t;
 		}
@@ -116,5 +115,5 @@
 		public Text generateText() {
 			Text t = new Text("CommentTemplate");
-    		t.setColor(Color.green.darker());
+    		t.setColor(Colour.GREEN.darker());
     		return t;
 		}
@@ -125,6 +124,6 @@
 		public Text generateText() {
 			Text t = new Text("StatsTemplate");
-    		t.setColor(Color.BLACK);
-    		t.setBackgroundColor(new Color(0.9F, 0.9F, 0.9F));
+    		t.setColor(Colour.BLACK);
+    		t.setBackgroundColor(new Colour(0.9F, 0.9F, 0.9F));
     		t.setFamily(Text.MONOSPACED_FONT);
     		t.setSize(14);
@@ -140,5 +139,5 @@
     		t.setFontStyle("Bold");
     		t.setFamily("SansSerif");
-    		t.setColor(Color.BLUE);
+    		t.setColor(Colour.BLUE);
     		t.setPosition(25, 50);
     		return t;
@@ -157,6 +156,6 @@
 		public Text generateText() {
 			Text t = new Text("TooltipTemplate");
-    		t.setColor(Color.BLACK);
-    		t.setBackgroundColor(new Color(0.7F, 0.7F, 0.9F));
+    		t.setColor(Colour.BLACK);
+    		t.setBackgroundColor(new Colour(0.7F, 0.7F, 0.9F));
     		// t.setFamily(Text.MONOSPACED_FONT);
     		t.setSize(14);
Index: /trunk/src/org/expeditee/stats/SessionStats.java
===================================================================
--- /trunk/src/org/expeditee/stats/SessionStats.java	(revision 1101)
+++ /trunk/src/org/expeditee/stats/SessionStats.java	(revision 1102)
@@ -19,6 +19,4 @@
 package org.expeditee.stats;
 
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
 import java.sql.Time;
 import java.util.ArrayList;
@@ -27,7 +25,7 @@
 import java.util.List;
 
-import org.expeditee.gui.DisplayIO;
+import org.expeditee.gio.input.KBMInputEvent;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.Frame;
-import org.expeditee.gui.FrameMouseActions;
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.TimeKeeper;
@@ -103,5 +101,5 @@
 		stats.append(getCharacterStats());
 
-		stats.append("Version: ").append(DisplayIO.TITLE);
+		stats.append("Version: ").append(DisplayController.TITLE);
 
 		return stats.toString();
@@ -159,6 +157,6 @@
 			chars += counts[i];
 
-		chars -= counts[KeyEvent.VK_BACK_SPACE];
-		chars -= counts[KeyEvent.VK_DELETE];
+		chars -= counts[Text.BACKSPACE_CHARACTER];
+		chars -= counts[Text.DELETE_CHARACTER];
 
 		int EOS = counts['.'] + counts[','] + counts['!'] + counts['?'];
@@ -177,7 +175,7 @@
 		appendStat(stats, "Escape", _EscapeCount);
 		appendStat(stats, "Backspace", _BackspaceCount);
-		appendStat(stats, "Left", _MouseCounters[MouseEvent.BUTTON1]);
-		appendStat(stats, "Middle", _MouseCounters[MouseEvent.BUTTON2]);
-		appendStat(stats, "Right", _MouseCounters[MouseEvent.BUTTON3]);
+		appendStat(stats, "Left", _MouseCounters[KBMInputEvent.MouseButton.LEFT.ordinal()]);
+		appendStat(stats, "Middle", _MouseCounters[KBMInputEvent.MouseButton.MIDDLE.ordinal()]);
+		appendStat(stats, "Right", _MouseCounters[KBMInputEvent.MouseButton.RIGHT.ordinal()]);
 
 		return stats.toString();
@@ -231,7 +229,7 @@
 	 *            ascii value for the typed character
 	 */
-	public static void TypedChar(int ch) {
-		if (ch == KeyEvent.VK_BACK_SPACE || ch == KeyEvent.VK_DELETE)
-			_BackspaceCount++;
+	public static void TypedChar(int ch)
+	{
+		if (ch == ((int) Text.BACKSPACE_CHARACTER) || ch == ((int) Text.DELETE_CHARACTER)) _BackspaceCount++;
 		UserEvent();
 		_CharCounts[ch]++;
@@ -252,5 +250,5 @@
 
 		_FrameEvents.add(Formatter.getTimeWithMillis(elapsedTime) + " "
-				+ DisplayIO.getMouseX() + " " + FrameMouseActions.getY() + " "
+				+ DisplayController.getMouseX() + " " + DisplayController.getMouseY() + " "
 				+ description);
 	}
@@ -278,7 +276,7 @@
 	}
 
-	public static void MouseClicked(int button) {
+	public static void MouseClicked(KBMInputEvent.MouseButton button) {
 		UserEvent();
-		_MouseCounters[button]++;
+		_MouseCounters[button.ordinal()]++;
 	}
 
Index: /trunk/src/org/expeditee/stats/StatsFrame.java
===================================================================
--- /trunk/src/org/expeditee/stats/StatsFrame.java	(revision 1101)
+++ /trunk/src/org/expeditee/stats/StatsFrame.java	(revision 1102)
@@ -19,8 +19,9 @@
 package org.expeditee.stats;
 
-import java.awt.event.MouseEvent;
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
+
+import org.expeditee.gio.input.KBMInputEvent;
 
 public class StatsFrame extends SessionStats {
@@ -162,13 +163,13 @@
 	
 	public static String getLeftButtonCount() {
-		return _MouseCounters[MouseEvent.BUTTON1] + "";
+		return _MouseCounters[KBMInputEvent.MouseButton.LEFT.ordinal()] + "";
 	}
 	
 	public static String getMiddleButtonCount() {
-		return _MouseCounters[MouseEvent.BUTTON2] + "";
+		return _MouseCounters[KBMInputEvent.MouseButton.MIDDLE.ordinal()] + "";
 	}
 	
 	public static String getRightButtonCount() {
-		return _MouseCounters[MouseEvent.BUTTON3] + "";
+		return _MouseCounters[KBMInputEvent.MouseButton.RIGHT.ordinal()] + "";
 	}
 }
Index: /trunk/src/org/expeditee/taskmanagement/EntitySaveManager.java
===================================================================
--- /trunk/src/org/expeditee/taskmanagement/EntitySaveManager.java	(revision 1101)
+++ /trunk/src/org/expeditee/taskmanagement/EntitySaveManager.java	(revision 1102)
@@ -24,9 +24,7 @@
 import java.util.Set;
 
-import javax.swing.SwingUtilities;
-
 
 /**
- * Manages time/resource-consuming saving procedures. For enties in an expeditee Frame that
+ * Manages time/resource-consuming saving procedures. For entities in an expeditee Frame that
  * requires heavy-duty saving, implement the entity as a SaveableEntity.
  * 
@@ -135,5 +133,5 @@
 	 * Saves all current registered entities and clears registrations.
 	 * 
-	 * Returns immediatly.
+	 * Returns immediately.
 	 */
 	public synchronized void saveAll() {
@@ -167,5 +165,5 @@
 	/**
 	 * If something is saving, this will block the thread until all entities that
-	 * have been requested to be saved has finished their saving proccesses.
+	 * have been requested to be saved has finished their saving processes.
 	 * 
 	 * @throws InterruptedException 
@@ -237,6 +235,6 @@
 				if (entity.doesNeedSaving()) {
 					
-					// notify observers that save has started - on swing thread
-					SwingUtilities.invokeLater(new SafeFireEvent(entity, true));
+					// notify observers that save has started
+					(new SafeFireEvent(entity, true)).run();
 	
 					// Complete the save
@@ -248,5 +246,5 @@
 	
 					// notify observers that save has finished - on swing thread
-					SwingUtilities.invokeLater(new SafeFireEvent(entity, false));
+					(new SafeFireEvent(entity, false)).run();
 				}
 			}
@@ -254,5 +252,5 @@
 		
 		/**
-		 * Notifies all listners of save start/completion event when run.
+		 * Notifies all listeners of save start/completion event when run.
 		 * 
 		 * @author Brook Novak
Index: /trunk/tests/org/expeditee/gui/AttributeValuePairTest.java
===================================================================
--- /trunk/tests/org/expeditee/gui/AttributeValuePairTest.java	(revision 1101)
+++ /trunk/tests/org/expeditee/gui/AttributeValuePairTest.java	(revision 1102)
@@ -1,8 +1,7 @@
 package org.expeditee.gui;
-
-import java.awt.Color;
 
 import junit.framework.TestCase;
 
+import org.expeditee.core.Colour;
 import org.expeditee.items.Text;
 
@@ -35,8 +34,8 @@
 		attributes.setText("c:red");
 		assertTrue(AttributeUtils.setAttribute(attributes, attributes));
-		assertEquals(Color.red, attributes.getColor());
+		assertEquals(Colour.RED, attributes.getColor());
 		attributes.setText("color:green");
 		assertTrue(AttributeUtils.setAttribute(attributes, attributes));
-		assertEquals(Color.green, attributes.getColor());
+		assertEquals(Colour.GREEN, attributes.getColor());
 	}
 
Index: /trunk/tests/org/expeditee/gui/DisplayIOTest.java
===================================================================
--- /trunk/tests/org/expeditee/gui/DisplayIOTest.java	(revision 1101)
+++ /trunk/tests/org/expeditee/gui/DisplayIOTest.java	(revision 1102)
@@ -11,8 +11,8 @@
 		showBlankFrame();
 
-		DisplayIO.ToggleTwinFrames();
-		assertTrue(DisplayIO.isTwinFramesOn());
-		DisplayIO.ToggleTwinFrames();
-		assertFalse(DisplayIO.isTwinFramesOn());
+		DisplayController.toggleTwinFrames();
+		assertTrue(DisplayController.isTwinFramesOn());
+		DisplayController.toggleTwinFrames();
+		assertFalse(DisplayController.isTwinFramesOn());
 	}
 
@@ -22,11 +22,11 @@
 		
 		//Draw a rectangle
-		DisplayIO.setCursorPosition(250, 250);
+		DisplayController.setCursorPosition(250, 250);
 		Thread.sleep(100);
-		DisplayIO.clickMouse(InputEvent.BUTTON3_MASK);
+		DisplayController.clickMouse(InputEvent.BUTTON3_MASK);
 		Thread.sleep(100);
-		DisplayIO.setCursorPosition(500, 500);
+		DisplayController.setCursorPosition(500, 500);
 		Thread.sleep(100);
-		DisplayIO.clickMouse(InputEvent.BUTTON3_MASK);
+		DisplayController.clickMouse(InputEvent.BUTTON3_MASK);
 		Thread.sleep(1000);
 		//Check that the line is there
@@ -42,11 +42,11 @@
 	public static void drawLine() throws InterruptedException {
 		//Draw a line
-		DisplayIO.setCursorPosition(100, 100);
+		DisplayController.setCursorPosition(100, 100);
 		Thread.sleep(500);
-		DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
+		DisplayController.clickMouse(InputEvent.BUTTON2_MASK);
 		Thread.sleep(100);
-		DisplayIO.setCursorPosition(200, 200);
+		DisplayController.setCursorPosition(200, 200);
 		Thread.sleep(100);
-		DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
+		DisplayController.clickMouse(InputEvent.BUTTON2_MASK);
 		Thread.sleep(100);
 	}
Index: /trunk/tests/org/expeditee/gui/FrameKeyboardsActionsTest.java
===================================================================
--- /trunk/tests/org/expeditee/gui/FrameKeyboardsActionsTest.java	(revision 1101)
+++ /trunk/tests/org/expeditee/gui/FrameKeyboardsActionsTest.java	(revision 1102)
@@ -12,22 +12,22 @@
 	public final void testTypeText() throws Exception {
 		Frame testFrame = showBlankFrame();
-		DisplayIO.typeKey(KeyEvent.VK_ESCAPE);
-		DisplayIO.typeText("hello");
+		DisplayController.typeKey(KeyEvent.VK_ESCAPE);
+		DisplayController.typeText("hello");
 		// Pick the item up in the middle
 		Item currentItem = FrameUtils.getCurrentItem();
 		assertNotNull(currentItem);
-		DisplayIO.setCursorPosition(currentItem.getX()
+		DisplayController.setCursorPosition(currentItem.getX()
 				+ currentItem.getBoundsWidth() / 2,
 				FrameMouseActions.MouseY - 2);
 		Thread.sleep(DELAY);
-		DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
+		DisplayController.clickMouse(InputEvent.BUTTON2_MASK);
 		Thread.sleep(DELAY);
-		DisplayIO.setCursorPosition(
+		DisplayController.setCursorPosition(
 				Math.round(FrameGraphics.getMaxFrameSize().getWidth() / 2),
 				FrameMouseActions.MouseY);
 		Thread.sleep(DELAY);
-		DisplayIO.typeKey(KeyEvent.VK_ESCAPE);
+		DisplayController.typeKey(KeyEvent.VK_ESCAPE);
 		Thread.sleep(DELAY);
-		DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
+		DisplayController.clickMouse(InputEvent.BUTTON2_MASK);
 		Thread.sleep(DELAY);
 
@@ -35,11 +35,11 @@
 		assertEquals(currentItem.getX(), FrameMouseActions.getX());
 
-		DisplayIO.typeKey(KeyEvent.VK_ESCAPE);
+		DisplayController.typeKey(KeyEvent.VK_ESCAPE);
 
-		DisplayIO.typeStringDirect(0.05, "Hello Again!");
+		DisplayController.typeStringDirect(0.05, "Hello Again!");
 
-		DisplayIO.typeKey(KeyEvent.VK_ESCAPE);
+		DisplayController.typeKey(KeyEvent.VK_ESCAPE);
 
-		DisplayIO.typeText("Hello Again");
+		DisplayController.typeText("Hello Again");
 
 		assertEquals(4, testFrame.getItems(false).size());
Index: /trunk/tests/org/expeditee/gui/FrameMouseActionsTest.java
===================================================================
--- /trunk/tests/org/expeditee/gui/FrameMouseActionsTest.java	(revision 1101)
+++ /trunk/tests/org/expeditee/gui/FrameMouseActionsTest.java	(revision 1102)
@@ -16,5 +16,5 @@
 		testLeftRanging(title);
 
-		String newFrameName = DisplayIO.getCurrentFrame().getName();
+		String newFrameName = DisplayController.getCurrentFrame().getName();
 		Navigation.Back();
 
@@ -30,5 +30,5 @@
 		DisplayIOTest.drawLine();
 		
-		newFrameName = DisplayIO.getCurrentFrame().getName();
+		newFrameName = DisplayController.getCurrentFrame().getName();
 		Navigation.Back();
 		
@@ -45,12 +45,12 @@
 	private void testLeftRanging(Text title) throws InterruptedException {
 		int y = title.getY() - 2;
-		DisplayIO.setCursorPosition(title.getX(), y);
+		DisplayController.setCursorPosition(title.getX(), y);
 		Thread.sleep(500);
-		DisplayIO.pressMouse(InputEvent.BUTTON1_MASK);
+		DisplayController.pressMouse(InputEvent.BUTTON1_MASK);
 		Thread.sleep(100);
-		DisplayIO.setCursorPosition(title.getX() + title.getBoundsWidth() / 2,
+		DisplayController.setCursorPosition(title.getX() + title.getBoundsWidth() / 2,
 				y);
 		Thread.sleep(500);
-		DisplayIO.releaseMouse(InputEvent.BUTTON1_MASK);
+		DisplayController.releaseMouse(InputEvent.BUTTON1_MASK);
 		Thread.sleep(100);
 
@@ -59,14 +59,14 @@
 
 		// Highlight then unhighlight
-		DisplayIO.setCursorPosition(title.getX(), y);
+		DisplayController.setCursorPosition(title.getX(), y);
 		Thread.sleep(500);
-		DisplayIO.pressMouse(InputEvent.BUTTON1_MASK);
+		DisplayController.pressMouse(InputEvent.BUTTON1_MASK);
 		Thread.sleep(100);
-		DisplayIO.setCursorPosition(title.getX() + title.getBoundsWidth() / 2,
+		DisplayController.setCursorPosition(title.getX() + title.getBoundsWidth() / 2,
 				y);
 		Thread.sleep(500);
-		DisplayIO.setCursorPosition(title.getX(), y);
+		DisplayController.setCursorPosition(title.getX(), y);
 		Thread.sleep(500);
-		DisplayIO.releaseMouse(InputEvent.BUTTON1_MASK);
+		DisplayController.releaseMouse(InputEvent.BUTTON1_MASK);
 		Thread.sleep(500);
 
Index: /trunk/tests/org/expeditee/gui/FreeItemsTest.java
===================================================================
--- /trunk/tests/org/expeditee/gui/FreeItemsTest.java	(revision 1101)
+++ /trunk/tests/org/expeditee/gui/FreeItemsTest.java	(revision 1102)
@@ -13,13 +13,13 @@
 
 		FrameMouseActions.pickup(testFrame.getTitleItem());
-		assertTrue(FreeItems.itemsAttachedToCursor());
+		assertTrue(FreeItems.hasItemsAttachedToCursor());
 		assertTrue(FreeItems.textOnlyAttachedToCursor());
 
 		FrameMouseActions.anchor(FreeItems.getInstance());
-		assertFalse(FreeItems.itemsAttachedToCursor());
+		assertFalse(FreeItems.hasItemsAttachedToCursor());
 		assertFalse(FreeItems.textOnlyAttachedToCursor());
 
 		FrameMouseActions.pickup(testFrame.getAllItems());
-		assertTrue(FreeItems.itemsAttachedToCursor());
+		assertTrue(FreeItems.hasItemsAttachedToCursor());
 		assertFalse(FreeItems.textOnlyAttachedToCursor());
 		assertEquals(8, FreeItems.getTextItems().size());
@@ -31,5 +31,5 @@
 
 		FrameMouseActions.anchor(FreeItems.getInstance());
-		assertFalse(FreeItems.itemsAttachedToCursor());
+		assertFalse(FreeItems.hasItemsAttachedToCursor());
 		assertFalse(FreeItems.textOnlyAttachedToCursor());
 	}
Index: /trunk/tests/org/expeditee/gui/GuiTestCase.java
===================================================================
--- /trunk/tests/org/expeditee/gui/GuiTestCase.java	(revision 1101)
+++ /trunk/tests/org/expeditee/gui/GuiTestCase.java	(revision 1102)
@@ -18,5 +18,5 @@
 		Frame testFrame = FrameIO.LoadFrame("ExpediteeTest1");
 		testFrame.clear(false);
-		DisplayIO.setCurrentFrame(testFrame, true);
+		DisplayController.setCurrentFrame(testFrame, true);
 		return testFrame;
 	}
@@ -25,5 +25,5 @@
 		Frame testFrame = FrameIO.LoadFrame(frameName);
 		testFrame.clear(false);
-		DisplayIO.setCurrentFrame(testFrame, true);
+		DisplayController.setCurrentFrame(testFrame, true);
 		return testFrame;
 	}
Index: /trunk/tests/org/expeditee/io/ConversionTest.java
===================================================================
--- /trunk/tests/org/expeditee/io/ConversionTest.java	(revision 1101)
+++ /trunk/tests/org/expeditee/io/ConversionTest.java	(revision 1102)
@@ -1,5 +1,4 @@
 package org.expeditee.io;
 
-import java.awt.Color;
 import java.awt.Font;
 import java.awt.Point;
@@ -10,4 +9,5 @@
 import junit.framework.TestCase;
 
+import org.expeditee.core.Colour;
 import org.expeditee.items.Item;
 import org.expeditee.items.Justification;
@@ -17,44 +17,44 @@
 
 	public final void testGetColor() {
-		assertEquals(null, Conversion.getColor("TrAnSpArEnT", Color.white));
-		assertEquals(null, Conversion.getColor("Clear", Color.white));
-		assertEquals(null, Conversion.getColor("Auto", Color.white));
-		assertEquals(null, Conversion.getColor("Default", Color.white));
-		assertEquals(null, Conversion.getColor("adf", Color.red));
-		assertEquals(null, Conversion.getColor("none", Color.red));
-		assertEquals(null, Conversion.getColor("null", Color.red));
-		assertEquals(null, Conversion.getColor(null, Color.red));
-		assertEquals(null, Conversion.getColor("a0a0a0", Color.white));
-
-		assertEquals(Color.red, Conversion.getColor("100 0 0", Color.white));
-		assertEquals(Color.green, Conversion.getColor("0 100 0", Color.white));
-		assertEquals(Color.blue, Conversion.getColor("0 0 100", Color.white));
-		assertEquals(Color.white, Conversion.getColor("100 100 100",
-				Color.white));
-		assertEquals(Color.gray, Conversion.getColor("50 50 50", Color.white));
-		assertEquals(Color.green, Conversion.getColor("-100 +0 -100",
-				Color.white));
-		assertEquals(Color.green, Conversion.getColor("-10 +100 +0",
-				Color.black));
-		assertEquals(Color.green, Conversion.getColor("+0 +110 +0", null));
-
-		assertEquals(Conversion.getColor("red9", Color.white), new Color(0.9F,
+		assertEquals(null, Conversion.getColor("TrAnSpArEnT", Colour.WHITE));
+		assertEquals(null, Conversion.getColor("Clear", Colour.WHITE));
+		assertEquals(null, Conversion.getColor("Auto", Colour.WHITE));
+		assertEquals(null, Conversion.getColor("Default", Colour.WHITE));
+		assertEquals(null, Conversion.getColor("adf", Colour.RED));
+		assertEquals(null, Conversion.getColor("none", Colour.RED));
+		assertEquals(null, Conversion.getColor("null", Colour.RED));
+		assertEquals(null, Conversion.getColor(null, Colour.RED));
+		assertEquals(null, Conversion.getColor("a0a0a0", Colour.WHITE));
+
+		assertEquals(Colour.RED, Conversion.getColor("100 0 0", Colour.WHITE));
+		assertEquals(Colour.GREEN, Conversion.getColor("0 100 0", Colour.WHITE));
+		assertEquals(Colour.BLUE, Conversion.getColor("0 0 100", Colour.WHITE));
+		assertEquals(Colour.WHITE, Conversion.getColor("100 100 100",
+				Colour.WHITE));
+		assertEquals(Colour.GREY, Conversion.getColor("50 50 50", Colour.WHITE));
+		assertEquals(Colour.GREEN, Conversion.getColor("-100 +0 -100",
+				Colour.WHITE));
+		assertEquals(Colour.GREEN, Conversion.getColor("-10 +100 +0",
+				Colour.BLACK));
+		assertEquals(Colour.GREEN, Conversion.getColor("+0 +110 +0", null));
+
+		assertEquals(Conversion.getColor("red9", Colour.WHITE), new Colour(0.9F,
 				0.0F, 0.0F));
-		assertEquals(Conversion.getColor("BlUe15", Color.white), new Color(
+		assertEquals(Conversion.getColor("BlUe15", Colour.WHITE), new Colour(
 				0.0F, 0.0F, 1.0F));
-		assertEquals(Conversion.getColor("GREEN0", Color.white), new Color(
+		assertEquals(Conversion.getColor("GREEN0", Colour.WHITE), new Colour(
 				0.0F, 0.0F, 0.0F));
-		assertEquals(Conversion.getColor("GREEN3", Color.white), new Color(
+		assertEquals(Conversion.getColor("GREEN3", Colour.WHITE), new Colour(
 				0.0F, 0.3F, 0.0F));
-		assertEquals(Conversion.getColor("Blue1", Color.white), new Color(0.0F,
+		assertEquals(Conversion.getColor("Blue1", Colour.WHITE), new Colour(0.0F,
 				0.0F, 0.1F));
 	}
 
 	public final void testGetExpediteeColorCode() {
-		assertTrue(Conversion.getExpediteeColorCode(Color.red)
+		assertTrue(Conversion.getExpediteeColorCode(Colour.RED)
 				.equals("100 0 0"));
-		assertTrue(Conversion.getExpediteeColorCode(Color.green).equals(
+		assertTrue(Conversion.getExpediteeColorCode(Colour.GREEN).equals(
 				"0 100 0"));
-		assertTrue(Conversion.getExpediteeColorCode(Color.blue).equals(
+		assertTrue(Conversion.getExpediteeColorCode(Colour.BLUE).equals(
 				"0 0 100"));
 	}
@@ -127,14 +127,14 @@
 
 		// Test Color Conversion
-		assertEquals(Color.darkGray, Conversion.Convert(Color.class,
+		assertEquals(Colour.DARK_GREY, Conversion.Convert(Colour.class,
 				"dark_gray"));
-		assertEquals(Color.darkGray, Conversion
-				.Convert(Color.class, "DARKGRAY"));
-		assertEquals(Color.red, Conversion.Convert(Color.class, "red"));
-		assertEquals(Color.red, Conversion.Convert(Color.class, "Red"));
-		assertEquals(Color.red, Conversion.Convert(Color.class, "RED"));
-		assertEquals(Color.red, Conversion.Convert(Color.class, " 100 "));
-		assertEquals(Color.green, Conversion.Convert(Color.class, "0  100"));
-		assertEquals(Color.blue, Conversion.Convert(Color.class, "0 0 100"));
+		assertEquals(Colour.DARK_GREY, Conversion
+				.Convert(Colour.class, "DARKGRAY"));
+		assertEquals(Colour.RED, Conversion.Convert(Colour.class, "red"));
+		assertEquals(Colour.RED, Conversion.Convert(Colour.class, "Red"));
+		assertEquals(Colour.RED, Conversion.Convert(Colour.class, "RED"));
+		assertEquals(Colour.RED, Conversion.Convert(Colour.class, " 100 "));
+		assertEquals(Colour.GREEN, Conversion.Convert(Colour.class, "0  100"));
+		assertEquals(Colour.BLUE, Conversion.Convert(Colour.class, "0 0 100"));
 		// Test Boolean Conversion
 		assertEquals(true, Conversion.Convert(boolean.class, ""));
@@ -151,10 +151,10 @@
 
 	public final void testConvertClassStringObject() {
-		assertEquals(new Color(255, 0, 255), Conversion.Convert(Color.class,
+		assertEquals(Colour.FromRGB255(255, 0, 255), Conversion.Convert(Colour.class,
 				"+100 +0 +100", null));
-		assertEquals(Color.red, Conversion.Convert(Color.class, "+100 +0 -100",
-				Color.blue));
-		assertEquals(Color.black, Conversion.Convert(Color.class, "-0 +0 -100",
-				Color.blue));
+		assertEquals(Colour.RED, Conversion.Convert(Colour.class, "+100 +0 -100",
+				Colour.BLUE));
+		assertEquals(Colour.BLACK, Conversion.Convert(Colour.class, "-0 +0 -100",
+				Colour.BLUE));
 		// Float test
 		assertEquals(2.0F, Conversion.Convert(float.class, "2.0", null));
@@ -305,5 +305,5 @@
 
 			assertEquals("100 0 0", Conversion.ConvertToExpeditee(getPosition,
-					Color.red));
+					Colour.RED));
 
 			assertEquals(null, Conversion.ConvertToExpeditee(getPosition, null));
@@ -325,7 +325,7 @@
 
 	public final void testGetCssColor() {
-		assertEquals("rgb(255,0,0)", Conversion.getCssColor(Color.red));
-		assertEquals("rgb(255,0,255)", Conversion.getCssColor(Color.magenta));
-		assertEquals("rgb(128,128,128)", Conversion.getCssColor(Color.gray));
+		assertEquals("rgb(255,0,0)", Conversion.getCssColor(Colour.RED));
+		assertEquals("rgb(255,0,255)", Conversion.getCssColor(Colour.MAGENTA));
+		assertEquals("rgb(128,128,128)", Conversion.getCssColor(Colour.GREY));
 	}
 }
Index: /trunk/tests/org/expeditee/items/widgets/InteractiveWidgetTest.java
===================================================================
--- /trunk/tests/org/expeditee/items/widgets/InteractiveWidgetTest.java	(revision 1101)
+++ /trunk/tests/org/expeditee/items/widgets/InteractiveWidgetTest.java	(revision 1102)
@@ -7,18 +7,18 @@
 	public void testParseArgs1() {
 		
-		assertNull(InteractiveWidget.parseArgs(null));
-		assertNull(InteractiveWidget.parseArgs(""));
-		assertNull(InteractiveWidget.parseArgs("         "));
+		assertNull(Widget.parseArgs(null));
+		assertNull(Widget.parseArgs(""));
+		assertNull(Widget.parseArgs("         "));
 		
-		String[] args = InteractiveWidget.parseArgs("arg1");
+		String[] args = Widget.parseArgs("arg1");
 		assertEquals(1, args.length);
 		assertEquals("arg1", args[0]);
 		
-		args = InteractiveWidget.parseArgs("arg1 arg2");
+		args = Widget.parseArgs("arg1 arg2");
 		assertEquals(2, args.length);
 		assertEquals("arg1", args[0]);
 		assertEquals("arg2", args[1]);
 		
-		args = InteractiveWidget.parseArgs("  )*^*$^   24224 5775    13 :  ");
+		args = Widget.parseArgs("  )*^*$^   24224 5775    13 :  ");
 		assertEquals(5, args.length);
 		assertEquals(")*^*$^", args[0]);
@@ -31,46 +31,46 @@
 	public void testParseArgs2() {
 		
-		String[] args = InteractiveWidget.parseArgs("\"");
+		String[] args = Widget.parseArgs("\"");
 		assertNull(args);
 		
-		args = InteractiveWidget.parseArgs("\"\"");
+		args = Widget.parseArgs("\"\"");
 		assertEquals(1, args.length);
 		assertEquals("\"", args[0]);
 		
-		args = InteractiveWidget.parseArgs("\"\"\"\"\"\"\"");
+		args = Widget.parseArgs("\"\"\"\"\"\"\"");
 		assertEquals(1, args.length);
 		assertEquals("\"\"\"", args[0]);
 		
-		args = InteractiveWidget.parseArgs("  \"         \"   ");
+		args = Widget.parseArgs("  \"         \"   ");
 		assertEquals(1, args.length);
 		assertEquals("         ", args[0]);
 		
-		args = InteractiveWidget.parseArgs("arg1\" \"");
+		args = Widget.parseArgs("arg1\" \"");
 		assertEquals(1, args.length);
 		assertEquals("arg1 ", args[0]);
 		
-		args = InteractiveWidget.parseArgs("arg1\" \"+8");
+		args = Widget.parseArgs("arg1\" \"+8");
 		assertEquals(1, args.length);
 		assertEquals("arg1 +8", args[0]);
 		
-		args = InteractiveWidget.parseArgs("abc\" \"de 123\" \"45");
+		args = Widget.parseArgs("abc\" \"de 123\" \"45");
 		assertEquals(2, args.length);
 		assertEquals("abc de", args[0]);
 		assertEquals("123 45", args[1]);
 		
-		args = InteractiveWidget.parseArgs("adgdag\" adgdgadag");
+		args = Widget.parseArgs("adgdag\" adgdgadag");
 		assertEquals(1, args.length);
 		assertEquals("adgdag adgdgadag", args[0]);
 		
-		args = InteractiveWidget.parseArgs("abc\"\"\" s \"   ggg");
+		args = Widget.parseArgs("abc\"\"\" s \"   ggg");
 		assertEquals(2, args.length);
 		assertEquals("abc\" s ", args[0]);
 		assertEquals("ggg", args[1]);
 		
-		args = InteractiveWidget.parseArgs("abc\"\"123");
+		args = Widget.parseArgs("abc\"\"123");
 		assertEquals(1, args.length);
 		assertEquals("abc\"123", args[0]);
 		
-		args = InteractiveWidget.parseArgs("file=\"a URL with spaces\" title=\"A title with spaces and \"\"quotes\"\"\"");
+		args = Widget.parseArgs("file=\"a URL with spaces\" title=\"A title with spaces and \"\"quotes\"\"\"");
 		assertEquals(2, args.length);
 		assertEquals("file=a URL with spaces", args[0]);
@@ -101,9 +101,9 @@
 	private void AssertArgParsingAndFormatting(String str) {
 		
-		String[] args1 = InteractiveWidget.parseArgs(str);
+		String[] args1 = Widget.parseArgs(str);
 		
-		String formatted = InteractiveWidget.formatArgs(args1);
+		String formatted = Widget.formatArgs(args1);
 		
-		String[] args2 = InteractiveWidget.parseArgs(formatted);
+		String[] args2 = Widget.parseArgs(formatted);
 		
 		if (args1 == null || args2 == null) assertEquals(args1, args2);
