Index: trunk/src/org/apollo/ApolloSystem.java
===================================================================
--- trunk/src/org/apollo/ApolloSystem.java	(revision 1241)
+++ trunk/src/org/apollo/ApolloSystem.java	(revision 1242)
@@ -32,7 +32,7 @@
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.settings.UserSettings;
 import org.expeditee.items.Item;
 import org.expeditee.items.Text;
+import org.expeditee.settings.UserSettings;
 
 /**
@@ -155,5 +155,5 @@
 		if (profile == null) {
 			try {
-				profile = FrameIO.CreateNewProfile(UserSettings.DEFAULT_PROFILE_NAME);
+				profile = FrameIO.CreateNewProfile(UserSettings.DEFAULT_PROFILE_NAME, null);
 			} catch (Exception e) {
 				e.printStackTrace();
Index: trunk/src/org/expeditee/actions/Misc.java
===================================================================
--- trunk/src/org/expeditee/actions/Misc.java	(revision 1241)
+++ trunk/src/org/expeditee/actions/Misc.java	(revision 1242)
@@ -46,7 +46,5 @@
 import org.expeditee.gio.gesture.StandardGestureActions;
 import org.expeditee.gui.AttributeUtils;
-import org.expeditee.io.Conversion;
 import org.expeditee.gui.DisplayController;
-import org.expeditee.io.ExpReader;
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameGraphics;
@@ -58,4 +56,6 @@
 import org.expeditee.gui.Reminders;
 import org.expeditee.gui.TimeKeeper;
+import org.expeditee.io.Conversion;
+import org.expeditee.io.ExpReader;
 import org.expeditee.items.Item;
 import org.expeditee.items.ItemUtils;
@@ -1334,5 +1334,5 @@
 		homeFrame.removeAllItems(homeFrame.getItems());
 		homeFrame.addText(0, 0, "title", null);
-		FrameUtils.CreateDefaultProfile(UserSettings.UserName.get(), homeFrame);
+		FrameUtils.CreateDefaultProfile(UserSettings.UserName.get(), homeFrame, null);
 	}
 	
@@ -1523,6 +1523,5 @@
 	String frameName = frame.getName();
 	    
-	String frameDir = framePath + Conversion.getFramesetName(frameName)
-	    + File.separator;
+	String frameDir = frame.getFramesetPath(); //framePath + Conversion.getFramesetName(frameName) + File.separator;
 	String localFname = Conversion.getFrameNumber(frameName)
 	    + ExpReader.EXTENTION;
Index: trunk/src/org/expeditee/core/Colour.java
===================================================================
--- trunk/src/org/expeditee/core/Colour.java	(revision 1241)
+++ trunk/src/org/expeditee/core/Colour.java	(revision 1242)
@@ -1,3 +1,5 @@
 package org.expeditee.core;
+
+import org.expeditee.items.Text;
 
 /**
@@ -9,5 +11,5 @@
  *
  */
-public class Colour {
+public class Colour implements Representable {
 
 	private short r, g, b, a;
@@ -280,3 +282,10 @@
 		return new Colour(this);
 	}
+
+	@Override
+	public Text generateRepresentation(String content, String frameset) {
+		Text t = new Text(content);
+		t.setColor(this);
+		return t;
+	}
 }
Index: trunk/src/org/expeditee/core/Representable.java
===================================================================
--- trunk/src/org/expeditee/core/Representable.java	(revision 1242)
+++ trunk/src/org/expeditee/core/Representable.java	(revision 1242)
@@ -0,0 +1,7 @@
+package org.expeditee.core;
+
+import org.expeditee.items.Text;
+
+public interface Representable {
+	public Text generateRepresentation(String content, String frameset);
+}
Index: trunk/src/org/expeditee/gio/gesture/StandardGestureActions.java
===================================================================
--- trunk/src/org/expeditee/gio/gesture/StandardGestureActions.java	(revision 1241)
+++ trunk/src/org/expeditee/gio/gesture/StandardGestureActions.java	(revision 1242)
@@ -90,5 +90,5 @@
 		CUT, 
 		DELETE, 
-		DROP_DOWN, // F0 (ESC) (Seems to locate the cursor underneath the current/last item?)
+		DROP_DOWN, // F0 (ESC) (Positions the cursor below the current text item.  Similar to enter in traditional editors.)
 		EXTRACT_ATTRIBUTES, 
 		EXTRUDE, 
@@ -743,5 +743,5 @@
 				RefreshGestureData data = (RefreshGestureData) gesture.getData();
 				if (data.shouldReloadFrameFirst()) {
-					MessageBay.displayMessage("Forced reload before forced refresh");
+					MessageBay.displayMessage("Loaded in data from external edit made my another user.");
 					DisplayController.Reload(DisplayController.TwinFramesSide.LEFT);
 				}
Index: trunk/src/org/expeditee/gui/Browser.java
===================================================================
--- trunk/src/org/expeditee/gui/Browser.java	(revision 1241)
+++ trunk/src/org/expeditee/gui/Browser.java	(revision 1242)
@@ -536,11 +536,10 @@
 	}
 
