Index: /trunk/src/org/apollo/agents/MelodySearch.java
===================================================================
--- /trunk/src/org/apollo/agents/MelodySearch.java	(revision 1433)
+++ /trunk/src/org/apollo/agents/MelodySearch.java	(revision 1434)
@@ -11,5 +11,4 @@
 
 import org.apollo.ApolloSystem;
-import org.apollo.io.AudioPathManager;
 import org.apollo.meldex.DynamicProgrammingAlgorithm;
 import org.apollo.meldex.McNabMongeauSankoffAlgorithm;
@@ -28,5 +27,5 @@
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
-import org.expeditee.settings.folders.FolderSettings;
+import org.expeditee.gui.management.ResourceManager;
 import org.expeditee.items.Item;
 import org.expeditee.items.ItemUtils;
@@ -34,4 +33,5 @@
 import org.expeditee.items.widgets.WidgetCorner;
 import org.expeditee.items.widgets.WidgetEdge;
+import org.expeditee.settings.folders.FolderSettings;
 
 /**
@@ -278,11 +278,9 @@
 						
 						// Get cached melody from file if it is up to date
-						String metaFilePath = 
-							AudioPathManager.AUDIO_HOME_DIRECTORY 
-							+ MELODY_METAFILE_PREFIX
-							+ localFilename
-							+ MELODY_METAFILE_SUFFIX;
-						
-						File localFile = new File(AudioPathManager.AUDIO_HOME_DIRECTORY + localFilename);
+						String metaFileRelativePath = MELODY_METAFILE_PREFIX + localFilename + MELODY_METAFILE_SUFFIX;
+						String metaFilePath = ResourceManager.getAudioResource(metaFileRelativePath, DisplayController.getCurrentFrame()).getAbsolutePath();
+						
+						//File localFile = new File(AudioPathManager.AUDIO_HOME_DIRECTORY + localFilename);
+						File localFile = ResourceManager.getAudioResource(localFilename, DisplayController.getCurrentFrame());
 						if (!localFile.exists()) continue;
 						
Index: /trunk/src/org/apollo/audio/structure/AudioStructureModel.java
===================================================================
--- /trunk/src/org/apollo/audio/structure/AudioStructureModel.java	(revision 1433)
+++ /trunk/src/org/apollo/audio/structure/AudioStructureModel.java	(revision 1434)
@@ -16,5 +16,4 @@
 import org.apollo.audio.ApolloSubjectChangedEvent;
 import org.apollo.io.AudioIO;
-import org.apollo.io.AudioPathManager;
 import org.apollo.mvc.AbstractSubject;
 import org.apollo.mvc.SubjectChangedEvent;
@@ -30,4 +29,5 @@
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
+import org.expeditee.gui.management.ResourceManager;
 import org.expeditee.io.Conversion;
 import org.expeditee.items.ItemUtils;
@@ -433,5 +433,6 @@
 				try {
 					
-					tmodel.runningTimeMS = AudioIO.getRunningTime(AudioPathManager.AUDIO_HOME_DIRECTORY + localFilename);
+					String localFilePath = ResourceManager.getAudioResource(localFilename, DisplayController.getCurrentFrame()).getAbsolutePath();
+					tmodel.runningTimeMS = AudioIO.getRunningTime(localFilePath);
 				
 				} catch (IOException e) {
Index: /trunk/src/org/apollo/audio/util/MultiTrackPlaybackController.java
===================================================================
--- /trunk/src/org/apollo/audio/util/MultiTrackPlaybackController.java	(revision 1433)
+++ /trunk/src/org/apollo/audio/util/MultiTrackPlaybackController.java	(revision 1434)
@@ -20,5 +20,4 @@
 import org.apollo.audio.structure.TrackGraphLoopException;
 import org.apollo.audio.structure.TrackGraphNode;
-import org.apollo.io.AudioPathManager;
 import org.apollo.io.AudioIO.AudioFileLoader;
 import org.apollo.mvc.AbstractSubject;
@@ -34,4 +33,5 @@
 import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.DisplayObserver;
+import org.expeditee.gui.management.ResourceManager;
 
 public class MultiTrackPlaybackController 
@@ -1004,6 +1004,7 @@
 						
 						try {
+							String filepath = ResourceManager.getAudioResource(absNode.getTrackNode().getLocalFilename(), DisplayController.getCurrentFrame()).getAbsolutePath();
 							stm = TrackModelLoadManager.getInstance().load(
-									AudioPathManager.AUDIO_HOME_DIRECTORY + absNode.getTrackNode().getLocalFilename(), 
+									filepath, 
 									absNode.getTrackNode().getLocalFilename(), 
 									new Observer() { // opps, my confusing design pattern gone wrong!
Index: /trunk/src/org/apollo/audio/util/SoundDesk.java
===================================================================
--- /trunk/src/org/apollo/audio/util/SoundDesk.java	(revision 1433)
+++ /trunk/src/org/apollo/audio/util/SoundDesk.java	(revision 1434)
@@ -71,7 +71,7 @@
 	
 	/** Where the mixes are saved to. */
-	private static final String MIX_BANKS_FILEPATH = AudioPathManager.AUDIO_HOME_DIRECTORY + ".banks";
-	
-	private static final String MASTER_MIX_FILEPATH = AudioPathManager.AUDIO_HOME_DIRECTORY + ".mastermix";
+	private static final String MIX_BANKS_FILEPATH = AudioPathManager.AUDIO_USERNAME_HOME_DIRECTORY + ".banks";
+	
+	private static final String MASTER_MIX_FILEPATH = AudioPathManager.AUDIO_USERNAME_HOME_DIRECTORY + ".mastermix";
 	
 	private static final String NO_SOLO_PREFIX = "~#SOLOOFF#~";
Index: /trunk/src/org/apollo/gui/FrameLayoutDaemon.java
===================================================================
--- /trunk/src/org/apollo/gui/FrameLayoutDaemon.java	(revision 1433)
+++ /trunk/src/org/apollo/gui/FrameLayoutDaemon.java	(revision 1434)
@@ -15,5 +15,4 @@
 import org.apollo.audio.util.Timeline;
 import org.apollo.io.AudioIO;
-import org.apollo.io.AudioPathManager;
 import org.apollo.mvc.AbstractSubject;
 import org.apollo.mvc.Observer;
@@ -32,4 +31,5 @@
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FreeItems;
+import org.expeditee.gui.management.ResourceManager;
 import org.expeditee.items.Item;
 import org.expeditee.items.ItemUtils;
@@ -766,6 +766,7 @@
 				// so cann afford to hang the thread a little for checking the actual time...
 				if (runningTime <= 0) {
-					File f = new File(AudioPathManager.AUDIO_HOME_DIRECTORY +
-							sampledTrackWidget.getLocalFileName());
+					//File f = new File(AudioPathManager.AUDIO_HOME_DIRECTORY +
+					//		sampledTrackWidget.getLocalFileName());
+					File f = ResourceManager.getAudioResource(sampledTrackWidget.getLocalFileName(), DisplayController.getCurrentFrame());
 					if (f.exists()) {
 						try {
Index: /trunk/src/org/apollo/io/AudioPathManager.java
===================================================================
--- /trunk/src/org/apollo/io/AudioPathManager.java	(revision 1433)
+++ /trunk/src/org/apollo/io/AudioPathManager.java	(revision 1434)
@@ -7,11 +7,15 @@
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Random;
+import java.util.function.Predicate;
 
 import org.apollo.audio.structure.AudioStructureModel;
 import org.apollo.util.ApolloSystemLog;
 import org.apollo.util.RegExpFileFilter;
-import org.expeditee.auth.AuthenticatorBrowser;
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameIO;
+import org.expeditee.gui.management.ResourceManager;
 import org.expeditee.settings.UserSettings;
 
@@ -29,5 +33,5 @@
 
 	/** Suffixed with the native file separator */
-	public static String AUDIO_HOME_DIRECTORY = null;
+	public static String AUDIO_USERNAME_HOME_DIRECTORY = null;
 	
 	/** Stores all virtual names created by this repository. */
@@ -39,97 +43,46 @@
 
 	private static Random rand = new Random(System.currentTimeMillis());
-
-	// **** DB
-	// Some work to be done here => remove dependency in code on 'AUDIO_HOME_DIRECTORY'
-	// and change it to use audio dir list from UserSettings
-	public static void changeParentAndSubFolders(String newFolder) {
-		
-		if (AuthenticatorBrowser.isAuthenticationRequired() && System.getProperty("user.name").equals(AuthenticatorBrowser.USER_NOBODY)) {
-			System.err.println("**** AudioPathManager::changeParentAndSubFolder(): Nothing to do for user '" + AuthenticatorBrowser.USER_NOBODY + "'");
-			return;
-		}
-		
-		if (UserSettings.PublicAndPrivateResources) {
-			//String resourcesPublicPath = FrameIO.PARENT_FOLDER + "resources-public" + File.separator;
-			String userName = UserSettings.UserName.get();
-			//String resourcesPrivateIndividualPath = FrameIO.PARENT_FOLDER + "resources-" + userName + File.separator;
-			if (AuthenticatorBrowser.isAuthenticationRequired()) {
-				System.err.println("**** AudioPathManager::changeParentAndSubFolder(): Setting 'audio' folder to resources-" + userName);
-			}
-			//AUDIO_HOME_DIRECTORY = resourcesPrivateIndividualPath + "audio" + File.separatorChar;
-			AUDIO_HOME_DIRECTORY = FrameIO.AUDIO_PRIVATE_PATH;
-		}
-		else {
-			AUDIO_HOME_DIRECTORY = FrameIO.PARENT_FOLDER + "audio" + File.separatorChar;;
-		}
-	}
-	
-	public static void activateAndScanAudioDir()
-	{
-		changeParentAndSubFolders(FrameIO.PARENT_FOLDER);
-		
-		// Ensure audio directory exists
-		File dir = new File(AUDIO_HOME_DIRECTORY);
-		if (!dir.exists()) {
-			if (!dir.mkdir()) {
-				ApolloSystemLog.println("Unable to create missing audio home directory");
-			}
-		}
-
+	
+	// TODO: this function called during startup?  In browser construction?  When FrameIO.changeParentAndSubFolders() is called?  Separation of apollo from expeditee core?
+	public static void activateAndScanAudioDirs() {
+		// If we are in old regime then there is no AUDIO_USERNAME_PRIVATE_PATH.
+		AUDIO_USERNAME_HOME_DIRECTORY = FrameIO.AUDIO_USERNAME_PRIVATE_PATH == null ? FrameIO.AUDIO_PATH : FrameIO.AUDIO_USERNAME_PRIVATE_PATH;
+		
 		// Load counter
-		loadCounter(AUDIO_HOME_DIRECTORY);
-	}
-	
+		loadCounter();
+	}
 	
 	/**
 	 * Loads the counter
-	 * @param dir The dir where the audio files live.
-	 */
-	private static void loadCounter(String audio_dir_str) {
-		File audio_dir = new File(audio_dir_str);
-		
-		String[] files = getAudioFileNames(audio_dir);
-		if (files == null) { // Due to IO exception
-			ApolloSystemLog.printError("Failed to read audio directory");
-			return;
-		}
+	 */
+	private static void loadCounter() {
+		List<String> audioFileNames = getAudioFileNames();
+		
 		long count = 0;
-		if (files != null) {
-			for (String f : files) {
-	
-				int start = -1, end = -1;
-				for (int i = 0; i < f.length(); i++) {
-					if (Character.isDigit(f.charAt(i)) && start == -1) {
-						start = i;
-					} else if (!Character.isDigit(f.charAt(i)) && start != -1) {
-						end = i;
-						break;
-					}
-				}
-				
-				if (start >= 0 && end == -1) {
-					end = f.length();
-				}
-	
-				if (start > 0 && end >= start) { // not start >= 0 since missing preable
-	
-					String tmp = f.substring(start, end);
-					long l = Long.parseLong(tmp);
-					if (l >= count)
-						count = l + 1;
-				}
-			}
-		}
-
+		for (String f : audioFileNames) {
+			
+			int start = -1, end = -1;
+			for (int i = 0; i < f.length(); i++) {
+				if (Character.isDigit(f.charAt(i)) && start == -1) {
+					start = i;
+				} else if (!Character.isDigit(f.charAt(i)) && start != -1) {
+					end = i;
+					break;
+				}
+			}
+			
+			if (start >= 0 && end == -1) {
+				end = f.length();
+			}
+
+			if (start > 0 && end >= start) { // not start >= 0 since missing preable
+
+				String tmp = f.substring(start, end);
+				long l = Long.parseLong(tmp);
+				if (l >= count)
+					count = l + 1;
+			}
+		}
 		counter = count;
-	}
-	
-	/**
-	 * @param dir
-	 * @return
-	 * 		Null if an IO exception occurs
-	 */
-	private static String[] getAudioFileNames(File dir) {
-		return dir.list(new RegExpFileFilter("^[A-Z]+\\d+.*$"));
 	}
 	
@@ -140,8 +93,26 @@
 	 * 		read list of files.
 	 */
-	public static String[] getAudioFileNames() {
-		File audioDir = new File(AUDIO_HOME_DIRECTORY);
-		if (!audioDir.exists() || !audioDir.isDirectory()) return null;
-		return getAudioFileNames(audioDir);
+	public static List<String> getAudioFileNames() {
+		Predicate<File> isFile = file -> {
+			File dirForFile = file.toPath().getParent().toFile();
+			if (!dirForFile.exists()) {
+				if (!dirForFile.mkdir()) {
+					ApolloSystemLog.println("Unable to create missing audio directory: " + dirForFile.toString());
+				}
+			}
+			if (file.isFile()) {
+				return true;
+			}
+			return false;
+		};		
+		List<File> allFilesInAudioDirectories = ResourceManager.gatherAudioResources(isFile, DisplayController.getCurrentFrame());
+		List<String> audioFileNames = new ArrayList<String>(); 
+		RegExpFileFilter regExpFileFilter = new RegExpFileFilter("^[A-Z]+\\d+.*$");
+		for (File file: allFilesInAudioDirectories) {
+			if (regExpFileFilter.accept(file, file.getAbsolutePath())) {
+				audioFileNames.add(file.getName());
+			}
+		}
+		return audioFileNames;
 	}
 	
@@ -168,5 +139,5 @@
 		String filename = generateRandomFilenameBase() + "." + extension;
 		
-		File f = new File(AUDIO_HOME_DIRECTORY + filename);
+		File f = new File(AUDIO_USERNAME_HOME_DIRECTORY + filename);
 
 		if (AudioStructureModel.getInstance().getTrackGraphInfo(filename, null) != null ||
@@ -206,5 +177,5 @@
 
 		// Build the filename string
-		return preamble + counter;
+		return UserSettings.UserName.get() + preamble + counter;
 		
 	}
@@ -222,5 +193,5 @@
 
 		// Ensure that the name base file exists. Assumes the audio home directory exists.
-		File vnameBase = new File(AUDIO_HOME_DIRECTORY + VIRTUAL_NAME_BASEFILE);
+		File vnameBase = new File(AUDIO_USERNAME_HOME_DIRECTORY + VIRTUAL_NAME_BASEFILE);
 		if (!vnameBase.exists()) {
 			try {
Index: /trunk/src/org/apollo/util/AudioPurger.java
===================================================================
--- /trunk/src/org/apollo/util/AudioPurger.java	(revision 1433)
+++ /trunk/src/org/apollo/util/AudioPurger.java	(revision 1434)
@@ -11,4 +11,6 @@
 import org.apollo.widgets.SampledTrack;
 import org.expeditee.settings.folders.FolderSettings;
+import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.management.ResourceManager;
 import org.expeditee.items.ItemUtils;
 
@@ -26,6 +28,6 @@
 	public static void purgeLocalAudio() {
 		
-		String[] audioFiles = AudioPathManager.getAudioFileNames();
-		if (audioFiles == null || audioFiles.length == 0) return;
+		List<String> audioFiles = AudioPathManager.getAudioFileNames();
+		if (audioFiles == null || audioFiles.size() == 0) return;
 		
 		
@@ -50,15 +52,12 @@
 		for (String audioFile : audioFiles) {
 			if (!referencedAudio.contains(audioFile)) {
-				
-				File unreferencedFile = new File(AudioPathManager.AUDIO_HOME_DIRECTORY + audioFile);
+				File unreferencedFile = ResourceManager.getAudioResource(audioFile, DisplayController.getCurrentFrame());
+				//File unreferencedFile = new File(AudioPathManager.AUDIO_HOME_DIRECTORY + audioFile);
 				ApolloSystemLog.println("Deleting unreference audio file \"" + audioFile + "\"");
 				unreferencedFile.delete();
 				
 				// Also delete any melody meta
-				File melodyMetaFile = new File(
-						AudioPathManager.AUDIO_HOME_DIRECTORY +
-						MelodySearch.MELODY_METAFILE_PREFIX + 
-						audioFile +
-						MelodySearch.MELODY_METAFILE_SUFFIX);
+				String melodyFileName = MelodySearch.MELODY_METAFILE_PREFIX + audioFile + MelodySearch.MELODY_METAFILE_SUFFIX;
+				File melodyMetaFile = ResourceManager.getAudioResource(melodyFileName, DisplayController.getCurrentFrame());
 				
 				if (melodyMetaFile.exists()) melodyMetaFile.delete();
Index: /trunk/src/org/apollo/widgets/FramePlayer.java
===================================================================
--- /trunk/src/org/apollo/widgets/FramePlayer.java	(revision 1433)
+++ /trunk/src/org/apollo/widgets/FramePlayer.java	(revision 1434)
@@ -107,5 +107,5 @@
 		
 		// Read typed frames
-		File f = new File(AudioPathManager.AUDIO_HOME_DIRECTORY + TYPED_FRAMED_HISTORY_FILE);
+		File f = new File(AudioPathManager.AUDIO_USERNAME_HOME_DIRECTORY + TYPED_FRAMED_HISTORY_FILE);
 		if (f.exists()) {
 			BufferedReader in = null;
@@ -147,5 +147,5 @@
 		try {
 			// Open the vbase for appending
-			out = new FileWriter(AudioPathManager.AUDIO_HOME_DIRECTORY + TYPED_FRAMED_HISTORY_FILE, false); 
+			out = new FileWriter(AudioPathManager.AUDIO_USERNAME_HOME_DIRECTORY + TYPED_FRAMED_HISTORY_FILE, false); 
 			for (String str : typedFrameNames) {
 				out.write(str + "\n");
@@ -802,5 +802,6 @@
 		}
 		
-	    ComboBoxModel<String> model = new DefaultComboBoxModel<String>((String[]) orderedModelData.toArray());
+	    ComboBoxModel<String> model = new DefaultComboBoxModel<String>((String[]) orderedModelData.toArray(new String[] {}));
+		//ComboBoxModel model = new DefaultComboBoxModel(orderedModelData.toArray());
 	    
 	    // Remove helper tags from model data
Index: /trunk/src/org/apollo/widgets/SampledTrack.java
===================================================================
--- /trunk/src/org/apollo/widgets/SampledTrack.java	(revision 1433)
+++ /trunk/src/org/apollo/widgets/SampledTrack.java	(revision 1434)
@@ -23,4 +23,5 @@
 import javax.sound.sampled.LineUnavailableException;
 import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.swing.JSlider;
 import javax.swing.SwingUtilities;
 
@@ -70,4 +71,5 @@
 import org.expeditee.gui.FrameIO;
 import org.expeditee.gui.PopupManager;
+import org.expeditee.gui.management.ResourceManager;
 import org.expeditee.items.ItemParentStateChangedEvent;
 import org.expeditee.items.ItemUtils;
@@ -401,17 +403,41 @@
 		
 		});
-		
+				
 		fulltrackView.addKeyListener(new KeyListener() {
 
 			@Override
-			public void keyPressed(KeyEvent e)
-			{
+			public void keyPressed(KeyEvent e) {
 			}
 
 			@Override
-			public void keyReleased(KeyEvent e)
-			{
+			public void keyReleased(KeyEvent e)	{
+				
+				// On 26th September, Bryce added P M + - keys to play/pause/resume, mute and adjust volume. 
+				if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_P) {
+					try {
+						playbackControlPopup.playPauseResume();
+					} catch (LineUnavailableException e1) {
+						e1.printStackTrace();
+					}
+				} else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_M) {
+					boolean selected = playbackControlPopup.muteButton.isSelected();
+					playbackControlPopup.muteButton.setSelected(!selected);
+					playbackControlPopup.muteChanged();
+				} else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_SUBTRACT) {
+					JSlider volumeSlider = playbackControlPopup.volumeSlider;
+					int delta = Math.round(((float) (volumeSlider.getMaximum() - volumeSlider.getMinimum())) / 10f);
+					int newVolume = Math.max(volumeSlider.getValue() - delta, volumeSlider.getMinimum());
+					volumeSlider.setValue(newVolume);
+					playbackControlPopup.volumeChanged();
+				} else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ADD) {
+					JSlider volumeSlider = playbackControlPopup.volumeSlider;
+					int delta = Math.round(((float) (volumeSlider.getMaximum() - volumeSlider.getMinimum())) / 10f);
+					int newVolume = Math.min(volumeSlider.getValue() + delta, volumeSlider.getMaximum());
+					volumeSlider.setValue(newVolume);
+					playbackControlPopup.volumeChanged();
+				}
+				
 				// Toggle pitch-track indexing
-				if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_I) {
+				else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_I) {
 					setShouldOmitIndexAudio(!shouldOmitIndexAudio());
 					DisplayController.requestRefresh(true);
@@ -765,6 +791,7 @@
 				setLoadScreenMessage("Loading audio file...");
 				
-				f = new File(
-						AudioPathManager.AUDIO_HOME_DIRECTORY + localFileName);
+				//f = new File(
+				//		AudioPathManager.AUDIO_HOME_DIRECTORY + localFileName);
+				f = ResourceManager.getAudioResource(localFileName, getParentFrame());
 			}
 			
@@ -809,5 +836,6 @@
 					// If recovering - might be recovering an existing track that had been
 					// saved to the repository .. thus re-use the old file
-					trackModel.setFilepath(AudioPathManager.AUDIO_HOME_DIRECTORY + localFileName);
+					File audioResource = ResourceManager.getAudioResource(localFileName, getParentFrame());
+					trackModel.setFilepath(audioResource.getAbsolutePath());
 				}
 				
@@ -940,5 +968,6 @@
 		// If saving for the file time then get a filename
 		if (trackModel.getFilepath() == null) {
-			trackModel.setFilepath(AudioPathManager.AUDIO_HOME_DIRECTORY + localFileName);
+			File audioResource = ResourceManager.getAudioResource(localFileName, DisplayController.getCurrentFrame());
+			trackModel.setFilepath(audioResource.getAbsolutePath());
 			loadFilenameArgument = localFileName; // set to now local, next load will be local
 		}
@@ -1029,5 +1058,6 @@
 		
 		// Get rid of local file
-		File oldLocalFile = new File(AudioPathManager.AUDIO_HOME_DIRECTORY + localFileName);
+		//File oldLocalFile = new File(AudioPathManager.AUDIO_HOME_DIRECTORY + localFileName);
+		File oldLocalFile = ResourceManager.getAudioResource(localFileName, getParentFrame());
 		if (oldLocalFile.isFile() && oldLocalFile.exists()) {
 			try {
@@ -1157,6 +1187,7 @@
 			return recoveryFile.getAbsolutePath();
 		}
-			
-		return AudioPathManager.AUDIO_HOME_DIRECTORY + localFileName;
+		
+		File audioResource = ResourceManager.getAudioResource(localFileName, getParentFrame());			
+		return audioResource.getAbsolutePath();
 		
 		
@@ -2005,68 +2036,5 @@
 				try {
 	
-					if (!SoundDesk.getInstance().isPlaying(trackMix.getChannelID())) { // play / resume
-						
-						int startFrame = -1, endFrame = -1;
-						
-						// Resume playback?
-						if (SoundDesk.getInstance().isPaused(trackMix.getChannelID())) {
-							startFrame = SoundDesk.getInstance().getLastPlayedFramePosition(trackMix.getChannelID());
-							if (startFrame >= 0 && startFrame < trackModel.getFrameCount()) {
-				
-								// The user may have edited the audio track and reselected it
-								// since the last pause. Thus select an appropriate end frame
-								endFrame = (trackModel.getSelectionLength() > 1) ?
-										trackModel.getSelectionStart() + trackModel.getSelectionLength():
-											trackModel.getFrameCount() - 1;
-									
-								// Changed selection? it play range invalid?
-								if (endFrame <= startFrame || startFrame < trackModel.getSelectionStart()) {
-									startFrame = -1; // Play new selection (see below)
-								
-								} else if (endFrame >= trackModel.getFrameCount()) {
-									endFrame = trackModel.getFrameCount() - 1;
-								}		
-								
-							}
-						}
-						
-						// Play from beginning of selection to end of selection
-						if (startFrame < 0) {
-							startFrame = trackModel.getSelectionStart();
-							endFrame = (trackModel.getSelectionLength() > 1) ?
-									startFrame + trackModel.getSelectionLength():
-										trackModel.getFrameCount() - 1;
-						}
-	
-						// Safety clamp:
-						if (endFrame >= trackModel.getFrameCount()) {
-							endFrame = trackModel.getFrameCount() - 1;
-						}	
-						
-						if (startFrame < endFrame) {
-							SoundDesk.getInstance().playSampledTrackModel(
-									trackModel, 
-									trackMix.getChannelID(), 
-									startFrame, 
-									endFrame, 
-									0);
-						}
-	
-					} else { // pause
-						
-						TrackSequence ts = SoundDesk.getInstance().getTrackSequence(trackMix.getChannelID());
-
-						if (ts != null &&
-								ts.isPlaying()) {
-							
-							// Mark channel as paused.
-							SoundDesk.getInstance().setPaused(trackMix.getChannelID(), true);
-							
-							// Stop playback for this channel
-							ApolloPlaybackMixer.getInstance().stop(ts);
-							
-						}
-						
-					}
+					playPauseResume();
 					
 				} catch (LineUnavailableException e1) {
@@ -2094,4 +2062,71 @@
 			} else if (e.getSource() == miscButton) {
 				expand(false);
+			}
+		}
+
+		private void playPauseResume() throws LineUnavailableException {
+			if (!SoundDesk.getInstance().isPlaying(trackMix.getChannelID())) { // play / resume
+				
+				int startFrame = -1, endFrame = -1;
+				
+				// Resume playback?
+				if (SoundDesk.getInstance().isPaused(trackMix.getChannelID())) {
+					startFrame = SoundDesk.getInstance().getLastPlayedFramePosition(trackMix.getChannelID());
+					if (startFrame >= 0 && startFrame < trackModel.getFrameCount()) {
+
+						// The user may have edited the audio track and reselected it
+						// since the last pause. Thus select an appropriate end frame
+						endFrame = (trackModel.getSelectionLength() > 1) ?
+								trackModel.getSelectionStart() + trackModel.getSelectionLength():
+									trackModel.getFrameCount() - 1;
+							
+						// Changed selection? it play range invalid?
+						if (endFrame <= startFrame || startFrame < trackModel.getSelectionStart()) {
+							startFrame = -1; // Play new selection (see below)
+						
+						} else if (endFrame >= trackModel.getFrameCount()) {
+							endFrame = trackModel.getFrameCount() - 1;
+						}		
+						
+					}
+				}
+				
+				// Play from beginning of selection to end of selection
+				if (startFrame < 0) {
+					startFrame = trackModel.getSelectionStart();
+					endFrame = (trackModel.getSelectionLength() > 1) ?
+							startFrame + trackModel.getSelectionLength():
+								trackModel.getFrameCount() - 1;
+				}
+
+				// Safety clamp:
+				if (endFrame >= trackModel.getFrameCount()) {
+					endFrame = trackModel.getFrameCount() - 1;
+				}	
+				
+				if (startFrame < endFrame) {
+					SoundDesk.getInstance().playSampledTrackModel(
+							trackModel, 
+							trackMix.getChannelID(), 
+							startFrame, 
+							endFrame, 
+							0);
+				}
+
+			} else { // pause
+				
+				TrackSequence ts = SoundDesk.getInstance().getTrackSequence(trackMix.getChannelID());
+
+				if (ts != null &&
+						ts.isPlaying()) {
+					
+					// Mark channel as paused.
+					SoundDesk.getInstance().setPaused(trackMix.getChannelID(), true);
+					
+					// Stop playback for this channel
+					ApolloPlaybackMixer.getInstance().stop(ts);
+					
+				}
+				
 			}
 		}
Index: /trunk/src/org/expeditee/auth/AuthenticatorBrowser.java
===================================================================
--- /trunk/src/org/expeditee/auth/AuthenticatorBrowser.java	(revision 1433)
+++ /trunk/src/org/expeditee/auth/AuthenticatorBrowser.java	(revision 1434)
@@ -81,5 +81,5 @@
 	
 	private KeyStore keyStore = KeyStore.getInstance(KeystoreType);
-	public static String USER_NOBODY = "nobody";
+	public static String USER_NOBODY = "${USER.NAME}";
 		
 	private static final byte[] TRUE = "yes".getBytes();
@@ -124,5 +124,5 @@
 		g.setWindowSize(new Dimension(UserSettings.InitialWidth.get(), UserSettings.InitialHeight.get()));
 		setInputManagerWindowRoutines();
-		
+				
 		// Load documentation and start pages
 		FrameUtils.extractResources(false);
@@ -133,4 +133,7 @@
 		// initialing settings does not require a user profile established
 		Settings.Init();
+		
+		// Ensure messages go to public directory whilst we are not logged into an account.
+		FrameIO.MESSAGES_PATH = Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-public").resolve("messages").toString() + File.separator;
 		
 		// navigate to authentication frame
Index: /trunk/src/org/expeditee/auth/account/Authenticate.java
===================================================================
--- /trunk/src/org/expeditee/auth/account/Authenticate.java	(revision 1433)
+++ /trunk/src/org/expeditee/auth/account/Authenticate.java	(revision 1434)
@@ -32,4 +32,5 @@
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameIO;
+import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
 import org.expeditee.items.Item;
@@ -96,7 +97,8 @@
 			
 			// Parse the users profile to refresh settings.
-			Text settingsLink = new Text("settings");
-			settingsLink.setLink(oneFrame.getFramesetName() + "2");
-			Settings.parseSettings(settingsLink);
+			//Text settingsLink = new Text("settings");
+			//settingsLink.setLink(oneFrame.getFramesetName() + "2");
+			//Settings.parseSettings(settingsLink);
+			FrameUtils.ParseProfile(oneFrame);
 			
 			// At this point we at least login, but maybe with problems.
Index: /trunk/src/org/expeditee/auth/account/Create.java
===================================================================
--- /trunk/src/org/expeditee/auth/account/Create.java	(revision 1433)
+++ /trunk/src/org/expeditee/auth/account/Create.java	(revision 1434)
@@ -36,4 +36,5 @@
 import org.expeditee.gui.MessageBay;
 import org.expeditee.gui.MessageBay.Progress;
+import org.expeditee.gui.management.ProfileManager;
 import org.expeditee.io.ExpReader;
 import org.expeditee.items.Item;
@@ -85,4 +86,5 @@
 		
 		// Update in memory settings
+		ProfileManager.ensureDefaultProfile();
 		System.setProperty("user.name", username);
 		UserSettings.UserName.set(username);
@@ -119,5 +121,5 @@
 		
 		System.err.println("**** Hardwired call in Apollo's AuthioPathManager");
-		AudioPathManager.activateAndScanAudioDir(); // ****
+		AudioPathManager.activateAndScanAudioDirs(); // ****
 		
 		progress = progress(message + "Done.", progress, step, progressBar);
Index: /trunk/src/org/expeditee/gui/Browser.java
===================================================================
--- /trunk/src/org/expeditee/gui/Browser.java	(revision 1433)
+++ /trunk/src/org/expeditee/gui/Browser.java	(revision 1434)
@@ -269,13 +269,15 @@
 		Text.InitFonts();
 
-		Settings.Init();
-		Frame userProfile = loadProfiles();
-
 		if (!AuthenticatorBrowser.isAuthenticationRequired() && UserSettings.PublicAndPrivateResources) {
-			String userName = UserSettings.ProfileName.get();
+			String userName = System.getProperty("user.name"); //UserSettings.ProfileName.get();
 			if (!FrameIO.personalResourcesExist(userName)) {
 				FrameIO.setupPersonalResources(userName);
 			}
 		}
+		
+		Settings.Init();
+		Frame userProfile = loadInitialProfiles();
+		FrameIO.changeParentAndSubFolders(FrameIO.PARENT_FOLDER);
+		
 		// Listen for save status to display during and after runtime
 		EntitySaveManager.getInstance().addSaveStateChangedEventListener(this);
@@ -285,5 +287,4 @@
 			
 			// Go to the start frame if specified, otherwise go to the profile frame
-			Frame start = null;
 			if (getStartFrame() == null) {
 				setStartFrame(UserSettings.StartFrame.get());
@@ -293,4 +294,5 @@
 			}
 
+			Frame start = null;
 			if ((start = FrameIO.LoadFrame(getStartFrame())) != null) {
 				// Make sure HomeFrame gets set
@@ -527,11 +529,11 @@
 	 * @return The user's profile frame.
 	 */
-	public static Frame loadProfiles()
+	public static Frame loadInitialProfiles()
 	{
 		String defaultProfileName = UserSettings.DEFAULT_PROFILE_NAME;
-		String userName = UserSettings.ProfileName.get();
-
+		String userName = System.getProperty("user.name");
+
+		Frame defaultProfile = loadProfile(defaultProfileName);
 		Frame userProfile = loadProfile(userName);
-		Frame defaultProfile = loadProfile(defaultProfileName);
 		
 		MessageBay.warningMessages(FrameUtils.ParseProfile(defaultProfile));
@@ -544,9 +546,11 @@
 		}
 		
-		MessageBay.warningMessages(FrameUtils.ParseProfile(userProfile));
+		//MessageBay.warningMessages(FrameUtils.ParseProfile(userProfile));
 		
 		if (cursor != null && !FreeItems.hasCursor()) {
 			FreeItems.setCursor(cursor);
 		}
+		
+		FrameUtils.ParseProfile(userProfile);
 		
 		return userProfile;
Index: /trunk/src/org/expeditee/gui/Frame.java
===================================================================
--- /trunk/src/org/expeditee/gui/Frame.java	(revision 1433)
+++ /trunk/src/org/expeditee/gui/Frame.java	(revision 1434)
@@ -20,4 +20,5 @@
 
 import java.io.File;
+import java.nio.file.Paths;
 import java.sql.Time;
 import java.util.ArrayList;
@@ -41,4 +42,5 @@
 import org.expeditee.core.bounds.PolygonBounds;
 import org.expeditee.encryption.items.EncryptionPermissionTriple;
+import org.expeditee.encryption.items.surrogates.Label;
 import org.expeditee.gio.EcosystemManager;
 import org.expeditee.gio.gesture.Gesture;
@@ -190,4 +192,6 @@
 	private String _groupFrameName;
 	private Frame _groupFrame = null;
+
+	private List<String> labelsOnLastBodySet;
 	
 	public enum BodyType {
@@ -353,5 +357,5 @@
 	 */
 	public List<Item> getSortedItems(boolean requireVisible) {
-		ItemsList listToLoopOver = _body;
+		ItemsList listToLoopOver = getBody(true);
 		listToLoopOver.sort();
 		return getItems(requireVisible, listToLoopOver);
@@ -389,5 +393,5 @@
 			throw new NullPointerException("i");
 		}	
-		return _body.contains(i);
+		return getBody(true).contains(i);
 	}
 
@@ -404,6 +408,7 @@
 	 * @return the list of body text items.
 	 */
-	public List<Text> getBodyTextItems(boolean includeAnnotations)
-	{
+	public List<Text> getBodyTextItems(boolean includeAnnotations) {
+		ensureBody();
+		
 		List<Text> bodyTextItems = new ArrayList<Text>();
 		
@@ -467,7 +472,6 @@
 	 *         found.
 	 */
-	public Item getItemWithID(int id)
-	{
-		for (Item i : _body) {
+	public Item getItemWithID(int id) {
+		for (Item i : getAllFrameItemsRaw()) {
 			if (i.getID() == id) {
 				return i;
@@ -761,5 +765,5 @@
 		_permissionTriple = new PermissionTriple(permission);
 
-		if (_body.size() > 0) {
+		if (getBody(false).size() > 0) {
 			refreshItemPermissions(permission.getPermission(_owner, groupMembers));
 		}
@@ -787,5 +791,5 @@
 		_creationDate = date;
 		_modifiedDate = date;
-		for (Item i : _body) {
+		for (Item i : getAllFrameItemsRaw()) {
 			i.setDateCreated(date);
 		}
@@ -855,5 +859,5 @@
 
 	public void invalidateSorted() {
-		_body.invalidateSorted();
+		getBody(false).invalidateSorted();
 	}
 
@@ -871,9 +875,9 @@
 		if (item == null) { return; }
 		
-		addItem(item, recalculate, _body);
+		addItem(item, recalculate, getBody(false));
 		if (item.isSurrogate()) {
-			addItem(item, recalculate, _surrogateItemsBody);
+			addItem(item, recalculate, getSurrogateBody());
 		} else {
-			addItem(item, recalculate, _primaryItemsBody);
+			addItem(item, recalculate, getPrimaryBody());
 		}
 	}
@@ -988,6 +992,6 @@
 
 	public void addAllItems(Collection<Item> toAdd)	{
-		addAllItems(toAdd, _body);
-		addAllItems(toAdd, _primaryItemsBody);
+		addAllItems(toAdd, getBody(false));
+		addAllItems(toAdd, getPrimaryBody());
 	}
 	
@@ -1018,11 +1022,11 @@
 
 	public void removeItem(Item item, boolean recalculate) {
-		removeItem(item, recalculate, _body);
+		removeItem(item, recalculate, getBody(false));
 		if (item.isSurrogate()) {
-			removeItem(item, recalculate, _surrogateItemsBody);
+			removeItem(item, recalculate, getSurrogateBody());
 			Set<Item> primariesSurrogates = item.getPrimary().getSurrogates();
 			primariesSurrogates.remove(item);
 		} else {
-			removeItem(item, recalculate, _primaryItemsBody);
+			removeItem(item, recalculate, getPrimaryBody());
 		}
 	}
@@ -1075,8 +1079,7 @@
 	}
 
-	public void undo()
-	{
-		boolean bReparse = false;
-		boolean bRecalculate = false;
+	public void undo() {
+		boolean reparse = false;
+		boolean recalculate = false;
 
 		if (_undo.size() <= 0) {
@@ -1092,7 +1095,7 @@
 			_redo.push(undo);
     		for(Item i : undo.items) {
-    			_body.add(i);
-				bReparse |= i.hasOverlay();
-				bRecalculate |= i.recalculateWhenChanged();
+    			this.addItem(i);
+				reparse |= i.hasOverlay();
+				recalculate |= i.recalculateWhenChanged();
 				if (i instanceof Line) {
 					Line line = (Line) i;
@@ -1105,11 +1108,12 @@
     		break;
 		case movement:
-			ItemsList changed = new ItemsList(_body);
-			changed.retainHistory(undo.items);
+			ItemsList body = getBody(true);
+			ItemsList changed = new ItemsList(body);
+			changed.retainAll(undo.items);
 			_redo.push(new History(changed, History.Type.movement));
 			for(Item i : undo.items) {
 				int index;
-				if(i.isVisible() && (index = _body.indexOf(i)) != -1) {
-					_body.set(index, i);
+				if(i.isVisible() && (index = body.indexOf(i)) != -1) {
+					body.set(index, i);
 				}
     		}
@@ -1121,8 +1125,8 @@
 		StandardGestureActions.refreshHighlights();
 		
-		if (bReparse) {
+		if (reparse) {
 			FrameUtils.Parse(this, false, false);
 		} else {
-			notifyObservers(bRecalculate);
+			notifyObservers(recalculate);
 		}
 		
@@ -1152,5 +1156,6 @@
 			_undo.push(redo);
     		for(Item i : redo.items) {
-    			_body.remove(i);
+    			this.removeItem(i);
+    			//_body.remove(i);
 				bReparse |= i.hasOverlay();
 				bRecalculate |= i.recalculateWhenChanged();
@@ -1165,11 +1170,12 @@
     		break;
 		case movement:
-			ItemsList changed = new ItemsList(_body);
-			changed.retainHistory(redo.items);
+			ItemsList body = getBody(true);
+			ItemsList changed = new ItemsList(body);
+			changed.retainAll(redo.items);
 			_undo.push(new History(changed, History.Type.movement));
 			for(Item i : redo.items) {
 				int index;
-				if(i.isVisible() && (index = _body.indexOf(i)) != -1) {
-					_body.set(index, i);
+				if(i.isVisible() && (index = body.indexOf(i)) != -1) {
+					body.set(index, i);
 				}
     		}
@@ -1335,5 +1341,5 @@
 		// s.append(String.format("Last Mod. User: %s%n", _modifiedUser));
 		// s.append(String.format("Last Mod. Date: %s%n", _modifiedDate));
-		s.append(String.format("Items: %d%n", _body.size()));
+		s.append(String.format("Items: %d%n", getAllFrameItemsRaw().size()));
 		return s.toString();
 	}
@@ -1379,5 +1385,5 @@
 	{
 		// Check that this item is on the current frame
-		if (!_body.contains(from)) {
+		if (!getBody(true).contains(from)) {
 			return null;
 		}
@@ -1789,6 +1795,7 @@
 	 * Removes all non-title non-annotation items from this Frame. All removed
 	 * items are added to the backup-stack.
-	 */
-	public void clear(boolean keepAnnotations)
+	 */ 
+	@Deprecated
+	public void clearDeprecated(boolean keepAnnotations)
 	{
 		ItemsList newBody = new ItemsList();
@@ -1814,4 +1821,34 @@
 		change();
 
+		if (!keepAnnotations && _annotations != null) {
+			_annotations.clear();
+		}
+	}
+	
+	/**
+	 * Removes all items from the Frame except the Title Item and optionally the annotations.
+	 * All removed items are added to the backup-stack.
+	 * 
+	 * @param keepAnnotations true is annotations are not to be removed from the frame.
+	 */
+	public void clear(boolean keepAnnotations) {
+		ItemsList body = getBody(true);
+		ItemsList deleted = new ItemsList();
+		
+		for (Item bodyItem: body) {
+			boolean isAnnotationToKeep = bodyItem.isAnnotation() && keepAnnotations;
+			boolean isFrameTitle = bodyItem.isFrameTitle();
+			boolean isToBeRetained = isFrameTitle || isAnnotationToKeep;
+			if (isToBeRetained) {
+				continue;
+			}
+			
+			this.removeItem(bodyItem);
+			deleted.add(bodyItem);
+		}
+		
+		addToUndoDelete(deleted);
+		change();
+		
 		if (!keepAnnotations && _annotations != null) {
 			_annotations.clear();
@@ -1950,5 +1987,5 @@
 	 */
 	public String getFramesetPath() {
-		return this.getPath() + File.separator + this.getFramesetName() + File.separator;
+		return Paths.get(this.getPath()).resolve(this.getFramesetName()).toString() + File.separator;
 	}
 
@@ -2290,5 +2327,5 @@
 
 		for (Overlay o : getOverlays()) {
-			for(Item i : o.Frame._body) {
+			for(Item i : o.Frame.getBody(false)) {
 				i.setOverlayPermission(o.permission);
 			}
@@ -2568,4 +2605,17 @@
 	}
 	
+	/**
+	 * Returns a list of items for the specified BodyType.
+	 * 
+	 * Asking for the primary or surrogate items gives you exactly those.
+	 * 
+	 * Asking for the body items is a weird case because the body list is
+	 * transitory.  Therefore, when asking for the body items, this
+	 * function assumes that you want all items, reguardless of if they
+	 * are primaries or surrogates.  As of 20/08/2019, there are no places
+	 * in the code that asks for the body items to save.
+	 * @param type
+	 * @return
+	 */
 	public List<Item> getItemsToSave(BodyType type) {
 		assert(!type.equals(BodyType.BodyDisplay));
@@ -2574,5 +2624,5 @@
 			return getItemsToSave(_surrogateItemsBody);
 		case BodyDisplay:
-			return getItemsToSave(_body);
+			return getItemsToSave(new ItemsList(getAllFrameItemsRaw()));
 		case PrimaryBody:
 		default:
@@ -2632,5 +2682,5 @@
 
 	public Collection<Item> getAllItems() {
-		ItemsList allItems = new ItemsList(_body);
+		ItemsList allItems = new ItemsList(getBody(true));
 		
 		allItems.addAll(_overlayItems);
@@ -2721,6 +2771,6 @@
 	}
 
-	public void dispose()
-	{
+	@Deprecated
+	public void disposeDeprecated()	{
 		clearObservers();
 		
@@ -2732,4 +2782,24 @@
 		_body = null;
 		_frameName = null;
+	}
+	
+	/**
+	 * Disposes off all references associated with this frame.  
+	 * This operation is NOT REVERSEABLE through the history.
+	 */
+	public void dispose() {
+		clearObservers();
+		
+		List<Item> allFrameItems = getAllFrameItemsRaw();
+		
+		for (Item i: allFrameItems) {
+			i.dispose();
+		}
+
+		_frameName.dispose();
+		_frameName = null;
+		getBody(false).clear();
+		getPrimaryBody().clear();
+		getSurrogateBody().clear();
 	}
 
@@ -2800,5 +2870,5 @@
 	
 	public void moveItemToBodyHiddenDueToPermission(final Item i) {
-		_body.remove(i);
+		getBody(true).remove(i);
 		_bodyHiddenDueToPermissions.add(i);
 	}
@@ -2808,5 +2878,5 @@
 			_bodyHiddenDueToPermissions.remove(i);
 			i.setPermission(newPermission);
-			_body.add(i);
+			getBody(true).add(i);
 		}
 	}
@@ -2821,5 +2891,5 @@
 		}
 
-		for (Item i : _body) {
+		for (Item i : getBody(false)) {
 			if (i == null) {
 				continue;
@@ -2950,7 +3020,22 @@
 	}
 
-	public ItemsList getBody() {
+	public ItemsList getBody(boolean respectSurrogateMode) {
+		if (respectSurrogateMode) { ensureBody(); }		
 		return _body;
 	}
+
+	private void ensureBody() {
+		List<String> accessibleLabelsNames = Label.getAccessibleLabelsNames(getPrimaryBody());
+		if (!accessibleLabelsNames.equals(labelsOnLastBodySet)) {
+			this.parse();
+		}
+	}
+	
+	protected void setBody(List<Item> newBody, List<String> labelsOnSet) {
+		_body.clear();
+		_body.addAll(newBody);
+		this.labelsOnLastBodySet = labelsOnSet;
+	}
+	
 	protected ItemsList getPrimaryBody() {
 		return _primaryItemsBody;
@@ -2959,3 +3044,19 @@
 		return _surrogateItemsBody;
 	}
+	
+
+	/**
+	 * Gets all the items on the frame, regardless of whether they are primary or surrogate items.
+	 * 
+	 * Bryce says: This function will likely only ever be used inside Frame itself, as callers from
+	 * outside Frame should care about what the state of the Frame.
+	 * @return
+	 */
+	private List<Item> getAllFrameItemsRaw() {
+		Collection<Item> primaries = getPrimaryBody().underlying();
+		Collection<Item> surrogateBody = getSurrogateBody().underlying();
+		primaries.addAll(surrogateBody);
+		List<Item> allFrameItems = primaries.stream().distinct().collect(Collectors.toList());
+		return allFrameItems;
+	}
 }
Index: /trunk/src/org/expeditee/gui/FrameIO.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameIO.java	(revision 1433)
+++ /trunk/src/org/expeditee/gui/FrameIO.java	(revision 1434)
@@ -57,4 +57,6 @@
 import org.expeditee.encryption.io.EncryptedExpWriter;
 import org.expeditee.gio.EcosystemManager;
+import org.expeditee.gui.management.ProfileManager;
+import org.expeditee.gui.management.ResourceManager;
 import org.expeditee.io.Conversion;
 import org.expeditee.io.ExpReader;
@@ -110,13 +112,13 @@
 	public static String SHARED_FRAMESETS_PATH;
 	public static String CONTACTS_PATH;
-	public static String RESOURCES_PRIVATE_PATH;
-	public static String RESOURCES_PATH;
-	public static String FRAME_PRIVATE_PATH;
-	public static String IMAGES_PRIVATE_PATH;
-	public static String AUDIO_PRIVATE_PATH;
-	public static String HELP_PRIVATE_PATH;
 	public static String HELP_PATH;
 	public static String DEAD_DROPS_PATH;
 	public static String GROUP_PATH;
+	public static String RESOURCES_PRIVATE_PATH;
+	public static String RESOURCES_PATH;
+	public static String FRAME_USERNAME_PRIVATE_PATH;
+	public static String IMAGES_USERNAME_PRIVATE_PATH;
+	public static String AUDIO_USERNAME_PRIVATE_PATH;
+	public static String HELP_USERNAME_PRIVATE_PATH;
 
 	// Paths that appear to be unused.
@@ -144,5 +146,5 @@
 		
 		String resourcesPublicPath = PARENT_FOLDER + "resources-public" + File.separator;
-		String resourcesPrivateIndividualPath = PARENT_FOLDER + "resources-" + UserSettings.UserName.get() + File.separator;
+		String resourcesPrivateUserPath = PARENT_FOLDER + "resources-" + UserSettings.UserName.get() + File.separator;
 		
 		if (UserSettings.PublicAndPrivateResources) {
@@ -151,13 +153,13 @@
 			DICT_PATH = resourcesPublicPath + "dict" + File.separator;
 			HELP_PATH = resourcesPublicPath + "documentation" + File.separator;
-			HELP_PRIVATE_PATH = resourcesPrivateIndividualPath + "documentation" + File.separator;
+			HELP_USERNAME_PRIVATE_PATH = resourcesPrivateUserPath + "documentation" + File.separator;
 			FRAME_PATH = resourcesPublicPath + "framesets" + File.separator;
-			FRAME_PRIVATE_PATH = resourcesPrivateIndividualPath + "framesets" + File.separator;
-			MESSAGES_PATH = resourcesPrivateIndividualPath + "messages" + File.separator;
+			FRAME_USERNAME_PRIVATE_PATH = resourcesPrivateUserPath + "framesets" + File.separator;
+			MESSAGES_PATH = resourcesPrivateUserPath + "messages" + File.separator;
 			IMAGES_PATH = resourcesPublicPath + "images" + File.separator;
-			IMAGES_PRIVATE_PATH = resourcesPrivateIndividualPath + "images" + File.separator;
+			IMAGES_USERNAME_PRIVATE_PATH = resourcesPrivateUserPath + "images" + File.separator;
 			AUDIO_PATH = resourcesPublicPath + "audio" + File.separator;
-			AUDIO_PRIVATE_PATH = resourcesPrivateIndividualPath + "audio" + File.separator;
-			GROUP_PATH = resourcesPrivateIndividualPath + "groups" + File.separator;
+			AUDIO_USERNAME_PRIVATE_PATH = resourcesPrivateUserPath + "audio" + File.separator;
+			GROUP_PATH = resourcesPrivateUserPath + "groups" + File.separator;
 
 			// Used only when extracting resources (when expeditee is run for first time)
@@ -166,8 +168,8 @@
 			if (AuthenticatorBrowser.isAuthenticated()) {
 				// Paths for the new regime while authenticated
-				SHARED_FRAMESETS_PATH = resourcesPrivateIndividualPath + "framesets-shared" + File.separator;
-				DEAD_DROPS_PATH = resourcesPrivateIndividualPath + "deaddrops" + File.separator;
-				CONTACTS_PATH = resourcesPrivateIndividualPath + "contacts" + File.separator;
-				MAIL_PATH = resourcesPrivateIndividualPath + "mail" + File.separator;
+				SHARED_FRAMESETS_PATH = resourcesPrivateUserPath + "framesets-shared" + File.separator;
+				DEAD_DROPS_PATH = resourcesPrivateUserPath + "deaddrops" + File.separator;
+				CONTACTS_PATH = resourcesPrivateUserPath + "contacts" + File.separator;
+				MAIL_PATH = resourcesPrivateUserPath + "mail" + File.separator;
 			} else {
 				SHARED_FRAMESETS_PATH = null;
@@ -188,8 +190,8 @@
 			
 			// These paths are not used by old regime.
-			HELP_PRIVATE_PATH = null;
-			FRAME_PRIVATE_PATH = null;
-			IMAGES_PRIVATE_PATH = null;
-			AUDIO_PRIVATE_PATH = null;
+			HELP_USERNAME_PRIVATE_PATH = null;
+			FRAME_USERNAME_PRIVATE_PATH = null;
+			IMAGES_USERNAME_PRIVATE_PATH = null;
+			AUDIO_USERNAME_PRIVATE_PATH = null;
 			// - This last one is never used because old regime is never extracted.  If we are going to FrameUtils.extractResources then we are doing new regime.
 			RESOURCES_PRIVATE_PATH = null;
@@ -209,6 +211,6 @@
 		}
 		
-		System.err.println("**** FrameIO::changeParentAndSubFolder(): Calling AudioPathManger.changeParentAndSubFolder()");
-		AudioPathManager.changeParentAndSubFolders(newFolder);
+		//System.err.println("**** FrameIO::changeParentAndSubFolder(): Calling AudioPathManger.changeParentAndSubFolder()");
+		//AudioPathManager.changeParentAndSubFolders(newFolder);
 	}
 	
@@ -370,33 +372,37 @@
 		return null;
 	}
-
-	private static Frame LoadFromDisk(String framename, String knownPath,
-			boolean ignoreAnnotations) {
-		Frame loaded = null;
-
-		if (knownPath != null) {
-			loaded = LoadKnownPath(knownPath, framename);
-		} else {
-			List<String> directoriesToSearch = FolderSettings.FrameDirs.getAbsoluteDirs();
-			
-			for (String path : directoriesToSearch) {
-				loaded = LoadKnownPath(path, framename);
-				if (loaded != null) {
-					break;
-				}
-			}
-		}
-
-		if (loaded == null && FrameShare.getInstance() != null) {
-			loaded = FrameShare.getInstance().loadFrame(framename, knownPath);
-		}
-
-		if (loaded != null) {
-			FrameUtils.Parse(loaded, true, ignoreAnnotations);
-			FrameIO.setSavedProperties(loaded);
-		}
-
-		return loaded;
-	}
+	
+	private static Frame LoadFromDisk(String frameName, String knownPath, boolean ignoreAnnotationsOnParse) {
+		return ResourceManager.getExpediteeFrame(frameName, knownPath, ignoreAnnotationsOnParse);
+	}
+
+//	private static Frame LoadFromDisk(String framename, String knownPath,
+//			boolean ignoreAnnotations) {
+//		Frame loaded = null;
+//
+//		if (knownPath != null) {
+//			loaded = LoadKnownPath(knownPath, framename);
+//		} else {
+//			List<String> directoriesToSearch = FolderSettings.FrameDirs.getAbsoluteDirs();
+//			
+//			for (String path : directoriesToSearch) {
+//				loaded = LoadKnownPath(path, framename);
+//				if (loaded != null) {
+//					break;
+//				}
+//			}
+//		}
+//
+//		if (loaded == null && FrameShare.getInstance() != null) {
+//			loaded = FrameShare.getInstance().loadFrame(framename, knownPath);
+//		}
+//
+//		if (loaded != null) {
+//			FrameUtils.Parse(loaded, true, ignoreAnnotations);
+//			FrameIO.setSavedProperties(loaded);
+//		}
+//
+//		return loaded;
+//	}
 
 	/**
@@ -563,5 +569,5 @@
 	}
 
-	private static Frame LoadKnownPath(String path, String frameName) {
+	public static Frame LoadKnownPath(String path, String frameName) {
 		String fullPath = getFrameFullPathName(path, frameName);
 		if (fullPath == null) {
@@ -1381,5 +1387,5 @@
 	public static boolean isProfileFrame(Frame toCheck)
 	{
-		if (toCheck.getNumber() == 0) {
+		if (toCheck.getNumber() == 0 || toCheck.getFramesetName().equals(UserSettings.DEFAULT_PROFILE_NAME)) {
 			return false;
 		}
@@ -1401,13 +1407,19 @@
 
 	public static Frame CreateNewProfile(String username, Map<String, Setting> initialSettings, Map<String, Consumer<Frame>> toNotifyOnSet) throws InvalidFramesetNameException, ExistingFramesetException {
-		Frame profile = CreateFrameset(username, PROFILE_PATH, true);
-		if (profile != null) {
-			FrameUtils.CreateDefaultProfile(username, profile, initialSettings, toNotifyOnSet);
+//		Frame profile = CreateFrameset(username, PROFILE_PATH, true);
+//		if (profile != null) {
+//			FrameUtils.CreateDefaultProfile(username, profile, initialSettings, toNotifyOnSet);
+//		} else {
+//			System.err.println("An error occured while attempting to create the profile named: " + username);
+//			System.err.println("Unable to proceed.");
+//			System.exit(1);
+//		}
+//		return profile;
+		if (username.equals(UserSettings.DEFAULT_PROFILE_NAME)) {
+			ProfileManager.ensureDefaultProfile();
+			return FrameIO.LoadFrame(UserSettings.DEFAULT_PROFILE_NAME + "1");
 		} else {
-			System.err.println("An error occured while attempting to create the profile named: " + username);
-			System.err.println("Unable to proceed.");
-			System.exit(1);
-		}
-		return profile;
+			return ProfileManager.createProfile(username, initialSettings, toNotifyOnSet);
+		}
 	}
 
Index: /trunk/src/org/expeditee/gui/FrameUtils.java
===================================================================
--- /trunk/src/org/expeditee/gui/FrameUtils.java	(revision 1433)
+++ /trunk/src/org/expeditee/gui/FrameUtils.java	(revision 1434)
@@ -63,4 +63,6 @@
 import org.expeditee.gio.EcosystemManager;
 import org.expeditee.gio.gesture.StandardGestureActions;
+import org.expeditee.gui.management.ResourceManager;
+import org.expeditee.gui.management.ResourceUtil;
 import org.expeditee.items.Circle;
 import org.expeditee.items.Dot;
@@ -86,5 +88,4 @@
 import org.expeditee.settings.Settings;
 import org.expeditee.settings.UserSettings;
-import org.expeditee.settings.templates.TemplateSettings;
 import org.expeditee.stats.Logger;
 import org.expeditee.stats.SessionStats;
@@ -666,5 +667,5 @@
 	
 	private static boolean createPictureInBody(Frame frame, Text txt) {
-		return createPicture(frame, txt, frame.getBody());
+		return createPicture(frame, txt, frame.getBody(false));
 	}
 
@@ -726,11 +727,15 @@
 	
 	private static boolean createWidgetInBody(Frame frame, Text txt) {
-		return createWidget(frame, txt, frame.getBody());
-	}
-
-	public static List<String> ParseProfile(Frame profile) {
+		return createWidget(frame, txt, frame.getBody(false));
+	}
+
+	public static List<String> ParseProfile(Frame profile) {		
 		List<String> errors = new LinkedList<String>();
 
 		if (profile == null) {
+			return errors;
+		}
+		
+		if (profile.getFramesetName().equals(UserSettings.DEFAULT_PROFILE_NAME)) {
 			return errors;
 		}
@@ -771,4 +776,7 @@
 		}
 
+		// Tell the resource manager that it needs to refresh its context.
+		ResourceManager.invalidateAllResourceDirectories();
+		
 		return errors;
 	}
@@ -792,5 +800,4 @@
 			DisplayController.setCurrentFrame(firstFrame, true);
 		}
-
 	}
 
@@ -843,25 +850,39 @@
 		throw new RuntimeException("Missing value for profile attribute" + name);
 	}
-
-	public static ArrayList<String> getDirs(Item item) {
-		ArrayList<String> dirsToAdd = new ArrayList<String>();
+	
+	public static List<String> getDirs(Item item) {
+		List<String> dirsToAdd = new ArrayList<String>();
+		String currentFramesetFlag = ResourceUtil.CURRENT_FRAMESET_FLAG;
+		boolean need_file_sep_replace = (!File.separator.equals("/"));
+		
 		String dirListFrameName = item.getAbsoluteLink();
-		if (dirListFrameName != null) {
-			Frame dirListFrame = FrameIO.LoadFrame(dirListFrameName);
-			if (dirListFrame != null) {
-				for (Text t : dirListFrame.getBodyTextItems(false)) {
-					String dirName = t.getText().trim();
-					File tester = new File(dirName);
-					if (tester.exists() && tester.isDirectory()) {
-						if (dirName.endsWith(File.separator)) {
-							dirsToAdd.add(dirName);
-						} else {
-							dirsToAdd.add(dirName + File.separator);
-						}
-					}
-				}
-			}
-		}
-
+		if (dirListFrameName == null) {
+			return dirsToAdd;
+		}
+		Frame dirListFrame = FrameIO.LoadFrame(dirListFrameName);
+		if (dirListFrame == null) {
+			return dirsToAdd;
+		}
+		
+		List<Text> bodyTextItems = dirListFrame.getBodyTextItems(false);
+		for (Text t: bodyTextItems) {
+			String dirName = t.getText().trim();
+			
+			if (need_file_sep_replace) {
+				dirName = dirName.replace("/",File.separator);
+			}
+			
+			boolean isSpecialCase = dirName.startsWith(currentFramesetFlag);
+			File filePath = Paths.get(FrameIO.PARENT_FOLDER).resolve(dirName).toFile();
+			boolean locationExists = filePath.exists() && filePath.isDirectory();
+			if (isSpecialCase || locationExists) {
+				if (dirName.endsWith(File.separator)) {
+					dirsToAdd.add(dirName);
+				} else {
+					dirsToAdd.add(dirName + File.separator);
+				}
+			}
+		}
+		
 		return dirsToAdd;
 	}
@@ -1140,5 +1161,5 @@
 	 */	
 	public static void Parse(Frame toParse, boolean firstParse, boolean ignoreAnnotations) { 
-		List<String> accessList = Label.getAccessibleLabelsNames(new ItemsList(toParse.getPrimaryBody()));
+		List<String> accessList = Label.getAccessibleLabelsNames(toParse.getPrimaryBody());
 		
 		ItemsList primaries = toParse.getPrimaryBody();
@@ -1150,7 +1171,6 @@
 		toParse.getInteractableItems().clear();
 		List<Item> newBody = parseFromPrimary(primaries, accessList);
-		toParse.getBody().clear();
-		toParse.getBody().addAll(newBody);
-		generatingSupportingItems(toParse, toParse.getBody(), ignoreAnnotations);
+		toParse.setBody(newBody, accessList);
+		generatingSupportingItems(toParse, toParse.getBody(false), ignoreAnnotations);
 		
 		if (firstParse) {
@@ -1587,5 +1607,5 @@
 		CreateDefaultProfile(profileFor, profile, null, null);
 	}
-
+		
 	/**
 	 * Copies the content from the default profile to the specified profile.
@@ -1610,5 +1630,12 @@
 				try {
 					// If we do not have a default to copy, create one.
+					String existingUsername = UserSettings.UserName.get();
+					UserSettings.UserName.set("default");
+					FrameIO.changeParentAndSubFolders(FrameIO.PARENT_FOLDER);
+					UserSettings.setupDefaultFolders();
 					defaultFrame = FrameIO.CreateNewProfile(UserSettings.DEFAULT_PROFILE_NAME, null, null);
+					UserSettings.UserName.set(existingUsername);
+					FrameIO.changeParentAndSubFolders(FrameIO.PARENT_FOLDER);
+					UserSettings.setupDefaultFolders();
 				} catch (InvalidFramesetNameException invalidNameEx) {
 					MessageBay.errorMessage("Failed to create default profile named: "
@@ -1685,111 +1712,5 @@
 			}
 			MessageBay.suppressMessages(false);
-		} else {
-			title.setText("Default Profile Frame");
-			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.getSortedItems(), "@HelpIndex") != null) {
-							// yPos += spacing;
-							yPos += 30;
-							t = profile.addText(xPos, yPos, '@' + indexFrame.getFramesetName(), null);
-							t.setLink(indexFrame.getName());
-							t.setColor(Colour.GREY);
-						}
-					}
-					System.out.println();
-				}
-			}
-
-			xPos = 50;
-			yPos = 100;
-
-			// Populate Start Pages and Settings
-			File framesetDirectory = new File(FrameIO.FRAME_PATH);
-
-			if (framesetDirectory.exists()) {
-				File[] startpagesFramesets = framesetDirectory.listFiles();
-
-				if (startpagesFramesets != null) {
-					// Add Start Page title
-					Text templates = profile.addText(xPos, yPos, "@Start Pages", null);
-					templates.setSize(25);
-					templates.setFontStyle("Bold");
-					templates.setFamily("SansSerif");
-					templates.setColor(TemplateSettings.ColorWheel.get()[3]);
-
-					xPos += 25;
-
-					// Start Pages should be the first frame in its own frameset +
-					// frameset name should be present in FrameUtils.startPages[].
-					for (File startpagesFrameset : startpagesFramesets) {
-						String framesetName = startpagesFrameset.getName();
-
-						// Only add link if frameset is a startpage
-						for (int i = 0; i < startPages.length; i++) {
-							if (framesetName.equals(startPages[i])) {
-								Frame indexFrame = FrameIO.LoadFrame(framesetName + '1');
-
-								// Add start page link
-								if (indexFrame != null) {
-									yPos += 30;
-									t = profile.addText(xPos, yPos, '@' + indexFrame.getFramesetName(), null);
-									t.setLink(indexFrame.getName());
-									t.setColor(Colour.GREY);
-								}
-							}
-						}
-					}
-				}
-			}
-
-			FrameIO.SaveFrame(profile);
-
-			// Populate settings frameset
-			Settings.Init();
-			t = profile.addText(550, 100, "@Settings", null);
-			t.setSize((float) 25.0);
-			t.setFamily("SansSerif");
-			t.setFontStyle("Bold");
-			t.setColor(Colour.GREY);
-			Settings.generateSettingsTree(t);
-			System.out.println("@Settings: Default settings generation complete.");
-
-			FrameIO.SaveFrame(profile);
-		}
+		} 
 	}
 
Index: /trunk/src/org/expeditee/gui/ItemsList.java
===================================================================
--- /trunk/src/org/expeditee/gui/ItemsList.java	(revision 1433)
+++ /trunk/src/org/expeditee/gui/ItemsList.java	(revision 1434)
@@ -71,5 +71,5 @@
 	}
 	
-	public void retainHistory(ItemsList historyItems) {
+	public void retainAll(ItemsList historyItems) {
 		items.retainAll(historyItems.items);
 	}
Index: /trunk/src/org/expeditee/gui/MessageBay.java
===================================================================
--- /trunk/src/org/expeditee/gui/MessageBay.java	(revision 1433)
+++ /trunk/src/org/expeditee/gui/MessageBay.java	(revision 1434)
@@ -222,5 +222,5 @@
 	/** TODO: Comment. cts16 */
 	public synchronized static Text displayMessage(String message, String link, Colour color, boolean displayAlways,
-			String action) {
+			String action) {	
 		List<String> actions = new LinkedList<String>();
 		if (action != null) {
Index: /trunk/src/org/expeditee/gui/management/ProfileManager.java
===================================================================
--- /trunk/src/org/expeditee/gui/management/ProfileManager.java	(revision 1434)
+++ /trunk/src/org/expeditee/gui/management/ProfileManager.java	(revision 1434)
@@ -0,0 +1,281 @@
+package org.expeditee.gui.management;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+import org.expeditee.agents.ExistingFramesetException;
+import org.expeditee.agents.InvalidFramesetNameException;
+import org.expeditee.core.Colour;
+import org.expeditee.core.Point;
+import org.expeditee.gui.Frame;
+import org.expeditee.gui.FrameIO;
+import org.expeditee.gui.MessageBay;
+import org.expeditee.items.Item;
+import org.expeditee.items.ItemUtils;
+import org.expeditee.items.Text;
+import org.expeditee.setting.Setting;
+import org.expeditee.settings.Settings;
+import org.expeditee.settings.UserSettings;
+import org.expeditee.settings.templates.TemplateSettings;
+
+public class ProfileManager {
+
+	private static final String USER_NAME_PATTERN_INTERNAL = "USER.NAME";
+	private static final String DEFAULT = UserSettings.DEFAULT_PROFILE_NAME;
+	private static final String[] startPages = { "exploratorysearch", "webbrowser" };
+	public static final String USER_NAME_PATTERN = "${" + USER_NAME_PATTERN_INTERNAL + "}";
+
+	public static Frame createProfile(String profileFor, Map<String, Setting> specifiedSettings,
+			Map<String, Consumer<Frame>> notifyWhenGenerated) {
+		ensureDefaultProfile();
+		Frame profile = null;
+		Frame profileOne = null;
+		profileFor = FrameIO.ConvertToValidFramesetName(profileFor);
+		
+		try {
+			profile = FrameIO.CreateFrameset(profileFor, FrameIO.PROFILE_PATH, true);
+			profileOne = profile;
+			profile.setTitle(profileFor + "'s Profile");
+			Frame defaultFrame = FrameIO.LoadFrame(DEFAULT + "1");
+			MessageBay.suppressMessages(true);
+			UserSettings.UserName.set(profileFor);
+			UserSettings.ProfileName.set(profileFor);
+			
+			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(DEFAULT + 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 instance of ${USER.NAME} with 'profileFor'
+				// 4. Replace settings values of copied items with those specified in
+				// specifiedSettings (if present)
+				Collection<Item> defaultAllItems = defaultFrame.getAllItems();
+				Collection<Item> allItems = new ArrayList<Item>();
+				for (Item item: defaultAllItems) {
+					Item copyItem = item.copy();
+					allItems.add(copyItem);
+				}
+				profile.addAllItems(allItems);
+				
+				for (Item item: profile.getAllItems()) {
+					if (item instanceof Text) {
+						String content = item.getText();
+						item.setText(ResourceUtil.substitute(content, ProfileManager.USER_NAME_PATTERN_INTERNAL, profileFor));
+					}
+				}
+				
+				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, 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);
+						});
+					}
+				}
+				if (notifyWhenGenerated != null && notifyWhenGenerated.containsKey(category)) {
+					notifyWhenGenerated.get(category).accept(profile);
+				}
+				
+				FrameIO.SaveFrame(profile);
+			}
+			MessageBay.suppressMessages(false);
+		} catch (InvalidFramesetNameException | ExistingFramesetException e) {
+			String preamble = "Failed to create profile for '" + DEFAULT + "'. ";
+			if (e instanceof InvalidFramesetNameException) {
+				String message = preamble + "Profile names must start and end with a letter and must contain only letters and numbers";
+				MessageBay.errorMessage(message);
+			} else if (e instanceof ExistingFramesetException) {
+				String message = preamble + "A frameset with this name already exists in: " + FrameIO.PROFILE_PATH;
+				MessageBay.errorMessage(message);
+			}
+		}
+		
+		return profileOne;
+	}
+
+	/**
+	 * Checks if the default profile exists, creates it if it does not.
+	 */
+	public static void ensureDefaultProfile() {
+		// If we can load in the default profile, we have nothing to do.
+		Frame defaultFrame = FrameIO.LoadProfile(DEFAULT);
+		if (defaultFrame != null) {
+			return;
+		}
+		
+		// We do not have a default profile, generate one.
+		createDefaultProfile();
+	}
+
+	/**
+	 * Creates the default profile.
+	 */
+	private static void createDefaultProfile() {
+		try {
+			Frame profile = FrameIO.CreateFrameset(DEFAULT, FrameIO.PROFILE_PATH, true);
+			
+			// Give the first frame in the new profile an appropriate title.
+			Text titleItem = profile.getTitleItem();
+			if (titleItem != null) {
+				titleItem.setText("Default Profile Frame");
+			}
+			
+			// initial position for placing items.
+			int xPos = 300;
+			int yPos = 100;
+			
+			// Add documentation links
+			Path helpDirectory = Paths.get(FrameIO.HELP_PATH);
+			File[] helpFramesets = helpDirectory.toFile().listFiles();
+			if (helpFramesets != null) {
+				// Add the title for the help index
+				Text helpPagesTitle = profile.addText(xPos, yPos, "@Expeditee Help", null);
+				helpPagesTitle.setSize(25);
+				helpPagesTitle.setFontStyle("Bold");
+				helpPagesTitle.setFamily("SansSerif");
+				helpPagesTitle.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.getSortedItems(), "@HelpIndex") != null) {
+						// yPos += spacing;
+						yPos += 30;
+						Text helpLink = profile.addText(xPos, yPos, '@' + indexFrame.getFramesetName(), null);
+						helpLink.setLink(indexFrame.getName());
+						helpLink.setColor(Colour.GREY);
+					}
+				}
+				System.out.println();
+			}
+			
+			// Reset position
+			xPos = 50;
+			yPos = 100;
+			
+			// Add start pages
+			Path framesetDirectory = Paths.get(FrameIO.FRAME_PATH);
+			File[] startPageFramesets = framesetDirectory.toFile().listFiles();
+			if (startPageFramesets != null) {
+				// Add Start Page title
+				Text startPagesTitle = profile.addText(xPos, yPos, "@Start Pages", null);
+				startPagesTitle.setSize(25);
+				startPagesTitle.setFontStyle("Bold");
+				startPagesTitle.setFamily("SansSerif");
+				startPagesTitle.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 : startPageFramesets) {
+					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;
+								Text startPageLink = profile.addText(xPos, yPos, '@' + indexFrame.getFramesetName(), null);
+								startPageLink.setLink(indexFrame.getName());
+								startPageLink.setColor(Colour.GREY);
+							}
+						}
+					}
+				}
+			}
+
+			// Add 'default' settings frameset
+			Settings.Init();
+			Text settingsLink = profile.addText(550, 100, "@Settings", null);
+			settingsLink.setSize((float) 25.0);
+			settingsLink.setFamily("SansSerif");
+			settingsLink.setFontStyle("Bold");
+			settingsLink.setColor(Colour.GREY);
+			Settings.generateSettingsTree(settingsLink);
+			System.out.println("@Settings: Default settings generation complete.");
+
+			FrameIO.SaveFrame(profile);
+			
+			int lastNumber = FrameIO.getLastNumber(profile.getFramesetName());
+			for (int i  = 1; i <= lastNumber; i++) {
+				Frame frame = FrameIO.LoadFrame(DEFAULT + i);
+				frame.setOwner(DEFAULT);
+				for(Item item: frame.getAllItems()) {
+					item.setOwner(DEFAULT);
+					item.setRelativeLink();
+				}
+				frame.setChanged(true);
+				FrameIO.SaveFrame(frame);
+			}
+			
+		} catch (InvalidFramesetNameException | ExistingFramesetException e) {
+			String preamble = "Failed to create profile for '" + DEFAULT + "'. ";
+			if (e instanceof InvalidFramesetNameException) {
+				String message = preamble + "Profile names must start and end with a letter and must contain only letters and numbers";
+				MessageBay.errorMessage(message);
+			} else if (e instanceof ExistingFramesetException) {
+				String message = preamble + "A frameset with this name already exists in: " + FrameIO.PROFILE_PATH;
+				MessageBay.errorMessage(message);
+			}
+			return;
+		}
+	}
+}
Index: /trunk/src/org/expeditee/gui/management/ResourceManager.java
===================================================================
--- /trunk/src/org/expeditee/gui/management/ResourceManager.java	(revision 1434)
+++ /trunk/src/org/expeditee/gui/management/ResourceManager.java	(revision 1434)
@@ -0,0 +1,304 @@
+package org.expeditee.gui.management;
+
+import java.io.File;import java.io.FileFilter;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.Frame;
+import org.expeditee.gui.FrameIO;
+import org.expeditee.gui.FrameUtils;
+import org.expeditee.items.Picture;
+import org.expeditee.items.Text;
+import org.expeditee.network.FrameShare;
+import org.expeditee.setting.DirectoryListSetting;
+import org.expeditee.settings.folders.FolderSettings;
+
+public class ResourceManager {
+	
+	private static boolean commonInvalidated = false;
+	private static ResourceManager instance = new ResourceManager();
+	private static ResolvedDirectoryList frames = instance.new ResolvedDirectoryList(FolderSettings.FrameDirs);
+	private static ResolvedDirectoryList images = instance.new ResolvedDirectoryList(FolderSettings.ImageDirs);
+	private static ResolvedDirectoryList audio = instance.new ResolvedDirectoryList(FolderSettings.AudioDirs);
+	
+	public static void invalidateAllResourceDirectories() {
+		commonInvalidated = true;
+	}
+	
+	private static void refreshAll() {
+		Frame currentFrame = DisplayController.getCurrentFrame();
+		String framesetPath = currentFrame == null ? null : currentFrame.getFramesetPath();
+		frames.refresh(framesetPath);
+		images.refresh(framesetPath);
+		audio.refresh(framesetPath);
+	}
+	
+	/**
+	 * Creates a Frame object from an associated resour
+	 * @param frameName
+	 * @param knownPath
+	 * @param ignoreAnnotationsOnParse
+	 * @return
+	 */
+	public static Frame getExpediteeFrame(String frameName, String knownPath, boolean ignoreAnnotationsOnParse) {
+		Frame loaded = null;
+		if (knownPath != null) {
+			return FrameIO.LoadKnownPath(knownPath, frameName);
+		} else {
+			List<String> canditateDirectoriesForResource = frames.getDirectories();
+			for (String path: canditateDirectoriesForResource) {
+				loaded = FrameIO.LoadKnownPath(path, frameName);
+				if (loaded != null) {
+					break;
+				}
+			}
+		}
+		
+		if (loaded == null && FrameShare.getInstance() != null) {
+			loaded = FrameShare.getInstance().loadFrame(frameName, knownPath);
+		}
+		
+		if (loaded != null) {
+			FrameUtils.Parse(loaded, true, ignoreAnnotationsOnParse);
+			FrameIO.setSavedProperties(loaded);
+		}
+		
+		return loaded;
+	}
+	
+	/**
+	 * Creates a picture object from the information stored in the given Text
+	 * object.
+	 * @param source 
+	 * The Text file containing the information for sourcing and displaying the information.
+	 * @param tryRemote
+	 * True if the FrameShare should be consulted to source the image after local locations
+	 * have failed to find the corresponding file.
+	 * @return
+	 */
+	public static Picture getExpediteePicture(Text source, boolean tryRemote) {		
+		// Extract useful content from source text.
+		String content = source.getText().replaceFirst("@i:", "");
+		String path = "";
+		String size = "";
+		String fileName = "";
+		content = content.replaceAll("\n", "");
+		content = content.trim();
+		
+		// Image file names must contain a '.' to separate the file name from extension.
+		int fileSuffixCharIndex = content.indexOf('.');
+		if (fileSuffixCharIndex < 0) {
+			return null;
+		}
+		// Separate the path to resource file from additional information.
+		int endOfFileNameIndex = content.indexOf(' ', fileSuffixCharIndex);
+		if (endOfFileNameIndex < 0) {
+			path = content;
+			size = "";
+		} else {
+			path = content.substring(0, endOfFileNameIndex);
+			size = content.substring(endOfFileNameIndex).trim();
+		}
+		fileName = path;
+		
+		// Redacted images are generated in memory as noise rather than being 
+		// associated with a specific resource on the file system.  Therefore,
+		// no more work is required.
+		if (fileName.equals(Picture.REDACTED_IMAGE_NAME)) {
+			return new Picture(source, fileName, path, size);
+		}
+		
+		// Having gotten to this point, we now have to find the resource described
+		// by this Expeditee Text Item.
+		List<String> canditateDirectoriesForResource = images.getDirectories(source);
+		
+		// First try finding the resource in the directories specified by the 
+		// users settings frame.
+		File resourceFile = null;
+		for (String dir: canditateDirectoriesForResource) {
+			resourceFile = new File(dir + path);
+			if (resourceFile.exists() && !resourceFile.isDirectory()) {
+				break;
+			}
+		}
+		
+		// At this point, if resourceFile is pointing to a file object that
+		// either doesn't exist or is a directory, then we have not been able
+		// to find the correct file.
+		//
+		// If the correct file is out there then two more possibilities:
+		// a. The text Item is specifying an absolute path or,
+		// b. The text Item is specifying a path relative to this java project.
+		//		These are of the format "/packageA/packageB/filename".  For
+		//		example: "/org/expeditee/gui.management/ResourceManager.java"
+		//
+		// Bryce: Do we want to allow for the option of 
+		// it being a path relative to expeditee.home?
+		if (resourceFile == null || !resourceFile.exists() || resourceFile.isDirectory()) {
+			// Prepare for case a.
+			resourceFile = new File(path);
+		}
+		
+		if (!resourceFile.exists() || resourceFile.isDirectory()) {
+			// We are not looking at an absolute path so check option b.
+			URL resourceFileURL = ResourceManager.class.getResource(path);
+			
+			// Decode to remove %20 in Windows folder names
+			if (resourceFileURL != null) {
+				try {
+					path = URLDecoder.decode(resourceFileURL.getFile(), "UTF-8");
+				} catch (UnsupportedEncodingException e) {
+					e.printStackTrace();
+				}
+			}
+		} else {
+			// We are looking at an absolute path, option a.
+			path = resourceFile.getPath();
+		}
+		
+		// At this point, the resource has not been found locally.  One last
+		// option is that the FrameShare might be able to help us.
+		resourceFile = new File(path);
+		if (!resourceFile.exists() || resourceFile.isDirectory()) {
+			if (tryRemote && FrameShare.getInstance().loadImage(fileName, null)) {
+				// Recursive call, but with try remote as false.
+				// The above call to the FrameShare should have gotten us a local copy.
+				return getExpediteePicture(source, false);
+			} else {
+				return null;
+			}
+		}
+		
+		// If we have gotten here, we should have found the correct resourceFile
+		return new Picture(source, fileName, path, size);
+	}
+	
+	/**
+	 * Gets the audio file named 'localFileName' on the file system.  Searches
+	 * the locations listed in the users settings frame.
+	 * @param localFileName
+	 * @param parentFrame
+	 * @return
+	 */
+	public static File getAudioResource(String localFileName, Frame parentFrame) {
+		List<String> directories = audio.getDirectories(parentFrame);
+		for (String directory: directories) {
+			Path pathToFile = Paths.get(directory).resolve(localFileName);
+			File file = pathToFile.toFile();
+			if (file.exists() && !file.isDirectory()) {
+				return file;
+			}
+		}
+		
+		return null;
+	}
+	
+	/**
+	 * Gets all the audio files that match the given predicate 'includeFile'.
+	 * @param includeFile
+	 * @param parentFrame
+	 * @return
+	 */
+	public static List<File> gatherAudioResources(Predicate<File> includeFile, Frame parentFrame) {
+		List<String> directories = audio.getDirectories(parentFrame);
+		List<File> results = new ArrayList<File>();
+		for (String directory: directories) {
+			File dir = new File(directory);
+			if (dir.exists()) {
+				File[] canditates = dir.listFiles();
+				for (File f: canditates) {
+					if (!f.isDirectory() && includeFile.test(f)) {
+						results.add(f);
+					}
+				}
+			}
+		}
+		return results;
+	}
+	
+	private class ResolvedDirectoryList {
+		private List<String> directories = null;
+		private String contextFramesetPath = null;
+		private DirectoryListSetting source;
+		
+		public ResolvedDirectoryList(DirectoryListSetting source) {
+			this.source = source;			
+		}
+		
+		public List<String> getDirectories(Text context) {
+			return getDirectories(context.getParentOrCurrentFrame());
+		}
+		
+		public List<String> getDirectories(Frame context) {
+			String contextPath = context == null ? null : context.getFramesetPath();
+			return getDirectories(contextPath);
+		}
+		
+		public List<String> getDirectories() {
+			return getDirectories("");
+		}
+		
+		private List<String> getDirectories(String context) { 
+			if (commonInvalidated) {
+				ResourceManager.refreshAll();
+			} else { 
+				boolean isInitialSet = contextFramesetPath == null && context != null;
+				boolean settingToNull = context == null && contextFramesetPath != null;
+				boolean requiresRefresh = isInitialSet || settingToNull || !contextFramesetPath.equals(context); 
+				if (requiresRefresh) {
+					refresh(context);
+				}
+			}
+							
+			return directories;
+		}
+		
+		private void refresh(String context) {
+			List<String> unresolved = source.getAbsoluteDirs();
+			directories = resolve(unresolved, context);
+			contextFramesetPath = context;
+		}
+		
+		private List<String> resolve(List<String> unresolved, String context) {
+			if (context == null) {
+				return resolveWithNullContext(unresolved);
+			} 
+			
+			List<String> resolved = new ArrayList<String>();
+			
+			if (unresolved == null) {
+				return resolved;
+			}
+			
+			for (String s: unresolved) {
+				String local = ResourceUtil.substitute(s, ResourceUtil.CURRENT_FRAMESET_FLAG, context);
+				resolved.add(local);
+			}
+			return resolved;			
+		}
+		
+		private List<String> resolveWithNullContext(List<String> unresolved) {
+			List<String> resolved = new ArrayList<String>();
+			
+			if (unresolved == null) {
+				return resolved;
+			}
+			
+			for (String s: unresolved) {
+				String local = ResourceUtil.substitute(s, ResourceUtil.CURRENT_FRAMESET_FLAG, "ERROR.");
+				if (s.equals(local)) {
+					resolved.add(local);
+				}
+			}
+			
+			return resolved;
+		}
+	}
+}
Index: /trunk/src/org/expeditee/gui/management/ResourceUtil.java
===================================================================
--- /trunk/src/org/expeditee/gui/management/ResourceUtil.java	(revision 1434)
+++ /trunk/src/org/expeditee/gui/management/ResourceUtil.java	(revision 1434)
@@ -0,0 +1,76 @@
+package org.expeditee.gui.management;
+
+public class ResourceUtil {
+	
+	private static final char PATTERN_START_TWO = '{';
+	private static final char PATTERN_START_ONE = '$';
+	private static final char PATTERN_END = '}';
+	private static final char ESCAPE = '\\';
+
+	public static final String CURRENT_FRAMESET_FLAG = "${CURRENT_FRAMESET}";
+	public static final String CURRENT_USER = "${CURRENT_USER}";
+	
+	/**
+	 * Utility function that transforms a input string to a output string.
+	 * Any occurances of 'pattern' are replaced with 'replacement'.
+	 * \ is used as the escape key.
+	 * @param input The raw input
+	 * @param pattern The pattern to replace.  
+	 * This will be prepended by in ${ and appended by } in the input string.
+	 * @param replacement The replacement content to use.
+	 * @return The transformed string.
+	 */
+	protected static String substitute(String input, String pattern, String replacement) {		
+		StringBuilder outputSB = new StringBuilder();
+		StringBuilder inputSB = new StringBuilder(input.replace("\\", "\\\\") + ResourceUtil.ESCAPE);
+		StringBuilder patternSB = new StringBuilder();
+		boolean inPattern = false;
+		boolean patternStartPossible = true;
+		
+		int index = 0;
+		int length = inputSB.length() - 1;
+		while (index < length) {
+			char c = inputSB.charAt(index);
+			boolean startingPattern = patternStartPossible && 
+					c == ResourceUtil.PATTERN_START_TWO &&
+					outputSB.charAt(outputSB.length() - 1) == ResourceUtil.PATTERN_START_ONE;
+			boolean endingPattern = c == ResourceUtil.PATTERN_END;
+			
+			if (c == ResourceUtil.ESCAPE && !inPattern) {
+				index++;
+				c = inputSB.charAt(index);
+				outputSB.append(c);
+				if (c == PATTERN_START_ONE) {
+					patternStartPossible = false;
+				}
+			} else if (inPattern && endingPattern) {
+				String patternFound = patternSB.toString();
+				if (patternFound.equals(pattern)) {
+					outputSB.append(replacement);
+				} else {
+					outputSB.append("" + ResourceUtil.PATTERN_START_ONE + ResourceUtil.PATTERN_START_TWO);
+					outputSB.append(patternFound);
+					outputSB.append(ResourceUtil.PATTERN_END);
+				}
+				inPattern = false;
+				patternSB = new StringBuilder();
+			} else if (!inPattern && startingPattern) {
+				outputSB.deleteCharAt(outputSB.length() - 1);
+				inPattern = true;
+			} else if (inPattern) {
+				patternSB.append(c);
+			} else {
+				outputSB.append(c);
+				patternStartPossible = true;
+			}
+			
+			index++;
+		}
+		
+		if (patternSB.length() > 0) {
+			outputSB.append("${");
+		}
+		outputSB.append(patternSB);
+		return outputSB.toString();
+	}
+}
Index: /trunk/src/org/expeditee/items/ItemUtils.java
===================================================================
--- /trunk/src/org/expeditee/items/ItemUtils.java	(revision 1433)
+++ /trunk/src/org/expeditee/items/ItemUtils.java	(revision 1434)
@@ -39,4 +39,5 @@
 import org.expeditee.gui.FreeItems;
 import org.expeditee.gui.Vector;
+import org.expeditee.gui.management.ResourceManager;
 import org.expeditee.items.Item.HighlightMode;
 import org.expeditee.items.widgets.InteractiveWidgetInitialisationFailedException;
@@ -376,87 +377,91 @@
 	 */
 	public static Picture CreatePicture(Text source, boolean tryRemote) {
-		String text = source.getText();
-		String path = "";
-		String fileName = "";
-		String size = "";
-
-		try {
-			// remove @i tag
-			text = text.replaceFirst("@i:", "");
-			text = text.replaceAll("\n", "");
-			text = text.trim();
-
-			int fileSuffixChar = text.indexOf('.');
-			if (fileSuffixChar < 0) {
-				return null;
-			}
-			int endOfFileName = text.indexOf(' ', fileSuffixChar);
-			if (endOfFileName < 0) {
-				path = text;
-				size = "";
-			} else {
-				path = text.substring(0, endOfFileName);
-				size = text.substring(endOfFileName).trim();
-			}
-			fileName = path;
-			
-			if (!fileName.equals(Picture.REDACTED_IMAGE_NAME)) {
-				// try images subdirectory
-				File file = null;
-
-				for (String dir : FolderSettings.ImageDirs.getAbsoluteDirs()) {
-					file = new File(dir + path);
-					if (file.exists() && !file.isDirectory()) {
-						break;
-					}
-				}
-
-				if (file == null || !file.exists() || file.isDirectory()) {
-					file = new File(path);
-				}
-
-				// try relative path
-				if (!file.exists() || file.isDirectory()) {
-					URL picture = new Object().getClass().getResource(path);
-
-					// decode to remove %20 in windows folder names
-					if (picture != null) {
-						try {
-							path = URLDecoder.decode(picture.getFile(), "UTF-8");
-						} catch (UnsupportedEncodingException e) {
-							// TODO Auto-generated catch block
-							e.printStackTrace();
-						}
-					}
-
-				} else {
-					path = file.getPath();
-				}
-
-				// if the image isn't found by now, try remote servers
-				file = new File(path);
-				if (!file.exists() || file.isDirectory()) {
-	       			if(tryRemote && FrameShare.getInstance().loadImage(fileName, null)) {
-	       				// call CreatePicture again, but with tryRemote set to false so we won't get into an infinite loop
-	       				// if something goes wrong with finding the downloaded image
-	       				return CreatePicture(source, false);
-	       			}
-					return null;
-				}
-			}
-		} catch (Exception e) {
-			return null;
-		}
-
-		try {
-			Picture pic = new Picture(source, fileName, path, size);
-
-			return pic;
-		} catch (Exception e) {
-			e.printStackTrace();
-			return null;
-		}
-
-	}
+		return ResourceManager.getExpediteePicture(source, tryRemote);
+	}
+//	public static Picture CreatePicture(Text source, boolean tryRemote) {
+//		String text = source.getText();
+//		String path = "";
+//		String fileName = "";
+//		String size = "";
+//
+//		try {
+//			// remove @i tag
+//			text = text.replaceFirst("@i:", "");
+//			text = text.replaceAll("\n", "");
+//			text = text.trim();
+//
+//			int fileSuffixChar = text.indexOf('.');
+//			if (fileSuffixChar < 0) {
+//				return null;
+//			}
+//			int endOfFileName = text.indexOf(' ', fileSuffixChar);
+//			if (endOfFileName < 0) {
+//				path = text;
+//				size = "";
+//			} else {
+//				path = text.substring(0, endOfFileName);
+//				size = text.substring(endOfFileName).trim();
+//			}
+//			fileName = path;
+//			
+//			if (!fileName.equals(Picture.REDACTED_IMAGE_NAME)) {
+//				// try images subdirectory
+//				File file = null;
+//
+//				List<String> absoluteDirs = FolderSettings.ImageDirs.getAbsoluteDirs();
+//				for (String dir : absoluteDirs) {
+//					file = new File(dir + path);
+//					if (file.exists() && !file.isDirectory()) {
+//						break;
+//					}
+//				}
+//
+//				if (file == null || !file.exists() || file.isDirectory()) {
+//					file = new File(path);
+//				}
+//
+//				// try relative path
+//				if (!file.exists() || file.isDirectory()) {
+//					URL picture = new Object().getClass().getResource(path);
+//
+//					// decode to remove %20 in windows folder names
+//					if (picture != null) {
+//						try {
+//							path = URLDecoder.decode(picture.getFile(), "UTF-8");
+//						} catch (UnsupportedEncodingException e) {
+//							// TODO Auto-generated catch block
+//							e.printStackTrace();
+//						}
+//					}
+//
+//				} else {
+//					path = file.getPath();
+//				}
+//
+//				// if the image isn't found by now, try remote servers
+//				file = new File(path);
+//				if (!file.exists() || file.isDirectory()) {
+//	       			if(tryRemote && FrameShare.getInstance().loadImage(fileName, null)) {
+//	       				// call CreatePicture again, but with tryRemote set to false so we won't get into an infinite loop
+//	       				// if something goes wrong with finding the downloaded image
+//	       				return CreatePicture(source, false);
+//	       			}
+//					return null;
+//				}
+//			}
+//		} catch (Exception e) {
+//			return null;
+//		}
+//
+//		try {
+//			Picture pic = new Picture(source, fileName, path, size);
+//
+//			return pic;
+//		} catch (Exception e) {
+//			e.printStackTrace();
+//			return null;
+//		}
+//
+//	}
 	
 	public static Picture CreatePicture(Text source) {
Index: /trunk/src/org/expeditee/items/XRayable.java
===================================================================
--- /trunk/src/org/expeditee/items/XRayable.java	(revision 1433)
+++ /trunk/src/org/expeditee/items/XRayable.java	(revision 1434)
@@ -27,4 +27,5 @@
 import org.expeditee.encryption.items.surrogates.Label;
 import org.expeditee.gui.DisplayController;
+import org.expeditee.gui.Frame;
 
 public abstract class XRayable extends Item {
@@ -59,5 +60,6 @@
 			return true;
 		} else {
-			List<String> accessibleLabelsNames = Label.getAccessibleLabelsNames(this.getParent().getBody());
+			Frame parent = this.getParent();
+			List<String> accessibleLabelsNames = Label.getAccessibleLabelsNames(parent.getBody(true));
 			return accessibleLabelsNames.contains(encryptionLabel);
 		}
Index: /trunk/src/org/expeditee/setting/DirectoryListSetting.java
===================================================================
--- /trunk/src/org/expeditee/setting/DirectoryListSetting.java	(revision 1433)
+++ /trunk/src/org/expeditee/setting/DirectoryListSetting.java	(revision 1434)
@@ -3,7 +3,10 @@
 import java.io.File;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
+import org.expeditee.gui.DisplayController;
 import org.expeditee.gui.FrameIO;
 import org.expeditee.gui.FrameUtils;
@@ -11,5 +14,5 @@
 
 public class DirectoryListSetting extends ListSetting<String> {
-
+		
 	/*
 	public DirectoryListSetting(String tooltip, String name, List<String> value) {
@@ -23,8 +26,12 @@
 	@Override
 	public boolean setSetting(Text text) {
-		_value.addAll(FrameUtils.getDirs(text));
+		List<String> dirs = FrameUtils.getDirs(text);
+		if (!dirs.isEmpty()) {
+			_value.clear();
+			_value.addAll(dirs);
+		}
 		return true;
 	}
-
+	
 	public List<String> getAbsoluteDirs() {
 		String parent_folder = FrameIO.PARENT_FOLDER;
@@ -44,8 +51,6 @@
 				// => use it 'as is'
 				abs = rel;
-			}
-			else {
-				abs = parent_folder + rel;
-				
+			} else {
+				abs = parent_folder + rel;	
 			}
 			value_absolute_dir.add(abs);
Index: /trunk/src/org/expeditee/setting/ListSetting.java
===================================================================
--- /trunk/src/org/expeditee/setting/ListSetting.java	(revision 1433)
+++ /trunk/src/org/expeditee/setting/ListSetting.java	(revision 1434)
@@ -26,4 +26,5 @@
 import org.expeditee.gui.FrameIO;
 import org.expeditee.items.Text;
+import org.expeditee.settings.UserSettings;
 
 public abstract class ListSetting<T> extends VariableSetting {
@@ -68,6 +69,6 @@
 			listFrame.getTitleItem().delete();
 			
-			int x = 100;
-			int y = 100;
+			int x = UserSettings.TitlePosition.get();
+			int y = UserSettings.TitlePosition.get();
 			for (T v: _value) {
 				if (v == null) continue;
Index: /trunk/src/org/expeditee/settings/Settings.java
===================================================================
--- /trunk/src/org/expeditee/settings/Settings.java	(revision 1433)
+++ /trunk/src/org/expeditee/settings/Settings.java	(revision 1434)
@@ -21,4 +21,5 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -30,4 +31,5 @@
 import org.expeditee.gui.Frame;
 import org.expeditee.gui.FrameCreator;
+import org.expeditee.gui.FrameIO;
 import org.expeditee.gui.MessageBay;
 import org.expeditee.items.Item;
@@ -145,5 +147,6 @@
 		List<VariableSetting> set = new LinkedList<VariableSetting>();
 		
-		Frame child = text.getChild();
+		String linkForChild = text.getAbsoluteLink();
+		Frame child = FrameIO.LoadFrame(linkForChild, FrameIO.PROFILE_PATH);
 		
 		if(child == null) return set;
Index: /trunk/src/org/expeditee/settings/UserSettings.java
===================================================================
--- /trunk/src/org/expeditee/settings/UserSettings.java	(revision 1433)
+++ /trunk/src/org/expeditee/settings/UserSettings.java	(revision 1434)
@@ -35,4 +35,5 @@
 import org.expeditee.gui.FrameUtils;
 import org.expeditee.gui.MessageBay;
+import org.expeditee.gui.management.ProfileManager;
 import org.expeditee.items.Text;
 import org.expeditee.setting.BooleanSetting;
@@ -42,4 +43,5 @@
 import org.expeditee.setting.IntegerSetting;
 import org.expeditee.setting.ListSetting;
+import org.expeditee.setting.Setting;
 import org.expeditee.setting.StringSetting;
 import org.expeditee.settings.folders.FolderSettings;
@@ -52,5 +54,5 @@
 public abstract class UserSettings {
 	
-	public static String DEFAULT_PROFILE_NAME = "default";
+	public static final String DEFAULT_PROFILE_NAME = "default";
 	 
 	public static Boolean PublicAndPrivateResources;
@@ -66,6 +68,9 @@
 		@Override
 		public boolean setSetting(Text text) {
-    		if(text.getText().indexOf(':') == -1 || !text.hasLink()) {
-    			text.setLink(UserSettings.ProfileName.get() + "1");
+    		String profileName = UserSettings.ProfileName.get();
+			if(text.getText().indexOf(':') == -1 || !text.hasLink()) {
+				if (!profileName.equals(ProfileManager.USER_NAME_PATTERN)) {
+					text.setLink(profileName + "1");
+				}
     			//text.setLink(FrameIO.LoadProfile(UserSettings.ProfileName.get()).getName());
     		}
@@ -79,5 +84,5 @@
     			// MessageBay.warningMessage("Home frame: " + first
     			// + " is not a valid frame.");
-    			_value = FrameIO.LoadProfile(UserSettings.ProfileName.get()).getName();
+    			_value = profileName + "1";//FrameIO.LoadProfile(UserSettings.ProfileName.get()).getName();
     		}
     		return true;
@@ -104,7 +109,7 @@
 	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 UserName = new StringSetting("Profile name", FrameIO.ConvertToValidFramesetName(System.getProperty("user.name")));
-	
-	public static final StringSetting ProfileName = new StringSetting("Profile name", UserName.get());
+	public static final StringSetting UserName = new StringSetting("User name", "${USER.NAME}"); // FrameIO.ConvertToValidFramesetName(System.getProperty("user.name"))
+	
+	public static final StringSetting ProfileName = new StringSetting("Profile name", "${USER.NAME}");
 		
 	public static final BooleanSetting AntiAlias = new BooleanSetting("Whether anti-aliasing should be enabled", "AntiAlias", false);
@@ -246,7 +251,7 @@
 		if (PublicAndPrivateResources) {
 			FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.HELP_PATH);
-			FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.HELP_PRIVATE_PATH);
+			FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.HELP_USERNAME_PRIVATE_PATH);
 			FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.FRAME_PATH);
-			FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.FRAME_PRIVATE_PATH);
+			FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.FRAME_USERNAME_PRIVATE_PATH);
 			FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.MESSAGES_PATH);
 			if (AuthenticatorBrowser.isAuthenticated()) {
@@ -258,9 +263,9 @@
 			
 			FolderSettings.ImageDirs.addAbsoluteDir(FrameIO.IMAGES_PATH);
-			FolderSettings.ImageDirs.addAbsoluteDir(FrameIO.IMAGES_PRIVATE_PATH);
+			FolderSettings.ImageDirs.addAbsoluteDir(FrameIO.IMAGES_USERNAME_PRIVATE_PATH);
 			FolderSettings.ImageDirs.setDefault(FolderSettings.ImageDirs.get());
 			
 			FolderSettings.AudioDirs.addAbsoluteDir(FrameIO.AUDIO_PATH);
-			FolderSettings.AudioDirs.addAbsoluteDir(FrameIO.AUDIO_PRIVATE_PATH);
+			FolderSettings.AudioDirs.addAbsoluteDir(FrameIO.AUDIO_USERNAME_PRIVATE_PATH);
 			FolderSettings.AudioDirs.setDefault(FolderSettings.AudioDirs.get());
 		} else {