-	protected static Frame loadProfile(String userName)
-	{
+	protected static Frame loadProfile(String userName)	{
 		Frame profile = FrameIO.LoadProfile(userName);
 		
 		if (profile == null) {
 			try {
-				profile = FrameIO.CreateNewProfile(userName);
+				profile = FrameIO.CreateNewProfile(userName, null);
 			} catch (Exception e) {
 				// TODO tell the user that there was a problem creating the
Index: trunk/src/org/expeditee/gui/Frame.java
===================================================================
--- trunk/src/org/expeditee/gui/Frame.java	(revision 1241)
+++ trunk/src/org/expeditee/gui/Frame.java	(revision 1242)
@@ -19,4 +19,5 @@
 package org.expeditee.gui;
 
+import java.io.File;
 import java.sql.Time;
 import java.util.ArrayList;
@@ -35,8 +36,14 @@
 import org.expeditee.core.Image;
 import org.expeditee.core.bounds.PolygonBounds;
+import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gio.gesture.Gesture;
+import org.expeditee.gio.gesture.Gesture.GestureType;
 import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gio.gesture.StandardGestureActions.StandardGestureType;
+import org.expeditee.gio.gesture.data.RefreshGestureData;
 import org.expeditee.gio.input.KBMInputEvent.Key;
 import org.expeditee.gio.input.StandardInputEventListeners;
 import org.expeditee.io.Conversion;
+import org.expeditee.io.ExpReader;
 import org.expeditee.items.Constraint;
 import org.expeditee.items.Dot;
@@ -132,4 +139,7 @@
 	// for drawing purposes
 	private List<Widget> _iWidgets = new ArrayList<Widget>();
+	
+	// frame data
+	private Item frameData = new Text("Frame Data");
 
 	private int _lineCount = 0;
@@ -167,6 +177,5 @@
 
 	/** Default constructor, nothing is set. */
-	public Frame()
-	{
+	public Frame() {
 	}
 
@@ -292,6 +301,5 @@
 	 *            true if the frame should be recalculated first.
 	 */
-	public void notifyObservers(boolean bRecalculate)
-	{
+	public void notifyObservers(boolean bRecalculate) {
 		if (bRecalculate) {
 			recalculate();
@@ -1799,6 +1807,20 @@
 	 * @return The newly created Text Item
 	 */
-	public Text createBlankText(String templateType)
-	{
+	public Text createBlankText(String templateType) {
+		File file = new File(getFramePathReal());
+		long fileLastModified = file.lastModified();
+		long frameLastModified = this.getLastModifyPrecise();
+		//if (ExpReader.getVersion(getFramePathReal()) > this._version) {
+		if (fileLastModified > frameLastModified) {
+			GestureType refreshGestureType = StandardGestureActions.getInstance().gestureType(StandardGestureType.REFRESH);
+			RefreshGestureData refreshGestureData = new RefreshGestureData(true, false);
+			try {
+				StandardGestureActions.getInstance().onGesture(new Gesture(refreshGestureType, refreshGestureData));
+				EcosystemManager.getMiscManager().beep();
+			} catch (NullPointerException e) {
+				//Detected more recent data on file system than on Frame in memory.  Unfortunately not in a position to cause a refresh.
+			}
+		}
+		
 		SessionStats.CreatedText();
 		Text t;
@@ -1834,7 +1856,66 @@
 		return t;
 	}
-
-	public Item createDot()
-	{
+	
+	/**
+	 * Returns the data associated with the frame.
+	 * @return
+	 */
+	public List<String> getData() {
+		return frameData.getData();
+	}
+	
+	/**
+	 * Adds a piece of data to be associated with the frame.
+	 * @param dataItem
+	 */
+	public void addToData(String dataItem) {
+		frameData.addToData(dataItem);
+	}
+
+	/**
+	 * Returns the path (String) to the .exp file that this Frame represents.
+	 * This follows redirects, meaning that it provides the actual file from which 
+	 * the frames data is drawn from.
+	 * @return The path to the .exp file that this Frame represents
+	 * @see getFramePathLogical
+	 * @see getFramesetPath
+	 */
+	public String getFramePathReal() {
+		String framesetPath = getFramesetPath();
+		String redirect = ExpReader.redirectTo(getFramePathLogical());
+		
+		if (redirect == null) {
+			return getFramePathLogical();
+		}
+		
+		while (redirect != null) {
+			framesetPath = getFramesetPath() + redirect;
+			redirect = ExpReader.redirectTo(redirect);
+		}
+		return framesetPath;
+	}
+
+	/**
+	 * Returns the path (String) to the .exp file that this Frame represents.
+	 * Does not follow redirects, opting to instead provide the logical path to this file.
+	 * @return The path to the .exp file that this Frame represents
+	 * @see getFramePathReal
+	 * @see getFramesetPath
+	 */
+	public String getFramePathLogical() {
+		return getFramesetPath() + this.getNumber() + ExpReader.EXTENTION;
+	}
+
+	/**
+	 * Returns the path (String) to the frameset directory that the file that this Frame represents is contained within.
+	 * @return The path to this Frames frameset directory
+	 * @see getFramesetPathLogical
+	 * @see getFramesetPathReal
+	 */
+	public String getFramesetPath() {
+		return this.getPath() + File.separator + this.getFramesetName() + File.separator;
+	}
+
+	public Item createDot()	{
 		Item dot = new Dot(DisplayController.getMouseX(), DisplayController.getMouseY(), getNextItemID());
 
@@ -2462,4 +2543,5 @@
 	{
 		Collection<Item> allItems = new LinkedHashSet<Item>(_body);
+		
 		allItems.addAll(_overlayItems);
 		allItems.addAll(_vectorItems);
Index: trunk/src/org/expeditee/gui/FrameIO.java
===================================================================
--- trunk/src/org/expeditee/gui/FrameIO.java	(revision 1241)
+++ trunk/src/org/expeditee/gui/FrameIO.java	(revision 1242)
@@ -33,16 +33,22 @@
 import java.io.Writer;
 import java.nio.channels.FileChannel;
+import java.nio.file.Paths;
 import java.sql.Time;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 import org.expeditee.actions.Actions;
 import org.expeditee.agents.ExistingFramesetException;
+import org.expeditee.agents.InvalidFramesetNameException;
 import org.expeditee.auth.Authenticator;
 import org.expeditee.auth.EncryptedExpReader;
 import org.expeditee.auth.EncryptedExpWriter;
 import org.expeditee.auth.gui.MailBay;
+import org.expeditee.gio.EcosystemManager;
 import org.expeditee.io.Conversion;
 import org.expeditee.io.ExpReader;
@@ -59,4 +65,5 @@
 import org.expeditee.items.UserAppliedPermission;
 import org.expeditee.network.FrameShare;
+import org.expeditee.setting.Setting;
 import org.expeditee.settings.UserSettings;
 import org.expeditee.settings.folders.FolderSettings;
@@ -79,78 +86,94 @@
 
 	public static void changeParentFolder(String newFolder) {
+		// Partial Paths.
 		PARENT_FOLDER = newFolder;
+		String resourcesPublicPath = PARENT_FOLDER + "resources-public" + File.separator;
+		String resourcesPrivateIndividualPath = PARENT_FOLDER + "resources-" + UserSettings.UserName.get() + File.separator;
+		
+		// Standard paths.
 		PUBLIC_PATH = PARENT_FOLDER + "public" + File.separator;
-		FRAME_PATH = PARENT_FOLDER + "framesets" + File.separator;
 		MESSAGES_PATH = PARENT_FOLDER + "messages" + File.separator;
 		TRASH_PATH = PARENT_FOLDER + "trash" + File.separator;
-		IMAGES_PATH = PARENT_FOLDER + IMAGES_FOLDER;
 		HELP_PATH = PARENT_FOLDER + "documentation" + File.separator;
-		DICT_PATH = PARENT_FOLDER + "dict" + File.separator;
-		FONT_PATH = PARENT_FOLDER + "fonts" + File.separator;
 		PROFILE_PATH = PARENT_FOLDER + "profiles" + File.separator;
 		EXPORTS_DIR = PARENT_FOLDER + "exports" + File.separator;
 		STATISTICS_DIR = PARENT_FOLDER + "statistics" + File.separator;
 		LOGS_DIR = PARENT_FOLDER + "logs" + File.separator;
-		SHARED_BY_ME_FRAMESETS = PARENT_FOLDER + "framesets-shared-by-me" + File.separator;
-		SHARED_WITH_ME_FRAMESETS = PARENT_FOLDER + "framesets-shared-with-me" + File.separator;
-	}
-
-	/**
-	 * The default location for storing the framesets. Each frameset has its own
-	 * subdirectory in this directory.
-	 */
-	public static String IMAGES_FOLDER = "images" + File.separator;
-
+				
+		// New regime paths.
+		if (UserSettings.multiUserMode) {
+			SHARED_FRAMESETS_PATH = resourcesPrivateIndividualPath + "framesets-shared" + File.separator;
+			RESOURCES_PRIVATE = PARENT_FOLDER + "resources-private" + File.separator;
+			RESOURCES_PATH = resourcesPublicPath + "documentation" + File.separator;
+			FRAME_PRIVATE_PATH = resourcesPrivateIndividualPath + "framesets" + File.separator;
+			IMAGES_PRIVATE_PATH = resourcesPrivateIndividualPath + "images" + File.separator;
+			CONTACTS_PATH = resourcesPrivateIndividualPath + "contacts" + File.separator;
+		} else {
+			// If we are using the old regime then these paths should not be used.
+			SHARED_FRAMESETS_PATH = null;
+			RESOURCES_PRIVATE = null;		
+			RESOURCES_PATH = null;
+			FRAME_PRIVATE_PATH = null;
+			IMAGES_PRIVATE_PATH = null;
+			CONTACTS_PATH = null;
+		}
+		
+		// Conditional paths
+		if (UserSettings.multiUserMode) {
+			FONT_PATH = resourcesPublicPath + "fonts" + File.separator;
+			DICT_PATH = resourcesPublicPath + "dict" + File.separator;
+			IMAGES_PATH = resourcesPublicPath + "images" + File.separator;
+			FRAME_PATH = resourcesPublicPath + "framesets" + File.separator;
+		} else {
+			FONT_PATH = PARENT_FOLDER + "fonts" + File.separator;
+			DICT_PATH = PARENT_FOLDER + "dict" + File.separator;
+			IMAGES_PATH = PARENT_FOLDER + "images" + File.separator;
+			FRAME_PATH = PARENT_FOLDER + "framesets" + File.separator;
+		}
+	}
+
+	// The parent path that all others are relative to.  Also referred to as Expeditee Home.
+	public static String PARENT_FOLDER;
+	
+	// The below paths are categorised based on their use in the new/old regime.  See UserSettings.appendDefaultFolders for more inforamtion.
+	// Paths used by Both the new regime (multiuser mode) and the old regime.
+	public static String PROFILE_PATH;
+	public static String FRAME_PATH;
+	public static String MESSAGES_PATH;
+	public static String IMAGES_PATH;
+	public static String PUBLIC_PATH;
 	public static String TRASH_PATH;
-
-	public static String PARENT_FOLDER;
-
-	public static String FRAME_PATH;
-
-	public static String MESSAGES_PATH;
-
-	public static String PUBLIC_PATH;
-
-	public static String IMAGES_PATH;
-
+	
+	// Paths used by both the new regime and the old regime, that points to different locations based on regime setting.
+	public static String FONT_PATH;
+	public static String DICT_PATH;
+	public static String EXPORTS_DIR;
+	public static String STATISTICS_DIR;
+	public static String LOGS_DIR;
+	
+	// Paths used only by new regime.
+	public static String SHARED_FRAMESETS_PATH;
+	public static String CONTACTS_PATH;
+	public static String RESOURCES_PRIVATE;
+	public static String RESOURCES_PATH;
+	public static String FRAME_PRIVATE_PATH;
+	public static String IMAGES_PRIVATE_PATH;
+	
+	// Paths used only by old regime.
 	public static String HELP_PATH;
-
-	public static String FONT_PATH;
 	
+	// Paths that appear to be unused.
 	public static String TEMPLATES_PATH;
+			
+	// Variables for controlling cache functionality.
+	public static final int MAX_NAME_LENGTH = 64;
+	public static final int MAX_CACHE = 100;
+	private static HashMap<String, Frame> _Cache = new FrameCache();
+	private static boolean ENABLE_CACHE = true;
+	private static boolean _UseCache = true;
+	private static boolean _SuspendedCache = false;
 	
-	public static String DICT_PATH;
-
-	public static String PROFILE_PATH;
-
-	public static String EXPORTS_DIR;
-
-	public static String STATISTICS_DIR;
+	private static final String INF_FILENAME = "frame.inf";
 	
-	public static String SHARED_BY_ME_FRAMESETS;
-	
-	public static String SHARED_WITH_ME_FRAMESETS;
-
-	public static String LOGS_DIR;
-
-	private static final String INF_FILENAME = "frame.inf";
-
-	public static final String ILLEGAL_CHARS = ";:\\/?";
-
-	public static final int MAX_NAME_LENGTH = 64;
-
-	public static final int MAX_CACHE = 100;
-
-	private static HashMap<String, Frame> _Cache = new FrameCache();
-
-	// private static HashMap<String, String> _FramesetNameCache = new
-	// HashMap<String, String>();
-
-	private static boolean ENABLE_CACHE = true;
-
-	private static boolean _UseCache = true;
-
-	private static boolean _SuspendedCache = false;
-
 	// All methods are static, this should not be instantiated
 	private FrameIO() {
@@ -202,6 +225,20 @@
 	}
 	
+	/**
+	 * Loads a frame with the specified name.  
+	 * By using a dot separated framename, users are able to specify the path to find the frameset in.
+	 * @param frameName The frame to load.
+	 * @return the loaded frame
+	 */
 	public static Frame LoadFrame(String frameName) {
-		return LoadFrame(frameName, null, false);
+		if (frameName.contains(".")) {
+			String[] split = frameName.split("\\.");
+			String[] pathSplit = Arrays.copyOfRange(split, 0, split.length - 1);
+			String name = split[split.length - 1];
+			String path = Arrays.asList(pathSplit).stream().collect(Collectors.joining(File.separator));
+			return LoadFrame(name, Paths.get(FrameIO.PARENT_FOLDER).resolve(path).toString() + File.separator, false);
+		} else {
+			return LoadFrame(frameName, null, false); //framesets-bryce.home1
+		}
 	}
 
@@ -214,5 +251,5 @@
 			return null;
 		}
-
+		
 		String frameNameLower = frameName.toLowerCase();
 		// first try reading from cache
@@ -221,8 +258,8 @@
 			Frame frame = _Cache.get(frameNameLower);
 			
-			// if frame is cache is older than the one on disk then don't use the cached one
-			String p = frame.getPath() + frame.getNumber() + ".exp";
-			File file = new File(p);
-			if (file.lastModified() <= frame.getLastModifyPrecise()) {
+			// if frame in cache is older than the one on disk then don't use the cached one
+			File file = new File(frame.getFramePathReal());
+			long lastModified = file.lastModified();
+			if (lastModified <= frame.getLastModifyPrecise()) {
 				return frame;
 			}
@@ -232,5 +269,6 @@
 				+ " from disk.");
 
-		return LoadFromDisk(frameName, path, ignoreAnnotations);
+		Frame fromDisk = LoadFromDisk(frameName, path, ignoreAnnotations);
+		return fromDisk;
 	}
 
@@ -250,15 +288,15 @@
 		
 		try{
-				FileInputStream source_fis = new FileInputStream(source);
-				inputChannel = source_fis.getChannel();
+			FileInputStream source_fis = new FileInputStream(source);
+			inputChannel = source_fis.getChannel();
+			
+			FileOutputStream dest_fos = new FileOutputStream(dest);
+			outputChannel = dest_fos.getChannel();
 				
-				FileOutputStream dest_fos = new FileOutputStream(dest);
-				outputChannel = dest_fos.getChannel();
-				
-				outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
-				inputChannel.close();
-				outputChannel.close();
-				source_fis.close();
-				dest_fos.close();
+			outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
+			inputChannel.close();
+			outputChannel.close();
+			source_fis.close();
+			dest_fos.close();
 		}		 
 		catch(Exception e){	
@@ -301,9 +339,9 @@
 
 		if (knownPath != null) {
-			loaded = LoadKnowPath(knownPath, framename);
+			loaded = LoadKnownPath(knownPath, framename);
 		} else {
 			List<String> directoriesToSearch = FolderSettings.FrameDirs.get();
 			
-			if (UserSettings.Authenticated.get()) {
+			if (Authenticator.Authenticated) {
 				// if we are running Expeditee Authenticated, consult user profile as location for framesets first
 				String profilePath = FrameIO.PROFILE_PATH + UserSettings.UserName.get() + File.separator;
@@ -312,5 +350,5 @@
 			
 			for (String path : directoriesToSearch) {
-				loaded = LoadKnowPath(path, framename);
+				loaded = LoadKnownPath(path, framename);
 				if (loaded != null) {
 					break;
@@ -325,4 +363,5 @@
 		if (loaded != null) {
 			FrameUtils.Parse(loaded, true, ignoreAnnotations);
+			FrameIO.setSavedProperties(loaded);
 		}
 
@@ -357,5 +396,5 @@
 	/**
 	 * Gets the full path and file name of the frame.
-	 * 
+	 * This is a alias for Frame::getFramePathLogical
 	 * @param path-
 	 *            the directory in which to look for the frameset containing the
@@ -475,5 +514,5 @@
 	}
 
-	private static Frame LoadKnowPath(String path, String frameName) {
+	private static Frame LoadKnownPath(String path, String frameName) {
 		String fullPath = getFrameFullPathName(path, frameName);
 		if (fullPath == null) {
@@ -483,9 +522,26 @@
 		try {
 			FrameReader reader;
-
+			
+			// Get the frameset name.
+			int i = frameName.length() - 1;
+			for (; i >= 0; i--) {
+				if (!Character.isDigit(frameName.charAt(i))) {
+					break;
+				}	
+			}
+			if (i < 0) {
+				System.err.println("LoadKnownFrame was provided with a invalid Frame name: " + frameName);
+				return null;
+			}
+			String framesetName = frameName.substring(0, i + 1);
+			
+			String redirectTo = ExpReader.redirectTo(fullPath);
+			while (redirectTo != null) {
+				fullPath = path + framesetName + File.separator + redirectTo;
+				redirectTo = ExpReader.redirectTo(fullPath);
+			}
+			
 			if (fullPath.endsWith(ExpReader.EXTENTION)) {
 				if (EncryptedExpReader.isEncryptedExpediteeFile(fullPath)) {
-					//final boolean isProfile = frameName.startsWith(UserSettings.UserName.get());
-					//reader = new EncryptedExpReader(frameName, isProfile);
 					reader = new EncryptedExpReader(frameName);
 				} else {
@@ -919,5 +975,5 @@
 
 	private static boolean isValidFrameNameChar(char c) {
-		return Character.isLetterOrDigit(c) || c == '-';
+		return c == '-' || c == '.' || Character.isLetterOrDigit(c);
 	}
 
@@ -952,17 +1008,14 @@
 	 * 
 	 * @param toSave
-	 *            The Frame to save to disk
+	 *            	The Frame to save to disk
 	 * @param inc
-	 *            True if the saved frames counter should be incremented, false
-	 *            otherwise.
+	 *            	True if the saved frames counter should be incremented, false otherwise.
 	 * @param checkBackup
-	 *            True if the frame should be checked for the back up tag
-	 */
-	public static String SaveFrame(Frame toSave, boolean inc,
-			boolean checkBackup) {
-
+	 *            	True if the frame should be checked for the back up tag
+	 */
+	public static String SaveFrame(Frame toSave, boolean inc, boolean checkBackup) {
 		// TODO When loading a frame maybe append onto the event history too-
 		// with a break to indicate the end of a session
-
+		
 		if (toSave == null || !toSave.hasChanged() || toSave.isSaved()) {
 			return "";
@@ -982,5 +1035,4 @@
 
 		// Save frame that is not local through the Networking classes
-		// TODO
 		if (!toSave.isLocal()) {
 			return FrameShare.getInstance().saveFrame(toSave);
@@ -1012,7 +1064,6 @@
 		try {
 			// if its a new frame or an existing Exp frame...
-			if (fullPath == null || fullPath.endsWith(ExpReader.EXTENTION)) {
-				if (UserSettings.Authenticated.get() && 
-						toSave.getNumber() != Authenticator.PUBLIC_KEY_FRAME && 
+			if (fullPath == null || fullPath.endsWith(ExpReader.EXTENTION)) {				
+				if (toSave.getNumber() != Authenticator.CREDENTIALS_FRAME && 
 						toSave.getEncryptionLabel() != null) {
 					writer = new EncryptedExpWriter(toSave.getEncryptionLabel());
@@ -1022,4 +1073,12 @@
 					savedVersion = ExpReader.getVersion(fullPath);
 				}
+				
+				// Is the file this would be saved to a redirect?
+				String redirectTo = ExpReader.redirectTo(fullPath);
+				if (redirectTo != null) {
+					String redirectedPath = toSave.getFramePathReal();
+					writer.setOutputLocation(redirectedPath);
+				}
+				
 			} else {
 				writer = new KMSWriter();
@@ -1042,11 +1101,12 @@
 			// Check if we are trying to save an out of date version
 			String framesetName = toSave.getFramesetName();
-			long frameLastModify = toSave.getLastModifyPrecise();
-			long fileLastModify = new File(fullPath).lastModified();
-			boolean versionConflict = frameLastModify < fileLastModify;
 			boolean isBayFrameset = 
 					framesetName.equalsIgnoreCase(MessageBay.MESSAGES_FRAMESET_NAME) || 
 					framesetName.equalsIgnoreCase(MailBay.EXPEDITEE_MAIL_FRAMESET_NAME);
-			if ((savedVersion > toSave.getVersion() || versionConflict) && !isBayFrameset) {
+			long frameLastModify = toSave.getLastModifyPrecise();
+			long fileLastModify = new File(toSave.getFramePathReal()).lastModified();
+			boolean fileModifyConflict = fileLastModify > frameLastModify && !isBayFrameset;
+			boolean versionConflict = savedVersion > toSave.getVersion() && !isBayFrameset;
+			if (fileModifyConflict || versionConflict) {
 				// remove this frame from the cache if it is there
 				// This will make sure links to the original are set correctly
@@ -1063,6 +1123,13 @@
 				Text originalMessage = new Text(-1);
 				originalMessage.setColor(MessageBay.ERROR_COLOR);
-				originalMessage.setText(original.getName()
-						+ " was updated by another user.");
+				StringBuilder message = new StringBuilder(original.getName()
+						+ " was updated by another user. ");
+				if (fileModifyConflict) {
+					message.append("{ File modify conflict }");
+				}
+				if (versionConflict) {
+					message.append("{ Version conflict }");
+				}
+				originalMessage.setText(message.toString());
 				originalMessage.setLink(original.getName());
 				Text yourMessage = new Text(-1);
@@ -1073,4 +1140,5 @@
 				MessageBay.displayMessage(originalMessage);
 				MessageBay.displayMessage(yourMessage);
+				EcosystemManager.getMiscManager().beep();
 			} else if (checkBackup
 					&& ItemUtils.ContainsExactTag(toSave.getItems(),
@@ -1112,13 +1180,16 @@
 				ResumeCache();
 			}
-			// Update general stuff about frame
-			setSavedProperties(toSave);
 
 			// int oldMode = FrameGraphics.getMode();
 			// if (oldMode != FrameGraphics.MODE_XRAY)
 			// FrameGraphics.setMode(FrameGraphics.MODE_XRAY, true);
+			
 			writer.writeFrame(toSave);
 			// FrameGraphics.setMode(oldMode, true);
 			toSave.setSaved();
+			
+			// Update general stuff about frame
+			setSavedProperties(toSave);
+			
 			if (inc) {
 				SessionStats.SavedFrame(toSave.getName());
@@ -1144,6 +1215,5 @@
 			// re-parsing)
 			if (isProfileFrame(toSave)) {
-				Frame profile = FrameIO.LoadFrame(toSave.getFramesetName()
-						+ "1");
+				Frame profile = FrameIO.LoadFrame(toSave.getFramesetName() + "1");
 				assert (profile != null);
 				FrameUtils.ParseProfile(profile);
@@ -1155,4 +1225,5 @@
 			return null;
 		}
+		toSave.notifyObservers(false);
 
 		return writer.getFileContents();
@@ -1212,4 +1283,8 @@
 		_Cache.put(toAdd.getName().toLowerCase(), toAdd);
 	}
+	
+	public static void ClearCache() {
+		_Cache.clear();
+	}
 
 	/**
@@ -1241,7 +1316,7 @@
 	}
 
-	public static Frame CreateNewProfile(String username) throws Exception {
+	public static Frame CreateNewProfile(String username, Map<String, Setting> initialSettings) throws InvalidFramesetNameException, ExistingFramesetException  {
 		Frame profile = CreateFrameset(username, PROFILE_PATH, true);
-		FrameUtils.CreateDefaultProfile(username, profile);
+		FrameUtils.CreateDefaultProfile(username, profile, initialSettings);
 		return profile;
 	}
@@ -1477,10 +1552,9 @@
 	}
 
-	public static Frame CreateFrameset(String frameset, String path, boolean recreate) throws Exception
-	{
+	public static Frame CreateFrameset(String frameset, String path, boolean recreate) throws InvalidFramesetNameException, ExistingFramesetException {
 		String conversion = frameset + " --> ";
 
 		if (!isValidFramesetName(frameset)) {
-			throw new Exception("Invalid frameset name");
+			throw new InvalidFramesetNameException(frameset);
 		}
 
@@ -1557,4 +1631,6 @@
 		base.setOwner(UserSettings.UserName.get());
 		SaveFrame(base, true);
+		
+		FrameIO.setSavedProperties(base);
 
 		Logger.Log(Logger.SYSTEM, Logger.NEW_FRAMESET, "Created new frameset: " + frameset);
@@ -1801,12 +1877,4 @@
 			e.printStackTrace();
 		}
-		// } else {
-		//			
-		//			
-		//			
-		// MessageBay
-		// .errorMessage("Recieved save request for unknown public frame: "
-		// + frameName);
-		// }
 	}
 
@@ -1822,4 +1890,3 @@
 		toSave.setActiveTime(activeTime);
 	}
-
 }
Index: trunk/src/org/expeditee/gui/FrameUtils.java
===================================================================
--- trunk/src/org/expeditee/gui/FrameUtils.java	(revision 1241)
+++ trunk/src/org/expeditee/gui/FrameUtils.java	(revision 1242)
@@ -24,7 +24,11 @@
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
 import java.net.JarURLConnection;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -36,8 +40,12 @@
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
+import java.util.stream.Collectors;
 import java.util.zip.ZipEntry;
 
+import org.expeditee.agents.ExistingFramesetException;
+import org.expeditee.agents.InvalidFramesetNameException;
 import org.expeditee.auth.gui.MailBay;
 import org.expeditee.core.Colour;
@@ -67,4 +75,5 @@
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.items.widgets.WidgetEdge;
+import org.expeditee.setting.Setting;
 import org.expeditee.settings.Settings;
 import org.expeditee.settings.UserSettings;
@@ -76,6 +85,6 @@
 
 	/**
-	 * The list of known start pages framesets which will have prepopulated
-	 * links in the home frame.
+	 * The list of known start pages framesets which will have prepopulated links in
+	 * the home frame.
 	 */
 	public static final String[] startPages = { "exploratorysearch", "webbrowser" };
@@ -99,17 +108,15 @@
 	private static Item _tdfcItem = null;
 
-	public static float getResponseTimeTotal()
-	{
+	public static float getResponseTimeTotal() {
 		return _ResponseTimeSum;
 	}
 
-	public static float getLastResponseTime()
-	{
+	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...
+	 * 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
@@ -140,7 +147,5 @@
 
 		// Ensure the two items
-		if ((minX >= startX && minX <= endX)
-				|| (maxX >= startX && maxX <= endX)
-				|| (startX >= minX && startX <= maxX)
+		if ((minX >= startX && minX <= endX) || (maxX >= startX && maxX <= endX) || (startX >= minX && startX <= maxX)
 				|| (endX >= minX && endX <= maxX)) {
 			return true;
@@ -150,6 +155,5 @@
 	}
 
-	public static boolean sameBulletType(String bullet1, String bullet2)
-	{
+	public static boolean sameBulletType(String bullet1, String bullet2) {
 		if (bullet1 == null || bullet2 == null) {
 			return false;
@@ -160,11 +164,9 @@
 		}
 
-		if (Character.isLetter(bullet1.charAt(0))
-				&& Character.isLetter(bullet2.charAt(0))) {
+		if (Character.isLetter(bullet1.charAt(0)) && Character.isLetter(bullet2.charAt(0))) {
 			return true;
 		}
 
-		if (Character.isDigit(bullet1.charAt(0))
-				&& Character.isDigit(bullet2.charAt(0))) {
+		if (Character.isDigit(bullet1.charAt(0)) && Character.isDigit(bullet2.charAt(0))) {
 			return true;
 		}
@@ -205,11 +207,10 @@
 	 * @return
 	 */
-	public static int Align(List<Text> toAlign, boolean moveAll, int adjust,
-			List<Item> changedItems) {
+	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.
+		 * 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) {
@@ -232,6 +233,5 @@
 			lastBullet = StandardGestureActions.getAutoBullet(above.getText());
 		} else {
-			lastBullet = StandardGestureActions.getBullet(toAlign.get(0)
-					.getText());
+			lastBullet = StandardGestureActions.getBullet(toAlign.get(0).getText());
 		}
 		if (needsRenumbering(lastBullet)) {
@@ -251,6 +251,5 @@
 
 					// if we changed the item, add to changedItems list
-					if (changedItems != null
-							&& oldText != currentText.getText()
+					if (changedItems != null && oldText != currentText.getText()
 							&& !changedItems.contains(currentText)) {
 						Item copy = currentText.copy();
@@ -293,6 +292,5 @@
 
 			if (UserSettings.FormatSpacingMax.get() != null) {
-				double maxSpace = UserSettings.FormatSpacingMax.get()
-						* above.getSize();
+				double maxSpace = UserSettings.FormatSpacingMax.get() * above.getSize();
 				if (maxSpace < space) {
 					space = (int) Math.round(maxSpace);
@@ -301,6 +299,5 @@
 
 			if (UserSettings.FormatSpacingMin.get() != null) {
-				double minSpace = UserSettings.FormatSpacingMin.get()
-						* above.getSize();
+				double minSpace = UserSettings.FormatSpacingMin.get() * above.getSize();
 				if (minSpace > space) {
 					space = (int) Math.round(minSpace);
@@ -309,14 +306,9 @@
 
 			// Need to do things differently for FORMAT than for DROPPING
-			if (moveAll && above != curr.getNameItem()
-					&& above != curr.getTitleItem()) {
+			if (moveAll && above != curr.getNameItem() && above != curr.getTitleItem()) {
 				x = above.getX();
-				int y = above.getBounds().getMaxY()
-						+ space
-						+ (from.getY() - from.getBounds().getMinY());
-
-				if (changedItems != null
-						&& (from.getX() != x || from.getY() != y)
-						&& !changedItems.contains(from)) {
+				int y = above.getBounds().getMaxY() + space + (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());
@@ -343,6 +335,5 @@
 			int newPos = bottom + space + diff;
 
-			if (changedItems != null
-					&& ((moveAll && current.getX() != x) || current.getY() != newPos)
+			if (changedItems != null && ((moveAll && current.getX() != x) || current.getY() != newPos)
 					&& !changedItems.contains(current)) {
 				Item copy = current.copy();
@@ -411,5 +402,6 @@
 			// 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?")) {
+				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));
@@ -420,5 +412,6 @@
 			} 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?")) {
+					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));
@@ -440,11 +433,10 @@
 	}
 
-	// TODO: consider reloating this method to Frame class?    
-	protected static Item getAnnotation(Frame frame, String annotationStr)
-	{
+	// 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()) {				
+		for (Item i : frame.getAnnotationItems()) {
 
 			if (ItemUtils.startsWithTag(i, annotationStr)) {
@@ -458,42 +450,41 @@
 	}
 
-	protected static void doFrameTransition(Item frameTransition, Frame from, Frame to)
-	{
-		String s = frameTransition.getText();		
+	protected static void doFrameTransition(Item frameTransition, Frame from, Frame to) {
+		String s = frameTransition.getText();
 		String[] s_array = s.split(":");
-		if(s_array.length > 1){
+		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	   
-		}
-	}				
+			// 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.
+	 * 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
+	 *            True if the current Frame should be added to the back-stack, False
+	 *            otherwise
 	 */
-	public static void DisplayFrame(Frame toDisplay, boolean addToBack, boolean incrementStats)
-	{
+	public static void DisplayFrame(Frame toDisplay, boolean addToBack, boolean incrementStats) {
 		if (toDisplay == null) {
 			return;
 		}
-		
+
 		final PermissionPair framePermissions = toDisplay.getPermission();
-		if (framePermissions != null && framePermissions.getPermission(toDisplay.getOwner()) == UserAppliedPermission.denied) {
+		if (framePermissions != null
+				&& framePermissions.getPermission(toDisplay.getOwner()) == UserAppliedPermission.denied) {
 			MessageBay.errorMessage("Insufficient permissions to navigate to frame: " + toDisplay.getName());
 			return;
@@ -569,8 +560,9 @@
 			// 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
+			// 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);
+				doFrameTransition(frameTransition, current, toDisplay);
 			}
 		}
@@ -586,15 +578,14 @@
 
 	/**
-	 * Loads and displays the Frame with the given framename, and adds the
-	 * current frame to the back-stack if required.
+	 * 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
+	 *            True if the current Frame should be added to the back-stack, false
+	 *            otherwise
 	 */
-	public static void DisplayFrame(String frameName, boolean addToBack,
-			boolean incrementStats) {
+	public static void DisplayFrame(String frameName, boolean addToBack, boolean incrementStats) {
 		Frame newFrame = getFrame(frameName);
 
@@ -606,7 +597,7 @@
 
 	/**
-	 * 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)
+	 * 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
@@ -629,6 +620,6 @@
 
 	/**
-	 * Creates a new Picture Item from the given Text source Item and adds it to
-	 * the given Frame.
+	 * 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
@@ -647,6 +638,5 @@
 				// MessageBay.errorMessage("Expected image path after @i:");
 			} else {
-				MessageBay.errorMessage("Image " + imagePath
-						+ " could not be loaded");
+				MessageBay.errorMessage("Image " + imagePath + " could not be loaded");
 			}
 			return false;
@@ -658,6 +648,6 @@
 
 	/**
-	 * Creates an interactive widget and adds it to a frame. If txt has no
-	 * parent the parent will be set to frame.
+	 * Creates an interactive widget and adds it to a frame. If txt has no parent
+	 * the parent will be set to frame.
 	 * 
 	 * @param frame
@@ -713,8 +703,7 @@
 	}
 
-	public static List<String> ParseProfile(Frame profile)
-	{
+	public static List<String> ParseProfile(Frame profile) {
 		List<String> errors = new LinkedList<String>();
-		
+
 		if (profile == null) {
 			return errors;
@@ -722,6 +711,6 @@
 
 		/*
-		 * Make sure the correct cursor shows when turning off the custom cursor
-		 * and reparsing the profile frame
+		 * Make sure the correct cursor shows when turning off the custom cursor and
+		 * reparsing the profile frame
 		 */
 		FreeItems.getCursor().clear();
@@ -739,5 +728,5 @@
 					continue;
 				}
-				
+
 				String attribute = attributeFullCase.trim().toLowerCase().replaceAll("^@", "");
 
@@ -764,6 +753,5 @@
 	 * @param profile
 	 */
-	public static void loadFirstFrame(Frame profile)
-	{
+	public static void loadFirstFrame(Frame profile) {
 		if (UserSettings.HomeFrame.get() == null) {
 			UserSettings.HomeFrame.set(profile.getName());
@@ -781,6 +769,5 @@
 	}
 
-	public static Colour[] getColorWheel(Frame frame)
-	{
+	public static Colour[] getColorWheel(Frame frame) {
 		if (frame != null) {
 			List<Text> textItems = frame.getBodyTextItems(false);
@@ -797,6 +784,5 @@
 	}
 
-	public static String getLink(Item item, String alt)
-	{
+	public static String getLink(Item item, String alt) {
 		if (item == null || !(item instanceof Text)) {
 			return alt;
@@ -816,6 +802,5 @@
 	}
 
-	public static String getDir(String name)
-	{
+	public static String getDir(String name) {
 		if (name != null) {
 			File tester = new File(name);
@@ -833,6 +818,5 @@
 	}
 
-	public static ArrayList<String> getDirs(Item item)
-	{
+	public static ArrayList<String> getDirs(Item item) {
 		ArrayList<String> dirsToAdd = new ArrayList<String>();
 		String dirListFrameName = item.getAbsoluteLink();
@@ -857,16 +841,14 @@
 	}
 
-	public static void Parse(Frame toParse)
-	{
+	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.
+	 * 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)
-	{
+	public static void Parse(Frame toParse, boolean firstParse) {
 		Parse(toParse, firstParse, false);
 	}
@@ -877,10 +859,9 @@
 	 * @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.
+	 *            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)
-	{
+	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
@@ -892,5 +873,5 @@
 			ItemUtils.EnclosedCheck(toParse.getItems());
 		}
-		
+
 		List<Item> items = toParse.getItems();
 
@@ -937,6 +918,6 @@
 		}
 
-		//DotType pointtype = DotType.square;
-		//boolean filledPoints = true;
+		// DotType pointtype = DotType.square;
+		// boolean filledPoints = true;
 
 		UserAppliedPermission permission = toParse.getUserAppliedPermission();
@@ -958,46 +939,38 @@
 							Text txt = (Text) i;
 							String line = txt.getFirstLine();
-							line = ItemUtils.StripTag(line,
-									ItemUtils.GetTag(ItemUtils.TAG_POINTTYPE));
+							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);
+									String fill = line.substring(line.indexOf(" ") + 1);
 									if (fill.startsWith("nofill")) {
-										//filledPoints = false;
+										// filledPoints = false;
 									} else {
-										//filledPoints = true;
+										// filledPoints = true;
 									}
 								}
 
 								if (line.startsWith("circle")) {
-									//pointtype = DotType.circle;
+									// pointtype = DotType.circle;
 								} else {
-									//pointtype = DotType.square;
+									// pointtype = DotType.square;
 								}
 							}
-						}// check for new VECTOR items
-						else if (!DisplayController.isXRayMode()
-								&& ItemUtils.startsWithTag(i,
-										ItemUtils.TAG_VECTOR)
+						} // 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);
+								addVector(vectors, UserAppliedPermission.none, permission, i);
 							}
 						} else if (!DisplayController.isXRayMode()
-								&& ItemUtils.startsWithTag(i,
-										ItemUtils.TAG_ACTIVE_VECTOR)
-								&& i.getLink() != null) {
+								&& ItemUtils.startsWithTag(i, ItemUtils.TAG_ACTIVE_VECTOR) && i.getLink() != null) {
 							if (!i.getAbsoluteLink().equals(toParse.getName())) {
-								addVector(vectors,
-										UserAppliedPermission.followLinks,
-										permission, i);
+								addVector(vectors, UserAppliedPermission.followLinks, permission, i);
 							}
 						}
 						// check for new OVERLAY items
-						else if (!ignoreAnnotations && ItemUtils.startsWithTag(i, ItemUtils.TAG_OVERLAY) && i.getLink() != null) {
+						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
@@ -1014,7 +987,5 @@
 						}
 						// check for ACTIVE_OVERLAY items
-						else if (!ignoreAnnotations
-								&& ItemUtils.startsWithTag(i,
-										ItemUtils.TAG_ACTIVE_OVERLAY)
+						else if (!ignoreAnnotations && ItemUtils.startsWithTag(i, ItemUtils.TAG_ACTIVE_OVERLAY)
 								&& i.getLink() != null) {
 							String link = i.getAbsoluteLink();
@@ -1022,7 +993,5 @@
 								// This frame contains an active overlay which
 								// points to itself
-								MessageBay
-								.errorMessage(toParse.getName()
-										+ " contains an @ao which links to itself");
+								MessageBay.errorMessage(toParse.getName() + " contains an @ao which links to itself");
 								continue;
 							}
@@ -1032,6 +1001,5 @@
 							if (current != null) {
 								for (Overlay o : current.getOverlays()) {
-									if (o.Frame.getName()
-											.equalsIgnoreCase(link)) {
+									if (o.Frame.getName().equalsIgnoreCase(link)) {
 										overlayFrame = o.Frame;
 									}
@@ -1043,26 +1011,20 @@
 
 							// get level if specified
-							String level = new AttributeValuePair(i.getText())
-									.getValue();
+							String level = new AttributeValuePair(i.getText()).getValue();
 							// default permission (if none is specified)
-							PermissionPair permissionLevel = new PermissionPair(
-									level, UserAppliedPermission.followLinks);
+							PermissionPair permissionLevel = new PermissionPair(level,
+									UserAppliedPermission.followLinks);
 
 							if (overlayFrame != null) {
-								Overlay existingOverlay = Overlay.getOverlay(
-										overlays, overlayFrame);
+								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()));
+									Overlay newOverlay = new Overlay(overlayFrame,
+											permissionLevel.getPermission(overlayFrame.getOwner()));
 									i.setOverlay(newOverlay);
 									overlays.add(newOverlay);
 								} else {
-									existingOverlay.Frame
-									.setPermission(permissionLevel);
+									existingOverlay.Frame.setPermission(permissionLevel);
 								}
 							}
@@ -1071,16 +1033,11 @@
 						else {
 							if (!DisplayController.isXRayMode()) {
-								if (ItemUtils.startsWithTag(i,
-										ItemUtils.TAG_IMAGE, true)) {
+								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())) {
+								} else if (ItemUtils.startsWithTag(i, ItemUtils.TAG_FRAME_IMAGE) && i.getLink() != null
+										&& !i.getAbsoluteLink().equalsIgnoreCase(toParse.getName())) {
 									XRayable image = null;
 									if (i.hasEnclosures()) {
@@ -1095,10 +1052,6 @@
 									// FrameImage
 									toParse.addItem(image);
-								} else if (ItemUtils.startsWithTag(i,
-										ItemUtils.TAG_BITMAP_IMAGE)
-										&& i.getLink() != null
-										&& !i.getAbsoluteLink()
-										.equalsIgnoreCase(
-												toParse.getName())) {
+								} else if (ItemUtils.startsWithTag(i, ItemUtils.TAG_BITMAP_IMAGE) && i.getLink() != null
+										&& !i.getAbsoluteLink().equalsIgnoreCase(toParse.getName())) {
 									XRayable image = null;
 									if (i.hasEnclosures()) {
@@ -1116,10 +1069,9 @@
 								} else if (ItemUtils.startsWithTag(i, "@c")) {
 									// Can only have a @c
-									if (!i.hasEnclosures()
-											&& i.getLines().size() == 1) {
+									if (!i.hasEnclosures() && i.getLines().size() == 1) {
 										toParse.addItem(new Circle((Text) i));
 									}
 									// Check for JSItem
-								} else if(ItemUtils.startsWithTag(i, "@js")) {
+								} else if (ItemUtils.startsWithTag(i, "@js")) {
 									toParse.addItem(new JSItem((Text) i));
 									// Check for interactive widgets
@@ -1138,7 +1090,6 @@
 				Logger.Log(e);
 				e.printStackTrace();
-				MessageBay.warningMessage("Exception occured when loading "
-						+ i.getClass().getSimpleName() + "(ID: " + i.getID()
-						+ ") " + e.getMessage() != null ? e.getMessage() : "");
+				MessageBay.warningMessage("Exception occured when loading " + i.getClass().getSimpleName() + "(ID: "
+						+ i.getID() + ") " + e.getMessage() != null ? e.getMessage() : "");
 			}
 		}
@@ -1146,6 +1097,5 @@
 		/*
 		 * for (Item i : items) { if (i instanceof Dot) { ((Dot)
-		 * i).setPointType(pointtype); ((Dot) i).useFilledPoints(filledPoints);
-		 * } }
+		 * i).setPointType(pointtype); ((Dot) i).useFilledPoints(filledPoints); } }
 		 */
 
@@ -1166,6 +1116,6 @@
 	 * @param i
 	 */
-	private static void addVector(List<Vector> vectors, UserAppliedPermission defaultPermission, UserAppliedPermission framePermission, Item 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
@@ -1174,9 +1124,10 @@
 
 		// Get the permission from off the vector frame
-		UserAppliedPermission vectorPermission = UserAppliedPermission.getPermission(vector.getAnnotationValue("permission"), defaultPermission);
-		
+		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);
@@ -1195,12 +1146,11 @@
 	}
 
-	public static Item onItem(float floatX, float floatY, boolean changeLastEdited)
-	{
+	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.
+	 * Searches through the list of items on this frame to find one at the given x,y
+	 * coordinates.
 	 * 
 	 * @param x
@@ -1255,9 +1205,7 @@
 		} else {
 			if (LastEdited != null) {
-				if (LastEdited.contains(x, y)
-						&& !FreeItems.getInstance().contains(LastEdited)
+				if (LastEdited.contains(x, y) && !FreeItems.getInstance().contains(LastEdited)
 						&& LastEdited.getParent() == DisplayController.getCurrentFrame()
-						&& LastEdited.getParent().getItems().contains(LastEdited))
-				{
+						&& LastEdited.getParent().getItems().contains(LastEdited)) {
 					LastEdited.setOverlayPermission(UserAppliedPermission.full);
 					return LastEdited;
@@ -1273,5 +1221,6 @@
 
 				// 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.
+				// 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) {
@@ -1283,18 +1232,17 @@
 								Widget iw = wc.getWidgetSource();
 
-								if(iw.getBounds().contains(x, y)){
-
-									if( !FreeItems.getInstance().contains(i))
-									{
-										possibles.add(i);					    		
+								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 (i.contains(new Point(x, y))) {
+						if (!FreeItems.getInstance().contains(i)) {
+							possibles.add(i);
 						}
 					}
@@ -1316,11 +1264,10 @@
 		// 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)));
+		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)));
+			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);
@@ -1336,29 +1283,26 @@
 			}
 
-		}	
+		}
 
 		return closest;
 	}
-	
+
 	/**
 	 * Checks if the mouse is currently over an item.
 	 * 
-	 * @return
-	 * 		True if the mouse is over any item, false otherwise.
+	 * @return True if the mouse is over any item, false otherwise.
 	 */
-	public static boolean hasCurrentItem()
-	{
+	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()
-	{
+	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;
@@ -1373,13 +1317,11 @@
 	 * @return
 	 */
-	public static Collection<Item> getCurrentItems()
-	{
+	public static Collection<Item> getCurrentItems() {
 		return getCurrentItems(getCurrentItem());
 	}
 
-	public static Collection<Item> getCurrentItems(Item currentItem)
-	{
+	public static Collection<Item> getCurrentItems(Item currentItem) {
 		Collection<Item> enclosure = getEnclosingLineEnds();
-		
+
 		if (enclosure == null || enclosure.size() == 0) {
 			return null;
@@ -1388,11 +1330,11 @@
 		Item firstItem = enclosure.iterator().next();
 
-		Collection<Item> enclosed = getItemsEnclosedBy(DisplayController.getCurrentFrame(), firstItem.getEnclosedShape());
+		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
+		 * 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>();
@@ -1412,5 +1354,5 @@
 				}
 			}
-			
+
 			if (i instanceof WidgetCorner) {
 				if (!enclosedWidgets.contains(((WidgetCorner) i).getWidgetSource())) {
@@ -1418,5 +1360,5 @@
 				}
 			}
-			
+
 			i.setHighlightMode(Item.HighlightMode.None);
 			i.setHighlightColorToDefault();
@@ -1435,16 +1377,16 @@
 
 	/**
-	 * Gets the collection of Dot items that form the enclosure nearest to the current mouse position.
+	 * Gets the collection of Dot items that form the enclosure nearest to the
+	 * current mouse position.
 	 */
-	public static Collection<Item> getEnclosingLineEnds()
-	{
+	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.
+	 * Gets the collection of Dot items that form the enclosure nearest to the given
+	 * position.
 	 */
-	public static Collection<Item> getEnclosingLineEnds(Point position)
-	{
+	public static Collection<Item> getEnclosingLineEnds(Point position) {
 		// update enclosed shapes
 		Frame current = DisplayController.getCurrentFrame();
@@ -1484,5 +1426,5 @@
 		if (used.size() == 1) {
 			return used.get(0).getEnclosingDots();
-		// otherwise, determine which polygon is closest to the cursor
+			// otherwise, determine which polygon is closest to the cursor
 		} else {
 			Collections.sort(used, new Comparator<Item>() {
@@ -1503,5 +1445,5 @@
 
 						if (i < p2.getPointCount()) {
-							diff2 = Math.abs(p2.getPoint(i).getX() - mouseX)  + Math.abs(p2.getPoint(i).getY() - mouseY);
+							diff2 = Math.abs(p2.getPoint(i).getX() - mouseX) + Math.abs(p2.getPoint(i).getY() - mouseY);
 						}
 
@@ -1544,6 +1486,5 @@
 	// TODO Remove this method!!
 	// Can just getItemsWithin be used?
-	public static Collection<Item> getItemsEnclosedBy(Frame frame, PolygonBounds poly)
-	{
+	public static Collection<Item> getItemsEnclosedBy(Frame frame, PolygonBounds poly) {
 		Collection<Item> contained = frame.getItemsWithin(poly);
 
@@ -1570,198 +1511,190 @@
 		return results;
 	}
+	
+	public static void CreateDefaultProfile(String profileFor, Frame profile) {
+		CreateDefaultProfile(profileFor, profile, null);
+	}
 
 	/**
-	 * Fills the given Frame with default profile tags
+	 * Copies the content from the default profile to the specified profile.
+	 * @param profileFor Name of profile that is destination of copy.
+	 * @param profile Profile being setup.
+	 * @param specifiedTextSettings text settings to provide a default value for in the new profile
+	 * @param specifiedGenericSettings generic settings to provide a default value for in the new profile
 	 */
-	public static void CreateDefaultProfile(String username, Frame profile)
-	{
-		Text title = profile.getTitleItem();
-		if (username.equals(UserSettings.DEFAULT_PROFILE_NAME)) {
+	public static void CreateDefaultProfile(String profileFor, Frame profile, 
+			Map<String, Setting> specifiedSettings) {
+		// If this is already the default profile then nothing (other than setting
+		// title) needs to be done.
+		Text titleItem = profile.getTitleItem();
+		Text title = titleItem;
+		if (!profileFor.equals(UserSettings.DEFAULT_PROFILE_NAME)) {
+			// 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 defaultFrame = FrameIO.LoadProfile(UserSettings.DEFAULT_PROFILE_NAME);
+			if (defaultFrame == null) {
+				try {
+					// If we do not have a default to copy, create one.
+					defaultFrame = FrameIO.CreateNewProfile(UserSettings.DEFAULT_PROFILE_NAME, null);
+				} catch (InvalidFramesetNameException invalidNameEx) {
+					MessageBay.errorMessage("Failed to create default profile named: "
+							+ UserSettings.DEFAULT_PROFILE_NAME + ".  "
+							+ "Profile names must start and end with a letter and must contain only letters and numbers.");
+					return;
+				} catch (ExistingFramesetException existingFramesetEx) {
+					MessageBay.errorMessage("Failed to create the desired default frameset: "
+							+ UserSettings.DEFAULT_PROFILE_NAME + ", "
+							+ "because it already exists.  This should never happen as we shouldn't be asking to create it if it already exists.");
+					return;
+				}
+			}
+
+			MessageBay.suppressMessages(true);
+			int lastNumber = FrameIO.getLastNumber(defaultFrame.getFramesetName());
+			for (int i = 1; i <= lastNumber; i++) {
+				// Load in next default, if it doesn't exist continue loop.
+				defaultFrame = FrameIO.LoadFrame(defaultFrame.getFramesetName() + i);
+				if (defaultFrame == null) {
+					continue;
+				}
+
+				// Create the next next (currently blank) profile frame.
+				// If there is frame gaps in the default (say if there is no 4.exp but there is
+				// a 5.exp) then retain those gaps.
+				// This way copied relative links work.
+				while (profile.getNumber() < defaultFrame.getNumber()) {
+					profile = FrameIO.CreateFrame(profile.getFramesetName(), null, null);
+				}
+				// Ensure we are working from a blank slate.
+				profile.reset();
+				profile.removeAllItems(profile.getAllItems());
+
+				// For each item on defaultFrame:
+				// 1. Set all items to be relatively linked so once copied their links correctly
+				// point to the frame on the created profile rather than the default profile.
+				// 2. Copy item from defaultFrame to the current profile frame being
+				// constructed.
+				// 3. Replace settings values of copied items with those specified in
+				// specifiedSettings (if present)
+				for (Item item : defaultFrame.getAllItems()) {
+					item.setRelativeLink();
+				}
+				profile.addAllItems(defaultFrame.getAllItems());
+				if (i == 1 && titleItem != null) {
+					titleItem.setText(profileFor + "'s Profile");
+				}
+				String category = profile.getTitle();
+				List<String> settingsKeys = null;
+				if (specifiedSettings != null) {
+					settingsKeys = specifiedSettings.keySet().stream().filter(key -> 
+						key.startsWith(category)).collect(Collectors.toList());
+				}
+				if (settingsKeys != null) {
+					for (String key: settingsKeys) {
+						Setting setting = specifiedSettings.get(key);
+						String name = setting.getName();
+						Text representation = setting.generateRepresentation(name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(), profile.getFramesetName());
+						Collection<Text> canditates = profile.getTextItems();
+						canditates.removeIf(text -> !text.getText().startsWith(representation.getText().split(" ")[0]));
+						canditates.forEach(text -> {
+							Point backupPos = text.getPosition();
+							Item.DuplicateItem(representation, text);
+							text.setText(representation.getText());
+							text.setPosition(backupPos);
+						});
+					}
+				}
+				FrameIO.SaveFrame(profile);
+			}
+			MessageBay.suppressMessages(false);
+		} else {
 			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;
+			int xPos = 300;
+			int yPos = 100;
+			Text t;
+			
+			// 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);
+						}
 					}
-
-					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);
+					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);
+								}
 							}
 						}
@@ -1769,22 +1702,21 @@
 				}
 			}
-		}
-
-		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)
-	{
+
+			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
@@ -1806,16 +1738,13 @@
 	}
 
-	public static void setTdfcItem(Item _tdfcItem)
-	{
+	public static void setTdfcItem(Item _tdfcItem) {
 		FrameUtils._tdfcItem = _tdfcItem;
 	}
 
-	public static Item getTdfcItem()
-	{
+	public static Item getTdfcItem() {
 		return FrameUtils._tdfcItem;
 	}
 
-	public static void setLastEdited(Text lastEdited)
-	{
+	public static void setLastEdited(Text lastEdited) {
 		// If the lastEdited is being changed then check if its @i
 		Frame toReparse = null;
@@ -1834,20 +1763,12 @@
 					// 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 (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);
+									DisplayController.getCurrentFrame().removeAllItems(enclosure);
 									AxisAlignedBoxBounds rect = i.getEnclosedBox();
-									LastEdited
-									.setText(LastEdited.getText()
-											+ " "
-											+ Math.round(rect
-													.getWidth()));
+									LastEdited.setText(LastEdited.getText() + " " + Math.round(rect.getWidth()));
 									LastEdited.setPosition(rect.getTopLeft());
 									LastEdited.setThickness(i.getThickness());
@@ -1892,106 +1813,121 @@
 		}
 	}
-
+	
 	/**
-	 * 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
+	 * Extracts files/folders from assets/resources-public and assets/resources-private 
+	 * to {Expeditee Home}/resources-public and {Expeditee Home}/resources-private respectively.
+	 * @param force  if true, resources will be extracted even ifthey have already been extracted before.
 	 */
-	public static void extractResources(boolean force)
-	{
-		File check = new File(FrameIO.PARENT_FOLDER + ".res");
+	public static void extractResources(boolean force) {
+		// Extract private resources
+		Path resourcesPrivate = Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-private");
+		extractResources("org/expeditee/assets/resources-private", resourcesPrivate, force);
 		
-		if(!force && check.exists()) {
+		// Extract public resources
+		Path resourcesPublic = Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-public");
+		extractResources("org/expeditee/assets/resources-public", resourcesPublic, force);
+	}
+	
+	private static void extractResources(String source, Path destination, boolean force) {
+		// If resources have already been extracted, and we are not forcing the extraction, there is nothing to do.
+		if (!force && destination.resolve(".res").toFile().exists()) {
 			return;
 		}
 		
-		System.out.println("Extracting/Installing resources:");
+		System.out.println("Extracting/Installing resources to: " + destination.getFileName());
 		
-		try	{
-			check.getParentFile().mkdirs();
-			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")) {
-				JarURLConnection ju_connection=(JarURLConnection)docURL.openConnection();
-				JarFile jf =ju_connection.getJarFile();
+		// Create the destination
+		destination.getParent().toFile().mkdirs();
+		
+		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+		URL resourceUrl = classLoader.getResource(source);
+		if (resourceUrl.getProtocol().equals("jar")) {
+			try {
+				JarURLConnection ju_connection = (JarURLConnection) resourceUrl.openConnection();
+				JarFile jf = ju_connection.getJarFile();
 				Enumeration<JarEntry> jarEntries = jf.entries();
-				String res = "org/expeditee/assets/resources/";
-				int resLength = res.length();
-
-				ZipEntry ze;
-
-				while(jarEntries.hasMoreElements()) {
-					ze = jarEntries.nextElement();
-					if(!ze.getName().startsWith(res)) {
-						continue;
-					}
-					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(ze.isDirectory()) {
-						// System.out.println(out.getPath() + " IS DIRECTORY");
-						out.mkdirs();
-						continue;
-					}
-					FileOutputStream fOut = null;
-					InputStream fIn = null;
-					try {
-						// System.out.println(out.getPath());
-						fOut =  new FileOutputStream(out);
-						fIn = classLoader.getResourceAsStream(ze.getName());
-						byte[] bBuffer = new byte[1024];
-						int nLen;
-						while ((nLen = fIn.read(bBuffer)) > 0) {
-							fOut.write(bBuffer, 0, nLen);
-						}
-						fOut.flush();
-					} catch (Exception e) {
-						e.printStackTrace();
-					} finally {
-						if(fOut != null) {
-							fOut.close();
-						}
-						if(fIn != null) {
-							fIn.close();
-						}
-					}
-				}
-
-				// Copy files from the source folder to the profile folder
-			} else if (docURL.getProtocol().equals("bundleresource")) {
-				final URLConnection urlConnection = docURL.openConnection();
-				final Class<?> c = urlConnection.getClass();
-				final java.lang.reflect.Method toInvoke = c.getMethod("getFileURL");
-				final URL fileURL = (URL)toInvoke.invoke(urlConnection);
-				extractResourcesFromFolder(new File(fileURL.getPath()));
-			} else {
-				File folder = new File(docURL.toURI().getPath());
-				extractResourcesFromFolder(folder);
-			}
-		}
-		catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-	private static void extractResourcesFromFolder(File folder) throws IOException
-	{
+				extractFromJarFile(classLoader, jarEntries, source, destination);
+			} catch (IOException e) {
+				System.err.println("Error: FrameUtils::extractResources.  Exception whilst extracting resources from Jar File.  Message: " + e.getMessage());
+			}
+		} else if (resourceUrl.getProtocol().equals("bundleresource")) {
+			try {
+				URLConnection urlConnection = resourceUrl.openConnection();
+				Class<?> c = urlConnection.getClass();
+				java.lang.reflect.Method toInvoke = c.getMethod("getFileURL");
+				URL fileURL = (URL) toInvoke.invoke(urlConnection);
+				extractResourcesFromFolder(new File(fileURL.getPath()), source, destination);
+			} catch (IOException e) {
+				System.err.println("Error: FrameUtils::extractResources.  Problem opening connection to bundleresource.  Message: " + e.getMessage());
+			} catch (NoSuchMethodException e) {
+				System.err.println("Error: FrameUtils::extractResources.  Unable to find method URLConnection::getFileURL.  Message: " + e.getMessage());
+			} catch (InvocationTargetException e) {
+				System.err.println("Error: FrameUtils::extractResources.  Problem invoking URLConnection::getFileURL.  Message: " + e.getMessage());
+			} catch (IllegalAccessException e) {
+				System.err.println("Error: FrameUtils::extractResources.  Problem invoking URLConnection::getFileURL.  Message: " + e.getMessage());
+			}
+		} else { 
+			try {
+				File folder = new File(resourceUrl.toURI().getPath());
+				extractResourcesFromFolder(folder, source, destination);
+			} catch (URISyntaxException e) {
+				System.err.println("Error: FrameUtils::extractResources.  Problem converting URL to URI.  Message: " + e.getMessage());
+			} catch (IOException e) {
+				System.err.println("Error: FrameUtils::extractResources.  Exception whilst extracting resources from folder.  Message: " + e.getMessage());
+			}
+		}
+		
+		// Create the .res file to signal completion
+		try {
+			destination.resolve(".res").toFile().createNewFile();
+		} catch (IOException e) {
+			System.err.println("Error: FrameUtils::extractResources.  Unable to create the .res file to flag that resources have been extracted.  Message: " + e.getMessage());
+		}
+	}
+
+	private static void extractFromJarFile(ClassLoader classLoader, Enumeration<JarEntry> jarEntries, String source, Path destination) throws IOException {
+		while (jarEntries.hasMoreElements()) {
+			ZipEntry ze = jarEntries.nextElement();
+			if (!ze.getName().startsWith(source)) {
+				continue;
+			}
+			File out = destination.resolve(ze.getName().substring(source.length())).toFile();
+			if (ze.isDirectory()) {
+				out.mkdirs();
+				continue;
+			}
+			FileOutputStream fOut = null;
+			InputStream fIn = null;
+			try {
+				fOut = new FileOutputStream(out);
+				fIn = classLoader.getResourceAsStream(ze.getName());
+				byte[] bBuffer = new byte[1024];
+				int nLen;
+				while ((nLen = fIn.read(bBuffer)) > 0) {
+					fOut.write(bBuffer, 0, nLen);
+				}
+				fOut.flush();
+			} catch (Exception e) {
+				e.printStackTrace();
+			} finally {
+				if (fOut != null) {
+					fOut.close();
+				}
+				if (fIn != null) {
+					fIn.close();
+				}
+			}
+		}
+	}
+
+	private static void extractResourcesFromFolder(File folder, String source, Path destination) 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")) {
+			if (file.isFile()) {
+				if (!file.getName().contains(".svn")) {
 					files.add(file);
 				}
@@ -2003,9 +1939,8 @@
 		}
 		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;
-			//		}
+			String path = file.getPath();
+			System.out.println(path);
+			Path relativize = folder.toPath().relativize(Paths.get(file.getPath()));
+			File out = destination.resolve(relativize).toFile();
 			copyFile(file, out, true);
 		}
@@ -2017,10 +1952,9 @@
 	 * @throws IOException
 	 */
-	public static void copyFile(File src, File dst, boolean overWrite) throws IOException
-	{
-		if(!overWrite && dst.exists()) {
+	public static void copyFile(File src, File dst, boolean overWrite) throws IOException {
+		if (!overWrite && dst.exists()) {
 			return;
 		}
-		
+
 		dst.getParentFile().mkdirs();
 		FileOutputStream fOut = null;
@@ -2039,8 +1973,8 @@
 			e.printStackTrace();
 		} finally {
-			if(fOut != null) {
+			if (fOut != null) {
 				fOut.close();
 			}
-			if(fIn != null) {
+			if (fIn != null) {
 				fIn.close();
 			}
@@ -2048,11 +1982,9 @@
 	}
 
-	public static Text getLastEdited()
-	{
+	public static Text getLastEdited() {
 		return LastEdited;
 	}
 
-	public static Collection<Text> getCurrentTextItems()
-	{
+	public static Collection<Text> getCurrentTextItems() {
 		Collection<Text> currentTextItems = new LinkedHashSet<Text>();
 		Collection<Item> currentItems = getCurrentItems(null);
Index: trunk/src/org/expeditee/importer/pdfImporter.java
===================================================================
--- trunk/src/org/expeditee/importer/pdfImporter.java	(revision 1241)
+++ trunk/src/org/expeditee/importer/pdfImporter.java	(revision 1242)
@@ -77,5 +77,5 @@
 		}
 		
-		final String framesetPath = frameset.getPath()+name+File.separator;
+		final String framesetPath = frameset.getFramesetPath();
 		
 		System.out.println("PATH = " + framesetPath);
Index: trunk/src/org/expeditee/io/DefaultFrameReader.java
===================================================================
--- trunk/src/org/expeditee/io/DefaultFrameReader.java	(revision 1241)
+++ trunk/src/org/expeditee/io/DefaultFrameReader.java	(revision 1242)
@@ -89,4 +89,5 @@
 			_FrameTags.put('B', Frame.class.getMethod("setBackgroundColor",	pColor));
 			_FrameTags.put('K', Frame.class.getMethod("setEncryptionLabel", pString));
+			_FrameTags.put('T', Frame.class.getMethod("addToData", pString));
 
 			// Note: As of 26/11/18 there are no unused letter item tags.  Use other characters.
Index: trunk/src/org/expeditee/io/DefaultFrameWriter.java
===================================================================
--- trunk/src/org/expeditee/io/DefaultFrameWriter.java	(revision 1241)
+++ trunk/src/org/expeditee/io/DefaultFrameWriter.java	(revision 1242)
@@ -78,4 +78,5 @@
 			_FrameTags.put('B', Frame.class.getMethod("getBackgroundColor"));
 			_FrameTags.put('K', Frame.class.getMethod("getEncryptionLabel"));
+			_FrameTags.put('T', Frame.class.getMethod("getData"));
 			
 			// Note: As of 26/11/18 there are no unused letter item tags.  Use other characters.
Index: trunk/src/org/expeditee/io/ExpReader.java
===================================================================
--- trunk/src/org/expeditee/io/ExpReader.java	(revision 1241)
+++ trunk/src/org/expeditee/io/ExpReader.java	(revision 1242)
@@ -29,4 +29,5 @@
 import org.expeditee.core.Point;
 import org.expeditee.gui.Frame;
+import org.expeditee.gui.FrameIO;
 import org.expeditee.items.Constraint;
 import org.expeditee.items.Dot;
@@ -213,4 +214,5 @@
 		//newFrame.refreshItemPermissions();
 		_reader.close();
+		FrameIO.setSavedProperties(newFrame);
 		newFrame.setChanged(false);
 
@@ -344,3 +346,20 @@
 		return -1;
 	}
+	
+	public static String redirectTo(String fullPath) {
+		try {
+			BufferedReader reader = new BufferedReader(new FileReader(fullPath));
+			String next = "";
+			while (reader.ready() && !(next = reader.readLine()).equals("Z")) {
+				if (next.startsWith("REDIRECT:")) {
+					String redirectTo = next.replace("REDIRECT:", "");
+					reader.close();
+					return redirectTo;
+				}
+			}
+			reader.close();
+		} catch (Exception e) {
+		}
+		return null;
+	}
 }
Index: trunk/src/org/expeditee/io/HTMLWriter.java
===================================================================
--- trunk/src/org/expeditee/io/HTMLWriter.java	(revision 1241)
+++ trunk/src/org/expeditee/io/HTMLWriter.java	(revision 1242)
@@ -28,5 +28,4 @@
 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;
@@ -104,5 +103,5 @@
 			}
 			if (filesFolder.equals("")) {
-				filesFolder = "../" + FrameIO.IMAGES_FOLDER;
+				filesFolder = "../images/";
 			}
 		}
Index: trunk/src/org/expeditee/setting/ArraySetting.java
===================================================================
--- trunk/src/org/expeditee/setting/ArraySetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/ArraySetting.java	(revision 1242)
@@ -21,4 +21,7 @@
 import java.util.Arrays;
 
+import org.expeditee.core.Representable;
+import org.expeditee.gui.Frame;
+import org.expeditee.gui.FrameIO;
 import org.expeditee.items.Text;
 
@@ -28,6 +31,6 @@
 	protected T[] _value;
 	
-	public ArraySetting(String tooltip, T[] value) {
-		super(tooltip);
+	public ArraySetting(String tooltip, String name, T[] value) {
+		super(tooltip, name);
 		_default = Arrays.copyOf(value, value.length);
 		_value = value;
@@ -62,4 +65,33 @@
 		_value = Arrays.copyOf(_default, _default.length);
 	}
-
+	
+	@Override
+	public Text generateRepresentation(String label, String frameset) {
+		Text t = new Text(label);
+		
+		if (_value.length > 0) {
+			Frame arrayFrame = FrameIO.CreateFrame(frameset, null, null);
+			arrayFrame.getTitleItem().delete();
+			
+			int x = 100;
+			int y = 100;
+			for (T v: _value) {
+				if (v == null) continue;
+				Text representation;
+				if (v instanceof Representable) {
+					representation = ((Representable) v).generateRepresentation("Array Entry", "");
+					representation.setPosition(x, y);
+					representation.setID(arrayFrame.getNextItemID());
+					arrayFrame.addItem(representation);
+				} else {
+					representation = arrayFrame.addText(x, y, v.toString(), null);
+				}
+				y += representation.getBoundsHeight();
+			}
+			FrameIO.ForceSaveFrame(arrayFrame);
+			t.setLink(arrayFrame.getName());
+		}
+		
+		return t;
+	}
 }
Index: trunk/src/org/expeditee/setting/BooleanSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/BooleanSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/BooleanSetting.java	(revision 1242)
@@ -21,6 +21,6 @@
 public class BooleanSetting extends GenericSetting<Boolean> {
 
-	public BooleanSetting(String tooltip, Boolean value) {
-		super(Boolean.class, tooltip, value);
+	public BooleanSetting(String tooltip, String name, Boolean value) {
+		super(Boolean.class, tooltip, name, value);
 	}
 }
Index: trunk/src/org/expeditee/setting/FloatSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/FloatSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/FloatSetting.java	(revision 1242)
@@ -21,6 +21,6 @@
 public class FloatSetting extends GenericSetting<Float> {
 
-	public FloatSetting(String tooltip, Float value) {
-		super(Float.class, tooltip, value);
+	public FloatSetting(String tooltip, String name, Float value) {
+		super(Float.class, tooltip, name, value);
 	}
 }
Index: trunk/src/org/expeditee/setting/FrameSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/FrameSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/FrameSetting.java	(revision 1242)
@@ -24,6 +24,6 @@
 public abstract class FrameSetting extends Setting {
 
-	public FrameSetting(String tooltip) {
-		super(tooltip);
+	public FrameSetting(String tooltip, String name) {
+		super(tooltip, name);
 	}
 	
@@ -45,3 +45,8 @@
 	}
 
+	@Override
+	public Text generateRepresentation(String label, String frameset) {
+		Text t = new Text(label);
+		return t;
+	}
 }
Index: trunk/src/org/expeditee/setting/FunctionSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/FunctionSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/FunctionSetting.java	(revision 1242)
@@ -24,6 +24,6 @@
 public abstract class FunctionSetting extends Setting {
 	
-	public FunctionSetting(String tooltip) {
-		super(tooltip);
+	public FunctionSetting(String tooltip, String name) {
+		super(tooltip, name);
 	}
 	
@@ -45,3 +45,9 @@
 		return false;
 	}
+	
+	@Override
+	public Text generateRepresentation(String label, String frameset) {
+		Text text = new Text(label + ": false");
+		return text;
+	}
 }
Index: trunk/src/org/expeditee/setting/GenericSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/GenericSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/GenericSetting.java	(revision 1242)
@@ -43,6 +43,6 @@
 	 * @param value Default value
 	 */
-	public GenericSetting(Class<T> type, String tooltip, T value) {
-		super(tooltip);
+	public GenericSetting(Class<T> type, String tooltip, String name, T value) {
+		super(tooltip, name);
 		_type = type;
 		_default = value;
@@ -53,6 +53,6 @@
 	 * Instantiates a new setting with no default value
 	 */
-	public GenericSetting(Class<T> type, String tooltip) {
-		this(type, tooltip, (T) saneInitialValue(type));
+	public GenericSetting(Class<T> type, String tooltip, String name) {
+		this(type, tooltip, name, (T) saneInitialValue(type));
 	}
 	
@@ -137,4 +137,11 @@
 		_value = _default;
 	}
+	
+	@Override
+	public Text generateRepresentation(String name, String frameset) {
+		T value = get();
+		Text t = new Text(name + ": " + (value == null ? "" : value));
+		return t;
+	}
 
 }
Index: trunk/src/org/expeditee/setting/IntegerSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/IntegerSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/IntegerSetting.java	(revision 1242)
@@ -21,6 +21,6 @@
 public class IntegerSetting extends GenericSetting<Integer> {
 
-	public IntegerSetting(String tooltip, Integer value) {
-		super(Integer.class, tooltip, value);
+	public IntegerSetting(String tooltip, String name, Integer value) {
+		super(Integer.class, tooltip, name, value);
 	}
 }
Index: trunk/src/org/expeditee/setting/ListSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/ListSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/ListSetting.java	(revision 1242)
@@ -22,4 +22,7 @@
 import java.util.List;
 
+import org.expeditee.core.Representable;
+import org.expeditee.gui.Frame;
+import org.expeditee.gui.FrameIO;
 import org.expeditee.items.Text;
 
@@ -29,12 +32,12 @@
 	protected List<T> _value;
 	
-	public ListSetting(String tooltip, List<T> value) {
-		super(tooltip);
+	public ListSetting(String tooltip, String name, List<T> value) {
+		super(tooltip, name);
 		_default = new LinkedList<T>(value);
 		_value = value;
 	}
 	
-	public ListSetting(String tooltip) {
-		this(tooltip, new LinkedList<T>());
+	public ListSetting(String tooltip, String name) {
+		this(tooltip, name, new LinkedList<T>());
 	}
 	
@@ -57,3 +60,32 @@
 	}
 
+	@Override
+	public Text generateRepresentation(String label, String frameset) {
+		Text t = new Text(label);
+		
+		if (!_value.isEmpty()) {
+			Frame listFrame = FrameIO.CreateFrame(frameset, null, null);
+			listFrame.getTitleItem().delete();
+			
+			int x = 100;
+			int y = 100;
+			for (T v: _value) {
+				if (v == null) continue;
+				Text representation;
+				if (v instanceof Representable) {
+					representation = ((Representable) v).generateRepresentation("List Entry", "");
+					representation.setPosition(x, y);
+					representation.setID(listFrame.getNextItemID());
+					listFrame.addItem(representation);
+				} else {
+					representation = listFrame.addText(x, y, v.toString(), null);
+				}
+				y += representation.getBoundsHeight();
+			}
+			FrameIO.ForceSaveFrame(listFrame);
+			t.setLink(listFrame.getName());
+		}
+		
+		return t;
+	}
 }
Index: trunk/src/org/expeditee/setting/Setting.java
===================================================================
--- trunk/src/org/expeditee/setting/Setting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/Setting.java	(revision 1242)
@@ -19,16 +19,23 @@
 package org.expeditee.setting;
 
+import org.expeditee.core.Representable;
 import org.expeditee.items.Text;
 
-public abstract class Setting {
+public abstract class Setting implements Representable {
 	
 	private String _tooltip;
+	private String _name;
 	
-	public Setting(String tooltip) {
+	public Setting(String tooltip, String name) {
 		this._tooltip = tooltip;
+		this._name = name;
 	}
 	
 	public final String getTooltip() {
 		return _tooltip;
+	}
+	
+	public final String getName() {
+		return _name;
 	}
 	
Index: trunk/src/org/expeditee/setting/StringSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/StringSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/StringSetting.java	(revision 1242)
@@ -22,5 +22,5 @@
 
 	public StringSetting(String tooltip, String value) {
-		super(String.class, tooltip, value);
+		super(String.class, tooltip, value, value);
 	}
 }
Index: trunk/src/org/expeditee/setting/TextSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/TextSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/TextSetting.java	(revision 1242)
@@ -23,6 +23,6 @@
 public abstract class TextSetting extends GenericSetting<Text> {
 
-	public TextSetting(String tooltip) {
-		super(Text.class, tooltip, null);
+	public TextSetting(String tooltip, String name) {
+		super(Text.class, tooltip, name, null);
 		_default = generateText();
 		_value = _default;
@@ -41,4 +41,8 @@
 	
 	public abstract Text generateText();
+	
+	public Text generateRepresentation(String label, String frameset) {
+		return get();
+	}
 
 }
Index: trunk/src/org/expeditee/setting/VariableSetting.java
===================================================================
--- trunk/src/org/expeditee/setting/VariableSetting.java	(revision 1241)
+++ trunk/src/org/expeditee/setting/VariableSetting.java	(revision 1242)
@@ -21,6 +21,6 @@
 public abstract class VariableSetting extends Setting {
 	
-	public VariableSetting(String tooltip) {
-		super(tooltip);
+	public VariableSetting(String tooltip, String name) {
+		super(tooltip, name);
 	}
 	
Index: trunk/src/org/expeditee/settings/Settings.java
===================================================================
--- trunk/src/org/expeditee/settings/Settings.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/Settings.java	(revision 1242)
@@ -22,4 +22,5 @@
 import java.lang.reflect.Method;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
@@ -32,5 +33,4 @@
 import org.expeditee.items.widgets.Password;
 import org.expeditee.reflection.PackageLoader;
-import org.expeditee.setting.GenericSetting;
 import org.expeditee.setting.Setting;
 import org.expeditee.setting.VariableSetting;
@@ -229,16 +229,14 @@
 	}
 	
-	/** 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);
+	private static void generateSettingsTree(String page, Text text) {
+		Frame parent = text.getParentOrCurrentFrame();
+		FrameCreator frames = new FrameCreator(parent.getFramesetName(), parent.getPath(), page, false, false);
 		text.setLink(frames.getName());
 		
-		// add subpages of the current page
-		for(String k : _pages.keySet()) {
-			if(k.startsWith(page.toLowerCase()) && !k.equals(page)) {
+		// Add subpages of the current page by recursing
+		for (String k: _pages.keySet()) {
+			if (k.startsWith(page.toLowerCase()) && !k.equals(page)) {
 				String name = k.substring(page.length() + 1);
-				if(name.indexOf('.') != -1) {
+				if (name.indexOf('.') != -1) {
 					continue;
 				}
@@ -248,63 +246,60 @@
 		}
 		
+		// Start building current page
 		frames.setLastY(frames.getLastY() + 20);
-		
-		// add settings of the current page
+		// 	Add Settings of the current page
 		PageDescriptor pd = _pages.get(page);
-		if(pd != null) {
-			for(String str : pd.orderedEntries) {
-				String key = str.toLowerCase();
-				Setting s = pd.settings.get(key);
-				if(s == null) {
+		if (pd == null) {
+			frames.save();
+			return;
+		}
+		
+		
+		Iterator<String> keys = pd.orderedEntries.stream().map(t -> t.toLowerCase()).iterator();
+		while(keys.hasNext()) {
+			String key = keys.next();
+			Setting setting = pd.settings.get(key);
+			if (setting == null) {
+				continue;
+			}
+			
+			// Keep track of were we are placing items on Frames.
+			int x = 0, y = 0;
+			
+			if (key.equals("pass")) {
+				// Special case for Password widgets
+				Text passwordWidgetText = frames.addText("iw: org.expeditee.items.widgets.Passwsord", null, null, null, false);
+				Password pw = new Password(passwordWidgetText, null);
+				pw.setPassword("");
+				frames.getCurrentFrame().removeItem(passwordWidgetText);
+				frames.getCurrentFrame().addAllItems(pw.getItems());
+				x = passwordWidgetText.getX() + passwordWidgetText.getBoundsWidth();
+				y = passwordWidgetText.getY();
+			} else {
+				// Determine the content for a setting label.
+				String name = key.substring(0, 1).toUpperCase() + key.substring(1);
+				
+				// Construct and add text representation for setting.  
+				// If a setting has no initialised value then it is not included.
+				Text settingRepresentation = setting.generateRepresentation(name, frames.getCurrentFrame().getFramesetName()).copy();
+				if (settingRepresentation.getBounds() == null) {
 					continue;
 				}
-				String name = str.substring(0, 1).toUpperCase() + str.substring(1);
-				String value = "";
-				if(s instanceof GenericSetting && ((GenericSetting<?>) s).isPrimitive()) {
-					if(((GenericSetting<?>) s).get() != null) {
-						value = ": " + ((GenericSetting<?>) s).get();
-					} else {
-						value = ": ";
-					}
-				}
-				int x = 0, y = 0;
-				Text t;
-				if(key.equals("pass")) {
-					t = frames.addText("iw: org.expeditee.items.widgets.Password", null, null, null, false);
-					Password pw = new Password(t, null);
-					pw.setPassword((String) value);
-					frames.getCurrentFrame().removeItem(t);
-					frames.getCurrentFrame().addAllItems(pw.getItems());
-					x = pw.getX() + pw.getWidth();
-					y = pw.getY();
-				} else {
-					if(s instanceof GenericSetting && ((GenericSetting<?>) s).getType().equals(Text.class)) {
-    					t = (Text) ((GenericSetting<?>)s).get();
-    					if(t == null) {
-    						System.err.println("Failed to get Text setting \"" + str + "\"");
-    						continue;
-    					}
-    					t = t.copy();
-    					t.setID(frames.getCurrentFrame().getNextItemID());
-    					t.setText(name);
-    					frames.addItem(t, false);
-    				} else {
-    					t = frames.addText(name + value, null, null, null, false);
-    				}
-					x = t.getX() + t.getBoundsWidth();
-					y = t.getY();
-				}
-				x = Math.max(250, x + 20);
-				Text tt = frames.getCurrentFrame().addText(x, y, "// " + s.getTooltip(), null);
-				// rebuild to get the correct height since setWidth() doesn't immediately rebuild
-				tt.rebuild(true);
-				if(tt.getY() + tt.getBoundsHeight() > frames.getLastY()) {
-					frames.setLastY(tt.getY() + tt.getBoundsHeight());
-				}
+				settingRepresentation.setID(frames.getCurrentFrame().getNextItemID());
+				frames.addItem(settingRepresentation, false);				
+				x = settingRepresentation.getX() + settingRepresentation.getBoundsWidth();
+				y = settingRepresentation.getY();
+			}
+			
+			x = Math.max(250, x + 20);
+			// Add tooltip for setting
+			Text tooltip = frames.getCurrentFrame().addText(x, y, "// " + setting.getTooltip(), null);
+			tooltip.rebuild(true);
+			if (tooltip.getY() + tooltip.getBoundsHeight() > frames.getLastY()) {
+				frames.setLastY(tooltip.getY() + tooltip.getBoundsHeight());
 			}
 		}
 		
 		frames.save();
-		//FrameIO.SaveFrame(frame);
 	}
 }
Index: trunk/src/org/expeditee/settings/UserSettings.java
===================================================================
--- trunk/src/org/expeditee/settings/UserSettings.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/UserSettings.java	(revision 1242)
@@ -22,6 +22,6 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.nio.file.Paths;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
@@ -34,5 +34,4 @@
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
-import org.expeditee.items.Item;
 import org.expeditee.items.Text;
 import org.expeditee.setting.BooleanSetting;
@@ -53,6 +52,8 @@
 	
 	public static String DEFAULT_PROFILE_NAME = "default";
-	
-	public static final IntegerSetting Gravity = new IntegerSetting("Distance the cursor has to be from a text item to select the text item", 3);
+	 
+	public static Boolean multiUserMode;
+	
+	public static final IntegerSetting Gravity = new IntegerSetting("Distance the cursor has to be from a text item to select the text item", "Gravity", 3);
 	
 	public static final StringSetting StartFrame = new StringSetting("The frame to go to when Expeditee is started (defaults to the profile frame)", null);
@@ -82,7 +83,7 @@
 		}
 	};
-	public static final IntegerSetting InitialWidth = new IntegerSetting("Initial width of Expeditee window", 1024);
-	
-	public static final IntegerSetting InitialHeight = new IntegerSetting("Initial height of Expeditee window", 768);
+	public static final IntegerSetting InitialWidth = new IntegerSetting("Initial width of Expeditee window", "InitialWidth", 1024);
+	
+	public static final IntegerSetting InitialHeight = new IntegerSetting("Initial height of Expeditee window", "InitialHeight", 768);
 	
 	/*
@@ -90,71 +91,30 @@
 	 */
 	
-	public static final FloatSetting ScaleFactor = new FloatSetting("Scale Factor for drawing (TODO: does this even do anything?)", 1F);
-	
-	public static final FloatSetting FormatSpacingMin = new FloatSetting("Minimum spacing ratio", null);
-	
-	public static final FloatSetting FormatSpacingMax = new FloatSetting("Maximum spacing ratio", null);
-
-	public static final IntegerSetting LineStraightenThreshold = new IntegerSetting("Threshold for straightening a line (TODO: does this even do anything?)", 15);
-
-	public static final IntegerSetting NoOpThreshold = new IntegerSetting("Distance the cursor may be dragged before Gestures must be reinterpreted.  E.g. Copy becomes range.", 10);
-	
-	public static final IntegerSetting TitlePosition = new IntegerSetting("Position of title item in frame (TODO: find whether this is x-offset or y-offset)", 150);
-	
-	public static final StringSetting ProfileName = new StringSetting("Profile name", FrameIO.ConvertToValidFramesetName(System.getProperty("user.name"))) {
+	public static final FloatSetting ScaleFactor = new FloatSetting("Scale Factor for drawing (TODO: does this even do anything?)", "ScaleFactor", 1F);
+	
+	public static final FloatSetting FormatSpacingMin = new FloatSetting("Minimum spacing ratio", "FormatSpacingMin", null);
+	
+	public static final FloatSetting FormatSpacingMax = new FloatSetting("Maximum spacing ratio", "FormatSpacingMax", null);
+
+	public static final IntegerSetting LineStraightenThreshold = new IntegerSetting("Threshold for straightening a line (TODO: does this even do anything?)", "LineStraightenThreshold", 15);
+
+	public static final IntegerSetting NoOpThreshold = new IntegerSetting("Distance the cursor may be dragged before Gestures must be reinterpreted.  E.g. Copy becomes range.", "NoOpThreshold", 10);
+	
+	public static final IntegerSetting TitlePosition = new IntegerSetting("Position of title item in frame (TODO: find whether this is x-offset or y-offset)", "TitlePosition", 150);
+	
+	public static final StringSetting ProfileName = new StringSetting("Profile name", FrameIO.ConvertToValidFramesetName(System.getProperty("user.name")));
+	
+	public static final StringSetting UserName = new StringSetting("User name", ProfileName.get());
 		
-		/** Commit the change to the appropriate frame */
-		public void set(String value) {	
-			super.set(value);
-			commitToSettingsFrameItem(value, "ProfileName:");
-		};
-		
-		/** If authenticated, then resetting ProfileName should not do anything. */
-		public void reset() {
-			if (!Authenticated.get()) {
-				super.reset();
-			}
-		};
-	};
-	
-	public static final StringSetting UserName = new StringSetting("User name", ProfileName.get()) { 
-		/** Commit the change to the appropriate frame */
-		public void set(String value) {	
-			super.set(value);
-			commitToSettingsFrameItem(value, "UserName:");
-		};
-		
-		/** If authenticated, then resetting UserName should not do anything. */
-		public void reset() {
-			if (!Authenticated.get()) {
-				super.reset();
-			}
-		};
-	};
-		
-	public static final BooleanSetting AntiAlias = new BooleanSetting("Whether anti-aliasing should be enabled", false);
-
-	public static final BooleanSetting LineHighlight = new BooleanSetting("Whether lines should be highlighted", false);
-
-	public static final BooleanSetting Logging = new BooleanSetting("Whether logging should be enabled", false);
-
-	public static final BooleanSetting LogStats = new BooleanSetting("Whether stats should be logged", true);
-
-	public static final BooleanSetting Threading = new BooleanSetting("Whether threading should be enabled", true);
-
-	public static final BooleanSetting Authenticated = new BooleanSetting("Whether the current user is authenticated", false) {
-		public void set(Boolean value) {
-			super.set(value);
-			commitToSettingsFrameItem(value, "Authenticated:");
-		}
-		
-		// Authenticated must be maintained rather than rely on default value.
-		public void reset() {};
-		
-		public boolean setSetting(Text text) { 
-			return super.setSetting(text);
-		};
-	};
-	
+	public static final BooleanSetting AntiAlias = new BooleanSetting("Whether anti-aliasing should be enabled", "AntiAlias", false);
+
+	public static final BooleanSetting LineHighlight = new BooleanSetting("Whether lines should be highlighted", "LineHighlight", false);
+
+	public static final BooleanSetting Logging = new BooleanSetting("Whether logging should be enabled", "Logging", false);
+
+	public static final BooleanSetting LogStats = new BooleanSetting("Whether stats should be logged", "LogStats", true);
+
+	public static final BooleanSetting Threading = new BooleanSetting("Whether threading should be enabled", "Threading", true);
+
 	/*
 	 * Frames
@@ -167,5 +127,5 @@
 	 * Other
 	 */
-	public static final ListSetting<Text> Style = new ListSetting<Text>("Set the style (TODO: what does this do?)") {		
+	public static final ListSetting<Text> Style = new ListSetting<Text>("Set the style (TODO: what does this do?)", "Style") {		
 		@Override
 		public boolean setSetting(Text text) {
@@ -196,5 +156,5 @@
 	};
 	
-	public static final FunctionSetting SpellChecker = new FunctionSetting("Enables the dictionary with the default dictionary") {
+	public static final FunctionSetting SpellChecker = new FunctionSetting("Enables the dictionary with the default dictionary", "SpellChecker") {
 		@Override
 		public void run() {
@@ -208,5 +168,5 @@
 		}
 	};
-	public static final FrameSetting Spelling = new FrameSetting("Enables the dictionary and adds the items in the child frame to the dictionary") {
+	public static final FrameSetting Spelling = new FrameSetting("Enables the dictionary and adds the items in the child frame to the dictionary", "Spelling") {
 		@Override
 		public void run(Frame frame) {
@@ -219,5 +179,5 @@
 	};
 	
-	public static final FrameSetting GreenstoneSettings = new FrameSetting("Greenstone settings (TODO: What are these for?)") {
+	public static final FrameSetting GreenstoneSettings = new FrameSetting("Greenstone settings (TODO: What are these for?)", "GreenstoneSettings") {
 		@Override
 		public void run(Frame frame) {
@@ -226,5 +186,5 @@
 	};
 	
-	public static final FrameSetting Reminders = new FrameSetting("Reminders (TODO: What are these for?)") {
+	public static final FrameSetting Reminders = new FrameSetting("Reminders (TODO: What are these for?)", "Reminders") {
 		@Override
 		public void run(Frame frame) {
@@ -233,5 +193,5 @@
 	};
 	
-	public static final FrameSetting MailSettings = new FrameSetting("Mail Settings (TODO: How does this work?)") {
+	public static final FrameSetting MailSettings = new FrameSetting("Mail Settings (TODO: How does this work?)", "MailSettings") {
 		@Override
 		public void run(Frame frame) {
@@ -242,14 +202,23 @@
 	// add default values
 	static {
+		// Are we in the new regime or the old regime? 
+		File resFile = Paths.get(getDesiredExpediteeHome()).resolve(".res").toFile();
+		File resourcesPrivateFile = Paths.get(getDesiredExpediteeHome() + "resources-private" + File.separator).toFile();
+		if (resourcesPrivateFile.exists()) {
+			// If resources-private exists than this is a good sign we have new regime available.
+			multiUserMode = Boolean.TRUE;
+		} else if (resFile.exists()) {
+			// If we do not, but do have the .res file then this is a good sign we are in old regime.
+			multiUserMode = Boolean.FALSE;
+		} else {
+			// If we have neither then we are unpacking and therefore will have new regime available once unpacked.
+			multiUserMode = Boolean.TRUE;
+		}
+		
 		setupDefaultFolders();
 	}
-
-	public static void setupDefaultFolders() {
-		String expeditee_home = System.getProperty("expeditee.home");
-		if (expeditee_home != null) {
-		    FrameIO.changeParentFolder(expeditee_home + File.separator);
-		} else {
-		    FrameIO.changeParentFolder(getSaveLocation());
-		}
+		
+	public static void setupDefaultFolders() {		
+		FrameIO.changeParentFolder(getDesiredExpediteeHome());
 	  
 		FolderSettings.FrameDirs.get().clear();
@@ -258,15 +227,46 @@
 	}
 
+	private static String getDesiredExpediteeHome() {
+		String homeProperty = System.getProperty("expeditee.home");
+		String expeditee_home = homeProperty == null ? getSaveLocation() : homeProperty + File.separator;
+		return expeditee_home;
+	}
+
 	public static void appendDefaultFolders() {
-		FolderSettings.FrameDirs.get().add(FrameIO.FRAME_PATH);
-		FolderSettings.FrameDirs.get().add(FrameIO.PUBLIC_PATH);
-		FolderSettings.FrameDirs.get().add(FrameIO.PROFILE_PATH);
-		FolderSettings.FrameDirs.get().add(FrameIO.HELP_PATH);
-		FolderSettings.FrameDirs.get().add(FrameIO.MESSAGES_PATH);
-		FolderSettings.FrameDirs.get().add(FrameIO.SHARED_BY_ME_FRAMESETS);
-		FolderSettings.FrameDirs.get().add(FrameIO.SHARED_WITH_ME_FRAMESETS);
-		FolderSettings.FrameDirs.setDefault(FolderSettings.FrameDirs.get());
-		FolderSettings.ImageDirs.get().add(FrameIO.IMAGES_PATH);
-		FolderSettings.ImageDirs.setDefault(FolderSettings.ImageDirs.get());
+		if (multiUserMode) {
+			// The comments here explain how things have changed with the new regime.
+			// FrameDirs
+			// 1. PROFILE_PATH					Still points to same place.
+			// 2. SHARED_FRAMESETS_PATH			Still points to same place. (encryption stops just anyone reading it)
+			// 3. framesets-<username>			Generated on user account creation and must be refreshed on user switching.  Also gives access to tutorial stuffs.
+			// 4. FRAME_PATH					<expeditee-home>\resources-public\framesets.
+			// 5. HELP_PUBLIC_PATH				<expeditee-home>\resources-public\documentation.
+			// 6. MESSAGES_PATH					Still points to same place.  Should these be per user and encrypted?
+			// 7. PUBLIC_PATH					Still points to same place.  Kept for compatibility.
+			FolderSettings.FrameDirs.get().add(FrameIO.PROFILE_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.FRAME_PRIVATE_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.SHARED_FRAMESETS_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.FRAME_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.RESOURCES_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.MESSAGES_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.PUBLIC_PATH);
+			FolderSettings.FrameDirs.setDefault(FolderSettings.FrameDirs.get());
+						
+			// ImageDirs
+			// 1. resources-<username>\images	Generated on user account creation and must be refreshed on user switching.
+			// 2. IMAGES_PATH					<expeditee-home>\resources-public\images
+			FolderSettings.ImageDirs.get().add(FrameIO.IMAGES_PRIVATE_PATH);
+			FolderSettings.ImageDirs.get().add(FrameIO.IMAGES_PATH);
+			FolderSettings.ImageDirs.setDefault(FolderSettings.ImageDirs.get());
+		} else {
+			FolderSettings.FrameDirs.get().add(FrameIO.FRAME_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.PUBLIC_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.PROFILE_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.HELP_PATH);
+			FolderSettings.FrameDirs.get().add(FrameIO.MESSAGES_PATH);
+			FolderSettings.FrameDirs.setDefault(FolderSettings.FrameDirs.get());
+			FolderSettings.ImageDirs.get().add(FrameIO.IMAGES_PATH);
+			FolderSettings.ImageDirs.setDefault(FolderSettings.ImageDirs.get());
+		}
 	}
 
@@ -291,21 +291,3 @@
 		}
 	}
-	
-	private static void commitToSettingsFrameItem(Object value, String contentMatch) {
-		String profileName = UserSettings.UserName.get();
-		int lastNumber = FrameIO.getLastNumber(profileName);
-		for (int i = 1; i <= lastNumber; i++) {
-			Frame frame = FrameIO.LoadFrame(profileName + i);
-			if (frame != null) {
-	 			Collection<Item> items = frame.getAllItems();
-				boolean found = false;
-				for (Item item: items) {
-					if (item.getText().startsWith(contentMatch)) {
-						item.setText(contentMatch + " " + value);
-					}
-				}
-				if (found) { break; }
-			}
-		}
-	}
 }
Index: trunk/src/org/expeditee/settings/audio/AudioSettings.java
===================================================================
--- trunk/src/org/expeditee/settings/audio/AudioSettings.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/audio/AudioSettings.java	(revision 1242)
@@ -19,8 +19,5 @@
 package org.expeditee.settings.audio;
 
-import org.expeditee.items.Text;
-import org.expeditee.setting.BooleanSetting;
 import org.expeditee.setting.IntegerSetting;
-import org.expeditee.setting.StringSetting;
 
 /**
@@ -32,5 +29,5 @@
 	public static final int PLAYBACK_CLOCK_RESOLUTION = 50;
 		
-	public static final IntegerSetting PlaybackClockResolution = new IntegerSetting("Clock resolution (in milliseconds) for graphical updates when playing audio", 50);
+	public static final IntegerSetting PlaybackClockResolution = new IntegerSetting("Clock resolution (in milliseconds) for graphical updates when playing audio", "PlaybackClockResolution", 50);
 
 }
Index: trunk/src/org/expeditee/settings/experimental/ExperimentalFeatures.java
===================================================================
--- trunk/src/org/expeditee/settings/experimental/ExperimentalFeatures.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/experimental/ExperimentalFeatures.java	(revision 1242)
@@ -23,11 +23,11 @@
 public class ExperimentalFeatures {
 
-	public static final BooleanSetting AutoWrap = new BooleanSetting("Enable auto wrapping of text", false);
+	public static final BooleanSetting AutoWrap = new BooleanSetting("Enable auto wrapping of text", "AutoWrap", false);
 	
-	public static final BooleanSetting FrameZoom = new BooleanSetting("Enable zooming in and out of frame using F1/F2 or else shift with click-wheel", false);
+	public static final BooleanSetting FrameZoom = new BooleanSetting("Enable zooming in and out of frame using F1/F2 or else shift with click-wheel", "FrameZoom", false);
 	
-	public static final BooleanSetting FrameZoomAroundCursor = new BooleanSetting("If true, Frame Zooming uses the location of the mouse cursor as the central point to zoom in/out.", false);
+	public static final BooleanSetting FrameZoomAroundCursor = new BooleanSetting("If true, Frame Zooming uses the location of the mouse cursor as the central point to zoom in/out.", "FrameZoomAroundCursor", false);
 	
-	public static final BooleanSetting MousePan = new BooleanSetting("Enable panning of the frame by shift-click and dragging the mouse", false);
+	public static final BooleanSetting MousePan = new BooleanSetting("Enable panning of the frame by shift-click and dragging the mouse", "MousePan", false);
 	
 }
Index: trunk/src/org/expeditee/settings/exploratorysearch/ExploratorySearchSettings.java
===================================================================
--- trunk/src/org/expeditee/settings/exploratorysearch/ExploratorySearchSettings.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/exploratorysearch/ExploratorySearchSettings.java	(revision 1242)
@@ -19,8 +19,6 @@
 package org.expeditee.settings.exploratorysearch;
 
-import org.expeditee.items.Text;
 import org.expeditee.setting.BooleanSetting;
 import org.expeditee.setting.IntegerSetting;
-import org.expeditee.setting.StringSetting;
 
 /**
@@ -34,16 +32,16 @@
 	public static final int BROWSER_VERT_OFFSET = 50;
 	
-	public static final BooleanSetting BrowserFullScreen = new BooleanSetting("Start Exploratory Search browser in fullscreen", true);
+	public static final BooleanSetting BrowserFullScreen = new BooleanSetting("Start Exploratory Search browser in fullscreen", "BrowserFullScreen", true);
 	
-	public static final IntegerSetting BrowserDefaultWidth = new IntegerSetting("Default Browser width", 800);
+	public static final IntegerSetting BrowserDefaultWidth = new IntegerSetting("Default Browser width", "BrowserDefaultWidth", 800);
 	
-	public static final IntegerSetting BrowserDefaultHeight = new IntegerSetting("Default Browser height", 600);
+	public static final IntegerSetting BrowserDefaultHeight = new IntegerSetting("Default Browser height"," BrowserDefaultHeight",600);
 	
-	public static final IntegerSetting BrowserLeftMargin = new IntegerSetting("Size of left hand margin for Browser", 0);
+	public static final IntegerSetting BrowserLeftMargin = new IntegerSetting("Size of left hand margin for Browser","BrowserLeftMargin", 0);
 	
-	public static final IntegerSetting BrowserRightMargin = new IntegerSetting("Size of right hand margin for Browser", 0);
+	public static final IntegerSetting BrowserRightMargin = new IntegerSetting("Size of right hand margin for Browser", "BrowserRightMargin", 0);
 	
-	public static final IntegerSetting BrowserTopMargin = new IntegerSetting("Size of Top margin for Browser", 0);
+	public static final IntegerSetting BrowserTopMargin = new IntegerSetting("Size of Top margin for Browser", "BrowserTopMargin", 0);
 	
-	public static final IntegerSetting BrowserBottomMargin = new IntegerSetting("Size of bottom margin for Browser", 0);
+	public static final IntegerSetting BrowserBottomMargin = new IntegerSetting("Size of bottom margin for Browser", "BrowserBottomMargin", 0);
 }
Index: trunk/src/org/expeditee/settings/folders/FolderSettings.java
===================================================================
--- trunk/src/org/expeditee/settings/folders/FolderSettings.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/folders/FolderSettings.java	(revision 1242)
@@ -25,9 +25,8 @@
 import org.expeditee.setting.ListSetting;
 import org.expeditee.setting.Setting;
-import org.expeditee.settings.UserSettings;
 
 public class FolderSettings {
 
-	public static final ListSetting<String> FrameDirs = new ListSetting<String>("Directories to look in for frames") {
+	public static final ListSetting<String> FrameDirs = new ListSetting<String>("Directories to look in for frames", "FrameDirs") {
 		@Override
 		public boolean setSetting(Text text) {
@@ -36,5 +35,5 @@
 		}
 	};
-	public static final Setting FramesetDir = new Setting("Adds a directory to look in for frames") {
+	public static final Setting FramesetDir = new Setting("Adds a directory to look in for frames", "FramesetDir") {
 		@Override
 		public boolean setSetting(Text text) {
@@ -52,7 +51,13 @@
     		return false;
 		}
+		
+		@Override
+		public Text generateRepresentation(String label, String frameset) {
+			Text t = new Text(label);
+			return t;
+		}
 	};
 
-	public static ListSetting<String> ImageDirs = new ListSetting<String>("Directories to look in for images") {
+	public static ListSetting<String> ImageDirs = new ListSetting<String>("Directories to look in for images", "ImageDirs") {
 		@Override
 		public boolean setSetting(Text text) {
@@ -61,5 +66,5 @@
 		}
 	};
-	public static final Setting ImageDir = new Setting("Adds a directory to look in for images") {
+	public static final Setting ImageDir = new Setting("Adds a directory to look in for images", "ImageDir") {
 		@Override
 		public boolean setSetting(Text text) {
@@ -77,7 +82,13 @@
     		return false;
 		}
+		
+		@Override
+		public Text generateRepresentation(String label, String frameset) {
+			Text t = new Text(label);
+			return t;
+		}
 	};
 	
-	public static final Setting LogDir = new Setting("Set the directory to save logs") {
+	public static final Setting LogDir = new Setting("Set the directory to save logs", "LogDir") {
 		@Override
 		public boolean setSetting(Text text) {
@@ -91,4 +102,10 @@
     		return true;
 		}
+		
+		@Override
+		public Text generateRepresentation(String label, String frameset) {
+			Text t = new Text(label);
+			return t;
+		}
 	};
 }
Index: trunk/src/org/expeditee/settings/legacy/LegacyFeatures.java
===================================================================
--- trunk/src/org/expeditee/settings/legacy/LegacyFeatures.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/legacy/LegacyFeatures.java	(revision 1242)
@@ -4,4 +4,5 @@
 
 public class LegacyFeatures {
-	public static final BooleanSetting UseLegacyActionArgumentMapping = new BooleanSetting("Legacy action argument mapping does not allow for the possibility of actions being passed both floating content and the action item.", false);
+	public static final BooleanSetting UseLegacyActionArgumentMapping = 
+			new BooleanSetting("Legacy action argument mapping does not allow for the possibility of actions being passed both floating content and the action item.", "UseLegacyActionArgumentMapping", false);
 }
Index: trunk/src/org/expeditee/settings/network/NetworkSettings.java
===================================================================
--- trunk/src/org/expeditee/settings/network/NetworkSettings.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/network/NetworkSettings.java	(revision 1242)
@@ -33,7 +33,7 @@
 	public static final StringSetting HomePage = new StringSetting("The home page for the JfxBrowser", "https://duckduckgo.com");
 	
-	public static final IntegerSetting FrameShareTimeout = new IntegerSetting("Timeout for FrameShare socket, in milliseconds", 1000);
+	public static final IntegerSetting FrameShareTimeout = new IntegerSetting("Timeout for FrameShare socket, in milliseconds", "FrameShareTimeout", 1000);
 	
-	public static final FrameSetting FrameShare = new FrameSetting("Enable accessing remote frames") {
+	public static final FrameSetting FrameShare = new FrameSetting("Enable accessing remote frames", "FrameShare") {
 		@Override
 		public void run(Frame frame) {
Index: trunk/src/org/expeditee/settings/templates/TemplateSettings.java
===================================================================
--- trunk/src/org/expeditee/settings/templates/TemplateSettings.java	(revision 1241)
+++ trunk/src/org/expeditee/settings/templates/TemplateSettings.java	(revision 1242)
@@ -42,5 +42,5 @@
 	};
 	
-	public static final FrameSetting CursorFrame = new FrameSetting("Items on this frame will be used as the cursor (clearing the frame or removing the link will default back to a normal cursor)") {
+	public static final FrameSetting CursorFrame = new FrameSetting("Items on this frame will be used as the cursor (clearing the frame or removing the link will default back to a normal cursor)", "CursorFrame") {
 		@Override
 		public void run(Frame frame) {
@@ -55,5 +55,5 @@
 	
 	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 }) {
+			"ColorWheel", new Colour[] { Colour.BLACK, Colour.RED, Colour.BLUE, Item.GREEN, Colour.MAGENTA, Colour.YELLOW.darker(), Colour.WHITE }) {
 		@Override
 		public boolean setSetting(Text text) {
@@ -68,5 +68,5 @@
 	
 	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),
+			"FillColorWheel", 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
@@ -82,4 +82,5 @@
 	
 	public static final ArraySetting<Colour> BackgroundColorWheel = new ArraySetting<Colour>("The colours of items in the child frame are used to populate the colour wheel",
+			"BackgroundColorWheel",
 			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),
@@ -96,5 +97,5 @@
 	};
 	
-	public static final TextSetting ItemTemplate = new TextSetting("Template for normal text items") {
+	public static final TextSetting ItemTemplate = new TextSetting("Template for normal text items", "ItemTemplate") {
 		@Override
 		public Text generateText() {
@@ -102,5 +103,5 @@
 		}
 	};
-	public static final TextSetting AnnotationTemplate = new TextSetting("Template for annotation text items") {
+	public static final TextSetting AnnotationTemplate = new TextSetting("Template for annotation text items", "AnnotationTemplate") {
 		@Override
 		public Text generateText() {
@@ -111,5 +112,5 @@
 	};
 
-	public static final TextSetting CommentTemplate = new TextSetting("Template for code comment text items") {
+	public static final TextSetting CommentTemplate = new TextSetting("Template for code comment text items", "CommentTemplate") {
 		@Override
 		public Text generateText() {
@@ -120,5 +121,5 @@
 	};
 
-	public static final TextSetting StatTemplate = new TextSetting("Template for statistics (e.g. extracted attributes) text items") {
+	public static final TextSetting StatTemplate = new TextSetting("Template for statistics (e.g. extracted attributes) text items", "StatTemplate") {
 		@Override
 		public Text generateText() {
@@ -132,5 +133,5 @@
 	};
 	
-	public static final TextSetting TitleTemplate = new TextSetting("Template for Title text item") {
+	public static final TextSetting TitleTemplate = new TextSetting("Template for Title text item", "TitleTemplate") {
 		@Override
 		public Text generateText() {
@@ -145,5 +146,5 @@
 	};
 	
-	public static final TextSetting DotTemplate = new TextSetting("Template for dot items") {
+	public static final TextSetting DotTemplate = new TextSetting("Template for dot items", "DotTemplate") {
 		@Override
 		public Text generateText() {
@@ -152,5 +153,5 @@
 	};
 	
-	public static final TextSetting TooltipTemplate = new TextSetting("Template for tooltips") {
+	public static final TextSetting TooltipTemplate = new TextSetting("Template for tooltips", "TooltipTemplate") {
 		@Override
 		public Text generateText() {
